From 5bfdaef9806426c51981ed0d4c03f6833d80b6ee Mon Sep 17 00:00:00 2001 From: Guillaume Munch Date: Fri, 29 Apr 2016 22:48:53 +0100 Subject: [PATCH] TocWidget: clean-up the timer logic The timer logic introduced to solve bug #7138 was not entirely reliable; in particular it resulted in spurious updates (noticeable by the treeview collapsing just after one opens a branch, in particular). This commit cleans up the timer logic. I followed the original design decision of having an immediate update followed by a delayed update. Now the updates are appropriately compressed and done after a delay of 2s (as can be noticed with the treeview still collapsing, unfortunately, but after a more predictable delay...). --- src/frontends/qt4/GuiToc.cpp | 3 +- src/frontends/qt4/TocWidget.cpp | 51 +++++++++++++++++---------------- src/frontends/qt4/TocWidget.h | 19 ++++++++---- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/frontends/qt4/GuiToc.cpp b/src/frontends/qt4/GuiToc.cpp index 440422225e..b757c90458 100644 --- a/src/frontends/qt4/GuiToc.cpp +++ b/src/frontends/qt4/GuiToc.cpp @@ -50,7 +50,6 @@ GuiToc::~GuiToc() void GuiToc::updateView() { widget_->updateView(); - return; } @@ -71,7 +70,7 @@ void GuiToc::enableView(bool enable) widget_->checkModelChanged(); if (!enable) // In the opposite case, updateView() will be called anyway. - widget_->updateViewForce(); + widget_->updateViewNow(); } diff --git a/src/frontends/qt4/TocWidget.cpp b/src/frontends/qt4/TocWidget.cpp index e3693b7313..4fa6aef7a3 100644 --- a/src/frontends/qt4/TocWidget.cpp +++ b/src/frontends/qt4/TocWidget.cpp @@ -35,19 +35,18 @@ #include #include -#include #include -#define DELAY_UPDATE_VIEW - using namespace std; namespace lyx { namespace frontend { TocWidget::TocWidget(GuiView & gui_view, QWidget * parent) - : QWidget(parent), depth_(0), persistent_(false), gui_view_(gui_view), update_delay_(0) + : QWidget(parent), depth_(0), persistent_(false), gui_view_(gui_view), + update_timer_short_(new QTimer(this)), + update_timer_long_(new QTimer(this)) { setupUi(this); @@ -89,6 +88,16 @@ TocWidget::TocWidget(GuiView & gui_view, QWidget * parent) connect(filterLE, SIGNAL(textEdited(QString)), this, SLOT(filterContents())); + // setting the update timer + update_timer_short_->setSingleShot(true); + update_timer_long_->setSingleShot(true); + update_timer_short_->setInterval(0); + update_timer_long_->setInterval(2000); + connect(update_timer_short_, SIGNAL(timeout()), + this, SLOT(realUpdateView())); + connect(update_timer_long_, SIGNAL(timeout()), + this, SLOT(realUpdateView())); + init(QString()); } @@ -256,7 +265,7 @@ void TocWidget::on_updateTB_clicked() void TocWidget::on_sortCB_stateChanged(int state) { gui_view_.tocModels().sort(current_type_, state == Qt::Checked); - updateViewForce(); + updateViewNow(); } @@ -308,7 +317,7 @@ void TocWidget::on_typeCO_currentIndexChanged(int index) if (index == -1) return; current_type_ = typeCO->itemData(index).toString(); - updateViewForce(); + updateViewNow(); if (typeCO->hasFocus()) gui_view_.setFocus(); } @@ -380,27 +389,24 @@ void TocWidget::enableControls(bool enable) void TocWidget::updateView() { -// Enable if you dont want the delaying business, cf #7138. -#ifndef DELAY_UPDATE_VIEW - updateViewForce(); - return; -#endif - // already scheduled? - if (update_delay_ == -1) - return; - QTimer::singleShot(update_delay_, this, SLOT(updateViewForce())); // Subtler optimization for having the delay more UI invisible. // We trigger update immediately for sparse editation actions, // i.e. there was no editation/cursor movement in last 2 sec. // At worst there will be +1 redraw after 2s in a such "calm" mode. - if (update_delay_ != 0) - updateViewForce(); - update_delay_ = -1; + if (!update_timer_long_->isActive()) + update_timer_short_->start(); + // resets the timer to trigger after 2s + update_timer_long_->start(); } -void TocWidget::updateViewForce() +void TocWidget::updateViewNow() +{ + update_timer_long_->stop(); + update_timer_short_->start(); +} + +void TocWidget::realUpdateView() { - update_delay_ = 2000; if (!gui_view_.documentBufferView()) { tocTV->setModel(0); depthSL->setMaximum(0); @@ -456,7 +462,7 @@ void TocWidget::checkModelChanged() { if (!gui_view_.documentBufferView() || gui_view_.tocModels().model(current_type_) != tocTV->model()) - updateViewForce(); + realUpdateView(); } @@ -528,9 +534,6 @@ void TocWidget::init(QString const & str) typeCO->blockSignals(true); typeCO->setCurrentIndex(new_index); typeCO->blockSignals(false); - - // no delay when the whole outliner is reseted. - update_delay_ = 0; } } // namespace frontend diff --git a/src/frontends/qt4/TocWidget.h b/src/frontends/qt4/TocWidget.h index 39a6c2926a..ec1d5ad264 100644 --- a/src/frontends/qt4/TocWidget.h +++ b/src/frontends/qt4/TocWidget.h @@ -18,6 +18,7 @@ #include "Cursor.h" #include "FuncCode.h" +#include #include class QModelIndex; @@ -46,10 +47,10 @@ public: void checkModelChanged(); public Q_SLOTS: - /// Schedule new update of the display unless already scheduled. + /// Schedule an update of the dialog after a delay void updateView(); - /// Update the display of the dialog whilst it is still visible. - void updateViewForce(); + /// Schedule an update of the dialog immediately + void updateViewNow(); protected Q_SLOTS: /// @@ -72,6 +73,10 @@ protected Q_SLOTS: void showContextMenu(const QPoint & pos); +private Q_SLOTS: + /// Update the display of the dialog + void realUpdateView(); + private: /// void enableControls(bool enable = true); @@ -103,8 +108,12 @@ private: bool persistent_; /// GuiView & gui_view_; - // next delay for outliner update in ms. -1 when already scheduled. - int update_delay_; + // Timers for scheduling updates: one immediately and one after a delay. + // This is according to the logic of the previous code: when at rest, the + // update is carried out immediately, and when an update was done recently, + // we schedule an update to occur 2s after resting. + QTimer * update_timer_short_; + QTimer * update_timer_long_; }; } // namespace frontend