[LyX/master] Get rid of unnecessary flickering when clicking in outliner

Juergen Spitzmueller spitz at lyx.org
Sun Sep 17 16:01:29 UTC 2023


commit ac275a66b5d34e211ba6e63ea9a2d02efce7eb72
Author: Juergen Spitzmueller <spitz at lyx.org>
Date:   Sun Sep 17 19:17:12 2023 +0200

    Get rid of unnecessary flickering when clicking in outliner
    
    No need to collapse and re-expand the node where the currently selected
    item is in.
---
 src/frontends/qt/TocWidget.cpp |   72 ++++++++++++++++++++++++++++++++++++---
 src/frontends/qt/TocWidget.h   |    8 ++++-
 2 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/src/frontends/qt/TocWidget.cpp b/src/frontends/qt/TocWidget.cpp
index e3d857b..c5c2ea4 100644
--- a/src/frontends/qt/TocWidget.cpp
+++ b/src/frontends/qt/TocWidget.cpp
@@ -334,16 +334,20 @@ void TocWidget::on_depthSL_valueChanged(int depth)
 }
 
 
-void TocWidget::setTreeDepth(int depth)
+void TocWidget::setTreeDepth(int depth, bool const maintain_current)
 {
 	depth_ = depth;
 	if (!tocTV->model())
 		return;
 
-	if (depth == 0)
-		tocTV->collapseAll();
-	else
-		tocTV->expandToDepth(depth - 1);
+	if (maintain_current)
+		collapseAllOthers(depth);
+	else {
+		if (depth == 0)
+			tocTV->collapseAll();
+		else
+			tocTV->expandToDepth(depth - 1);
+	}
 }
 
 
@@ -518,7 +522,7 @@ void TocWidget::finishUpdateView()
 	// and outweighted by TocModels::reset() anyway.
 	if (canNavigate()) {
 		if (!persistent_ && !keep_expanded_)
-			setTreeDepth(depth_);
+			setTreeDepth(depth_, true);
 		keep_expanded_ = false;
 		persistentCB->setChecked(persistent_);
 		// select the item at current cursor location
@@ -573,6 +577,62 @@ void TocWidget::filterContents()
 }
 
 
+bool TocWidget::isAncestor(QModelIndex const & ancestor,
+			   QModelIndex const & descendant) const
+{
+	QModelIndex mi = descendant;
+	while (true) {
+		if (ancestor == mi.parent())
+			return true;
+		if (mi == QModelIndex())
+			return false;
+		mi = mi.parent();
+	}
+	return false;
+}
+
+
+QModelIndex TocWidget::getAncestor(QModelIndex const & descendant) const
+{
+	QModelIndex mi = descendant;
+	while (true) {
+		if (mi.parent() == QModelIndex())
+			return mi;
+		mi = mi.parent();
+	}
+	return mi;
+}
+
+
+void TocWidget::collapseAllOthers(int const depth)
+{
+	if (!tocTV->model())
+		return;
+
+	QModelIndexList indices = tocTV->model()->match(
+		tocTV->model()->index(0, 0),
+		Qt::DisplayRole, ".*", -1,
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+		Qt::MatchFlags(Qt::MatchRegularExpression|Qt::MatchRecursive));
+#else
+		// deprecated in Qt 5.15.
+		Qt::MatchFlags(Qt::MatchRegExp|Qt::MatchRecursive));
+#endif
+
+	int size = indices.size();
+	// collapse parents which are not in our ancestry line
+	for (int i = size - 1; i >= 0; i--) {
+		QModelIndex index = indices[i];
+		if (tocTV->isExpanded(index)
+		    && !isAncestor(index, tocTV->currentIndex())) {
+			tocTV->collapse(index);
+			if (depth > 0 && index.parent() == QModelIndex())
+				tocTV->expandRecursively(index, depth - 1);
+		}
+	}
+}
+
+
 static QString decodeType(QString const & str)
 {
 	QString type = str;
diff --git a/src/frontends/qt/TocWidget.h b/src/frontends/qt/TocWidget.h
index 079fd24..50c1089 100644
--- a/src/frontends/qt/TocWidget.h
+++ b/src/frontends/qt/TocWidget.h
@@ -102,8 +102,14 @@ private:
 	///
 	bool isSortable()
 		{ return current_type_ != "tableofcontents"; }
+	/// \returns the top-most ancestor of \p descendant
+	QModelIndex getAncestor(QModelIndex const & descendant) const;
+	/// \returns \c true if \p ancestor is an ancestor (parent, grandparent, etc.) of \p descendant
+	bool isAncestor(QModelIndex const & ancestor, QModelIndex const & descendant) const;
+	/// collapse all nodes to \c depth except for the branch of the currently active item
+	void collapseAllOthers(int const depth);
 	///
-	void setTreeDepth(int depth);
+	void setTreeDepth(int depth, bool const maintain_current = false);
 	///
 	void outline(FuncCode func_code);
 	/// finds the inset that is connected to the current item,


More information about the lyx-cvs mailing list