diff --git a/part.h b/part.h --- a/part.h +++ b/part.h @@ -254,7 +254,7 @@ private: bool aboutToShowContextMenu(QMenu *menu, QAction *action, QMenu *contextMenu); - void showMenu(const Okular::Page *page, const QPoint &point, const QString &bookmarkTitle = QString(), const Okular::DocumentViewport &vp = DocumentViewport()); + void showMenu(const Okular::Page *page, const QPoint &point, const QString &bookmarkTitle = QString(), const Okular::DocumentViewport &vp = DocumentViewport(), bool showTOCActions = false); bool eventFilter(QObject * watched, QEvent * event) override; Document::OpenResult doOpenFile(const QMimeType &mime, const QString &fileNameToOpen, bool *isCompressedFile); bool openUrl( const QUrl &url, bool swapInsteadOfOpening ); diff --git a/part.cpp b/part.cpp --- a/part.cpp +++ b/part.cpp @@ -2948,15 +2948,15 @@ void Part::slotShowTOCMenu(const Okular::DocumentViewport &vp, const QPoint &point, const QString &title) { - showMenu(m_document->page(vp.pageNumber), point, title, vp); + showMenu(m_document->page(vp.pageNumber), point, title, vp, true); } void Part::slotShowMenu(const Okular::Page *page, const QPoint &point) { showMenu(page, point); } -void Part::showMenu(const Okular::Page *page, const QPoint &point, const QString &bookmarkTitle, const Okular::DocumentViewport &vp) +void Part::showMenu(const Okular::Page *page, const QPoint &point, const QString &bookmarkTitle, const Okular::DocumentViewport &vp, bool showTOCActions) { if ( m_embedMode == PrintPreviewMode ) return; @@ -2990,6 +2990,19 @@ } QMenu *popup = new QMenu( widget() ); + if (showTOCActions) + { + popup->addAction( i18n("Expand whole section"), + m_toc.data(), &TOC::expandRecursively ); + popup->addAction( i18n("Collapse whole section"), + m_toc.data(), &TOC::collapseRecursively ); + popup->addAction( i18n("Expand all"), + m_toc.data(), &TOC::expandAll ); + popup->addAction( i18n("Collapse all"), + m_toc.data(), &TOC::collapseAll ); + reallyShow = true; + } + QAction *addBookmark = nullptr; QAction *removeBookmark = nullptr; QAction *fitPageWidth = nullptr; diff --git a/ui/toc.h b/ui/toc.h --- a/ui/toc.h +++ b/ui/toc.h @@ -47,6 +47,12 @@ void rollbackReload(); void finishReload(); + public Q_SLOTS: + void expandRecursively(); + void collapseRecursively(); + void expandAll(); + void collapseAll(); + Q_SIGNALS: void hasTOC(bool has); void rightClick( const Okular::DocumentViewport &, const QPoint &, const QString & ); diff --git a/ui/toc.cpp b/ui/toc.cpp --- a/ui/toc.cpp +++ b/ui/toc.cpp @@ -187,4 +187,50 @@ emit rightClick(viewport, e->globalPos(), m_model->data(index).toString()); } +void TOC::expandRecursively() +{ + QList worklist = { m_treeView->currentIndex() }; + if ( !worklist[0].isValid() ) + { + return; + } + while ( !worklist.isEmpty() ) + { + QModelIndex index = worklist.takeLast(); + m_treeView->expand( index ); + for ( int i = 0; i < m_model->rowCount(index); i++ ) + { + worklist += m_model->index( i, 0, index ); + } + } +} + +void TOC::collapseRecursively() +{ + QList worklist = { m_treeView->currentIndex() }; + if ( !worklist[0].isValid() ) + { + return; + } + while ( !worklist.isEmpty() ) + { + QModelIndex index = worklist.takeLast(); + m_treeView->collapse( index ); + for ( int i = 0; i < m_model->rowCount(index); i++ ) + { + worklist += m_model->index( i, 0, index ); + } + } +} + +void TOC::expandAll() +{ + m_treeView->expandAll(); +} + +void TOC::collapseAll() +{ + m_treeView->collapseAll(); +} + #include "moc_toc.cpp"