}
-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);
+ }
}
// 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
}
+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;
///
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,