[graphics/okular] /: Improve the sidebar's navigation and UX

Nate Graham null at kde.org
Wed May 27 14:37:43 BST 2020


Git commit b8b36ae529599da358f433fe23d7bac4dea79fa8 by Nate Graham.
Committed on 27/05/2020 at 13:37.
Pushed by ngraham into branch 'master'.

Improve the sidebar's navigation and UX

Okular's sidebar vertical view chooser toolbar suffers from a few issues:

* It's a nonstandard UI not used for category choosers in other pieces of KDE software,
  and not used in other FOSS document readers
* What is shown and what is hidden is simultaneously too configurable while still not
  offering the desirable UI common to other programs (i.e. no visible category chooser,
  but a sidebar capable of displaying thumbnails, table of contents, search results, etc.)
* With labels on it takes up quite a bit of horizontal space, while with labels off, the
  categories are less than clear
* UX is kind of clunky with nonstandard behaviors (e.g. clicking on the current category
  to hide that category's view while keeping the view chooser visible, showing mostly
  disabled items)
* It's made with custom painting code, which reduces maintainability and introduces bugs
  (e.g. https://bugs.kde.org/show_bug.cgi?id=408190)

This patch removes the vertical category chooser entirely and replaces it with a tabbed
view on the top of the sidebar itself. The tabs are icons-only and have large icons. A
button is added on the left side of the default toolbar to quickly hide or show the
sidebar. In order to make room for the new button, the Previous and Next buttons on the
toolbar are removed, as previous/next buttons are already present on the Page Bar on the
bottom of the window so there's no need to duplicate this functionality. This improves
the UX, fixes a variety of bugs, and deletes a lot of custom code of dubious long-term
maintainability.

![vokoscreenNG-2020-04-16_13-29-24](https://invent.kde.org/graphics/okular/uploads/a1f96a315b69282df51de9993b1befaf/vokoscreenNG-2020-04-16_13-29-24.webm)

BUG: 213508

BUG: 334441

BUG: 344599

BUG: 408190

CCBUG: 335189

FIXED-IN: 1.11.0

CHANGELOG: The sidebar can now be easily shown or hidden with a toolbar button, and the category chooser no longer takes up so much space

M  +-    --    doc/annotations.png
M  +-    --    doc/bookmark-management.png
M  +8    -10   doc/index.docbook
M  +-    --    doc/mainwindow.png
M  +-    --    doc/signatures-panel.png
M  +34   -34   part.cpp
M  +4    -2    part.h
M  +2    -3    part.rc
M  +10   -1    ui/bookmarklist.cpp
M  +11   -1    ui/layers.cpp
M  +11   -1    ui/side_reviews.cpp
M  +21   -654  ui/sidebar.cpp
M  +1    -19   ui/sidebar.h
M  +14   -1    ui/signaturepanel.cpp
M  +23   -0    ui/thumbnaillist.cpp
M  +2    -3    ui/thumbnaillist.h
M  +10   -1    ui/toc.cpp

https://invent.kde.org/graphics/okular/commit/b8b36ae529599da358f433fe23d7bac4dea79fa8

diff --git a/doc/annotations.png b/doc/annotations.png
index 4aa8eb450..80e7cbd88 100644
Binary files a/doc/annotations.png and b/doc/annotations.png differ
diff --git a/doc/bookmark-management.png b/doc/bookmark-management.png
index 0398e5fbd..a86bf856f 100644
Binary files a/doc/bookmark-management.png and b/doc/bookmark-management.png differ
diff --git a/doc/index.docbook b/doc/index.docbook
index 26fe49551..74130e34d 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -6,9 +6,8 @@
   <!ENTITY % addindex "IGNORE">
 ]>
 <!-- TODO
-add chapter about navigation panel
-Show/Hide Contens/Thumbnails/Reviews/Bookmarks bar to save screen space
-Use Small Icons and deselect Show Text to minimize the navigation panel
+add chapter about sidebar
+Show/Hide the whole thing to save screen space
 Describe all actions only possible in the navigation bars:
 Switching between documents using bookmarks
 Context menu actions like Rename Bookmarks etc.)
@@ -150,7 +149,7 @@ Context menu actions like Rename Bookmarks etc.)
 			Once you cross the border of a page, the mouse cursor appears on top or bottom of the screen again and you can just continue to drag.
 			</para>
 			<para>
-				The navigation panel on the left side of the screen enables two more ways of navigating
+				The sidebar on the left side of the screen enables two more ways of navigating
 				through a document:
 			</para>
 			<itemizedlist>
@@ -497,7 +496,7 @@ Context menu actions like Rename Bookmarks etc.)
 			<para>Text annotations like <guilabel>Yellow Highlighter</guilabel> and <guilabel>Black Underlining</guilabel>
 			for files with text like ⪚ &PDF;.</para>
 		      <para>Graphic annotations like <guilabel>Pop-up Note</guilabel>, <guilabel>Inline Note</guilabel>, <guilabel>Freehand Line</guilabel>, <guilabel>Highlighter</guilabel>, <guilabel>Straight Line</guilabel>, <guilabel>Polygon</guilabel>, <guilabel>Stamp</guilabel>, <guilabel>Underline</guilabel>, <guilabel>Ellipse</guilabel>, and <guilabel>Typewriter</guilabel> for all formats supported by &okular;.</para>
-			<para>Using the context menu either in the <guilabel>Reviews</guilabel> view of the navigation panel or in the main window you can open a <guilabel>Pop up Note</guilabel> for any kind of annotation and add or edit comments.</para>
+			<para>Using the context menu either in the <guilabel>Reviews</guilabel> view of the sidebar or in the main window you can open a <guilabel>Pop up Note</guilabel> for any kind of annotation and add or edit comments.</para>
 			<para>Annotations are not only limited to &PDF; files, they can be used for any format &okular; supports.</para>
 			<para>
                 &okular; has the "document archiving" feature. This is an &okular;-specific format for carrying the document plus various metadata related to it (currently only annotations). You can save a "document archive" from the open document by choosing <menuchoice><guimenu>File</guimenu><guisubmenu>Save As</guisubmenu></menuchoice> and selecting <guilabel>Okular document archive</guilabel> in the <guilabel>Filter</guilabel> selector. Documents saved this way will get <filename>.okular</filename> as their filename extension. To open an &okular; document archive, just open it with &okular; as it would be ⪚ a &PDF; document.
@@ -929,13 +928,12 @@ Context menu actions like Rename Bookmarks etc.)
 				&okular; has a very flexible bookmark system. &okular; saves the position on the page in bookmark and allows you to define more than one bookmark per page.
 			</para>
 			<para>
-			  To manage bookmarks in &okular; you can use <guilabel>Bookmarks</guilabel> view from <guilabel>Navigation Panel</guilabel>, <link linkend="menubookmarks">Bookmarks menu</link> or context menu of document view (click with &RMB; to open it).
+			  To manage bookmarks in &okular; you can use <guilabel>Bookmarks</guilabel> view from <guilabel>Sidebar</guilabel>, <link linkend="menubookmarks">Bookmarks menu</link> or context menu of document view (click with &RMB; to open it).
 			</para>
 			<sect2 id="bookmarks-view">
 				<title>Bookmarks view</title>
 				<para>
