commit bf7fc19d116871e9071c017ed9a6e47bcccb38c0
Author: Jean-Marc Lasgouttes <[email protected]>
Date: Thu Jul 17 13:47:29 2025 +0200
Fix update of statistics
The test (has the buffer changed?) was not sufficient, as the
selection matters too.
Move the optimization out of Statistics::update() and use it only for
the automatic update of the status bar.
Improve the test to catch the case where the selection changes.
Fixes bug #13197.
---
src/BufferView.cpp | 2 +-
src/Statistics.cpp | 15 ++++++++++-----
src/Statistics.h | 11 ++++++++---
src/frontends/qt/GuiView.cpp | 6 ++++--
4 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 517ef4185e..a7a5ad93ea 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -2145,7 +2145,7 @@ void BufferView::dispatch(FuncRequest const & cmd,
DispatchResult & dr)
}
case LFUN_STATISTICS: {
- Statistics & stats = buffer_.statistics();
+ Statistics stats;
stats.update(cur);
int const words = stats.word_count;
int const chars = stats.char_count;
diff --git a/src/Statistics.cpp b/src/Statistics.cpp
index 31e4105895..c6a0e0097d 100644
--- a/src/Statistics.cpp
+++ b/src/Statistics.cpp
@@ -31,14 +31,11 @@ using namespace support;
void Statistics::update(CursorData const & cur, bool skip)
{
- // early exit if the buffer has not changed since last time
- if (stats_id_ == cur.buffer()->id())
- return;
-
// reset counts
*this = Statistics();
skip_no_output_ = skip;
- stats_id_ = cur.buffer()->id();
+ last_buffer_id_ = cur.buffer()->id();
+ last_cur_ = cur;
if (cur.selection()) {
if (cur.inMathed())
@@ -125,5 +122,13 @@ void Statistics::update(Paragraph const & par, pos_type
from, pos_type to)
}
+bool Statistics::needsUpdate(CursorData const & cur) const
+{
+ return cur.buffer()->id() != last_buffer_id_
+ || (cur.selection() && cur != last_cur_)
+ || cur.selection() != last_cur_.selection();
+}
+
+
} // namespace lyx
diff --git a/src/Statistics.h b/src/Statistics.h
index 4ccd276752..8c3c824419 100644
--- a/src/Statistics.h
+++ b/src/Statistics.h
@@ -12,13 +12,13 @@
#ifndef STATISTICS_H
#define STATISTICS_H
+#include "Cursor.h"
+
#include "support/docstring.h"
#include "support/types.h"
namespace lyx {
-class CursorData;
-class CursorSlice;
class Text;
class Paragraph;
@@ -34,6 +34,9 @@ public:
/// Helper: count chars and words in the paragraphs of \c text
void update(Text const & text);
+ // Did the buffer or the selection change since last update?
+ bool needsUpdate(CursorData const & cur) const;
+
// Number of words
int word_count = 0;
// Number of non blank characters
@@ -59,7 +62,9 @@ private:
// Used in the code to track status
bool inword_ = false;
// The buffer id at last statistics computation.
- int stats_id_ = -1;
+ int last_buffer_id_ = -1;
+ // The selection at last statistics computation.
+ CursorData last_cur_;
};
}
diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp
index 91180c79b2..3edc86179c 100644
--- a/src/frontends/qt/GuiView.cpp
+++ b/src/frontends/qt/GuiView.cpp
@@ -1588,11 +1588,13 @@ void GuiView::showStats()
return;
// Don't attempt to calculate stats if
- // the buffer is busy as this might crash (#12935)
+ // * the buffer is busy, as this might crash (#12935)
+ // * the statistics do not need to be updated
Statistics & statistics = buf->statistics();
- if (!busy() && !bv->busy())
+ if (!busy() && !bv->busy() && statistics.needsUpdate(cur))
statistics.update(cur);
+
QStringList stats;
if (word_count_enabled_) {
int const words = statistics.word_count -
bv->stats_ref_value_w();
--
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs