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

Reply via email to