-				  To open <guilabel>Bookmarks</guilabel> view click on <guilabel>Bookmarks</guilabel> item on the <guilabel>Navigation Panel</guilabel>. If the <guilabel>Navigation Panel</guilabel> is not shown, use <menuchoice><shortcut><keycap>F7</keycap></shortcut> <guimenu>Settings</guimenu><guimenuitem>Show Navigation Panel</guimenuitem>
-				  </menuchoice> main menu item to make it visible.
+                    To open <guilabel>Bookmarks</guilabel> view, click on the <guilabel>Bookmarks</guilabel> tab at the top of the <guilabel>Sidebar</guilabel>. If the <guilabel>Sidebar</guilabel> is not shown, click the <guibutton>Show Sidebar</guibutton> button on the toolbar or the  menu item, or the <menuchoice><shortcut><keycap>F7</keycap></shortcut> <guimenu>Settings</guimenu><guimenuitem>Show Sidebar</guimenuitem></menuchoice> menu item to make it visible.
 				</para>
 				<screenshot>
 				    <screeninfo>Bookmark view context menu</screeninfo>
@@ -1897,11 +1895,11 @@ Context menu actions like Rename Bookmarks etc.)
 						<menuchoice>
 							<shortcut><keycap>F7</keycap></shortcut>
 							<guimenu>Settings</guimenu>
-							<guimenuitem>Show Navigation Panel</guimenuitem>
+							<guimenuitem>Show Sidebar</guimenuitem>
 						</menuchoice>
 					</term>
 					<listitem>
-						<para><action>Toggle the navigation panel</action> on and off.</para>
+						<para><action>Shows or hides the Sidebar.</action></para>
 					</listitem>
 				</varlistentry>
 				<varlistentry>
diff --git a/doc/mainwindow.png b/doc/mainwindow.png
index 3a622684d..122ccc618 100644
Binary files a/doc/mainwindow.png and b/doc/mainwindow.png differ
diff --git a/doc/signatures-panel.png b/doc/signatures-panel.png
index 93c81d19f..904446690 100644
Binary files a/doc/signatures-panel.png and b/doc/signatures-panel.png differ
diff --git a/part.cpp b/part.cpp
index b79e6056b..5a1eaeeee 100644
--- a/part.cpp
+++ b/part.cpp
@@ -418,18 +418,14 @@ m_cliPresentation(false), m_cliPrint(false), m_cliPrintAndExit(false), m_embedMo
     //      sLabel->setBuddy( m_searchWidget );
     //      m_searchToolBar->setStretchableWidget( m_searchWidget );
 
-    // [left toolbox: Table of Contents] | []
+    // [left toolbox optional item: Table of Contents] | []
     m_toc = new TOC( nullptr, m_document );
     connect( m_toc.data(), &TOC::hasTOC, this, &Part::enableTOC );
     connect( m_toc.data(), &TOC::rightClick, this, &Part::slotShowTOCMenu );
-    m_sidebar->addItem( m_toc, QIcon::fromTheme(QApplication::isLeftToRight() ? QStringLiteral("format-justify-left") : QStringLiteral("format-justify-right")), i18n("Contents") );
-    enableTOC( false );
 
-    // [left toolbox: Layers] | []
+    // [left toolbox optional item: Layers] | []
     m_layers = new Layers( nullptr, m_document );
     connect( m_layers.data(), &Layers::hasLayers, this, &Part::enableLayers );
-    m_sidebar->addItem( m_layers, QIcon::fromTheme( QStringLiteral("format-list-unordered") ), i18n( "Layers" ) );
-    enableLayers( false );
 
     // [left toolbox: Thumbnails and Bookmarks] | []
     QWidget * thumbsBox = new ThumbnailsBox( nullptr );
@@ -447,18 +443,14 @@ m_cliPresentation(false), m_cliPrint(false), m_cliPrintAndExit(false), m_embedMo
     // [left toolbox: Reviews] | []
     m_reviewsWidget = new Reviews( nullptr, m_document );
     m_sidebar->addItem( m_reviewsWidget, QIcon::fromTheme(QStringLiteral("draw-freehand")), i18n("Reviews") );
-    m_sidebar->setItemEnabled( m_reviewsWidget, false );
 
     // [left toolbox: Bookmarks] | []
     m_bookmarkList = new BookmarkList( m_document, nullptr );
     m_sidebar->addItem( m_bookmarkList, QIcon::fromTheme(QStringLiteral("bookmarks")), i18n("Bookmarks") );
-    m_sidebar->setItemEnabled( m_bookmarkList, false );
 
-    // [left toolbox: Signature Panel] | []
+    // [left toolbox optional item: Signature Panel] | []
     m_signaturePanel = new SignaturePanel( m_document, nullptr );
-    connect( m_signaturePanel.data(), &SignaturePanel::documentHasSignatures, this, &Part::showSidebarSignaturesItem );
-    m_sidebar->addItem( m_signaturePanel, QIcon::fromTheme(QStringLiteral("application-pkcs7-signature")), i18n("Signatures") );
-    showSidebarSignaturesItem( false );
+    connect( m_signaturePanel.data(), &SignaturePanel::documentHasSignatures, this, &Part::enableSidebarSignaturesItem );
 
     // widgets: [../miniBarContainer] | []
 #ifdef OKULAR_ENABLE_MINIBAR
@@ -865,7 +857,7 @@ void Part::setupActions()
     m_migrationMessage->addAction( m_saveAs );
 
     m_showLeftPanel = ac->add<KToggleAction>(QStringLiteral("show_leftpanel"));
-    m_showLeftPanel->setText(i18n( "Show &Navigation Panel"));
+    m_showLeftPanel->setText(i18n( "Show S&idebar"));
     m_showLeftPanel->setIcon(QIcon::fromTheme( QStringLiteral("view-sidetree") ));
     connect( m_showLeftPanel, &QAction::toggled, this, &Part::slotShowLeftPanel );
     ac->setDefaultShortcut(m_showLeftPanel, QKeySequence(Qt::Key_F7));
@@ -1695,9 +1687,9 @@ bool Part::openFile()
         setFileToWatch( localFilePath() );
 
     // if the 'OpenTOC' flag is set, open the TOC
-    if ( m_document->metaData( QStringLiteral("OpenTOC") ).toBool() && m_sidebar->isItemEnabled( m_toc ) && !m_sidebar->isCollapsed() && m_sidebar->currentItem() != m_toc )
+    if ( m_document->metaData( QStringLiteral("OpenTOC") ).toBool() && m_tocEnabled && m_sidebar->currentItem() != m_toc )
     {
-        m_sidebar->setCurrentItem( m_toc, Sidebar::DoNotUncollapseIfCollapsed );
+        m_sidebar->setCurrentItem( m_toc );
     }
     // if the 'StartFullScreen' flag is set and we're not in viewer widget mode, or the command line flag was
     // specified, start presentation
@@ -2043,7 +2035,6 @@ bool Part::slotAttemptReload( bool oneShot, const QUrl &newUrl )
         // store the current toolbox pane
         m_dirtyToolboxItem = m_sidebar->currentItem();
         m_wasSidebarVisible = m_sidebar->isSidebarVisible();
-        m_wasSidebarCollapsed = m_sidebar->isCollapsed();
 
         // store if presentation view was open
         m_wasPresentationOpen = ((PresentationWidget*)m_presentationWidget != nullptr);
@@ -2089,8 +2080,7 @@ bool Part::slotAttemptReload( bool oneShot, const QUrl &newUrl )
         m_oldUrl = QUrl();
         m_viewportDirty.pageNumber = -1;
         m_document->setRotation( m_dirtyPageRotation );
-        if ( m_sidebar->currentItem() != m_dirtyToolboxItem && m_sidebar->isItemEnabled( m_dirtyToolboxItem )
-            && !m_sidebar->isCollapsed() )
+        if ( m_sidebar->currentItem() != m_dirtyToolboxItem )
         {
             m_sidebar->setCurrentItem( m_dirtyToolboxItem );
         }
@@ -2098,10 +2088,6 @@ bool Part::slotAttemptReload( bool oneShot, const QUrl &newUrl )
         {
             m_sidebar->setSidebarVisibility( m_wasSidebarVisible );
         }
