From cd5bad62e039629d0642550b9cd64358104b0c66 Mon Sep 17 00:00:00 2001 From: Stefan Schimanski Date: Tue, 26 Feb 2008 13:07:59 +0000 Subject: [PATCH] * paragraph support for the global word list. To make it buffer dependent, we need the buffer pointer. In fact we already have a pointer to the text inset. So as soon as inset know their buffer we can easily switch to a buffer local word list. * there might be missing some more places to update the words from a buffer, like for example after backspace or more important when the cursor leaves a paragraph. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23244 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/Buffer.cpp | 15 ------- src/Buffer.h | 6 --- src/Paragraph.cpp | 75 +++++++++++++++++++++++++++++++- src/Paragraph.h | 12 +++++ src/Text.cpp | 18 +++----- src/WordList.cpp | 36 +++++++++++++-- src/WordList.h | 6 ++- src/frontends/qt4/GuiCompleter.h | 2 +- src/insets/InsetText.cpp | 4 +- 9 files changed, 131 insertions(+), 43 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index bd6b7f7fc7..de4b9ccd2e 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -204,9 +204,6 @@ public: /// A cache for the bibfiles (including bibfiles of loaded child /// documents), needed for appropriate update of natbib labels. mutable EmbeddedFileList bibfilesCache_; - - /// - WordList words_; }; /// Creates the per buffer temporary directory @@ -2668,16 +2665,4 @@ void Buffer::bufferErrors(TeXErrors const & terr, ErrorList & errorList) const } } - -void Buffer::registerWord(docstring const & word) -{ - d->words_.insert(word); -} - - -WordList const & Buffer::registeredWords() const -{ - return d->words_; -} - } // namespace lyx diff --git a/src/Buffer.h b/src/Buffer.h index ace9986f23..c35a2479c0 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -50,7 +50,6 @@ class TeXErrors; class TexRow; class TocBackend; class Undo; -class WordList; namespace frontend { class GuiBufferDelegate; @@ -452,11 +451,6 @@ public: bool isExportable(std::string const & format) const; /// std::vector exportableFormats(bool only_viewable) const; - - /// Register word for completion word list. - void registerWord(docstring const & word); - /// - WordList const & registeredWords() const; private: /// search for macro in local (buffer) table or in children diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 5d773ee34c..da573acbd1 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -39,7 +39,9 @@ #include "sgml.h" #include "TextClass.h" #include "TexRow.h" +#include "Text.h" #include "VSpace.h" +#include "WordList.h" #include "frontends/alert.h" @@ -196,6 +198,10 @@ public: typedef docstring TextContainer; /// TextContainer text_; + + typedef std::set Words; + /// + Words words_; }; @@ -233,7 +239,8 @@ Paragraph::Private::Private(Paragraph * owner) Paragraph::Private::Private(Private const & p, Paragraph * owner) : owner_(owner), inset_owner_(p.inset_owner_), fontlist_(p.fontlist_), params_(p.params_), changes_(p.changes_), insetlist_(p.insetlist_), - layout_(p.layout_), begin_of_body_(p.begin_of_body_), text_(p.text_) + layout_(p.layout_), begin_of_body_(p.begin_of_body_), text_(p.text_), + words_(p.words_) { id_ = paragraph_id++; } @@ -1039,6 +1046,7 @@ Paragraph::Paragraph(Paragraph const & par) : itemdepth(par.itemdepth), d(new Paragraph::Private(*par.d, this)) { + registerWords(); } @@ -1048,8 +1056,10 @@ Paragraph & Paragraph::operator=(Paragraph const & par) if (&par != this) { itemdepth = par.itemdepth; + deregisterWords(); delete d; d = new Private(*par.d, this); + registerWords(); } return *this; } @@ -1057,6 +1067,7 @@ Paragraph & Paragraph::operator=(Paragraph const & par) Paragraph::~Paragraph() { + deregisterWords(); delete d; } @@ -2678,4 +2689,66 @@ bool Paragraph::isSeparator(pos_type pos) const } +void Paragraph::deregisterWords() +{ + Private::Words::const_iterator it; + WordList & wl = theWordList(); + for (it = d->words_.begin(); it != d->words_.end(); ++it) + wl.remove(*it); + d->words_.clear(); +} + + +void Paragraph::collectWords(Buffer const & buf, CursorSlice const & sl) +{ + // find new words + bool inword = false; + + //lyxerr << "Words: "; + pos_type n = size(); + for (pos_type pos = 0; pos != n; ++pos) { + if (isDeleted(pos)) + continue; + + if (!isLetter(pos)) { + inword = false; + continue; + } + + if (inword) + continue; + + inword = true; + CursorSlice from = sl; + CursorSlice to = sl; + from.pos() = pos; + to.pos() = pos; + from.text()->getWord(from, to, WHOLE_WORD); + if (to.pos() - from.pos() < 6) + continue; + docstring word + = asString(buf, from.pos(), to.pos(), false); + d->words_.insert(word); + //lyxerr << word << " "; + } + //lyxerr << std::endl; +} + + +void Paragraph::registerWords() +{ + Private::Words::const_iterator it; + WordList & wl = theWordList(); + for (it = d->words_.begin(); it != d->words_.end(); ++it) + wl.insert(*it); +} + + +void Paragraph::updateWords(Buffer const & buf, CursorSlice const & sl) +{ + deregisterWords(); + collectWords(buf, sl); + registerWords(); +} + } // namespace lyx diff --git a/src/Paragraph.h b/src/Paragraph.h index 3c9e533562..03e88d51d8 100644 --- a/src/Paragraph.h +++ b/src/Paragraph.h @@ -31,6 +31,8 @@ class Buffer; class BufferParams; class Change; class Counters; +class Cursor; +class CursorSlice; class Inset; class InsetBibitem; class LaTeXFeatures; @@ -367,8 +369,18 @@ public: bool mw, ///< pos_type pos, ///< start from here. bool del = true) const; + + /// + void updateWords(Buffer const & buf, CursorSlice const & sl); private: + /// + void deregisterWords(); + /// + void collectWords(Buffer const & buf, CursorSlice const & sl); + /// + void registerWords(); + /// Pimpl away stuff class Private; /// diff --git a/src/Text.cpp b/src/Text.cpp index 5d334a253f..61242c0806 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -581,19 +581,7 @@ void Text::charInserted(Cursor & cur) && !par.isLetter(cur.pos() - 1)) { // get the word in front of cursor BOOST_ASSERT(this == cur.text()); - CursorSlice focus = cur.top(); - focus.backwardPos(); - CursorSlice from = focus; - CursorSlice to = focus; - getWord(from, to, PREVIOUS_WORD); - if (focus == from || to == from) - return; - docstring word - = par.asString(cur.buffer(), from.pos(), to.pos(), false); - - // register words longer than 5 characters - if (word.length() > 5) - cur.buffer().registerWord(word); + cur.paragraph().updateWords(cur.buffer(), cur.top()); } } @@ -1218,6 +1206,10 @@ bool Text::read(Buffer const & buf, Lexer & lex, // not BufferParams lyx::readParagraph(buf, pars_.back(), lex, errorList); + // register the words in the global word list + CursorSlice sl = CursorSlice(*insetPtr); + sl.pit() = pars_.size() - 1; + pars_.back().updateWords(buf, sl); } else if (token == "\\begin_deeper") { ++depth; } else if (token == "\\end_deeper") { diff --git a/src/WordList.cpp b/src/WordList.cpp index a5a8f4a78f..30ba5b63af 100644 --- a/src/WordList.cpp +++ b/src/WordList.cpp @@ -21,12 +21,20 @@ namespace lyx { +/// +WordList theGlobalWordList; + +WordList & theWordList() +{ + return theGlobalWordList; +} + /// struct WordList::Impl { /// size_t c_; /// - typedef stx::weighted_btree Words; + typedef stx::weighted_btree Words; /// Words words_; }; @@ -61,14 +69,34 @@ docstring const & WordList::word(size_t idx) const size_t WordList::size() const { - return d->words_.size(); + return d->words_.summed_weight(); } void WordList::insert(docstring const & w) { - d->words_.insert(w, size_t(1), stx::Void()); + Impl::Words::iterator it = d->words_.find(w); + if (it == d->words_.end()) + d->words_.insert(w, size_t(1), 1); + else { + it.data()++; + d->words_.change_weight(it, 1); + } +} + + +void WordList::remove(docstring const & w) +{ + Impl::Words::iterator it = d->words_.find(w); + if (it != d->words_.end()) { + it.data()--; + d->words_.change_weight(it, 0); + // We will not erase here, but instead we just leave it + // in the btree with weight 0. This avoid too much + // reorganisation of the tree all the time. + //if (it.data() == 0) + // d->words_.erase(w); + } } - } // namespace lyx diff --git a/src/WordList.h b/src/WordList.h index 263c4d40da..d02b0b7b88 100644 --- a/src/WordList.h +++ b/src/WordList.h @@ -29,12 +29,16 @@ public: size_t size() const; /// void insert(docstring const & w); - + /// + void remove(docstring const & w); + private: struct Impl; Impl * d; }; +WordList & theWordList(); + } // namespace lyx #endif // WORDLIST_H diff --git a/src/frontends/qt4/GuiCompleter.h b/src/frontends/qt4/GuiCompleter.h index da25bec19c..d6192dd81e 100644 --- a/src/frontends/qt4/GuiCompleter.h +++ b/src/frontends/qt4/GuiCompleter.h @@ -112,7 +112,7 @@ private: int updateLock_; /// the BufferView::inlineCursorPos might be reset by destructive /// operations like backspace. Hence, we have to keep this flag - /// in addition to know whether the popup is to be kept visible. + /// in addition to know whether the completion is to be kept visible. bool inlineVisible_; /// RtlItemDelegate * rtlItemDelegate_; diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp index 42d5cff3ce..7f146b1de3 100644 --- a/src/insets/InsetText.cpp +++ b/src/insets/InsetText.cpp @@ -80,12 +80,12 @@ public: /// virtual size_t size() const { - return buf_.registeredWords().size(); + return theWordList().size(); } /// virtual docstring const & data(size_t idx) const { - return buf_.registeredWords().word(idx); + return theWordList().word(idx); } private: