[patch] Selection stats in statusbar

Pavel Sanda sanda at lyx.org
Sat Jul 30 22:35:30 UTC 2022


On Fri, Jul 15, 2022 at 12:05:25AM +0200, Pavel Sanda wrote:
> On Thu, Jul 14, 2022 at 09:31:06AM +0200, Daniel wrote:
> > >The drawback is that's it's difficult to understand the interaction between
> > >the two timers now. I stared on the code for couple minutes and it was
> > >not clear to me what is the idea behind your stop/start changes.
> > 
> > Some comments would probably have been good. I could try to add them if
> > there is interest.
> 
> If I find little time I'll try the QTimer route and see whether we converge :)

So I tried to find the best from solution from both worlds.
In the attached patch we use QTimer (0.5s between updates) for updating stats.
To avoid tricky interactions with another timer and current messages in
status bar I simply cretaed completely new label next to the slider, so it's
independent mechanism with no interactions.

On top of that its possible to disable the visibility via context menu, but it's
part of session not new RC variable, which seems good enough compromise.

The update interval is now 0.5s, let me know if there is any slugishness
in your testing. I didn't see any, but I can easliy increase to 1s if need be.

Any objections now?

Pavel
-------------- next part --------------
diff --git a/lib/ui/stdcontext.inc b/lib/ui/stdcontext.inc
index bd94e7c904..8c79c5f351 100644
--- a/lib/ui/stdcontext.inc
+++ b/lib/ui/stdcontext.inc
@@ -731,6 +731,8 @@ Menuset
 		Separator
 		Item "Show Zoom Level|Z" "ui-toggle zoomlevel"
 		Item "Show Zoom Slider|S" "ui-toggle zoomslider"
+		Separator
+		Item "Show Document Statistics|D" "ui-toggle statistics"
 	End
 
 End
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 992b47a441..ae8245d070 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -4097,6 +4097,7 @@ void LyXAction::init()
                frame      : Toggle visibility of the frames around editing window.\n
                zoomslider : Toggle visibility of the zoom slider in statusbar.\n
                zoomlevel  : Toggle visibility of the zoom level display in statusbar.\n
+               statistics : Toggle visibility of the document statistics count in statusbar.\n
                fullscreen : Toggle fullscreen mode. This also covers calling the
                             previous functions. However #LFUN_TOOLBAR_TOGGLE for the
                             custom tweaks of the toolbars should be used.
diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp
index 8f6bf07115..c381d547b5 100644
--- a/src/frontends/qt/GuiView.cpp
+++ b/src/frontends/qt/GuiView.cpp
@@ -523,6 +523,7 @@ public:
 
 	///
 	QTimer statusbar_timer_;
+	QTimer statusbar_stats_timer_;
 	/// auto-saving of buffers
 	Timeout autosave_timeout_;
 
@@ -553,8 +554,8 @@ QSet<Buffer const *> GuiView::GuiViewPrivate::busyBuffers;
 
 GuiView::GuiView(int id)
 	: d(*new GuiViewPrivate(this)), id_(id), closing_(false), busy_(0),
-	  command_execute_(false), minibuffer_focus_(false), toolbarsMovable_(true),
-	  devel_mode_(false)
+	  command_execute_(false), minibuffer_focus_(false), stat_counts_enabled_(true),
+	  toolbarsMovable_(true), devel_mode_(false)
 {
 	connect(this, SIGNAL(bufferViewChanged()),
 	        this, SLOT(onBufferViewChanged()));
@@ -582,6 +583,9 @@ GuiView::GuiView(int id)
 	}
 	connect(&d.statusbar_timer_, SIGNAL(timeout()),
 		this, SLOT(clearMessage()));
+	connect(&d.statusbar_stats_timer_, SIGNAL(timeout()),
+		this, SLOT(showStats()));
+	d.statusbar_stats_timer_.start(1000);
 
 	// We don't want to keep the window in memory if it is closed.
 	setAttribute(Qt::WA_DeleteOnClose, true);
@@ -627,6 +631,13 @@ GuiView::GuiView(int id)
 		busySVG, SLOT(hide()));
 	connect(busySVG, SIGNAL(pressed()), this, SLOT(checkCancelBackground()));
 
+	stat_counts_ = new QLabel(statusBar());
+	stat_counts_->setAlignment(Qt::AlignCenter);
+	stat_counts_->setFrameStyle(QFrame::StyledPanel);
+	stat_counts_->hide();
+	statusBar()->addPermanentWidget(stat_counts_);
+
+
 	QFontMetrics const fm(statusBar()->fontMetrics());
 
 	zoom_slider_ = new QSlider(Qt::Horizontal, statusBar());