-        if ( m_sidebar->isCollapsed() != m_wasSidebarCollapsed )
-        {
-            m_sidebar->setCollapsed( m_wasSidebarCollapsed );
-        }
         if (m_wasPresentationOpen) slotShowPresentation();
         emit enablePrintAction(true && m_document->printingSupport() != Okular::Document::NoPrinting);
 
@@ -2236,12 +2222,18 @@ void Part::updateBookmarksActions()
 
 void Part::enableTOC(bool enable)
 {
-    m_sidebar->setItemEnabled(m_toc, enable);
+    if ( !enable ) {
+        m_tocEnabled = false;
+        return;
+    }
+
+    m_sidebar->addItem( m_toc, QIcon::fromTheme(QApplication::isLeftToRight() ? QStringLiteral("format-justify-left") : QStringLiteral("format-justify-right")), i18n("Contents") );
+    m_tocEnabled = true;
 
     // If present, show the TOC when a document is opened
-    if ( enable && m_sidebar->currentItem() != m_toc )
+    if ( m_sidebar->currentItem() != m_toc )
     {
-        m_sidebar->setCurrentItem( m_toc, Sidebar::DoNotUncollapseIfCollapsed );
+        m_sidebar->setCurrentItem( m_toc );
     }
 }
 
@@ -2252,12 +2244,24 @@ void Part::slotRebuildBookmarkMenu()
 
 void Part::enableLayers(bool enable)
 {
-    m_sidebar->setItemVisible( m_layers, enable );
+    if ( !enable ) {
+        m_layersEnabled = false;
+        return;
+    }
+
+    m_sidebar->addItem( m_layers, QIcon::fromTheme( QStringLiteral("format-list-unordered") ), i18n( "Layers" ) );
+    m_layersEnabled = true;
 }
 
-void Part::showSidebarSignaturesItem( bool show )
+void Part::enableSidebarSignaturesItem( bool enable )
 {
-    m_sidebar->setItemVisible( m_signaturePanel, show );
+    if ( !enable ) {
+        m_signaturePanelEnabled = false;
+        return;
+    }
+
+    m_sidebar->addItem( m_signaturePanel, QIcon::fromTheme(QStringLiteral("application-pkcs7-signature")), i18n("Signatures") );
+    m_signaturePanelEnabled = true;
 }
 
 void Part::slotShowFindBar()
@@ -2993,7 +2997,7 @@ void Part::slotNewConfig()
     m_document->reparseConfig();
 
     // update TOC settings
-    if ( m_sidebar->isItemEnabled(m_toc) )
+    if ( m_tocEnabled )
         m_toc->reparseConfig();
 
     // update ThumbnailList contents
@@ -3001,8 +3005,7 @@ void Part::slotNewConfig()
         m_thumbnailList->updateWidgets();
 
     // update Reviews settings
-    if ( m_sidebar->isItemEnabled(m_reviewsWidget) )
-        m_reviewsWidget->reparseConfig();
+    m_reviewsWidget->reparseConfig();
 
     setWindowTitleFromDocument ();
 
@@ -3509,9 +3512,6 @@ void Part::unsetDummyMode()
     if ( m_embedMode == PrintPreviewMode )
        return;
 
-    m_sidebar->setItemEnabled( m_reviewsWidget, true );
-    m_sidebar->setItemEnabled( m_bookmarkList, true );
-    m_sidebar->setItemEnabled( m_signaturePanel, true );
     m_sidebar->setSidebarVisibility( Okular::Settings::showLeftPanel() );
 
     // add back and next in history
diff --git a/part.h b/part.h
index d50c322ef..d5c52cc84 100644
--- a/part.h
+++ b/part.h
@@ -237,7 +237,7 @@ class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::Docu
         void enableTOC(bool enable);
         void slotRebuildBookmarkMenu();
         void enableLayers( bool enable );
-        void showSidebarSignaturesItem( bool show );
+        void enableSidebarSignaturesItem( bool enable );
 
     public Q_SLOTS:
         bool saveFile() override;
@@ -316,6 +316,7 @@ class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::Docu
         QPointer<ThumbnailList> m_thumbnailList;
         QPointer<PageView> m_pageView;
         QPointer<TOC> m_toc;
+        bool m_tocEnabled;
         QPointer<MiniBarLogic> m_miniBarLogic;
         QPointer<MiniBar> m_miniBar;
         QPointer<MiniBar> m_pageNumberTool;
@@ -326,7 +327,9 @@ class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::Docu
         QPointer<Reviews> m_reviewsWidget;
         QPointer<BookmarkList> m_bookmarkList;
         QPointer<Layers> m_layers;
+        bool m_layersEnabled;
         QPointer<SignaturePanel> m_signaturePanel;
+        bool m_signaturePanelEnabled;
 
         // document watcher (and reloader) variables
         KDirWatch *m_watcher;
@@ -338,7 +341,6 @@ class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::Docu
         bool m_wasPresentationOpen;
         QWidget *m_dirtyToolboxItem;
         bool m_wasSidebarVisible;
-        bool m_wasSidebarCollapsed;
         bool m_fileWasRemoved;
         Rotation m_dirtyPageRotation;
 
diff --git a/part.rc b/part.rc
index f71168ca8..723ccafc9 100644
--- a/part.rc
+++ b/part.rc
@@ -1,5 +1,5 @@
 <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="okular_part" version="44">
+<kpartgui name="okular_part" version="45">
 <MenuBar>
   <Menu name="file"><text>&File</text>
     <Action name="get_new_stuff" group="file_open"/>
@@ -95,8 +95,7 @@
   </Menu>
 </MenuBar>
 <ToolBar name="mainToolBar"><text>Main Toolbar</text>
-  <Action name="go_previous"/>
-  <Action name="go_next"/>
+  <Action name="show_leftpanel"/>
   <Separator/>
   <Action name="zoom_to" />
   <Action name="view_zoom_out"/>
diff --git a/ui/bookmarklist.cpp b/ui/bookmarklist.cpp
index ac6af93a9..52eb0291f 100644
--- a/ui/bookmarklist.cpp
+++ b/ui/bookmarklist.cpp
@@ -21,8 +21,11 @@
 #include <QIcon>
 
 #include <KLocalizedString>
+#include <KTitleWidget>
 #include <KTreeWidgetSearchLine>
 
+#include <kwidgetsaddons_version.h>
+
 #include "pageitemdelegate.h"
 #include "core/action.h"
 #include "core/bookmarkmanager.h"
