From 61c2c2ceddc0ebb8951b2aa7853789ffdfc859a0 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sun, 26 Aug 2018 13:56:37 +0200 Subject: [PATCH] TOC: Add collapse/expand options Large specifications with many (nested) sections are painful to navigate through when the TOC is expanded by default. Introduce four new options, "Expand/Collapse whole section" is based on Kate's document view while "Expand/Collapse all" was added to handle the top-level sections. As for other viewers, PDF.js uses shift-click to handle the former while using double-click on a the TOC icon to handle the latter. That is not very obvious, so extending the context menu seems the next best option. BUG: 216870 Differential Revision: https://phabricator.kde.org/D14904 --- part.cpp | 17 +++++++++++++++-- part.h | 2 +- ui/toc.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ ui/toc.h | 6 ++++++ 4 files changed, 68 insertions(+), 3 deletions(-) diff --git a/part.cpp b/part.cpp index 07cf6b0ba..2974159c3 100644 --- a/part.cpp +++ b/part.cpp @@ -2948,7 +2948,7 @@ void Part::slotPrintPreview() 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) @@ -2956,7 +2956,7 @@ 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 @@ void Part::showMenu(const Okular::Page *page, const QPoint &point, const QString } 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/part.h b/part.h index 798330fd0..ad963a90b 100644 --- a/part.h +++ b/part.h @@ -254,7 +254,7 @@ class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::Docu 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/ui/toc.cpp b/ui/toc.cpp index bc0bd990a..fadc1315a 100644 --- a/ui/toc.cpp +++ b/ui/toc.cpp @@ -187,4 +187,50 @@ void TOC::contextMenuEvent(QContextMenuEvent* e) 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" diff --git a/ui/toc.h b/ui/toc.h index d4b525c7e..75c4710ad 100644 --- a/ui/toc.h +++ b/ui/toc.h @@ -47,6 +47,12 @@ Q_OBJECT 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 & );