]> git.lyx.org Git - features.git/commitdiff
Automatically show the review toolbar if the document has tracked changes
authorGuillaume Munch <gm@lyx.org>
Sat, 30 Jan 2016 23:14:36 +0000 (23:14 +0000)
committerRichard Heck <rgheck@lyx.org>
Sun, 29 May 2016 21:55:42 +0000 (17:55 -0400)
(#8738)

For efficiency, we add a new flag to the buffer indicating when changes are
present. This flag is updated at each buffer update, and also when explicitly
requested via a dispatch result flag.

lib/ui/default.ui
src/Buffer.cpp
src/Buffer.h
src/Changes.cpp
src/Changes.h
src/Cursor.cpp
src/DispatchResult.h
src/Paragraph.cpp
src/Paragraph.h
src/frontends/qt4/GuiApplication.cpp
src/frontends/qt4/GuiView.cpp

index 51a7f9b90e5eaf85c81b70431687e8cd48ffb1e2..4a1e154aab7c19ae1168a7b0d4e57659bb5b6197 100644 (file)
@@ -34,7 +34,8 @@ Include "stdtoolbars.inc"
 # math: the toolbar is visible only when in math
 # mathmacrotemplate: the toolbar is visible only when in a macro definition
 # table: the toolbar is visible only when in a table
-# review: the toolbar is visible only when inside a tracked change
+# review: the toolbar is visible only when tracked changes are present or
+#         change tracking is enabled
 # ipa: the toolbar is only visible when inside an ipa inset
 #
 # top: the toolbar should be at the top of the window
index e2185fbd897a18711e63f3a4c0335fa66ad007d9..ac64cf2f2630a82ca9a41d7af31bc7f894ca3447 100644 (file)
@@ -370,6 +370,10 @@ public:
                + (with_blanks ? blank_count_ : 0);
        }
 
+       // does the buffer contains tracked changes? (if so, we automatically
+       // display the review toolbar)
+       mutable bool tracked_changes_present_;
+
 private:
        /// So we can force access via the accessors.
        mutable Buffer const * parent_buffer;
@@ -442,6 +446,7 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_,
        preview_file_ = cloned_buffer_->d->preview_file_;
        preview_format_ = cloned_buffer_->d->preview_format_;
        preview_error_ = cloned_buffer_->d->preview_error_;
+       tracked_changes_present_ = cloned_buffer_->d->tracked_changes_present_;
 }
 
 
@@ -2768,6 +2773,8 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr)
                if (params().save_transient_properties)
                        undo().recordUndoBufferParams(CursorData());
                params().track_changes = !params().track_changes;
+               if (!params().track_changes)
+                       dr.forceChangesUpdate();
                break;
 
        case LFUN_CHANGES_OUTPUT:
@@ -4584,6 +4591,7 @@ void Buffer::updateBuffer(UpdateScope scope, UpdateType utype) const
        // update all caches
        clearReferenceCache();
        updateMacros();
+       setChangesPresent(false);
 
        Buffer & cbuf = const_cast<Buffer &>(*this);
 
@@ -4847,6 +4855,9 @@ void Buffer::updateBuffer(ParIterator & parit, UpdateType utype) const
                // set the counter for this paragraph
                d->setLabel(parit, utype);
 
+               // update change-tracking flag 
+               parit->addChangesToBuffer(*this);
+
                // now the insets
                InsetList::const_iterator iit = parit->insetList().begin();
                InsetList::const_iterator end = parit->insetList().end();
@@ -5111,4 +5122,29 @@ string Buffer::includedFilePath(string const & name, string const & ext) const
                                   from_utf8(filePath())));
 }
 
+
+void Buffer::setChangesPresent(bool b) const
+{
+       d->tracked_changes_present_ = b;
+}
+
+
+bool Buffer::areChangesPresent() const
+{
+       return d->tracked_changes_present_;
+}
+
+
+void Buffer::updateChangesPresent() const
+{
+       LYXERR(Debug::CHANGES, "Buffer::updateChangesPresent");
+       setChangesPresent(false);
+       ParConstIterator it = par_iterator_begin();
+       ParConstIterator const end = par_iterator_end();
+       for (; !areChangesPresent() && it != end; ++it)
+               it->addChangesToBuffer(*this);
+}
+
+
+
 } // namespace lyx
index 3f5ab2231bdc0d194d4bbccb0f22db3760028f1f..d4074b0fdb3b916e6d6bae2a918292ba12171015 100644 (file)
@@ -760,6 +760,12 @@ public:
        int wordCount() const;
        int charCount(bool with_blanks) const;
 