@@ -125,9 +128,15 @@ BookmarkList::BookmarkList( Okular::Document *document, QWidget *parent )
     : QWidget( parent ), m_document( document ), m_currentDocumentItem( nullptr )
 {
     QVBoxLayout *mainlay = new QVBoxLayout( this );
-    mainlay->setContentsMargins( 0, 0, 0, 0 );
     mainlay->setSpacing( 6 );
 
+    KTitleWidget *titleWidget = new KTitleWidget( this );
+    #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 53, 0)
+    titleWidget->setLevel( 2 );
+    #endif
+    titleWidget->setText( i18n( "Bookmarks" ) );
+    mainlay->addWidget( titleWidget );
+    mainlay->setAlignment( titleWidget, Qt::AlignHCenter );
     m_searchLine = new KTreeWidgetSearchLine( this );
     mainlay->addWidget( m_searchLine );
     m_searchLine->setPlaceholderText(i18n( "Search..." ));
diff --git a/ui/layers.cpp b/ui/layers.cpp
index 832bfd700..059746430 100644
--- a/ui/layers.cpp
+++ b/ui/layers.cpp
@@ -11,10 +11,14 @@
 #include "settings.h"
 
 // qt/kde includes
+#include <ktitlewidget.h>
+#include <klocalizedstring.h>
 #include <QVBoxLayout>
 #include <QTreeView>
 #include <qheaderview.h>
 
+#include <kwidgetsaddons_version.h>
+
 // local includes
 #include "core/document.h"
 #include "ktreeviewsearchline.h"
@@ -23,11 +27,17 @@
 Layers::Layers(QWidget *parent, Okular::Document *document) : QWidget(parent), m_document(document)
 {
     QVBoxLayout * const mainlay = new QVBoxLayout( this );
-    mainlay->setContentsMargins( 0, 0, 0, 0 );
     mainlay->setSpacing( 6 );
 
     m_document->addObserver( this );
 
+    KTitleWidget *titleWidget = new KTitleWidget( this );
+    #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 53, 0)
+    titleWidget->setLevel( 2 );
+    #endif
+    titleWidget->setText( i18n( "Layers" ) );
+    mainlay->addWidget( titleWidget );
+    mainlay->setAlignment( titleWidget, Qt::AlignHCenter );
     m_searchLine = new KTreeViewSearchLine( this );
     mainlay->addWidget( m_searchLine );
     m_searchLine->setCaseSensitivity( Okular::Settings::self()->layersSearchCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive );
diff --git a/ui/side_reviews.cpp b/ui/side_reviews.cpp
index 40d6bbfb7..c8ed59417 100644
--- a/ui/side_reviews.cpp
+++ b/ui/side_reviews.cpp
@@ -23,8 +23,11 @@
 #include <qaction.h>
 #include <KLocalizedString>
 #include <kiconloader.h>
+#include <KTitleWidget>
 #include <QIcon>
 
+#include <kwidgetsaddons_version.h>
+
 // local includes
 #include "core/annotations.h"
 #include "core/document.h"
@@ -89,9 +92,14 @@ Reviews::Reviews( QWidget * parent, Okular::Document * document )
 {
     // create widgets and layout them vertically
     QVBoxLayout * vLayout = new QVBoxLayout( this );
-    vLayout->setContentsMargins( 0, 0, 0, 0 );
     vLayout->setSpacing( 6 );
 
+    KTitleWidget *titleWidget = new KTitleWidget( this );
+    #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 53, 0)
+    titleWidget->setLevel( 2 );
+    #endif
+    titleWidget->setText( i18n("Reviews") );
+
     m_view = new TreeView( m_document, this );
     m_view->setAlternatingRowColors( true );
     m_view->setSelectionMode( QAbstractItemView::ExtendedSelection );
@@ -121,6 +129,8 @@ Reviews::Reviews( QWidget * parent, Okular::Document * document )
     m_searchLine->setCaseSensitivity( Okular::Settings::self()->reviewsSearchCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive );
     m_searchLine->setRegularExpression( Okular::Settings::self()->reviewsSearchRegularExpression() );
     connect(m_searchLine, &KTreeViewSearchLine::searchOptionsChanged, this, &Reviews::saveSearchOptions);
+    vLayout->addWidget( titleWidget );
+    vLayout->setAlignment( titleWidget, Qt::AlignHCenter );
     vLayout->addWidget( m_searchLine );
     vLayout->addWidget( m_view );
     vLayout->addWidget( toolBar );
diff --git a/ui/sidebar.cpp b/ui/sidebar.cpp
index b96156fc0..b53c6f78d 100644
--- a/ui/sidebar.cpp
+++ b/ui/sidebar.cpp
@@ -10,7 +10,6 @@
 
 #include "sidebar.h"
 
-#include <qabstractitemdelegate.h>
 #include <qaction.h>
 #include <qapplication.h>
 #include <qevent.h>
@@ -19,11 +18,10 @@
 #include <qlabel.h>
 #include <qlayout.h>
 #include <qlist.h>
-#include <qlistwidget.h>
 #include <qpainter.h>
 #include <qscrollbar.h>
 #include <qsplitter.h>
-#include <qstackedwidget.h>
+#include <qtabwidget.h>
 #include <qmimedata.h>
 
 #include <kiconloader.h>
@@ -34,440 +32,24 @@
 
 #include "settings.h"
 
-static const int SidebarItemType = QListWidgetItem::UserType + 1;
-
-/* List item representing a sidebar entry. */
-class SidebarItem : public QListWidgetItem
-{
-    public:
-        SidebarItem( QWidget* w, const QIcon &icon, const QString &text )
-            : QListWidgetItem( nullptr, SidebarItemType ),
-              m_widget( w )
-        {
-            setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
-            setIcon( icon );
-            setText( text );
-            setToolTip( text );
-        }
-
-        SidebarItem(const SidebarItem &) = delete;
-        SidebarItem &operator=(const SidebarItem &) = delete;
-
-        QWidget* widget() const
-        {
-            return m_widget;
-        }
-
-    private:
-        QWidget *m_widget;
-};
-
-
-/* A simple delegate to paint the icon of each item */
-#define ITEM_MARGIN_LEFT 5
-#define ITEM_MARGIN_TOP 5
-#define ITEM_MARGIN_RIGHT 5
-#define ITEM_MARGIN_BOTTOM 5
-#define ITEM_PADDING 5
-
-class SidebarDelegate : public QAbstractItemDelegate
-{
-    Q_OBJECT
-
-    public:
-        SidebarDelegate( QObject *parent = Q_NULLPTR );
-        ~SidebarDelegate() override;
-
-        void setShowText( bool show );
-        bool isTextShown() const;
-
-
-        // from QAbstractItemDelegate
-        void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
-        QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
-
-    private slots:
-        void updateBrushCache();
-
-    private:
-        bool m_showText;
-        QScopedPointer<KStatefulBrush> m_windowBackground;
-        QScopedPointer<KStatefulBrush> m_windowForeground;
-        QScopedPointer<KStatefulBrush> m_selectionBackground;
-        QScopedPointer<KStatefulBrush> m_selectionForeground;
-};
-
-SidebarDelegate::SidebarDelegate( QObject *parent )
-    : QAbstractItemDelegate( parent ), m_showText( true ),
-    m_windowBackground( nullptr ), m_windowForeground( nullptr ),
-    m_selectionBackground( nullptr ), m_selectionForeground( nullptr )
-{
-    updateBrushCache();
-    connect(qApp, &QGuiApplication::paletteChanged, this, &SidebarDelegate::updateBrushCache);
-}
-
-SidebarDelegate::~SidebarDelegate()
-{
-}
-
-void SidebarDelegate::setShowText( bool show )
-{
-    m_showText = show;
-}
-
-bool SidebarDelegate::isTextShown() const
-{
-    return m_showText;
-}
-
-void SidebarDelegate::updateBrushCache()
-{
-    m_windowBackground.reset(new KStatefulBrush(KColorScheme::Window, KColorScheme::NormalBackground));
-    m_windowForeground.reset(new KStatefulBrush(KColorScheme::Window, KColorScheme::NormalText));
-    m_selectionBackground.reset(new KStatefulBrush(KColorScheme::Selection, KColorScheme::NormalBackground));
-    m_selectionForeground.reset(new KStatefulBrush(KColorScheme::Selection, KColorScheme::NormalText));
-}
-
-void SidebarDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
-{
-    QBrush backBrush;
-    QColor foreColor;
-    bool disabled = false;
-    bool hover = false;
-
-    if ( !( option.state & QStyle::State_Enabled ) )
-    {
-        backBrush = m_windowBackground->brush(QPalette::Disabled);
-        foreColor = m_windowForeground->brush(QPalette::Disabled).color();
-        disabled = true;
-    }
-    else if ( option.state & QStyle::State_HasFocus )
-    {
-        backBrush = m_selectionBackground->brush(option.palette);
-        foreColor = m_selectionForeground->brush(option.palette).color();
-    }
-    else if ( option.state & QStyle::State_Selected )
-    {
-        backBrush = m_selectionBackground->brush(option.palette);
-        foreColor = m_windowForeground->brush(option.palette).color();
-    }
-    else if ( option.state & QStyle::State_MouseOver )
-    {
-        backBrush = m_selectionBackground->brush(option.palette).color().lighter( 115 );
-        foreColor = m_windowForeground->brush(option.palette).color();
-        hover = true;
-    }
-    else /*if ( option.state & QStyle::State_Enabled )*/
-    {
-        backBrush = m_windowBackground->brush(option.palette);
-        foreColor = m_windowForeground->brush(option.palette).color();
-    }
-    QStyle *style = QApplication::style();
-    QStyleOptionViewItem opt( option );
-    // KStyle provides an "hover highlight" effect for free;
-    // but we want that for non-KStyle-based styles too
-    if ( !style->inherits( "KStyle" ) && hover )
-    {
-        Qt::BrushStyle bs = opt.backgroundBrush.style();
-        if ( bs > Qt::NoBrush && bs < Qt::TexturePattern )
-            opt.backgroundBrush = opt.backgroundBrush.color().lighter( 115 );
-        else
-            opt.backgroundBrush = backBrush;
-    }
-    painter->save();
-    style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, nullptr );
-    painter->restore();
-    QIcon icon = index.data( Qt::DecorationRole ).value< QIcon >();
-    if ( !icon.isNull() )
-    {
-        QPoint iconpos(
-            ( option.rect.width() - option.decorationSize.width() ) / 2,
-            ITEM_MARGIN_TOP
-        );
-        iconpos += option.rect.topLeft();
-        QIcon::Mode iconmode = disabled ? QIcon::Disabled : QIcon::Normal;
-        painter->drawPixmap( iconpos, icon.pixmap( option.decorationSize, iconmode ) );
-    }
-
-    if ( m_showText )
-    {
-        QString text = index.data( Qt::DisplayRole ).toString();
-        QRect fontBoundaries = QFontMetrics( option.font ).boundingRect( QRect(), Qt::AlignCenter, text );
-        QPoint textPos(
-            ITEM_MARGIN_LEFT + ( option.rect.width() - ITEM_MARGIN_LEFT - ITEM_MARGIN_RIGHT - fontBoundaries.width() ) / 2,
-            ITEM_MARGIN_TOP + option.decorationSize.height() + ITEM_PADDING
-        );
-        fontBoundaries.translate( -fontBoundaries.topLeft() );
-        fontBoundaries.translate( textPos );
-        fontBoundaries.translate( option.rect.topLeft() );
-        painter->setPen( foreColor );
-        painter->drawText( fontBoundaries, Qt::AlignCenter, text );
-    }
-}
-
-QSize SidebarDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
-{
-    QSize baseSize( option.decorationSize.width(), option.decorationSize.height() );
-    if ( m_showText )
-    {
-        QRect fontBoundaries = QFontMetrics( option.font ).boundingRect( QRect(), Qt::AlignCenter, index.data( Qt::DisplayRole ).toString() );
-        baseSize.setWidth( qMax( fontBoundaries.width(), baseSize.width() ) );
-        baseSize.setHeight( baseSize.height() + fontBoundaries.height() + ITEM_PADDING );
-    }
-    return baseSize + QSize( ITEM_MARGIN_LEFT + ITEM_MARGIN_RIGHT, ITEM_MARGIN_TOP + ITEM_MARGIN_BOTTOM );
-}
-
-
-/* A custom list widget that ignores the events for disabled items */
-class SidebarListWidget : public QListWidget
-{
-    Q_OBJECT
-    public:
-        SidebarListWidget( QWidget *parent = Q_NULLPTR );
-        ~SidebarListWidget() override;
-
-        int countVisible() const {
-            int ret = 0;
-            for ( int i = 0, c = count(); i < c; ++i ) {
-                ret += !item(i)->isHidden();
-            }
-            return ret;
-        }
-
-    protected:
-        // from QListWidget
-        void mouseDoubleClickEvent( QMouseEvent *event ) override;
-        void mouseMoveEvent( QMouseEvent *event ) override;
-        void mousePressEvent( QMouseEvent *event ) override;
-        void mouseReleaseEvent( QMouseEvent *event ) override;
-
-        QModelIndex moveCursor( QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers ) override;
-
-    private:
-        // These two are used to keep track of the row an initial mousePress-
-        // Event() occurs on and the row the cursor moves over while the left
-        // mouse button is pressed, respectively, as well as for event compre-
-        // ssion, to avoid calling SideBar::itemClicked() multiple times for
-        // the same item in a row on mouseMoveEvent()'s. This code is written
-        // under the assumption that the number and positions of items in the
-        // list won't change while the user interacts with it using the mouse.
-        // Future work here must see to that this assumption continues to hold
-        // up, or achieve calling SideBar::itemClicked() differently.
-        int mousePressedRow;
-        int rowUnderMouse;
-};
-
-SidebarListWidget::SidebarListWidget( QWidget *parent )
-    : QListWidget( parent )
-{
-    mousePressedRow = -1;
-    rowUnderMouse = -1;
-}
-
-SidebarListWidget::~SidebarListWidget()
-{
-}
-
-void SidebarListWidget::mouseDoubleClickEvent( QMouseEvent *event )
-{
-    QModelIndex index = indexAt( event->pos() );
-    if ( index.isValid() && !( index.flags() & Qt::ItemIsSelectable ) )
-        return;
-
-    QListWidget::mouseDoubleClickEvent( event );
-}
-
-void SidebarListWidget::mouseMoveEvent( QMouseEvent *event )
-{
-    QModelIndex index = indexAt( event->pos() );
-
-    if ( index.isValid() )
-    {
-        if ( index.flags() & Qt::ItemIsSelectable )
-        {
-            if ( event->buttons() & Qt::LeftButton
-                 && index.row() != mousePressedRow
-                 && index.row() != rowUnderMouse )
-            {
-                mousePressedRow = -1;
-                rowUnderMouse = index.row();
-
-                QMetaObject::invokeMethod(parent(), "itemClicked", Qt::DirectConnection,
-                    Q_ARG(QListWidgetItem*, item(index.row())));
-            }
-        }
-        else
-            return;
-    }
-
-    QListWidget::mouseMoveEvent( event );
-}
-
-void SidebarListWidget::mousePressEvent( QMouseEvent *event )
-{
-    QModelIndex index = indexAt( event->pos() );
-
-    if ( index.isValid() )
-    {
-        if ( index.flags() & Qt::ItemIsSelectable )
-        {
-            if ( event->buttons() & Qt::LeftButton )
-                mousePressedRow = index.row();
-        }
-        else
-            return;
-    }
-
-    QListWidget::mousePressEvent( event );
-}
-
-void SidebarListWidget::mouseReleaseEvent( QMouseEvent *event )
-{
-    QModelIndex index = indexAt( event->pos() );
-
-    if ( index.isValid() )
-    {
-        if ( index.flags() & Qt::ItemIsSelectable )
-        {
-            if ( event->button() == Qt::LeftButton
-                 && index.row() != rowUnderMouse )
-            {
-                QMetaObject::invokeMethod(parent(), "itemClicked", Qt::DirectConnection,
-                    Q_ARG(QListWidgetItem*, item(index.row())));
-            }
-        }
-        else
-        {
-            mousePressedRow = -1;
-            rowUnderMouse = -1;
-
-            return;
-        }
-    }
-
-    mousePressedRow = -1;
-    rowUnderMouse = -1;
-
-    QListWidget::mouseReleaseEvent( event );
-}
-
-QModelIndex SidebarListWidget::moveCursor( QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers )
-{
-    Q_UNUSED( modifiers )
-    QModelIndex oldindex = currentIndex();
-    QModelIndex newindex = oldindex;
-    switch ( cursorAction )
-    {
-        case MoveUp:
-        case MovePrevious:
-        {
-            int row = oldindex.row() - 1;
-            while ( row > -1 && !( model()->index( row, 0 ).flags() & Qt::ItemIsSelectable ) ) --row;
-            if ( row > -1 )
-                newindex = model()->index( row, 0 );
-            break;
-        }
-        case MoveDown:
-        case MoveNext:
-        {
-            int row = oldindex.row() + 1;
-            int max = model()->rowCount();
-            while ( row < max && !( model()->index( row, 0 ).flags() & Qt::ItemIsSelectable ) ) ++row;
-            if ( row < max )
-                newindex = model()->index( row, 0 );
-            break;
-        }
-        case MoveHome:
-        case MovePageUp:
-        {
-            int row = 0;
-            while ( row < oldindex.row() && !( model()->index( row, 0 ).flags() & Qt::ItemIsSelectable ) ) ++row;
-            if ( row < oldindex.row() )
-                newindex = model()->index( row, 0 );
-            break;
-        }
-        case MoveEnd:
-        case MovePageDown:
-        {
-            int row = model()->rowCount() - 1;
-            while ( row > oldindex.row() && !( model()->index( row, 0 ).flags() & Qt::ItemIsSelectable ) ) --row;
-            if ( row > oldindex.row() )
-                newindex = model()->index( row, 0 );
-            break;
-        }
-        // no navigation possible for these
-        case MoveLeft:
-        case MoveRight:
-            break;
-    }
-
-    // dirty hack to change item when the key cursor changes item
-    if ( oldindex != newindex )
-    {
-        emit itemClicked( itemFromIndex( newindex ) );
-    }
-    return newindex;
-}
-
-
 /* Private storage. */
 class Sidebar::Private
 {
 public:
     Private()
-        : sideWidget( nullptr ), bottomWidget( nullptr ), splitterSizesSet( false ),
-          itemsHeight( 0 )
+        : sideWidget( nullptr ), bottomWidget( nullptr ), splitterSizesSet( false )
     {
     }
 
-    int indexOf(QWidget *w) const
-    {
-        for (int i = 0; i < pages.count(); ++i) {
-            if (pages[i]->widget() == w) return i;
-        }
-        return -1;
-    }
-
-    void adjustListSize( bool recalc, bool expand = true );
-
-    SidebarListWidget *list;
     QSplitter *splitter;
-    QStackedWidget *stack;
+    QTabWidget *viewChooserTabs;
     QWidget *sideContainer;
-    QLabel *sideTitle;
     QVBoxLayout *vlay;
     QWidget *sideWidget;
     QWidget *bottomWidget;
-    QList< SidebarItem* > pages;
     bool splitterSizesSet;
-    int itemsHeight;
-    SidebarDelegate *sideDelegate;
 };
 
-void Sidebar::Private::adjustListSize( bool recalc, bool expand )
-{
-    QSize bottomElemSize( list->sizeHintForIndex( list->model()->index( list->count() - 1, 0 ) ) );
-    if ( recalc )
-    {
-        int w = 0;
-        for ( int i = 0; i < list->count(); ++i )
-        {
-            QSize s = list->sizeHintForIndex( list->model()->index( i, 0 ) );
-            if ( s.width() > w )
-                w = s.width();
-        }
-        bottomElemSize.setWidth( w );
-    }
-    itemsHeight = bottomElemSize.height() * list->countVisible();
-    list->setMinimumHeight( itemsHeight + list->frameWidth() * 2 );
-
-    int curWidth = list->minimumWidth();
-    int newWidth = expand
-                   ? qMax( bottomElemSize.width() + list->frameWidth() * 2, curWidth )
-                   : qMin( bottomElemSize.width() + list->frameWidth() * 2, curWidth );
-    list->setFixedWidth( newWidth );
-}
-
 
 Sidebar::Sidebar( QWidget *parent )
     : QWidget( parent ), d( new Private )
@@ -479,49 +61,23 @@ Sidebar::Sidebar( QWidget *parent )
     setAutoFillBackground( true );
     setAcceptDrops( true );
 
-    d->list = new SidebarListWidget( this );
-    mainlay->addWidget( d->list );
-    d->list->setMouseTracking( true );
-    d->list->viewport()->setAttribute( Qt::WA_Hover );
-    d->sideDelegate = new SidebarDelegate( d->list );
-    d->sideDelegate->setShowText( Okular::Settings::sidebarShowText() );
-    d->list->setItemDelegate( d->sideDelegate );
-    d->list->setUniformItemSizes( true );
-    d->list->setSelectionMode( QAbstractItemView::SingleSelection );
-    int iconsize = Okular::Settings::sidebarIconSize();
-    d->list->setIconSize( QSize( iconsize, iconsize ) );
-    d->list->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
-    d->list->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
-    d->list->setContextMenuPolicy( Qt::CustomContextMenu );
-    d->list->viewport()->setAutoFillBackground( false );
-
     d->splitter = new QSplitter( this );
     mainlay->addWidget( d->splitter );
     d->splitter->setOpaqueResize( true );
     d->splitter->setChildrenCollapsible( false );
 
+    // d->sideContainer holds all the actual content
     d->sideContainer = new QWidget( d->splitter );
     d->sideContainer->setMinimumWidth( 90 );
     d->sideContainer->setMaximumWidth( 600 );
     d->vlay = new QVBoxLayout( d->sideContainer );
     d->vlay->setContentsMargins( 0, 0, 0, 0 );
 
-    d->sideTitle = new QLabel( d->sideContainer );
-    d->vlay->addWidget( d->sideTitle );
-    QFont tf = d->sideTitle->font();
-    tf.setBold( true );
-    d->sideTitle->setFont( tf );
-    d->sideTitle->setMargin( 3 );
-    d->sideTitle->setIndent( 3 );
+    d->viewChooserTabs = new QTabWidget( d->sideContainer );
+    d->viewChooserTabs->setDocumentMode(true);
+    d->vlay->addWidget( d->viewChooserTabs );
 
-    d->stack = new QStackedWidget( d->sideContainer );
-    d->vlay->addWidget( d->stack );
-
-    connect(d->list, &SidebarListWidget::customContextMenuRequested, this, &Sidebar::listContextMenu);
     connect(d->splitter, &QSplitter::splitterMoved, this, &Sidebar::splitterMoved);
-
-    setCollapsed( true );
-    setFocusProxy( d->list );
 }
 
 Sidebar::~Sidebar()
@@ -534,14 +90,14 @@ int Sidebar::addItem( QWidget *widget, const QIcon &icon, const QString &text )
     if ( !widget )
         return -1;
 
-    SidebarItem *newitem = new SidebarItem( widget, icon, text );
-    d->list->addItem( newitem );
-    d->pages.append( newitem );
-    widget->setParent( d->stack );
-    d->stack->addWidget( widget );
-    // updating the minimum height of the icon view, so all are visible with no scrolling
-    d->adjustListSize( false, true );
-    return d->pages.count() - 1;
+    widget->setParent( d->viewChooserTabs );
+    d->viewChooserTabs->addTab( widget, icon, text );
+    const int thisTabIndex = d->viewChooserTabs->count() - 1;
+    // Hide all text and use large icons
+    d->viewChooserTabs->setTabText( thisTabIndex, QString() );
+    d->viewChooserTabs->setIconSize( QSize(22, 22) );
+    d->viewChooserTabs->setTabToolTip( thisTabIndex, text );
+    return thisTabIndex;
 }
 
 void Sidebar::setMainWidget( QWidget *widget )
