From 833f0bab524dca79aa99a602c8424972e95b04fb Mon Sep 17 00:00:00 2001 From: Stefan Schimanski Date: Thu, 21 Feb 2008 19:43:16 +0000 Subject: [PATCH] * minimize redraws during completion git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23105 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferView.cpp | 43 +++++++++++++++++++++++++++-- src/BufferView.h | 5 ++-- src/frontends/qt4/GuiCompleter.cpp | 44 ++++++++++++++++++++---------- src/frontends/qt4/GuiCompleter.h | 2 ++ src/insets/InsetText.cpp | 4 ++- 5 files changed, 79 insertions(+), 19 deletions(-) diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 59fe43298b..540ba866dd 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -2190,12 +2190,51 @@ DocIterator const & BufferView::inlineCompletionPos() const } -void BufferView::setInlineCompletion(DocIterator const & pos, +bool samePar(DocIterator const & a, DocIterator const & b) +{ + if (a.empty() && b.empty()) + return true; + if (a.empty() || b.empty()) + return false; + return &a.innerParagraph() == &b.innerParagraph(); +} + + +void BufferView::setInlineCompletion(Cursor & cur, DocIterator const & pos, docstring const & completion, size_t uniqueChars) { - d->inlineCompletionPos = pos; + uniqueChars = min(completion.size(), uniqueChars); + bool changed = d->inlineCompletion != completion + || d->inlineCompletionUniqueChars != uniqueChars; + bool singlePar = true; d->inlineCompletion = completion; d->inlineCompletionUniqueChars = min(completion.size(), uniqueChars); + + lyxerr << "setInlineCompletion pos=" << pos << " completion=" << completion << " uniqueChars=" << uniqueChars << std::endl; + + // at new position? + DocIterator const & old = d->inlineCompletionPos; + if (old != pos) { + lyxerr << "inlineCompletionPos changed" << std::endl; + // old or pos are in another paragraph? + if ((!samePar(cur, pos) && !pos.empty()) + || (!samePar(cur, old) && !old.empty())) { + singlePar = false; + lyxerr << "different paragraph" << std::endl; + } + d->inlineCompletionPos = pos; + } + + // set update flags + if (changed) { + lyxerr << "inlineCompletion changed" << std::endl; + + Update::flags flags + = cur.disp_.update() | Update::Force; + if (singlePar && !(flags | Update::SinglePar)) + flags = flags | Update::SinglePar; + cur.updateFlags(flags); + } } } // namespace lyx diff --git a/src/BufferView.h b/src/BufferView.h index ffac857fa2..a79c7bbb62 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -169,8 +169,9 @@ public: /// return the position in the buffer of the inline completion postfix. DocIterator const & inlineCompletionPos() const; /// set the inline completion postfix and its position in the buffer. - void setInlineCompletion(DocIterator const & pos, docstring const & completion, - size_t uniqueChars = 0); + /// Updates the updateFlags in \c cur. + void setInlineCompletion(Cursor & cur, DocIterator const & pos, + docstring const & completion, size_t uniqueChars = 0); /// translate and insert a character, using the correct keymap. void translateAndInsert(char_type c, Text * t, Cursor & cur); diff --git a/src/frontends/qt4/GuiCompleter.cpp b/src/frontends/qt4/GuiCompleter.cpp index fff172ff2c..3e2cdcd2ae 100644 --- a/src/frontends/qt4/GuiCompleter.cpp +++ b/src/frontends/qt4/GuiCompleter.cpp @@ -119,12 +119,13 @@ public: } private: + /// Inset::CompletionListPtr list; }; GuiCompleter::GuiCompleter(GuiWorkArea * gui, QObject * parent) - : QCompleter(parent), gui_(gui) + : QCompleter(parent), gui_(gui), updateLock_(0) { // Setup the completion popup setModel(new GuiCompletionModel(this, Inset::CompletionListPtr())); @@ -235,10 +236,8 @@ void GuiCompleter::updateVisibility(Cursor & cur, bool start, bool keep, bool cu inline_timer_.stop(); // hide old inline completion - if (inlineVisible()) { - gui_->bufferView().setInlineCompletion(DocIterator(), docstring()); - cur.updateFlags(Update::Force | Update::SinglePar); - } + if (inlineVisible()) + gui_->bufferView().setInlineCompletion(cur, DocIterator(), docstring()); } // we inserted something and are in a possible popup state? @@ -261,7 +260,10 @@ void GuiCompleter::updateVisibility(Cursor & cur, bool start, bool keep, bool cu void GuiCompleter::updateVisibility(bool start, bool keep) { Cursor cur = gui_->bufferView().cursor(); + cur.updateFlags(Update::None); + updateVisibility(cur, start, keep); + if (cur.disp_.update()) gui_->bufferView().processUpdateFlags(cur.disp_.update()); } @@ -320,8 +322,7 @@ void GuiCompleter::updateInline(Cursor & cur, QString const & completion) // set inline completion at cursor position size_t uniqueTo = max(longestUniqueCompletion().size(), prefix.size()); - gui_->bufferView().setInlineCompletion(cur, postfix, uniqueTo - prefix.size()); - cur.updateFlags(Update::Force | Update::SinglePar); + gui_->bufferView().setInlineCompletion(cur, cur, postfix, uniqueTo - prefix.size()); } @@ -344,9 +345,6 @@ void GuiCompleter::updatePopup(Cursor & cur) complete(insetRect); QTreeView * p = static_cast(popup()); p->setColumnWidth(0, popup()->width() - 22 - p->verticalScrollBar()->width()); - - // update highlight - updateInline(cur, currentCompletion()); } @@ -404,6 +402,8 @@ void GuiCompleter::showInline(Cursor & cur) void GuiCompleter::showPopup() { Cursor cur = gui_->bufferView().cursor(); + cur.updateFlags(Update::None); + showPopup(cur); // redraw if needed @@ -415,6 +415,8 @@ void GuiCompleter::showPopup() void GuiCompleter::showInline() { Cursor cur = gui_->bufferView().cursor(); + cur.updateFlags(Update::None); + showInline(cur); // redraw if needed @@ -438,8 +440,9 @@ void GuiCompleter::activate() void GuiCompleter::tab() { BufferView * bv = &gui_->bufferView(); - Cursor & cur = bv->cursor(); - + Cursor cur = bv->cursor(); + cur.updateFlags(Update::None); + // check that inline completion is active if (!inlineVisible()) { // try to activate the inline completion @@ -504,7 +507,7 @@ QString GuiCompleter::currentCompletion() const void GuiCompleter::setCurrentCompletion(QString const & s) -{ +{ QAbstractItemModel const & model = *popup()->model(); size_t n = model.rowCount(); if (n == 0) @@ -512,7 +515,9 @@ void GuiCompleter::setCurrentCompletion(QString const & s) // select the first if s is empty if (s.length() == 0) { + updateLock_++; popup()->setCurrentIndex(model.index(0, 0)); + updateLock_--; return; } @@ -530,7 +535,9 @@ void GuiCompleter::setCurrentCompletion(QString const & s) if (i == n) i = 0; + updateLock_++; popup()->setCurrentIndex(model.index(i, 0)); + updateLock_--; } @@ -561,11 +568,14 @@ docstring GuiCompleter::longestUniqueCompletion() const { void GuiCompleter::popupActivated(const QString & completion) { - Cursor & cur = gui_->bufferView().cursor(); + Cursor cur = gui_->bufferView().cursor(); + cur.updateFlags(Update::None); + docstring prefix = cur.inset().completionPrefix(cur); docstring postfix = from_utf8(fromqstr(completion.mid(prefix.length()))); cur.inset().insertCompletion(cur, postfix, true); updateVisibility(cur, false); + if (cur.disp_.update()) gui_->bufferView().processUpdateFlags(cur.disp_.update()); } @@ -573,8 +583,14 @@ void GuiCompleter::popupActivated(const QString & completion) void GuiCompleter::popupHighlighted(const QString & completion) { + if (updateLock_ > 0) + return; + Cursor cur = gui_->bufferView().cursor(); + cur.updateFlags(Update::None); + updateInline(cur, completion); + if (cur.disp_.update()) gui_->bufferView().processUpdateFlags(cur.disp_.update()); } diff --git a/src/frontends/qt4/GuiCompleter.h b/src/frontends/qt4/GuiCompleter.h index c604800a0b..f0890a184d 100644 --- a/src/frontends/qt4/GuiCompleter.h +++ b/src/frontends/qt4/GuiCompleter.h @@ -107,6 +107,8 @@ private: QTimer inline_timer_; /// QString last_selection_; + /// lock to stop updates of the inline completion + int updateLock_; }; // GuiCompleter } // namespace frontend diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp index 9f54b337c0..21cc96bb41 100644 --- a/src/insets/InsetText.cpp +++ b/src/insets/InsetText.cpp @@ -540,8 +540,10 @@ bool InsetText::insertCompletion(Cursor & cur, docstring const & s, { if (!completionSupported(cur)) return false; - + + BOOST_ASSERT(cur.bv().cursor() == cur); cur.insert(s); + cur.bv().cursor() = cur; return true; }