commit e0e765f6a98ac58aa7a7f422a747f8db3bff615d Author: Guillaume Munch <g...@lyx.org> Date: Mon Oct 10 00:36:26 2016 +0200
Get rid of dirty BufferView pointer Now that there is a signal to inform the controller when the buffer view has changed, it is no longer necessary to store a perishable pointer to a buffer view in the dialog view. (Indeed, it was only really useful for checking whether the new buffer view pointer was different from the old one.) TODO: other dialogs should be audited for similar hazards. --- src/frontends/qt4/GuiViewSource.cpp | 115 +++++++++++++++++------------------ src/frontends/qt4/GuiViewSource.h | 41 ++++++------ 2 files changed, 77 insertions(+), 79 deletions(-) diff --git a/src/frontends/qt4/GuiViewSource.cpp b/src/frontends/qt4/GuiViewSource.cpp index 1ed549a..60a75ad 100644 --- a/src/frontends/qt4/GuiViewSource.cpp +++ b/src/frontends/qt4/GuiViewSource.cpp @@ -47,10 +47,10 @@ using namespace std; namespace lyx { namespace frontend { -ViewSourceWidget::ViewSourceWidget() - : bv_(0), document_(new QTextDocument(this)), - highlighter_(new LaTeXHighlighter(document_)), - update_timer_(new QTimer(this)) +ViewSourceWidget::ViewSourceWidget(QWidget * parent) + : QWidget(parent), + document_(new QTextDocument(this)), + highlighter_(new LaTeXHighlighter(document_)) { setupUi(this); @@ -63,16 +63,9 @@ ViewSourceWidget::ViewSourceWidget() connect(masterPerspectiveCB, SIGNAL(toggled(bool)), this, SLOT(contentsChanged())); connect(updatePB, SIGNAL(clicked()), - this, SLOT(updateViewNow())); + this, SIGNAL(needUpdate())); connect(outputFormatCO, SIGNAL(activated(int)), this, SLOT(setViewFormat(int))); - connect(outputFormatCO, SIGNAL(activated(int)), - this, SLOT(contentsChanged())); - - // setting the update timer - update_timer_->setSingleShot(true); - connect(update_timer_, SIGNAL(timeout()), - this, SLOT(realUpdateView())); // setting a document at this point trigger an assertion in Qt // so we disable the signals here: @@ -93,7 +86,7 @@ ViewSourceWidget::ViewSourceWidget() } -void ViewSourceWidget::getContent(BufferView const * view, +void ViewSourceWidget::getContent(BufferView const & view, Buffer::OutputWhat output, docstring & str, string const & format, bool master) { @@ -102,33 +95,23 @@ void ViewSourceWidget::getContent(BufferView const * view, pit_type par_begin; pit_type par_end; - if (!view->cursor().selection()) { - par_begin = view->cursor().bottom().pit(); + if (!view.cursor().selection()) { + par_begin = view.cursor().bottom().pit(); par_end = par_begin; } else { - par_begin = view->cursor().selectionBegin().bottom().pit(); - par_end = view->cursor().selectionEnd().bottom().pit(); + par_begin = view.cursor().selectionBegin().bottom().pit(); + par_end = view.cursor().selectionEnd().bottom().pit(); } if (par_begin > par_end) swap(par_begin, par_end); odocstringstream ostr; - texrow_ = view->buffer() + texrow_ = view.buffer() .getSourceCode(ostr, format, par_begin, par_end + 1, output, master); //ensure that the last line can always be selected in its full width str = ostr.str() + "\n"; } -void ViewSourceWidget::setBufferView(BufferView const * bv) -{ - if (bv_ != bv) { - setText(); - bv_ = bv; - } - setEnabled(bv ? true : false); -} - - bool ViewSourceWidget::setText(QString const & qstr) { bool const changed = document_->toPlainText() != qstr; @@ -142,7 +125,7 @@ bool ViewSourceWidget::setText(QString const & qstr) void ViewSourceWidget::contentsChanged() { if (autoUpdateCB->isChecked()) - updateViewNow(); + Q_EMIT needUpdate(); } @@ -152,31 +135,42 @@ void ViewSourceWidget::setViewFormat(int const index) string format = fromqstr(outputFormatCO->itemData(index).toString()); if (view_format_ != format) { view_format_ = format; - // emit signal - formatChanged(); + Q_EMIT needUpdate(); } } -void ViewSourceWidget::updateView() +int ViewSourceWidget::updateDelay() const { const int long_delay = 400; const int short_delay = 60; // a shorter delay if just the current paragraph is shown - update_timer_->start((contentsCO->currentIndex() == 0) ? - short_delay : long_delay); + return (contentsCO->currentIndex() == 0) ? short_delay : long_delay; } -void ViewSourceWidget::updateViewNow() +void GuiViewSource::scheduleUpdate() +{ + update_timer_->start(widget_->updateDelay()); +} + + +void GuiViewSource::scheduleUpdateNow() { update_timer_->start(0); } -void ViewSourceWidget::realUpdateView() +void GuiViewSource::realUpdateView() { - if (!bv_) { + widget_->updateView(bufferview()); + updateTitle(); +} + + +void ViewSourceWidget::updateView(BufferView const * bv) +{ + if (!bv) { setText(); setEnabled(false); return; @@ -199,7 +193,7 @@ void ViewSourceWidget::realUpdateView() output = Buffer::OnlyBody; docstring content; - getContent(bv_, output, content, view_format_, + getContent(*bv, output, content, view_format_, masterPerspectiveCB->isChecked()); QString old = document_->toPlainText(); QString qcontent = toqstr(content); @@ -218,7 +212,7 @@ void ViewSourceWidget::realUpdateView() } #endif // prevent gotoCursor() - viewSourceTV->blockSignals(true); + QSignalBlocker blocker(viewSourceTV); bool const changed = setText(qcontent); if (changed && !texrow_) { @@ -254,7 +248,7 @@ void ViewSourceWidget::realUpdateView() } else if (texrow_) { // Use the available position-to-row conversion to highlight // the current selection in the source - std::pair<int,int> rows = texrow_->rowFromCursor(bv_->cursor()); + std::pair<int,int> rows = texrow_->rowFromCursor(bv->cursor()); int const beg_row = rows.first; int const end_row = rows.second; @@ -306,7 +300,6 @@ void ViewSourceWidget::realUpdateView() viewSourceTV->setTextCursor(c); viewSourceTV->horizontalScrollBar()->setValue(h_scroll); } // else if (texrow) - viewSourceTV->blockSignals(false); } @@ -342,18 +335,15 @@ void ViewSourceWidget::goToCursor() const -void ViewSourceWidget::updateDefaultFormat() +void ViewSourceWidget::updateDefaultFormat(BufferView const & bv) { - if (!bv_) - return; - - outputFormatCO->blockSignals(true); + QSignalBlocker blocker(outputFormatCO); outputFormatCO->clear(); outputFormatCO->addItem(qt_("Default"), QVariant(QString("default"))); int index = 0; - vector<string> tmp = bv_->buffer().params().backends(); + vector<string> tmp = bv.buffer().params().backends(); vector<string>::const_iterator it = tmp.begin(); vector<string>::const_iterator en = tmp.end(); for (; it != en; ++it) { @@ -370,8 +360,6 @@ void ViewSourceWidget::updateDefaultFormat() index = outputFormatCO->count() -1; } setViewFormat(index); - - outputFormatCO->blockSignals(false); } @@ -414,31 +402,39 @@ void ViewSourceWidget::restoreSession(QString const & session_key) .toBool(); autoUpdateCB->setChecked(checked); if (checked) - updateView(); + Q_EMIT needUpdate(); } GuiViewSource::GuiViewSource(GuiView & parent, Qt::DockWidgetArea area, Qt::WindowFlags flags) - : DockView(parent, "view-source", qt_("Code Preview"), area, flags) + : DockView(parent, "view-source", qt_("Code Preview"), area, flags), + widget_(new ViewSourceWidget(this)), + update_timer_(new QTimer(this)) { - widget_ = new ViewSourceWidget; setWidget(widget_); - connect(widget_, SIGNAL(formatChanged()), this, SLOT(updateTitle())); + + // setting the update timer + update_timer_->setSingleShot(true); + connect(update_timer_, SIGNAL(timeout()), + this, SLOT(realUpdateView())); + + connect(widget_, SIGNAL(needUpdate()), this, SLOT(scheduleUpdateNow())); } -GuiViewSource::~GuiViewSource() +void GuiViewSource::on_bufferViewChanged() { - delete widget_; + widget_->setText(); + widget_->setEnabled((bool)bufferview()); } void GuiViewSource::updateView() { if (widget_->autoUpdateCB->isChecked()) { - widget_->setBufferView(bufferview()); - widget_->updateView(); + widget_->setEnabled((bool)bufferview()); + scheduleUpdate(); } widget_->masterPerspectiveCB->setEnabled(buffer().parent()); updateTitle(); @@ -447,8 +443,9 @@ void GuiViewSource::updateView() void GuiViewSource::enableView(bool enable) { - widget_->setBufferView(bufferview()); - widget_->updateDefaultFormat(); + widget_->setEnabled((bool)bufferview()); + if (bufferview()) + widget_->updateDefaultFormat(*bufferview()); if (!enable) // In the opposite case, updateView() will be called anyway. widget_->contentsChanged(); diff --git a/src/frontends/qt4/GuiViewSource.h b/src/frontends/qt4/GuiViewSource.h index 33a9c13..f2bc1ce 100644 --- a/src/frontends/qt4/GuiViewSource.h +++ b/src/frontends/qt4/GuiViewSource.h @@ -43,29 +43,27 @@ class ViewSourceWidget : public QWidget, public Ui::ViewSourceUi Q_OBJECT public: - ViewSourceWidget(); - /// - void setBufferView(BufferView const * bv); + ViewSourceWidget(QWidget * parent); /// returns true if the string has changed bool setText(QString const & qstr = QString()); /// void saveSession(QString const & session_key) const; /// void restoreSession(QString const & session_key); + /// + int updateDelay() const; protected: /// void resizeEvent (QResizeEvent * event); public Q_SLOTS: - /// schedule an update after delay - void updateView(); - /// schedule an update now - void updateViewNow(); + /// + void updateView(BufferView const * bv); /// void setViewFormat(int const index); // - void updateDefaultFormat(); + void updateDefaultFormat(BufferView const & bv); /// void contentsChanged(); /// @@ -74,28 +72,20 @@ public Q_SLOTS: docstring currentFormatName(BufferView const * bv) const; Q_SIGNALS: - void formatChanged() const; - -private Q_SLOTS: - /// update content - void realUpdateView(); + void needUpdate() const; private: /// Get the source code of selected paragraphs, or the whole document. - void getContent(BufferView const * view, Buffer::OutputWhat output, + void getContent(BufferView const & view, Buffer::OutputWhat output, docstring & str, std::string const & format, bool master); /// Grab double clicks on the viewport bool eventFilter(QObject * obj, QEvent * event); /// - BufferView const * bv_; - /// QTextDocument * document_; /// LaTeX syntax highlighter LaTeXHighlighter * highlighter_; /// std::string view_format_; - /// - QTimer * update_timer_; /// TexRow information from the last source view. If TexRow is unavailable /// for the last format then texrow_ is null. unique_ptr<TexRow> texrow_; @@ -112,8 +102,6 @@ public: Qt::DockWidgetArea area = Qt::BottomDockWidgetArea, ///< Position of the dock (and also drawer) Qt::WindowFlags flags = 0); - ~GuiViewSource(); - /// Controller inherited method. ///@{ bool initialiseParams(std::string const & source); @@ -129,13 +117,26 @@ public: bool wantInitialFocus() const { return false; } ///@} +public Q_SLOTS: + /// + void on_bufferViewChanged();//override + private Q_SLOTS: /// The title displayed by the dialog reflects source type. void updateTitle(); + /// schedule an update after delay + void scheduleUpdate(); + /// schedule an update now + void scheduleUpdateNow(); + + /// update content + void realUpdateView(); private: /// The encapsulated widget. ViewSourceWidget * widget_; + /// + QTimer * update_timer_; }; } // namespace frontend