@@ -580,114 +136,27 @@ void Sidebar::setBottomWidget( QWidget *widget )
     }
 }
 
-void Sidebar::setItemEnabled( QWidget *widget, bool enabled )
-{
-    const int index = d->indexOf( widget );
-    setIndexEnabled( index, enabled );
-}
-
-void Sidebar::setIndexEnabled( int index, bool enabled )
-{
-    if ( index < 0 || index >= d->pages.count() )
-        return;
-
-    Qt::ItemFlags f = d->pages.at( index )->flags();
-    if ( enabled )
-    {
-        f |= Qt::ItemIsEnabled;
-        f |= Qt::ItemIsSelectable;
-    }
-    else
-    {
-        f &= ~Qt::ItemIsEnabled;
-        f &= ~Qt::ItemIsSelectable;
-    }
-    d->pages.at( index )->setFlags( f );
-
-    if ( !enabled && index == d->list->currentRow() && isSidebarVisible() )
-        // find an enabled item, and select that one
-        for ( int i = 0; i < d->pages.count(); ++i )
-            if ( d->pages.at(i)->flags() & Qt::ItemIsEnabled )
-            {
-                setCurrentIndex( i );
-                break;
-            }
-}
-
-bool Sidebar::isItemEnabled( QWidget *widget ) const
+void Sidebar::setCurrentItem( QWidget *widget )
 {
-    const int index = d->indexOf( widget );
-    return isIndexEnabled( index );
-}
-
-bool Sidebar::isIndexEnabled( int index ) const
-{
-    if ( index < 0 )
-        return false;
-
-    Qt::ItemFlags f = d->pages.at( index )->flags();
-    return ( f & Qt::ItemIsEnabled ) == Qt::ItemIsEnabled;
-}
-
-void Sidebar::setCurrentItem( QWidget *widget, SetCurrentItemBehaviour b )
-{
-    const int index = d->indexOf( widget );
-    setCurrentIndex( index, b );
-}
-
-void Sidebar::setCurrentIndex( int index, SetCurrentItemBehaviour b )
-{
-    if ( index < 0 || !isIndexEnabled( index ) )
-        return;
-
-    itemClicked( d->pages.at( index ), b );
-    QModelIndex modelindex = d->list->model()->index( index, 0 );
-    d->list->setCurrentIndex( modelindex );
-    d->list->selectionModel()->select( modelindex, QItemSelectionModel::ClearAndSelect );
+    d->viewChooserTabs->setCurrentWidget( widget );
 }
 
 QWidget *Sidebar::currentItem() const
 {
-    const int row = d->list->currentRow();
-    if (row < 0 || row >= d->pages.count())
+    if ( d->viewChooserTabs->currentIndex() == -1 )
         return nullptr;
 
-    return d->pages[row]->widget();
+    return d->viewChooserTabs->currentWidget();
 }
 
 void Sidebar::setSidebarVisibility( bool visible )
 {
-    if ( visible != d->list->isHidden() )
-        return;
-
-    static bool wasCollapsed = isCollapsed();
-
-    d->list->setHidden( !visible );
-    if ( visible )
-    {
-        setCollapsed( wasCollapsed );
-        wasCollapsed = false;
-    }
-    else
-    {
-        wasCollapsed = isCollapsed();
-        setCollapsed( true );
-    }
+    d->sideContainer->setHidden( !visible );
 }
 
 bool Sidebar::isSidebarVisible() const
 {
-    return !d->list->isHidden();
-}
-
-void Sidebar::setCollapsed( bool collapsed )
-{
-    d->sideContainer->setHidden( collapsed );
-}
-
-bool Sidebar::isCollapsed() const
-{
-    return d->sideContainer->isHidden();
+    return !d->sideContainer->isHidden();
 }
 
 void Sidebar::moveSplitter(int sideWidgetSize)