+       // this is const because it does not modify the buffer's real contents,
+       // only the mutable flag.
+       void setChangesPresent(bool) const;
+       bool areChangesPresent() const;
+       void updateChangesPresent() const;
+
 private:
        friend class MarkAsExporting;
        /// mark the buffer as busy exporting something, or not
index 9fa46f92a36708281f150212012dc87514696464..616daf029f50aa615d4bba3a5a919d6cbf8fc798 100644 (file)
@@ -298,8 +298,21 @@ bool Changes::isChanged(pos_type const start, pos_type const end) const
 }
 
 
+bool Changes::isChanged() const
+{
+       ChangeTable::const_iterator it = table_.begin();
+       ChangeTable::const_iterator const itend = table_.end();
+       for (; it != itend; ++it) {
+               if (it->change.changed())
+                       return true;
+       }
+       return false;
+}
+
+
 void Changes::merge()
 {
+       bool merged = false;
        ChangeTable::iterator it = table_.begin();
 
        while (it != table_.end()) {
@@ -312,6 +325,7 @@ void Changes::merge()
                                << it->range.start);
 
                        table_.erase(it);
+                       merged = true;
                        // start again
                        it = table_.begin();
                        continue;
@@ -330,6 +344,7 @@ void Changes::merge()
                        (it + 1)->change.changetime = max(it->change.changetime,
                                                          (it + 1)->change.changetime);
                        table_.erase(it);
+                       merged = true;
                        // start again
                        it = table_.begin();
                        continue;
@@ -337,6 +352,8 @@ void Changes::merge()
 
                ++it;
        }
+       if (merged && !isChanged())
+               is_update_required_ = true;
 }
 
 
@@ -517,4 +534,15 @@ void Changes::addToToc(DocIterator const & cdit, Buffer const & buffer,
        }
 }
 
+
+void Changes::updateBuffer(Buffer const & buf)
+{
+       is_update_required_ = false;
+       if (!buf.areChangesPresent() && isChanged())
+               buf.setChangesPresent(true);
+}
+
+
+
+
 } // namespace lyx
index 27710476a66d5349d784d3af5bf872b033f8ec6f..1d55b03b548acd191cb36d77d764bc16df0bc130 100644 (file)
@@ -78,6 +78,8 @@ class BufferParams;
 
 class Changes {
 public:
+       Changes() : is_update_required_(false) {}
+
        /// set the pos to the given change
        void set(Change const & change, pos_type pos);
        /// set the range (excluding end) to the given change
@@ -98,6 +100,8 @@ public:
 
        /// return true if there is a change in the given range (excluding end)
        bool isChanged(pos_type start, pos_type end) const;
+       ///
+       bool isChanged() const;
 
        /// return true if the whole range is deleted
        bool isDeleted(pos_type start, pos_type end) const;
@@ -119,6 +123,11 @@ public:
        void addToToc(DocIterator const & cdit, Buffer const & buffer,
                bool output_active) const;
 
+       ///
+       void updateBuffer(Buffer const & buf);
+       ///
+       bool isUpdateRequired() const { return is_update_required_; }
+
 private:
        class Range {
        public:
@@ -161,6 +170,10 @@ private:
 
        /// table of changes, every row a change and range descriptor
        ChangeTable table_;
+
+       /// signals that the buffer's flag tracked_changes_present_ needs to be
+       /// recalculated
+       bool is_update_required_;
 };
 
 
index ed182ace64de377e72099c7f7d49eeb634d2be34..1f84f45feaace06c37a8156e9c4fa35b7c829537 100644 (file)
@@ -2426,6 +2426,12 @@ void Cursor::checkBufferStructure()
                // In case the master has no gui associated with it,
                // the TocItem is not updated (part of bug 5699).
                buffer()->tocBackend().updateItem(*this);
+
+       // If the last tracked change of the paragraph has just been
+       // deleted, then we need to recompute the buffer flag
+       // tracked_changes_present_.
+       if (inTexted() && paragraph().isChangeUpdateRequired())
+               disp_.forceChangesUpdate();
 }
 
 
index 21dfa4f92bd018dcb44d45e3f9be3b71da36a50f..f546be27bc1cf2754ecbe068b15b9b4a574fcda9 100644 (file)
@@ -29,7 +29,8 @@ public:
                        error_(false),
                        update_(Update::None),
                        need_buf_update_(false),
-                       need_msg_update_(true)
+                       need_msg_update_(true),
+                       need_changes_update_(false)
        {}
        ///
        DispatchResult(bool dispatched, Update::flags f) :
