commit 685fc1aa0f4babb52f9b1698a2f7a5bae087ab7c
Author: Guillaume Munch <[email protected]>
Date: Sat Jan 30 23:14:36 2016 +0000
Automatically show the review toolbar if the document has tracked changes
(#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.
diff --git a/lib/ui/default.ui b/lib/ui/default.ui
index 51a7f9b..4a1e154 100644
--- a/lib/ui/default.ui
+++ b/lib/ui/default.ui
@@ -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
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index e2185fb..ac64cf2 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -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
diff --git a/src/Buffer.h b/src/Buffer.h
index 3f5ab22..d4074b0 100644
--- a/src/Buffer.h
+++ b/src/Buffer.h
@@ -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
diff --git a/src/Changes.cpp b/src/Changes.cpp
index 9fa46f9..616daf0 100644
--- a/src/Changes.cpp
+++ b/src/Changes.cpp
@@ -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
diff --git a/src/Changes.h b/src/Changes.h
index 2771047..1d55b03 100644
--- a/src/Changes.h
+++ b/src/Changes.h
@@ -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_;
};
diff --git a/src/Cursor.cpp b/src/Cursor.cpp
index ed182ac..1f84f45 100644
--- a/src/Cursor.cpp
+++ b/src/Cursor.cpp
@@ -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();
}
diff --git a/src/DispatchResult.h b/src/DispatchResult.h
index 21dfa4f..f546be2 100644
--- a/src/DispatchResult.h
+++ b/src/DispatchResult.h
@@ -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_;
};
diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp
index 9fe4de8..7f736fc 100644
--- a/src/Paragraph.cpp
+++ b/src/Paragraph.cpp
@@ -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);
diff --git a/src/Paragraph.h b/src/Paragraph.h
index 73de6c1..6f8d248 100644
--- a/src/Paragraph.h
+++ b/src/Paragraph.h
@@ -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;
///
diff --git a/src/frontends/qt4/GuiApplication.cpp
b/src/frontends/qt4/GuiApplication.cpp
index 6fb5499..d52fe56 100644
--- a/src/frontends/qt4/GuiApplication.cpp
+++ b/src/frontends/qt4/GuiApplication.cpp
@@ -1395,6 +1395,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
diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
index 8133ac2..d228ca4 100644
--- a/src/frontends/qt4/GuiView.cpp
+++ b/src/frontends/qt4/GuiView.cpp
@@ -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;