From: Juergen Spitzmueller Date: Sun, 17 Sep 2023 17:17:12 +0000 (+0200) Subject: Get rid of unnecessary flickering when clicking in outliner X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=ac275a66b5d34e211ba6e63ea9a2d02efce7eb72;p=features.git 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. --- diff --git a/src/frontends/qt/TocWidget.cpp b/src/frontends/qt/TocWidget.cpp index e3d857b1dd..c5c2ea4ee3 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 079fd24deb..50c10893c3 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,