Merge branch '2.0.x' of git.lyx.org:lyx into 2.0.x

This commit is contained in:
Jean-Marc Lasgouttes 2012-09-24 16:01:29 +02:00
commit a602f21dc4
48 changed files with 21578 additions and 22499 deletions

View File

@ -31784,7 +31784,8 @@ type "icon"
arg "dialog-show spellchecker"
\end_inset
starts the spell checking beginning from the current cursor position.
starts the spell checking from either the current cursor position or the
beginning of the currently selected text.
A sidebar will appear showing any incorrect (or unknown) word found, allowing
you to edit and replace it in a second line.
Whenever an unknown word is found, the word is highlighted and the text

View File

@ -32730,7 +32730,8 @@ arg "dialog-show spellchecker"
\end_inset
starten.
Die Prüfung beginnt an der Cursorposition.
Die Prüfung beginnt entweder an der aktuellen Cursorposition oder dem Beginn
des momentan markierten Textabschnitts.
Eine Seitenleiste erscheint und zeigt jedes falsche (oder unbekannte) gefundene
Wort an und erlaubt es diese zu korrigieren.
Wenn ein unbekanntes Wort gefunden wird, wird das Wort markiert und der
@ -35736,12 +35737,12 @@ Nicht-typographisches
\end_inset
Anführungszeichen Fügt dieses Anführungszeichen ein: ", unabhängig vom Anführung
szeichen-Stil der im Menü
szeichen-Stil der im Dialog
\family sans
Dokument\SpecialChar \menuseparator
Einstellungen
\family default
Dialog unter
unter
\family sans
Sprache
\family default
@ -35753,11 +35754,17 @@ Einfaches
\begin_inset space ~
\end_inset
Anführungszeichen Fügt dieses Anführungszeichen ein:
\begin_inset Quotes grs
\end_inset
Anführungszeichen Fügt ein einfaches Anführungszeichen im Anführungszeichenstil
ein, der im Dialog
\family sans
Dokument\SpecialChar \menuseparator
Einstellungen
\family default
unter
\family sans
Sprache
\family default
eingestellt ist.
\end_layout
\begin_layout Description
@ -35818,9 +35825,11 @@ Symbole
\end_inset
Erstellt eine Formel mit einer sogenannten tipa-Einfügung.
In diese kann man Befehle eingeben um phonetische Symbole der IPA zu erzeugen.
Für dieses Feature muss das LaTeX-Paket
Erstellt eine Einfügung, in die man Symbole des Internationalen Phonetischen
Alphabets (IPA) eingeben kann, und öffnet eine Symbolleiste, die einen
Großteil dieser Symbole bereitstellt.
Um dieses Feature mit traditionellem LaTeX nutzen zu können, muss das LaTeX-Pak
et
\series bold
tipa
\series default
@ -35838,34 +35847,13 @@ LaTeX-Paket ! tipa
\begin_inset Newline newline
\end_inset
Für weitere Informationen über dieses Feature siehe die Dokumentation von
\series bold
tipa,
\begin_inset CommandInset citation
LatexCommand cite
key "tipa"
\end_inset
\series default
und diese Wiki-Seite:
\begin_inset Newline newline
\end_inset
\begin_inset Flex URL
status open
\begin_layout Plain Layout
http://wiki.lyx.org/LyX/LinguistLyX
\end_layout
\end_inset
Weitere Informationen über dieses Feature bietet das Linguistik-Handbuch
unter
\family sans
Hilfe\SpecialChar \menuseparator
Spezielle Handbücher
\family default
.
\end_layout
\begin_layout Subsection

View File

@ -32135,7 +32135,11 @@ type "icon"
arg "dialog-show spellchecker"
\end_inset
inicia la revisión a partir de la posición del cursor.
inicia la revisión o a partir de la posición del cursor o a la
\lang english
beginning of the currently selected text
\lang spanish
.
Se muestra una ventana en la que aparece un cuadro con cualquier palabra
incorrecta o desconocida, que puedes reemplazar en el cuadro siguiente.
Siempre que se encuentra una palabra incorrecta el texto se desplaza hasta

View File

