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

Reply via email to