@@ -952,6 +963,7 @@ void GuiView::saveLayout() const
 	settings.setValue("icon_size", toqstr(d.iconSize(iconSize())));
 	settings.setValue("zoom_value_visible", zoom_value_->isVisible());
 	settings.setValue("zoom_slider_visible", zoom_slider_->isVisible());
+	settings.setValue("document_stats_enabled", stat_counts_enabled_);
 }
 
 
@@ -1001,6 +1013,9 @@ bool GuiView::restoreLayout()
 	zoom_in_->setVisible(show_zoom_slider);
 	zoom_out_->setVisible(show_zoom_slider);
 
+	stat_counts_enabled_ = settings.value("document_stats_enabled", true).toBool();
+	stat_counts_->setVisible(stat_counts_enabled_); 
+
 	if (guiApp->platformName() == "qt4x11" || guiApp->platformName() == "xcb") {
 		QPoint pos = settings.value("pos", QPoint(50, 50)).toPoint();
 		QSize size = settings.value("size", QSize(690, 510)).toSize();
@@ -1271,6 +1286,7 @@ void GuiView::closeEvent(QCloseEvent * close_event)
 
 	// Make sure the timer time out will not trigger a statusbar update.
 	d.statusbar_timer_.stop();
+	d.statusbar_stats_timer_.stop();
 
 	// Saving fullscreen requires additional tweaks in the toolbar code.
 	// It wouldn't also work under linux natively.
@@ -1376,6 +1392,37 @@ void GuiView::clearMessage()
 	d.statusbar_timer_.stop();
 }
 
+void GuiView::showStats()
+{
+	if (!stat_counts_enabled_)
+		return;
+	BufferView * bv = currentBufferView();
+	Buffer * buf = bv ? &bv->buffer() : nullptr;
+	if (buf) {
+		Cursor const & cur = bv->cursor();
+		DocIterator from, to;
+		if (cur.selection()) {
+			from = cur.selectionBegin();
+			to = cur.selectionEnd();
+		} else {
+			from = doc_iterator_begin(buf);
+			to = doc_iterator_end(buf);
+		}
+		buf->updateStatistics(from, to);
+
+		int const words = buf->wordCount();
+		int const chars = buf->charCount(false);
+		int const chars_blanks = buf->charCount(true);
+
+		QString stats = "w:" + QString::number(words) + " c:" +  QString::number(chars) +
+				 " cb:" + QString::number(chars_blanks);
+		stat_counts_->setText(stats);
+		stat_counts_->show();
+	} else
+		stat_counts_->hide();
+
+	d.statusbar_stats_timer_.start(500);
+}
 
 void GuiView::updateWindowTitle(GuiWorkArea * wa)
 {
@@ -2419,6 +2466,8 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
 			flag.setOnOff(zoom_value_ ? zoom_value_->isVisible() : false);
 		} else if (cmd.argument() == "zoomslider") {
 			flag.setOnOff(zoom_slider_ ? zoom_slider_->isVisible() : false);
+		} else if (cmd.argument() == "statistics") {
+			flag.setOnOff(stat_counts_enabled_);
 		} else
 			flag.setOnOff(isFullScreen());
 		break;
@@ -4904,6 +4953,9 @@ bool GuiView::lfunUiToggle(string const & ui_component)
 		zoom_slider_->setVisible(!zoom_slider_->isVisible());
 		zoom_in_->setVisible(zoom_slider_->isVisible());
 		zoom_out_->setVisible(zoom_slider_->isVisible());
+	} else if (ui_component == "statistics") {
+		stat_counts_enabled_ = !stat_counts_enabled_;
+		stat_counts_->setVisible(stat_counts_enabled_);
 	} else if (ui_component == "frame") {
 		int const l = contentsMargins().left();
 
diff --git a/src/frontends/qt/GuiView.h b/src/frontends/qt/GuiView.h
index 241701cb8f..12e33878d3 100644
--- a/src/frontends/qt/GuiView.h
+++ b/src/frontends/qt/GuiView.h
@@ -235,6 +235,8 @@ public Q_SLOTS:
 	/// idle timeout.
 	/// clear any temporary message and replace with current status.
 	void clearMessage();
+	/// show documents stats in toolbar and trigger new iteration
+	void showStats();
 	///
 	void updateWindowTitle(GuiWorkArea * wa);
 	///
@@ -508,8 +510,12 @@ private:
 	QLabel * shell_escape_;
 	/// Statusbar widget that shows read-only status
 	QLabel * read_only_;
-	/// Statusbar widget that shows version control status
+	/// Statusbar widget that document count statistics
 	QLabel * version_control_;
+	/// Statusbar widget that shows version control status
+	QLabel * stat_counts_;
+	///
+	bool stat_counts_enabled_;
 	/// Statusbar widget that shows zoom value
 	QLabel * zoom_value_;
 	/// The zoom slider widget


More information about the lyx-devel mailing list