@@ -37,7 +38,8 @@ public:
                        error_(false),
                        update_(f),
                        need_buf_update_(false),
-                       need_msg_update_(true)
+                       need_msg_update_(true),
+                       need_changes_update_(false)
        {}
        ///
        bool dispatched() const { return dispatched_; }
@@ -57,12 +59,14 @@ public:
        Update::flags screenUpdate() const { return update_; }
        ///
        void screenUpdate(Update::flags f) { update_ = f; }
+
        /// Does the buffer need updating?
        bool needBufferUpdate() const { return need_buf_update_; }
        /// Force the buffer to be updated
        void forceBufferUpdate() { need_buf_update_ = true; }
        /// Clear the flag indicating we need an update
        void clearBufferUpdate() { need_buf_update_ = false; }
+
        /// Do we need to display a message in the status bar?
        bool needMessageUpdate() const { return need_msg_update_; }
        /// Force the message to be displayed
@@ -70,6 +74,14 @@ public:
        /// Clear the flag indicating we need to display the message
        void clearMessageUpdate() { need_msg_update_ = false; }
 
+       /// Do we need to update the change tracking presence flag?
+       bool needChangesUpdate() { return need_changes_update_; }
+       /// Force the change tracking presence flag to be updated
+       void forceChangesUpdate() { need_changes_update_ = true; }
+       /// Clear the flag indicating that we need to update the change tracking
+       /// presence flag
+       void clearChangesUpdate() { need_changes_update_ = false; }
+
 private:
        /// was the event fully dispatched?
        bool dispatched_;
@@ -83,6 +95,8 @@ private:
        bool need_buf_update_;
        ///
        bool need_msg_update_;
+       ///
+       bool need_changes_update_;
 };
 
 
index a405b6a806d7d2fd8f49f8bbb08b339a16e2c73a..d6106b37d4f919b4e31abb8f7882735fc077feaf 100644 (file)
@@ -562,6 +562,18 @@ void Paragraph::addChangesToToc(DocIterator const & cdit,
 }
 
 
+void Paragraph::addChangesToBuffer(Buffer const & buf) const
+{
+       d->changes_.updateBuffer(buf);
+}
+
+
+bool Paragraph::isChangeUpdateRequired() const
+{
+       return d->changes_.isUpdateRequired();
+}
+
+
 bool Paragraph::isDeleted(pos_type start, pos_type end) const
 {
        LASSERT(start >= 0 && start <= size(), return false);
index 73de6c173b6112d08bca2c9d4e8a9b19384d7c23..6f8d248ca0625e0019eb46c0ed7a0076252ff706 100644 (file)
@@ -153,6 +153,10 @@ public:
        ///
        void addChangesToToc(DocIterator const & cdit, Buffer const & buf,
                bool output_active) const;
+       /// set the buffer flag if there are changes in the paragraph
+       void addChangesToBuffer(Buffer const & buf) const;
+       ///
+       bool isChangeUpdateRequired() const;
        ///
        Language const * getParLanguage(BufferParams const &) const;
        ///
index 8b613794df03bfbe45baeb78d251d41d0a3dbadd..d64c9619fcccb07c4ccf0220793ef7693077d947 100644 (file)
@@ -1399,6 +1399,9 @@ void GuiApplication::updateCurrentView(FuncRequest const & cmd, DispatchResult &
                if (dr.needBufferUpdate()) {
                        bv->cursor().clearBufferUpdate();
                        bv->buffer().updateBuffer();
+               } else if (dr.needChangesUpdate()) {
+                       // updateBuffer() already updates the change-tracking presence flag
+                       bv->buffer().updateChangesPresent();
                }
                // BufferView::update() updates the ViewMetricsInfo and
                // also initializes the position cache for all insets in
index 8133ac246f7ddbf3f80a2a463964bd1ff517044f..d228ca470dbe762ddfb8aa43e309972805848fc3 100644 (file)
@@ -1552,8 +1552,9 @@ void GuiView::updateToolbars()
                        context |= Toolbars::MATH;
                if (lyx::getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled())
                        context |= Toolbars::TABLE;
-               if (lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled()
-                       && lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onOff(true))
+               if (currentBufferView()->buffer().areChangesPresent()
+                   || (lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled()
+                       && lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onOff(true)))
                        context |= Toolbars::REVIEW;
                if (lyx::getStatus(FuncRequest(LFUN_IN_MATHMACROTEMPLATE)).enabled())
                        context |= Toolbars::MATHMACROTEMPLATE;