@ -33154,168 +33154,63 @@ name "sec:Correcteur-Orthographique"
\end_layout
\begin_layout Standard
LyX n'a pas lui-même de correcteur orthographique incorporé.
Il utilise plutôt un programme extérieur comme
\family typewriter
aspell
\family default
,
\family typewriter
ispell
\family default
,
\family typewriter
hspell
\family default
, ou encore
\family typewriter
pspell
\family default
.
Cette section suppose que vous avez déjà installé et configuré un de ces
programmes.
\family typewriter
aspell
\family default
peut être considéré comme le successeur de
\family typewriter
ispell
\family default
, il est donc préférable d'utiliser
\family typewriter
aspell
\family default
.
\family typewriter
hspell
\family default
est un correcteur orthographique en Hébreu.
Le correcteur orthographique utilisé et ses paramètres sont modifiés dans
le menu
\lang english
LyX has a built-in spell checker.
The menu
\family sans
\lang french
Outils\SpecialChar \menuseparator
Préférences
\family default
dans la rubrique
\family sans
Paramètres
\begin_inset space ~
\end_inset
de
\begin_inset space ~
\end_inset
langue
\family default
.
\end_layout
\begin_layout Standard
Avec LyX pour Windows, la case de sélection pour le programme de correction
orthographique est désactivée puisque seul
\family typewriter
aspell
\family default
peut être utilisé.
\end_layout
\begin_layout Standard
LyX est doté d'un correcteur orthographique intégré.
On appelle le correcteur orthographique à partir de la position courante
du curseur, soit en activant le menu
\family sans
Outils\SpecialChar \menuseparator
Correcteur
\begin_inset space ~
\end_inset
orthographique
\family default
, soit en cliquant sur le bouton
\lang english
, the key
\family sans
F7
\family default
or the toolbar button
\begin_inset Info
type "icon"
arg "dialog-show spellchecker"
\end_inset
de la barre d'outils, soit encore en utilisant le raccourci clavier
starts the spell checking beginning from either the current cursor position
or the beginning of the currently selected text.
A sidebar will appear showing any incorrect (or unknown) word found, allowing
you to edit and replace it in a second line.
Whenever an unknown word is found, the word is highlighted and the text
scrolled so that it is visible.
In the spellchecker sidebar, there is a box showing suggestions for a correctio
n, if any could be found.
Clicking on one of the corrections will copy it to the
\family sans
F7
Replacement
\family default
.
Une fenêtre latérale s'ouvre et montre tout mot incorrect ou inconnu trouvé.
Elle vous permet de le corriger ou de le remplacer.
Dès qu'un mot inconnu est trouvé, il est affiché et le texte défile pour
le rendre visible.
Dans la fenêtre latérale du correcteur orthographique, il y a une case
qui vous propose des suggestions de correction, si il en a trouvé.
En cliquant sur une de ces suggestions elle est recopiée dans le champ
\family sans
Remplace
\family default
r, en double-cliquant on effectue directement le remplacement.
Un mot inconnu du correcteur, mais qui serait correctement écrit, peut
être ajouté à votre dictionnaire personnel.
field, double-click directly invokes the replacement.
Unknown but correctly typed words can be added to the personal dictionary.
\end_layout
\begin_layout Standard
Implicitement le dictionnaire qui est utilisé est déterminé par la langue
du document qui est fixée dans la fenêtre de dialogue
\lang english
By default, the dictionary file used is determined by the document language
that is set in the
\family sans
Document\SpecialChar \menuseparator
Paramètres
Settings
\family default
.
Vous pouvez utiliser un autre dictionnaire en donnant le nom d'une autre
langue dans le menu déroulant
\family sans
Langue
\family default
en haut de la fenêtre latérale du correcteur.
LyX peut effectuer la correction dans les documents multilingues, si vous
avez marqué le texte avec la langue appropriée et si les dictionnaires
adéquats sont installés: LyX commute automatiquement vers le bon dictionnaire.
\end_layout
\begin_layout Standard
Quand la vérification orthographique est terminée, vous êtes informés du
nombre de mots qui ont été vérifiés.
\end_layout
\begin_layout Subsubsection*
Limitations
\end_layout
\begin_layout Standard
Il n'est pas possible de changer en une seule opération l'orthographe d'un
mot dans tout le document, il faut soit le faire pour chaque occurrence
du mot séparément, soit utiliser
\family sans
Rechercher
\begin_inset space ~
\end_inset
et
\begin_inset space ~
\end_inset
Remplacer
\family default
pour le faire.
\end_layout
\begin_layout Standard
LyX ne peut pas faire une vérification d'orthographe correcte sur un document
contenant plusieurs langues.
En principe cela marche avec
\family typewriter
pspell
\family default
, à condition de bien avoir marqué les différents langages.
dialog.
You can specify the language of a word in the spellchecker dialog by choosing
a different one at the top of the dialog.
LyX can correctly spell check documents containing multiple languages.
This work if you have marked the different languages appropriately and
have the spell checker dictionaries installed.
LyX automatically switches to the appropriate dictionary file.
\end_layout
\begin_layout Subsection
@ -33386,7 +33281,9 @@ man-page
peuvent être disponibles.
Avec Windows, on ne trouve que
\family typewriter
hunspell;
hunspell
\family default
;
\end_layout
\begin_layout Description

View File

@ -40049,7 +40049,12 @@ type "icon"
arg "dialog-show spellchecker"
\end_inset
を使用すると、現在のカーソル位置からスペルチェックが始まります。
\lang english
starts the spell checking beginning from either the current cursor position
or the beginning of the currently selected text.
\lang japanese
\lang english
A sidebar will appear showing any incorrect (or unknown) word found, allowing
you to edit and replace it in a second line.

View File

@ -400,6 +400,8 @@ $$
\bottomfraction
\caption[]{}
\cc{}
\ce{}
\cf{}
\ccname
\centering
\centerline{translate}

1159
po/ar.po

File diff suppressed because it is too large Load Diff

1162
po/ca.po

File diff suppressed because it is too large Load Diff

1165
po/cs.po

File diff suppressed because it is too large Load Diff

