Am 12.04.2011 um 10:41 schrieb Pavel Sanda: > hi, > > there is last critical bug in bugzilla (#7394 - Crash while selecting texts) > and its no showstopper. i would like to make final release at the end of > april. > > the last unfinished thing is the documentation. if you go through > http://wiki.lyx.org/LyX/NewInLyX20 there is bunch of things which were > not added to documentation yet (red icons on the right side). > > if you added some feature which is not in our manuals yet (or outdated) please > consider to contribute documentation to it as well. (please remember to switch > on the change tracking so our translators see whats happening).
I feel some responsibility here. I'll have a look soon. > i haven't decided yet whether we should go for rc4 (~20th) or directly > final one (~29th). lets see what will happen to the codebase in between. > > please note we are in more strict committing mode and untrivial patches > to code should go through list and have ack from another developer. I have four patches pending - more or less trivial. Perhaps, some of them could be considered to go in. 1) A forgotten implementation of "remove from personal dictionary" for enchant. 2) Some fixes for misspelled marker and cursor move. (Inspired by Vincent's questions) 3) Check for all non-word-characters around single hard-hyphen and apostrophe. 4) Fix for wrap around loop of spell checker GUI. (See ticket #7429) Personally I'd like to apply 1) and 4) most. Stephan
Index: src/EnchantChecker.h =================================================================== --- src/EnchantChecker.h (Revision 38352) +++ src/EnchantChecker.h (Arbeitskopie) @@ -34,7 +34,7 @@ enum Result check(WordLangTuple const &); void suggest(WordLangTuple const &, docstring_list &); void insert(WordLangTuple const &); - void remove(WordLangTuple const &) {}; + void remove(WordLangTuple const &); void accept(WordLangTuple const &); bool hasDictionary(Language const * lang) const; docstring const error(); Index: src/EnchantChecker.cpp =================================================================== --- src/EnchantChecker.cpp (Revision 38352) +++ src/EnchantChecker.cpp (Arbeitskopie) @@ -138,6 +138,16 @@ advanceChangeNumber(); } } + + +void EnchantChecker::remove(WordLangTuple const & word) +{ + Spellers::iterator it = d->spellers_.find(word.lang()->code()); + if (it != d->spellers_.end()) { + it->second.speller->remove(to_utf8(word.word())); + advanceChangeNumber(); + } +} void EnchantChecker::accept(WordLangTuple const & word)
Index: src/Cursor.h =================================================================== --- src/Cursor.h (Revision 38352) +++ src/Cursor.h (Arbeitskopie) @@ -300,6 +300,8 @@ /// the result is not empty. When not in text mode /// and after leaving the word the result is empty. DocIterator newWord() const { return new_word_; } + /// validate the "new born word" position + void checkNewWordPosition(); public: //private: @@ -310,8 +312,6 @@ void saveBeforeDispatchPosXY(); private: - /// validate the "new born word" position - void checkNewWordPosition(); /// clear the "new born word" position void clearNewWordPosition(); Index: src/Cursor.cpp =================================================================== --- src/Cursor.cpp (Revision 38352) +++ src/Cursor.cpp (Arbeitskopie) @@ -269,6 +269,7 @@ clearTargetX(); selection_ = false; mark_ = false; + clearNewWordPosition(); } @@ -276,6 +277,7 @@ void Cursor::setCursor(DocIterator const & cur) { DocIterator::operator=(cur); + checkNewWordPosition(); } @@ -1970,6 +1938,7 @@ updateTextTargetOffset(); if (updateNeeded) forceBufferUpdate(); + clearNewWordPosition(); } return false; } @@ -2042,6 +2011,7 @@ if (updateNeeded) forceBufferUpdate(); updateTextTargetOffset(); + clearNewWordPosition(); return true; } Index: src/Text2.cpp =================================================================== --- src/Text2.cpp (Revision 38352) +++ src/Text2.cpp (Arbeitskopie) @@ -567,6 +567,7 @@ LASSERT(this == cur.text(), /**/); cur.boundary(boundary); setCursor(cur.top(), par, pos); + cur.checkNewWordPosition(); if (setfont) cur.setCurrentFont(); }
Index: src/Paragraph.h =================================================================== --- src/Paragraph.h (Revision 38352) +++ src/Paragraph.h (Arbeitskopie) @@ -423,6 +423,8 @@ /// True if the element at this point is a hard hyphen or a apostrophe /// If it is enclosed by spaces return false bool isHardHyphenOrApostrophe(pos_type pos) const; + /// True if the element at this point is part of a word + bool isWordCharacter(pos_type pos) const; /// returns true if at least one line break or line separator has been deleted /// at the beginning of the paragraph (either physically or logically) Index: src/Paragraph.cpp =================================================================== --- src/Paragraph.cpp (Revision 38352) +++ src/Paragraph.cpp (Arbeitskopie) @@ -2858,10 +2858,18 @@ // to get an impression how complex this is. if (isHardHyphenOrApostrophe(pos)) return false; - char_type const c = d->text_[pos]; + return !isWordCharacter(pos); +} + + +bool Paragraph::isWordCharacter(pos_type pos) const +{ + const char_type c = d->text_[pos]; + if (isLetterChar(c) || isDigitASCII(c)) + return true; // We want to pass the escape chars to the spellchecker docstring const escape_chars = from_utf8(lyxrc.spellchecker_esc_chars); - return !isLetterChar(c) && !isDigitASCII(c) && !contains(escape_chars, c); + return contains(escape_chars, c); } @@ -2875,8 +2883,8 @@ return false; int nextpos = pos + 1; int prevpos = pos > 0 ? pos - 1 : 0; - if ((nextpos == psize || isSpace(nextpos)) - && (pos == 0 || isSpace(prevpos))) + if ((nextpos == psize || !isWordCharacter(nextpos)) + && (pos == 0 || !isWordCharacter(prevpos))) return false; return c == '\'' || ((nextpos == psize || d->text_[nextpos] != '-')
Index: src/frontends/qt4/GuiSpellchecker.cpp =================================================================== --- src/frontends/qt4/GuiSpellchecker.cpp (Revision 38352) +++ src/frontends/qt4/GuiSpellchecker.cpp (Arbeitskopie) @@ -60,7 +60,7 @@ struct SpellcheckerWidget::Private { Private(SpellcheckerWidget * parent, DockView * dv) - : p(parent), dv_(dv), start_(true), incheck_(false) {} + : p(parent), dv_(dv), incheck_(false), wrap_around_(false) {} /// update from controller void updateSuggestions(docstring_list & words); /// move to next position after current word @@ -90,9 +90,11 @@ /// current word being checked and lang code WordLangTuple word_; /// - bool start_; + DocIterator start_; /// bool incheck_; + /// + bool wrap_around_; }; @@ -175,15 +177,8 @@ { BufferView * bv = d->gv_->documentBufferView(); setEnabled(bv != 0); - if (bv && hasFocus() && d->start_) { - d->start_ = false; - - BufferView * bv = d->gv_->documentBufferView(); - std::set<Language const *> languages = - bv->buffer().masterBuffer()->getLanguages(); - if (!languages.empty()) - d->setLanguage(*languages.begin()); - + if (bv && hasFocus() && d->start_.empty()) { + d->start_ = bv->cursor(); d->check(); } } @@ -191,17 +186,18 @@ bool SpellcheckerWidget::Private::continueFromBeginning() { - 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(); - return false; - } - dispatch(FuncRequest(LFUN_BUFFER_BEGIN)); - return true; + 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(); + return false; + } + dispatch(FuncRequest(LFUN_BUFFER_BEGIN)); + wrap_around_ = true; + return true; } @@ -220,6 +216,9 @@ //FIXME we must be at the end of a cell dispatch(FuncRequest(LFUN_CHAR_FORWARD)); } + if (wrap_around_ && start_ < bv->cursor()) { + dv_->hide(); + } } @@ -237,7 +236,16 @@ bool SpellcheckerWidget::initialiseParams(std::string const &) { - d->start_ = true; + BufferView * bv = d->gv_->documentBufferView(); + if (bv == 0) + return false; + std::set<Language const *> languages = + bv->buffer().masterBuffer()->getLanguages(); + if (!languages.empty()) + d->setLanguage(*languages.begin()); + d->start_ = DocIterator(); + d->wrap_around_ = false; + d->incheck_ = false; return true; } @@ -380,11 +388,19 @@ // end of document if (from == doc_iterator_end(&bv->buffer())) { + if (wrap_around_ || start_ == doc_iterator_begin(&bv->buffer())) { + dv_->hide(); + return; + } if (continueFromBeginning()) check(); return; } + if (wrap_around_ && start_ < from) { + dv_->hide(); + } + word_ = word_lang; // set suggestions