@@ -699,58 +168,6 @@ void Sidebar::moveSplitter(int sideWidgetSize)
     d->splitter->setSizes( splitterSizeList );
 }
 
-void Sidebar::setItemVisible( QWidget *widget, bool visible )
-{
-    const int index = d->indexOf( widget );
-    if ( index < 0 )
-        return;
-
-    d->list->setRowHidden( index, !visible );
-    setIndexEnabled( index, visible );
-}
-
-void Sidebar::itemClicked( QListWidgetItem *item )
-{
-    itemClicked( item, UncollapseIfCollapsed );
-}
-
-void Sidebar::itemClicked( QListWidgetItem *item, SetCurrentItemBehaviour b )
-{
-    if ( !item )
-        return;
-
-    SidebarItem* sbItem = dynamic_cast< SidebarItem* >( item );
-    if ( !sbItem )
-        return;
-
-    if ( sbItem->widget() == d->stack->currentWidget() )
-    {
-        if ( !isCollapsed() )
-        {
-            d->list->selectionModel()->clear();
-            setCollapsed( true );
-        }
-        else
-        {
-            if ( b == UncollapseIfCollapsed )
-            {
-                setCollapsed( false );
-                d->list->show();
-            }
-        }
-    }
-    else
-    {
-        if ( isCollapsed() && b == UncollapseIfCollapsed )
-        {
-            setCollapsed( false );
-            d->list->show();
-        }
-        d->stack->setCurrentWidget( sbItem->widget() );
-        d->sideTitle->setText( sbItem->toolTip() );
-    }
-}
-
 void Sidebar::splitterMoved( int /*pos*/, int index )
 {
     // if the side panel has been resized, save splitter sizes
@@ -764,56 +181,6 @@ void Sidebar::saveSplitterSize() const
     Okular::Settings::self()->save();
 }
 