1162
po/da.po

File diff suppressed because it is too large Load Diff

1001
po/de.po

File diff suppressed because it is too large Load Diff

1159
po/el.po

File diff suppressed because it is too large Load Diff

1159
po/en.po

File diff suppressed because it is too large Load Diff

7461
po/es.po

File diff suppressed because it is too large Load Diff

1162
po/eu.po

File diff suppressed because it is too large Load Diff

1162
po/fi.po

File diff suppressed because it is too large Load Diff

1162
po/fr.po

File diff suppressed because it is too large Load Diff

1162
po/gl.po

File diff suppressed because it is too large Load Diff

1159
po/he.po

File diff suppressed because it is too large Load Diff

1162
po/hu.po

File diff suppressed because it is too large Load Diff

1162
po/ia.po

File diff suppressed because it is too large Load Diff

1162
po/id.po

File diff suppressed because it is too large Load Diff

1162
po/it.po

File diff suppressed because it is too large Load Diff

1162
po/ja.po

File diff suppressed because it is too large Load Diff

1159
po/nb.po

File diff suppressed because it is too large Load Diff

1159
po/nl.po

File diff suppressed because it is too large Load Diff

1162
po/nn.po

File diff suppressed because it is too large Load Diff

1162
po/pl.po

File diff suppressed because it is too large Load Diff

1162
po/pt.po

File diff suppressed because it is too large Load Diff

1162
po/ro.po

File diff suppressed because it is too large Load Diff

1162
po/ru.po

File diff suppressed because it is too large Load Diff

1145
po/sk.po

File diff suppressed because it is too large Load Diff

1159
po/sr.po

File diff suppressed because it is too large Load Diff

1162
po/sv.po

File diff suppressed because it is too large Load Diff

1162
po/tr.po

File diff suppressed because it is too large Load Diff

