mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 10:00:33 +00:00
Run updateBuffer when adding/merging changes
Following 4a4ded22
, the enabling of some change-related functions is
handled in updateBuffer. However, this method is not ran at every
document change for performance reasons.
This patch adds code to every place that modifies
Paragraph::Private::changes_ that checks whether the `changedness' of
the paragraph, err... changes.
To this end, a new helper struct is introduced that remembers
paragraph state at contruction time, and compares it to new state in
the destructor.
New forceUpdate/needUpdate methods are added to Buffer class, since
the cursor is in general not available in the places where these
changes are made.
Fixes bug #12074.
This commit is contained in:
parent
e6bc78d9e8
commit
f3a0e8ff9a
@ -354,6 +354,9 @@ public:
|
||||
/// whether the bibinfo cache is valid
|
||||
mutable bool bibinfo_cache_valid_;
|
||||
|
||||
///
|
||||
mutable bool need_update;
|
||||
|
||||
private:
|
||||
int word_count_;
|
||||
int char_count_;
|
||||
@ -460,7 +463,7 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_,
|
||||
internal_buffer(false), read_only(readonly_), file_fully_loaded(false),
|
||||
need_format_backup(false), ignore_parent(false), macro_lock(false),
|
||||
externally_modified_(false), bibinfo_cache_valid_(false),
|
||||
word_count_(0), char_count_(0), blank_count_(0)
|
||||
need_update(false), word_count_(0), char_count_(0), blank_count_(0)
|
||||
{
|
||||
refreshFileMonitor();
|
||||
if (!cloned_buffer_) {
|
||||
@ -5286,6 +5289,18 @@ void Buffer::updateBuffer(ParIterator & parit, UpdateType utype, bool const dele
|
||||
}
|
||||
|
||||
|
||||
void Buffer::forceUpdate() const
|
||||
{
|
||||
d->need_update = true;
|
||||
}
|
||||
|
||||
|
||||
bool Buffer::needUpdate() const
|
||||
{
|
||||
return d->need_update;
|
||||
}
|
||||
|
||||
|
||||
int Buffer::spellCheck(DocIterator & from, DocIterator & to,
|
||||
WordLangTuple & word_lang, docstring_list & suggestions) const
|
||||
{
|
||||
|
@ -735,6 +735,10 @@ public:
|
||||
void updateBuffer(UpdateScope scope, UpdateType utype) const;
|
||||
///
|
||||
void updateBuffer(ParIterator & parit, UpdateType utype, bool const deleted = false) const;
|
||||
/// Forces an updateBuffer() call
|
||||
void forceUpdate() const;
|
||||
/// Do we need to call updateBuffer()?
|
||||
bool needUpdate() const;
|
||||
|
||||
/// Spellcheck starting from \p from.
|
||||
/// \p from initial position, will then points to the next misspelled
|
||||
@ -771,7 +775,7 @@ public:
|
||||
int wordCount() const;
|
||||
int charCount(bool with_blanks) const;
|
||||
|
||||
/// FIXME: dummy function for now
|
||||
///
|
||||
bool areChangesPresent() const;
|
||||
|
||||
///
|
||||
|
@ -2417,7 +2417,7 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0)
|
||||
// Do we have a selection?
|
||||
theSelection().haveSelection(cursor().selection());
|
||||
|
||||
if (cur.needBufferUpdate()) {
|
||||
if (cur.needBufferUpdate() || buffer().needUpdate()) {
|
||||
cur.clearBufferUpdate();
|
||||
buffer().updateBuffer();
|
||||
}
|
||||
|
@ -564,6 +564,48 @@ Paragraph::Private::Private(Private const & p, Paragraph * owner,
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Paragraph
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace {
|
||||
|
||||
/** This helper class should be instantiated at the start of methods
|
||||
* that can create or merge changes. If as a result the value of
|
||||
* Paragraph::isChanged is modified, it makes sure that updateBuffer()
|
||||
* will be run.
|
||||
*/
|
||||
struct ChangesMonitor {
|
||||
///
|
||||
ChangesMonitor(Paragraph & par)
|
||||
: par_(par), was_changed_(par.isChanged()) {}
|
||||
///
|
||||
~ChangesMonitor()
|
||||
{
|
||||
/* We may need to run updateBuffer to check whether the buffer
|
||||
* contains changes (and toggle the changes toolbar). We do it
|
||||
* when:
|
||||
* 1. the `changedness' of the paragraph has changed,
|
||||
* 2. and we are not in the situation where the buffer has changes
|
||||
* and new changes are added to the paragraph.
|
||||
*/
|
||||
if (par_.isChanged() != was_changed_
|
||||
&& par_.inInset().isBufferValid()
|
||||
&& !(par_.inInset().buffer().areChangesPresent() && par_.isChanged()))
|
||||
par_.inInset().buffer().forceUpdate();
|
||||
}
|
||||
|
||||
private:
|
||||
///
|
||||
Paragraph const & par_;
|
||||
///
|
||||
bool was_changed_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void Paragraph::addChangesToToc(DocIterator const & cdit, Buffer const & buf,
|
||||
bool output_active, TocBackend & backend) const
|
||||
{
|
||||
@ -629,6 +671,9 @@ Change Paragraph::parEndChange() const
|
||||
|
||||
void Paragraph::setChange(Change const & change)
|
||||
{
|
||||
// Make sure that Buffer::hasChangesPresent is updated
|
||||
ChangesMonitor cm(*this);
|
||||
|
||||
// beware of the imaginary end-of-par character!
|
||||
d->changes_.set(change, 0, size() + 1);
|
||||
|
||||
@ -655,6 +700,9 @@ void Paragraph::setChange(Change const & change)
|
||||
|
||||
void Paragraph::setChange(pos_type pos, Change const & change)
|
||||
{
|
||||
// Make sure that Buffer::hasChangesPresent is updated
|
||||
ChangesMonitor cm(*this);
|
||||
|
||||
LASSERT(pos >= 0 && pos <= size(), return);
|
||||
d->changes_.set(change, pos);
|
||||
|
||||
@ -674,6 +722,9 @@ Change const & Paragraph::lookupChange(pos_type pos) const
|
||||
|
||||
void Paragraph::acceptChanges(pos_type start, pos_type end)
|
||||
{
|
||||
// Make sure that Buffer::hasChangesPresent is updated
|
||||
ChangesMonitor cm(*this);
|
||||
|
||||
LASSERT(start >= 0 && start <= size(), return);
|
||||
LASSERT(end > start && end <= size() + 1, return);
|
||||
|
||||
@ -712,6 +763,9 @@ void Paragraph::rejectChanges(pos_type start, pos_type end)
|
||||
LASSERT(start >= 0 && start <= size(), return);
|
||||
LASSERT(end > start && end <= size() + 1, return);
|
||||
|
||||
// Make sure that Buffer::hasChangesPresent is updated
|
||||
ChangesMonitor cm(*this);
|
||||
|
||||
for (pos_type pos = start; pos < end; ++pos) {
|
||||
switch (lookupChange(pos).type) {
|
||||
case Change::UNCHANGED:
|
||||
@ -747,6 +801,9 @@ void Paragraph::Private::insertChar(pos_type pos, char_type c,
|
||||
{
|
||||
LASSERT(pos >= 0 && pos <= int(text_.size()), return);
|
||||
|
||||
// Make sure that Buffer::hasChangesPresent is updated
|
||||
ChangesMonitor cm(*owner_);
|
||||
|
||||
// track change
|
||||
changes_.insert(change, pos);
|
||||
|
||||
@ -779,6 +836,9 @@ bool Paragraph::insertInset(pos_type pos, Inset * inset,
|
||||
LASSERT(inset, return false);
|
||||
LASSERT(pos >= 0 && pos <= size(), return false);
|
||||
|
||||
// Make sure that Buffer::hasChangesPresent is updated
|
||||
ChangesMonitor cm(*this);
|
||||
|
||||
// Paragraph::insertInset() can be used in cut/copy/paste operation where
|
||||
// d->inset_owner_ is not set yet.
|
||||
if (d->inset_owner_ && !d->inset_owner_->insetAllowed(inset->lyxCode()))
|
||||
@ -801,6 +861,9 @@ bool Paragraph::eraseChar(pos_type pos, bool trackChanges)
|
||||
{
|
||||
LASSERT(pos >= 0 && pos <= size(), return false);
|
||||
|
||||
// Make sure that Buffer::hasChangesPresent is updated
|
||||
ChangesMonitor cm(*this);
|
||||
|
||||
// keep the logic here in sync with the logic of isMergedOnEndOfParDeletion()
|
||||
|
||||
if (trackChanges) {
|
||||
@ -1707,6 +1770,9 @@ void Paragraph::insert(pos_type pos, docstring const & str,
|
||||
void Paragraph::appendChar(char_type c, Font const & font,
|
||||
Change const & change)
|
||||
{
|
||||
// Make sure that Buffer::hasChangesPresent is updated
|
||||
ChangesMonitor cm(*this);
|
||||
|
||||
// track change
|
||||
d->changes_.insert(change, d->text_.size());
|
||||
// when appending characters, no need to update tables
|
||||
@ -1719,6 +1785,9 @@ void Paragraph::appendChar(char_type c, Font const & font,
|
||||
void Paragraph::appendString(docstring const & s, Font const & font,
|
||||
Change const & change)
|
||||
{
|
||||
// Make sure that Buffer::hasChangesPresent is updated
|
||||
ChangesMonitor cm(*this);
|
||||
|
||||
pos_type end = s.size();
|
||||
size_t oldsize = d->text_.size();
|
||||
size_t newsize = oldsize + end;
|
||||
|
Loading…
Reference in New Issue
Block a user