-void Sidebar::listContextMenu( const QPoint pos )
-{
-    QMenu menu( this );
-    menu.setTitle( i18n( "Okular" ) );
-    QAction *showTextAct = menu.addAction( i18n( "Show Text" ) );
-    showTextAct->setCheckable( true );
-    showTextAct->setChecked( d->sideDelegate->isTextShown() );
-    connect(showTextAct, &QAction::toggled, this, &Sidebar::showTextToggled);
-    menu.addSeparator();
-    QActionGroup *sizeGroup = new QActionGroup( &menu );
-    int curSize = d->list->iconSize().width();
-#define ADD_SIZE_ACTION( text, _itssize ) \
-{ \
-    const int itssize = static_cast< int >( _itssize ); \
-    QAction *sizeAct = menu.addAction( text ); \
-    sizeAct->setCheckable( true ); \
-    sizeAct->setData( QVariant::fromValue( itssize ) ); \
-    sizeAct->setChecked( itssize == curSize ); \
-    sizeGroup->addAction( sizeAct ); \
-}
-    ADD_SIZE_ACTION( i18n( "Small Icons" ), KIconLoader::SizeSmallMedium )
-    ADD_SIZE_ACTION( i18n( "Normal Icons" ), KIconLoader::SizeMedium )
-    ADD_SIZE_ACTION( i18n( "Large Icons" ), KIconLoader::SizeLarge )
-#undef ADD_SIZE_ACTION
-    connect(sizeGroup, &QActionGroup::triggered, this, &Sidebar::iconSizeChanged);
-    menu.exec( mapToGlobal( pos ) );
-}
-
-void Sidebar::showTextToggled( bool on )
-{
-    d->sideDelegate->setShowText( on );
-    d->adjustListSize( true, on );
-    d->list->reset();
-    d->list->update();
-    Okular::Settings::setSidebarShowText( on );
-    Okular::Settings::self()->save();
-}
-
-void Sidebar::iconSizeChanged( QAction *action )
-{
-    int size = action->data().toInt();
-    int oldSize = d->list->iconSize().width();
-    d->list->setIconSize( QSize( size, size ) );
-    d->adjustListSize( true, size > oldSize );
-    d->list->reset();
-    d->list->update();
-    Okular::Settings::setSidebarIconSize( size );
-    Okular::Settings::self()->save();
-}
-
 void Sidebar::dragEnterEvent( QDragEnterEvent* event )
 {
     event->setAccepted( event->mimeData()->hasUrls() );
diff --git a/ui/sidebar.h b/ui/sidebar.h
index 2baa41c2d..7e70aa367 100644
--- a/ui/sidebar.h
+++ b/ui/sidebar.h
@@ -28,22 +28,12 @@ class OKULARPART_EXPORT Sidebar : public QWidget
         void setMainWidget( QWidget *widget );
         void setBottomWidget( QWidget *widget );
 
-        void setItemEnabled( QWidget *widget, bool enabled );
-        bool isItemEnabled( QWidget *widget ) const;
-
-        void setItemVisible( QWidget *widget, bool visible );
-
-        enum SetCurrentItemBehaviour { UncollapseIfCollapsed, DoNotUncollapseIfCollapsed };
-
-        void setCurrentItem( QWidget *widget, SetCurrentItemBehaviour b = UncollapseIfCollapsed );
+        void setCurrentItem( QWidget *widget );
         QWidget *currentItem() const;
 
         void setSidebarVisibility( bool visible );
         bool isSidebarVisible() const;
 
-        void setCollapsed( bool collapsed );
-        bool isCollapsed() const;
-
         void moveSplitter( int sideWidgetSize );
 
     Q_SIGNALS:
@@ -54,17 +44,9 @@ class OKULARPART_EXPORT Sidebar : public QWidget
         void dropEvent( QDropEvent* event ) override;
 
     private Q_SLOTS:
-        void itemClicked( QListWidgetItem *item );
         void splitterMoved( int pos, int index );
-        void listContextMenu( const QPoint );
-        void showTextToggled( bool );
-        void iconSizeChanged( QAction *action );
 
     private:
-        void setIndexEnabled( int index, bool enabled );
-        void setCurrentIndex( int index, SetCurrentItemBehaviour b = UncollapseIfCollapsed );
-        bool isIndexEnabled( int index ) const;
-        void itemClicked( QListWidgetItem *item, SetCurrentItemBehaviour b );
         void saveSplitterSize() const;
 
         // private storage
diff --git a/ui/signaturepanel.cpp b/ui/signaturepanel.cpp
index 298a39512..847e60d99 100644
--- a/ui/signaturepanel.cpp
+++ b/ui/signaturepanel.cpp
@@ -15,6 +15,9 @@
 #include "revisionviewer.h"
 #include "signaturepropertiesdialog.h"
 
+#include <kwidgetsaddons_version.h>
+
+#include <KTitleWidget>
 #include <KLocalizedString>
 
 #include <QMenu>
@@ -40,6 +43,14 @@ SignaturePanel::SignaturePanel( Okular::Document *document, QWidget *parent )
     : QWidget( parent ), d_ptr( new SignaturePanelPrivate )
 {
     Q_D( SignaturePanel );
+
+
+    KTitleWidget *titleWidget = new KTitleWidget( this );
+    #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 53, 0)
+    titleWidget->setLevel( 2 );
+    #endif
+    titleWidget->setText( i18n( "Signatures" ) );
+
     d->m_view = new QTreeView( this );
     d->m_view->setAlternatingRowColors( true );
     d->m_view->setSelectionMode( QAbstractItemView::SingleSelection );
@@ -54,8 +65,10 @@ SignaturePanel::SignaturePanel( Okular::Document *document, QWidget *parent )
     connect( d->m_view, &QTreeView::customContextMenuRequested, this, &SignaturePanel::slotShowContextMenu );
 
     auto vLayout = new QVBoxLayout( this );
-    vLayout->setContentsMargins( 0, 0, 0, 0 );
     vLayout->setSpacing( 6 );
+
+    vLayout->addWidget( titleWidget );
+    vLayout->setAlignment( titleWidget, Qt::AlignHCenter );
     vLayout->addWidget( d->m_view );
 }
 
diff --git a/ui/thumbnaillist.cpp b/ui/thumbnaillist.cpp
index 3ea0f38b9..54d0c0168 100644
--- a/ui/thumbnaillist.cpp
+++ b/ui/thumbnaillist.cpp
@@ -20,9 +20,13 @@
 #include <QSizePolicy>
 #include <QStyle>
 #include <QTimer>
+#include <QVBoxLayout>
 
 #include <KLocalizedString>
 #include <KActionCollection>
+#include <KTitleWidget>
+
+#include <kwidgetsaddons_version.h>
 
 // local includes
 #include "pagepainter.h"
@@ -36,6 +40,25 @@
 
 class ThumbnailWidget;
 
+ThumbnailsBox::ThumbnailsBox( QWidget * parent ) : QWidget( parent ) {
+    QVBoxLayout *vbox = new QVBoxLayout(this);
+    vbox->setSpacing(0);
+
+    KTitleWidget *titleWidget = new KTitleWidget( this );
+    #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 53, 0)
+    titleWidget->setLevel( 2 );
+    #endif
+    titleWidget->setText( i18n( "Thumbnails" ) );
+    vbox->addWidget( titleWidget );
+    vbox->setAlignment( titleWidget, Qt::AlignHCenter );
+}
+
+QSize ThumbnailsBox::sizeHint() const
+{
+    return QSize();
+}
+
+
 class ThumbnailListPrivate : public QWidget
 {
     Q_OBJECT
diff --git a/ui/thumbnaillist.h b/ui/thumbnaillist.h
index 14cb6205e..0be9dd336 100644
--- a/ui/thumbnaillist.h
+++ b/ui/thumbnaillist.h
@@ -12,7 +12,6 @@
 
 #include <QScrollArea>
 #include <QToolBar>
-#include <QVBoxLayout>
 
 #include "core/observer.h"
 
@@ -77,8 +76,8 @@ class ThumbnailsBox : public QWidget
     Q_OBJECT
 
     public:
-        explicit ThumbnailsBox( QWidget * parent ) : QWidget( parent ) { QVBoxLayout *vbox = new QVBoxLayout(this); vbox->setContentsMargins(0, 0, 0, 0); vbox->setSpacing(0);}
-        QSize sizeHint() const override { return QSize(); }
+        explicit ThumbnailsBox( QWidget * parent );
+        QSize sizeHint() const override;
 };
 
 /**
diff --git a/ui/toc.cpp b/ui/toc.cpp
index 26d86fd68..ef1a4e99d 100644
--- a/ui/toc.cpp
+++ b/ui/toc.cpp
@@ -18,6 +18,9 @@
 
 #include <klineedit.h>
 #include <KLocalizedString>
+#include <KTitleWidget>
+
+#include <kwidgetsaddons_version.h>
 
 // local includes
 #include "ktreeviewsearchline.h"
@@ -30,9 +33,15 @@
 TOC::TOC(QWidget *parent, Okular::Document *document) : QWidget(parent), m_document(document)
 {
     QVBoxLayout *mainlay = new QVBoxLayout( this );
-    mainlay->setContentsMargins( 0, 0, 0, 0 );
     mainlay->setSpacing( 6 );
 
+    KTitleWidget *titleWidget = new KTitleWidget( this );
+    #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 53, 0)
+    titleWidget->setLevel( 2 );
+    #endif
+    titleWidget->setText( i18n( "Contents" ) );
+    mainlay->addWidget( titleWidget );
+    mainlay->setAlignment( titleWidget, Qt::AlignHCenter );
     m_searchLine = new KTreeViewSearchLine( this );
     mainlay->addWidget( m_searchLine );
     m_searchLine->setPlaceholderText(i18n( "Search..." ));


More information about the kde-doc-english mailing list