1162
po/uk.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3271,7 +3271,7 @@ void Buffer::getSourceCode(odocstream & os, string const format,
writeLyXHTMLSource(os, runparams, output);
} else if (runparams.flavor == OutputParams::TEXT) {
if (output == OnlyPreamble) {
os << _("% Plaintext does not have a preamble.");
os << "% "<< _("Plain text does not have a preamble.");
} else
writePlaintextFile(*this, os, runparams);
} else if (params().isDocBook()) {
@ -4323,8 +4323,9 @@ int Buffer::spellCheck(DocIterator & from, DocIterator & to,
WordLangTuple wl;
suggestions.clear();
word_lang = WordLangTuple();
bool const to_end = to.empty();
DocIterator const end = to_end ? doc_iterator_end(this) : to;
// OK, we start from here.
DocIterator const end = doc_iterator_end(this);
for (; from != end; from.forwardPos()) {
// We are only interested in text so remove the math CursorSlice.
while (from.inMathed()) {
@ -4332,8 +4333,8 @@ int Buffer::spellCheck(DocIterator & from, DocIterator & to,
from.pos()++;
}
// If from is at the end of the document (which is possible
// when leaving the mathed) LyX will crash later.
if (from == end)
// when leaving the mathed) LyX will crash later otherwise.
if (from.atEnd() || (!to_end && from >= end))
break;
to = from;
from.paragraph().spellCheck();

View File

@ -984,8 +984,10 @@ bool handleFoundFile(string const & ff, DepTable & head)
}
bool checkLineBreak(string const & ff, DepTable & head)
bool completeFilename(string const & ff, DepTable & head)
{
// If we do not find a dot, we suspect
// a fragmental file name
if (!contains(ff, '.'))
return false;
@ -993,6 +995,68 @@ bool checkLineBreak(string const & ff, DepTable & head)
return handleFoundFile(ff, head);
}
int iterateLine(string const token, regex const reg, string const & closing,
int fragment_pos, DepTable & head)
{
smatch what;
string::const_iterator first = token.begin();
string::const_iterator end = token.end();
bool fragment = false;
string last_match;
while (regex_search(first, end, what, reg)) {
// if we have a dot, try to handle as file
if (contains(what.str(1), '.')) {
first = what[0].second;
if (what.str(2) == closing) {
handleFoundFile(what.str(1), head);
// since we had a closing bracket,
// do not investigate further
fragment = false;
} else
// if we have no closing bracket,
// try to handle as file nevertheless
fragment = !handleFoundFile(
what.str(1) + what.str(2), head);
}
// if we do not have a dot, check if the line has
// a closing bracket (else, we suspect a line break)
else if (what.str(2) != closing) {
first = what[0].second;
fragment = true;
} else {
// we have a closing bracket, so the content
// is not a file name.
// no need to investigate further
first = what[0].second;
fragment = false;
}
last_match = what.str(1);
}
// We need to consider the result from previous line iterations:
// We might not find a fragment here, but another one might follow
// E.g.: (filename.ext) <filenam
// Vice versa, we consider the search completed if a real match
// follows a potential fragment from a previous iteration.
// E.g. <some text we considered a fragment (filename.ext)
// result = -1 means we did not find a fragment!
int result = -1;
int last_match_pos = -1;
if (!last_match.empty() && token.find(last_match) != string::npos)
last_match_pos = int(token.find(last_match));
if (fragment) {
if (last_match_pos > fragment_pos)
result = last_match_pos;
else
result = fragment_pos;
} else
if (last_match_pos < fragment_pos)
result = fragment_pos;
return result;
}
} // anon namespace
@ -1013,8 +1077,6 @@ void LaTeX::deplog(DepTable & head)
// but instead only a line like this into the log:
// Writing index file sample.idx
static regex const reg4("Writing index file (.+).*");
// files also can be enclosed in <...>
static regex const reg5("<([^>]+)(.).*");
static regex const regoldnomencl("Writing glossary file (.+).*");
static regex const regnomencl("Writing nomenclature file (.+).*");
// If a toc should be created, MikTex does not write a line like
@ -1024,6 +1086,9 @@ void LaTeX::deplog(DepTable & head)
// This line is also written by tetex.
// This line is not present if no toc should be created.
static regex const miktexTocReg("\\\\tf@toc=\\\\write.*");
// file names can be enclosed in <...> (anywhere on the line)
static regex const reg5(".*<[^>]+.*");
// and also (...) anywhere on the line
static regex const reg6(".*\\([^)]+.*");
FileName const fn = makeAbsPath(logfile);
@ -1031,10 +1096,12 @@ void LaTeX::deplog(DepTable & head)
string lastline;
while (ifs) {
// Ok, the scanning of files here is not sufficient.
// Sometimes files are named by "File:<EFBFBD> xxx" only
// So I think we should use some regexps to find files instead.
// Sometimes files are named by "File: xxx" only
// Therefore we use some regexps to find files instead.
// Note: all file names and paths might contains spaces.
bool found_file = false;
// Also, file names might be broken across lines. Therefore
// we mark (potential) fragments and merge those lines.
bool fragment = false;
string token;
getline(ifs, token);
// MikTeX sometimes inserts \0 in the log file. They can't be
@ -1083,100 +1150,72 @@ void LaTeX::deplog(DepTable & head)
// (1) "File: file.ext"
if (regex_match(token, sub, reg1)) {
// check for dot
found_file = checkLineBreak(sub.str(1), head);
// is this a fragmental file name?
fragment = !completeFilename(sub.str(1), head);
// However, ...
if (suffixIs(token, ")"))
// no line break for sure
// pretend we've been successfully searching
found_file = true;
// no fragment for sure
fragment = false;
// (2) "No file file.ext"
} else if (regex_match(token, sub, reg2)) {
// file names must contains a dot, line ends with dot
if (contains(sub.str(1), '.') && sub.str(2) == ".")
found_file = handleFoundFile(sub.str(1), head);
fragment = !handleFoundFile(sub.str(1), head);
else
// we suspect a line break
found_file = false;
fragment = true;
// (3) "\openout<nr> = `file.ext'."
} else if (regex_match(token, sub, reg3)) {
// search for closing '. at the end of the line
if (sub.str(2) == "\'.")
found_file = handleFoundFile(sub.str(1), head);
fragment = !handleFoundFile(sub.str(1), head);
else
// probable line break
found_file = false;
// potential fragment
fragment = true;
// (4) "Writing index file file.ext"
} else if (regex_match(token, sub, reg4))
// check for dot
found_file = checkLineBreak(sub.str(1), head);
// (5) "<file.ext>"
else if (regex_match(token, sub, reg5)) {
// search for closing '>' and dot ('*.*>') at the eol
if (contains(sub.str(1), '.') && sub.str(2) == ">")
found_file = handleFoundFile(sub.str(1), head);
else
// probable line break
found_file = false;
// (6) "Writing nomenclature file file.ext"
} else if (regex_match(token, sub, regnomencl) ||
// fragmential file name?
fragment = !completeFilename(sub.str(1), head);
// (5) "Writing nomenclature file file.ext"
else if (regex_match(token, sub, regnomencl) ||
regex_match(token, sub, regoldnomencl))
// check for dot
found_file = checkLineBreak(sub.str(1), head);
// (7) "\tf@toc=\write<nr>" (for MikTeX)
// fragmental file name?
fragment= !completeFilename(sub.str(1), head);
// (6) "\tf@toc=\write<nr>" (for MikTeX)
else if (regex_match(token, sub, miktexTocReg))
found_file = handleFoundFile(onlyFileName(changeExtension(
fragment = !handleFoundFile(onlyFileName(changeExtension(
file.absFileName(), ".toc")), head);
else
// not found, but we won't check further
// pretend we've been successfully searching
found_file = true;
fragment = false;
// (8) "(file.ext"
// note that we can have several of these on one line
int fragment_pos = -1;
// (7) "<file.ext>"
// We can have several of these on one line
// (and in addition to those above)
if (regex_match(token, sub, reg5)) {
// search for strings in <...>
static regex reg5_1("<([^>]+)(.)");
fragment_pos = iterateLine(token, reg5_1, ">",
fragment_pos, head);
fragment = (fragment_pos != -1);
}
// (8) "(file.ext)"
// We can have several of these on one line
// this must be queried separated, because of
// cases such as "File: file.ext (type eps)"
// where "File: file.ext" would be skipped
if (regex_match(token, sub, reg6)) {
// search for strings in (...)
static regex reg6_1("\\(([^()]+)(.)");
smatch what;
string::const_iterator first = token.begin();
string::const_iterator end = token.end();
while (regex_search(first, end, what, reg6_1)) {
// if we have a dot, try to handle as file
if (contains(what.str(1), '.')) {
first = what[0].second;
if (what.str(2) == ")") {
handleFoundFile(what.str(1), head);
// since we had a closing bracket,
// do not investigate further
found_file = true;
} else
// if we have no closing bracket,
// try to handle as file nevertheless
found_file = handleFoundFile(
what.str(1) + what.str(2), head);
}
// if we do not have a dot, check if the line has
// a closing bracket (else, we suspect a line break)
else if (what.str(2) != ")") {
first = what[0].second;
found_file = false;
} else {
// we have a closing bracket, so the content
// is not a file name.
// no need to investigate further
// pretend we've been successfully searching
first = what[0].second;
found_file = true;
}
}
fragment_pos = iterateLine(token, reg6_1, ")",
fragment_pos, head);
fragment = (fragment_pos != -1);
}
if (!found_file)
// probable linebreak:
if (fragment)
// probable linebreak within file name:
// save this line
lastline = token;
else

View File

@ -2792,7 +2792,7 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
retval += inset->xhtml(xs, np);
}
} else {
char_type c = d->text_[i];
char_type c = getUChar(buf.params(), i);
if (style.pass_thru)
xs << c;

View File

@ -249,8 +249,10 @@ void Undo::clear()
d->undostack_.clear();
d->redostack_.clear();
d->undo_finished_ = true;
d->group_id = 0;
d->group_level = 0;
// We used to do that, but I believe it is better to keep
// groups (only used in Buffer::reload for now (JMarc)
//d->group_id = 0;
//d->group_level = 0;
}
@ -511,8 +513,10 @@ void Undo::beginUndoGroup()
void Undo::endUndoGroup()
{
if (d->group_level == 0)
if (d->group_level == 0) {
LYXERR0("There is no undo group to end here");
return;
}
--d->group_level;
if (d->group_level == 0) {
// real end of the group

View File

@ -1244,13 +1244,6 @@ void PrefDisplay::on_instantPreviewCO_currentIndexChanged(int index)
}
void PrefDisplay::on_displayGraphicsCB_toggled(bool on)
{
instantPreviewCO->setEnabled(on);
previewSizeSB->setEnabled(on && instantPreviewCO->currentIndex() > 0);
}
void PrefDisplay::apply(LyXRC & rc) const
{
switch (instantPreviewCO->currentIndex()) {
@ -1294,7 +1287,6 @@ void PrefDisplay::update(LyXRC const & rc)
}
displayGraphicsCB->setChecked(rc.display_graphics);
instantPreviewCO->setEnabled(rc.display_graphics);
previewSizeSB->setValue(rc.preview_scale_factor);
paragraphMarkerCB->setChecked(rc.paragraph_markers);
previewSizeSB->setEnabled(

View File

@ -281,7 +281,6 @@ public:
private Q_SLOTS:
void on_instantPreviewCO_currentIndexChanged(int);
void on_displayGraphicsCB_toggled(bool);
};

View File

@ -59,17 +59,22 @@ namespace frontend {
struct SpellcheckerWidget::Private
{
Private(SpellcheckerWidget * parent, DockView * dv)
: p(parent), dv_(dv), incheck_(false), wrap_around_(false) {}
Private(SpellcheckerWidget * parent, DockView * dv, GuiView * gv)
: p(parent), dv_(dv), gv_(gv), incheck_(false), wrap_around_(false) {}
/// update from controller
void updateSuggestions(docstring_list & words);
/// move to next position after current word
void forward();
/// check text until next misspelled/unknown word
void check();
///
/// close the spell checker dialog
void hide() const;
/// make/restore a selection between from and to
void setSelection(DocIterator const & from, DocIterator const & to) const;
/// if no selection was checked:
/// ask the user if the check should start over
bool continueFromBeginning();
///
/// set the given language in language chooser
void setLanguage(Language const * lang);
/// test and set guard flag
bool inCheck() {
@ -79,20 +84,46 @@ struct SpellcheckerWidget::Private
return false;
}
void canCheck() { incheck_ = false; }
/// check for wrap around of current position
bool isWrapAround(DocIterator cursor) const;
/// check for wrap around
void wrapAround(bool flag) {
wrap_around_ = flag;
if (flag) {
end_ = start_;
}
}
/// test for existing association with a document buffer
/// and test for already active check
bool disabled() {
return gv_->documentBufferView() == 0 || inCheck();
}
/// the cursor position of the buffer view
DocIterator const cursor() const;
/// status checks
bool isCurrentBuffer(DocIterator const & cursor) const;
bool isWrapAround(DocIterator const & cursor) const;
bool isWrapAround() const { return wrap_around_; }
bool atLastPos(DocIterator const & cursor) const;
/// validate the cached doc iterators
/// The spell checker dialog is not modal.
/// The user may change the buffer being checked and break the iterators.
void fixPositionsIfBroken();
///
Ui::SpellcheckerUi ui;
///
SpellcheckerWidget * p;
///
GuiView * gv_;
///
DockView * dv_;
///
GuiView * gv_;
/// current word being checked and lang code
WordLangTuple word_;
///
/// cursor position where spell checking starts
DocIterator start_;
/// range to spell check
/// for selection both are non-empty
/// after wrap around the start position becomes the end
DocIterator begin_;
DocIterator end_;
///
bool incheck_;
///
@ -101,10 +132,9 @@ struct SpellcheckerWidget::Private
SpellcheckerWidget::SpellcheckerWidget(GuiView * gv, DockView * dv, QWidget * parent)
: QTabWidget(parent), d(new Private(this, dv))
: QTabWidget(parent), d(new Private(this, dv, gv))
{
d->ui.setupUi(this);
d->gv_ = gv;
connect(d->ui.suggestionsLW, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
this, SLOT(on_replacePB_clicked()));
@ -178,53 +208,165 @@ void SpellcheckerWidget::on_replaceCO_highlighted(const QString & str)
void SpellcheckerWidget::updateView()
{
BufferView * bv = d->gv_->documentBufferView();
setEnabled(bv != 0);
if (bv && hasFocus() && d->start_.empty()) {
d->start_ = bv->cursor();
d->check();
// we need a buffer view and the buffer has to be writable
bool const enabled = bv != 0 && !bv->buffer().isReadonly();
setEnabled(enabled);
if (enabled && hasFocus()) {
Cursor const & cursor = bv->cursor();
if (d->start_.empty() || !d->isCurrentBuffer(cursor)) {
if (cursor.selection()) {
d->begin_ = cursor.selectionBegin();
d->end_ = cursor.selectionEnd();
d->start_ = d->begin_;
bv->cursor().setCursor(d->start_);
} else {
d->begin_ = DocIterator();
d->end_ = DocIterator();
d->start_ = cursor;
}
d->wrapAround(false);
d->check();
}
}
}
DocIterator const SpellcheckerWidget::Private::cursor() const
{
BufferView * bv = gv_->documentBufferView();
return bv ? bv->cursor() : DocIterator();
}
bool SpellcheckerWidget::Private::continueFromBeginning()
{
DocIterator const current_ = cursor();
if (isCurrentBuffer(current_) && !begin_.empty()) {
// selection was checked
// start over from beginning makes no sense
fixPositionsIfBroken();
hide();
if (current_ == start_) {
// no errors found... tell the user the good news
// so there is some feedback
QMessageBox::information(p,
qt_("Spell Checker"),
qt_("Spell check of the selection done, "
"did not find any errors."));
}
return false;
}
QMessageBox::StandardButton const answer = QMessageBox::question(p,
qt_("Spell Checker"),
qt_("We reached the end of the document, would you like to "
"continue from the beginning?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
if (answer == QMessageBox::No) {
dv_->hide();
fixPositionsIfBroken();
hide();
return false;
}
// there is no selection, start over from the beginning now
wrapAround(true);
dispatch(FuncRequest(LFUN_BUFFER_BEGIN));
wrap_around_ = true;
return true;
}
bool SpellcheckerWidget::Private::isWrapAround(DocIterator cursor) const
bool SpellcheckerWidget::Private::isCurrentBuffer(DocIterator const & cursor) const
{
return wrap_around_ && start_.buffer() == cursor.buffer() && start_ < cursor;
return start_.buffer() == cursor.buffer();
}
bool SpellcheckerWidget::Private::atLastPos(DocIterator const & cursor) const
{
bool const valid_end = !end_.empty();
return cursor.depth() <= 1 && (
cursor.atEnd() ||
(valid_end && isCurrentBuffer(cursor) && cursor >= end_));
}
bool SpellcheckerWidget::Private::isWrapAround(DocIterator const & cursor) const
{
return wrap_around_ && isCurrentBuffer(cursor) && start_ < cursor;
}
void SpellcheckerWidget::Private::fixPositionsIfBroken()
{
DocIterator const current_ = cursor();
if (!isCurrentBuffer(current_)) {
LYXERR(Debug::GUI, "wrong document of current cursor position " << start_);
start_ = current_;
begin_ = DocIterator();
end_ = DocIterator();
}
if (start_.fixIfBroken())
LYXERR(Debug::GUI, "broken start position fixed " << start_);
if (begin_.fixIfBroken()) {
LYXERR(Debug::GUI, "broken selection begin position fixed " << begin_);
begin_ = DocIterator();
end_ = DocIterator();
}
if (end_.fixIfBroken())
LYXERR(Debug::GUI, "broken selection end position fixed " << end_);
}
void SpellcheckerWidget::Private::hide() const
{
BufferView * bv = gv_->documentBufferView();
Cursor & bvcur = bv->cursor();
dv_->hide();
if (isCurrentBuffer(bvcur)) {
if (!begin_.empty() && !end_.empty()) {
// restore previous selection
setSelection(begin_, end_);
} else {
// restore cursor position
bvcur.setCursor(start_);
bvcur.clearSelection();
bv->processUpdateFlags(Update::Force | Update::FitCursor);
}
}
}
void SpellcheckerWidget::Private::setSelection(
DocIterator const & from, DocIterator const & to) const
{
BufferView * bv = gv_->documentBufferView();
DocIterator end = to;
if (from.pit() != end.pit()) {
// there are multiple paragraphs in selection
Cursor & bvcur = bv->cursor();
bvcur.setCursor(from);
bvcur.clearSelection();
bvcur.setSelection(true);
bvcur.setCursor(end);
bvcur.setSelection(true);
} else {
// FIXME LFUN
// If we used a LFUN, dispatch would do all of this for us
int const size = end.pos() - from.pos();
bv->putSelectionAt(from, size, false);
}
bv->processUpdateFlags(Update::Force | Update::FitCursor);
}
void SpellcheckerWidget::Private::forward()
{
BufferView * bv = gv_->documentBufferView();
DocIterator from = bv->cursor();
DocIterator const from = cursor();
dispatch(FuncRequest(LFUN_ESCAPE));
dispatch(FuncRequest(LFUN_CHAR_FORWARD));
if (bv->cursor().depth() <= 1 && bv->cursor().atLastPos()) {
continueFromBeginning();
fixPositionsIfBroken();
if (!atLastPos(cursor())) {
dispatch(FuncRequest(LFUN_CHAR_FORWARD));
}
if (atLastPos(cursor())) {
return;
}
if (from == bv->cursor()) {
if (from == cursor()) {
//FIXME we must be at the end of a cell
dispatch(FuncRequest(LFUN_CHAR_FORWARD));
}
if (isWrapAround(bv->cursor())) {
dv_->hide();
if (isWrapAround(cursor())) {
hide();
}
}
@ -247,12 +389,12 @@ bool SpellcheckerWidget::initialiseParams(std::string const &)
if (bv == 0)
return false;
std::set<Language const *> languages =
bv->buffer().masterBuffer()->getLanguages();
bv->buffer().masterBuffer()->getLanguages();
if (!languages.empty())
d->setLanguage(*languages.begin());
d->start_ = DocIterator();
d->wrap_around_ = false;
d->incheck_ = false;
d->wrapAround(false);
d->canCheck();
return true;
}
@ -260,7 +402,7 @@ bool SpellcheckerWidget::initialiseParams(std::string const &)
void SpellcheckerWidget::on_ignoreAllPB_clicked()
{
/// ignore all occurrences of word
if (d->inCheck())
if (d->disabled())
return;
LYXERR(Debug::GUI, "Spellchecker: ignore all button");
if (d->word_.lang() && !d->word_.word().empty())
@ -274,7 +416,7 @@ void SpellcheckerWidget::on_ignoreAllPB_clicked()
void SpellcheckerWidget::on_addPB_clicked()
{
/// insert word in personal dictionary
if (d->inCheck())
if (d->disabled())
return;
LYXERR(Debug::GUI, "Spellchecker: add word button");
theSpellChecker()->insert(d->word_);
@ -287,7 +429,7 @@ void SpellcheckerWidget::on_addPB_clicked()
void SpellcheckerWidget::on_ignorePB_clicked()
{
/// ignore this occurrence of word
if (d->inCheck())
if (d->disabled())
return;
LYXERR(Debug::GUI, "Spellchecker: ignore button");
d->forward();
@ -298,7 +440,7 @@ void SpellcheckerWidget::on_ignorePB_clicked()
void SpellcheckerWidget::on_findNextPB_clicked()
{
if (d->inCheck())
if (d->disabled())
return;
docstring const textfield = qstring_to_ucs4(d->ui.wordED->text());
docstring const datastring = find2string(textfield,
@ -311,7 +453,7 @@ void SpellcheckerWidget::on_findNextPB_clicked()
void SpellcheckerWidget::on_replacePB_clicked()
{
if (d->inCheck())
if (d->disabled())
return;
docstring const textfield = qstring_to_ucs4(d->ui.wordED->text());
docstring const replacement = qstring_to_ucs4(d->ui.replaceCO->currentText());
@ -333,7 +475,7 @@ void SpellcheckerWidget::on_replacePB_clicked()
void SpellcheckerWidget::on_replaceAllPB_clicked()
{
if (d->inCheck())
if (d->disabled())
return;
docstring const textfield = qstring_to_ucs4(d->ui.wordED->text());
docstring const replacement = qstring_to_ucs4(d->ui.replaceCO->currentText());
@ -385,11 +527,14 @@ void SpellcheckerWidget::Private::check()
BufferView * bv = gv_->documentBufferView();
if (!bv || bv->buffer().text().empty())
return;
fixPositionsIfBroken();
SpellChecker * speller = theSpellChecker();
if (speller && !speller->hasDictionary(bv->buffer().language())) {
int dsize = speller->numDictionaries();
if (0 == dsize) {
dv_->hide();
hide();
QMessageBox::information(p,
qt_("Spell Checker"),
qt_("Spell checker has no dictionaries."));
@ -398,14 +543,13 @@ void SpellcheckerWidget::Private::check()
}
DocIterator from = bv->cursor();
DocIterator to;
DocIterator to = isCurrentBuffer(from) ? end_ : doc_iterator_end(&bv->buffer());
WordLangTuple word_lang;
docstring_list suggestions;
LYXERR(Debug::GUI, "Spellchecker: start check at " << from);
int progress;
try {
progress = bv->buffer().spellCheck(from, to, word_lang, suggestions);
bv->buffer().spellCheck(from, to, word_lang, suggestions);
} catch (ExceptionMessage const & message) {
if (message.type_ == WarningException) {
Alert::warning(message.title_, message.details_);
@ -414,10 +558,10 @@ void SpellcheckerWidget::Private::check()
throw message;
}
// end of document
if (from == doc_iterator_end(&bv->buffer())) {
if (wrap_around_ || start_ == doc_iterator_begin(&bv->buffer())) {
dv_->hide();
// end of document or selection?
if (atLastPos(from)) {
if (isWrapAround()) {
hide();
return;
}
if (continueFromBeginning())
@ -426,7 +570,7 @@ void SpellcheckerWidget::Private::check()
}
if (isWrapAround(from)) {
dv_->hide();
hide();
return;
}
@ -435,13 +579,11 @@ void SpellcheckerWidget::Private::check()
// set suggestions
updateSuggestions(suggestions);
// set language
if (!word_lang.lang())
return;
setLanguage(word_lang.lang());
// FIXME LFUN
// If we used a LFUN, dispatch would do all of this for us
int const size = to.pos() - from.pos();
bv->putSelectionAt(from, size, false);
bv->processUpdateFlags(Update::Force | Update::FitCursor);
// mark misspelled word
setSelection(from, to);
}

View File

@ -55,9 +55,11 @@ InsetLabel::InsetLabel(Buffer * buf, InsetCommandParams const & p)
void InsetLabel::initView()
{
// FIXME: This seems to be used only for inset creation so
// we probably just need to call updateLabel() here.
updateLabelAndRefs(getParam("name"));
// This seems to be used only for inset creation.
// Therefore we do not update refs here, since this would
// erroneously change refs from existing duplicate labels
// (#8141).
updateLabel(getParam("name"));
}

View File

@ -15,6 +15,7 @@
#include "DispatchResult.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "InsetMathBrace.h"
#include "InsetMathFont.h"
#include "InsetMathScript.h"
#include "InsetMathSymbol.h"
@ -547,8 +548,16 @@ void InsetMathScript::write(WriteStream & os) const
if (hasDown() /*&& down().size()*/)
os << "_{" << down() << '}';
if (hasUp() /*&& up().size()*/)
os << "^{" << up() << '}';
if (hasUp() /*&& up().size()*/) {
// insert space if up() is empty or an empty brace inset
// (see bug 8305)
if (os.latex() && (up().size() == 0 ||
(up().size() == 1 && up().back()->asBraceInset() &&
up().back()->asBraceInset()->cell(0).empty())))
os << "^ {}";
else
os << "^{" << up() << '}';
}
if (lock_ && !os.latex())
os << "\\lyxlock ";

View File

@ -51,6 +51,8 @@ What's new
- Allow native LyX format to be shown in menu View->Source.
- Implementation of spell check of current selection (bug #2511).
* DOCUMENTATION AND LOCALIZATION
@ -97,12 +99,17 @@ What's new
- Embrace babel settings to \makeatletter ... \makeatother if they contain
an @ glyph.
- Improve the external file monitor. LyX should now also honor changes in
graphics that are included via ERT or generated via knitr (bug 8336).
- Fix LaTeX errors with right-to-left text when using XeTeX/Polyglossia
(part of bug 8251).
- Fix brackets direction in Hebrew documents when using XeTeX/Polyglossia
and in Arabic documents on plain text output (part of bug 8251).
- Fix bracket output with RTL languages (bug 8278).
- Fix babel call with Arabic (arabi).
- Fix suppression of language package.
@ -113,6 +120,11 @@ What's new
- Fix LaTeX output of IPA tone symbols.
- Fix support for mhchem upward arrows, which in mathed are rendered as
empty (brace insets) superscripts (bug 8305).
- Fix tex2lyx import of mhchem commands outside math mode (bug 8306).
* USER INTERFACE
@ -125,11 +137,17 @@ What's new
- Fix crash when using undo in a paragraph with layout Bibliography (bug 7111).
- Fix bug where references were erroneously changed when a duplicate label
name was resolved (bug 8147).
- Make sure that undo restores environment depth correctly (bug 8159).
- Make sure that undo restores paragraph longest label width correctly
(bug 8242).
- Fix undo machinery confusion after checking in a document under version
control (bug 8342).
- Do not forget the undo information when doing a Save As...
- Replace current selection when pasting (bug 8027).
@ -150,6 +168,9 @@ What's new
- When using a non-default language for the GUI, do not change locale
settings of child proceses (bug 7741).
- Do not disable Instant Preview widgets in preferences when Display
Graphics is unchecked (bug 7462).
* DOCUMENTATION AND LOCALIZATION