File indexing completed on 2024-04-28 15:51:58

0001 /*
0002     SPDX-FileCopyrightText: 2007 Pino Toscano <pino@kde.org>
0003     SPDX-FileCopyrightText: 2009 Eike Hein <hein@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "sidebar.h"
0009 
0010 #include <qaction.h>
0011 #include <qapplication.h>
0012 #include <qevent.h>
0013 #include <qfont.h>
0014 #include <qfontmetrics.h>
0015 #include <qlabel.h>
0016 #include <qlayout.h>
0017 #include <qlist.h>
0018 #include <qmimedata.h>
0019 #include <qpainter.h>
0020 #include <qscrollbar.h>
0021 #include <qsplitter.h>
0022 #include <qtabwidget.h>
0023 
0024 #include <KLocalizedString>
0025 #include <kcolorscheme.h>
0026 #include <kiconloader.h>
0027 #include <kurlmimedata.h>
0028 #include <qmenu.h>
0029 
0030 #include "settings.h"
0031 
0032 /* Private storage. */
0033 class Sidebar::Private
0034 {
0035 public:
0036     Private()
0037         : sideWidget(nullptr)
0038         , bottomWidget(nullptr)
0039         , splitterSizesSet(false)
0040     {
0041     }
0042 
0043     QSplitter *splitter;
0044     QTabWidget *viewChooserTabs;
0045     QWidget *sideContainer;
0046     QVBoxLayout *vlay;
0047     QWidget *sideWidget;
0048     QWidget *bottomWidget;
0049     bool splitterSizesSet;
0050 };
0051 
0052 Sidebar::Sidebar(QWidget *parent)
0053     : QWidget(parent)
0054     , d(new Private)
0055 {
0056     QHBoxLayout *mainlay = new QHBoxLayout(this);
0057     mainlay->setContentsMargins(0, 0, 0, 0);
0058     mainlay->setSpacing(0);
0059 
0060     setAutoFillBackground(true);
0061     setAcceptDrops(true);
0062 
0063     d->splitter = new QSplitter(this);
0064     mainlay->addWidget(d->splitter);
0065     d->splitter->setOpaqueResize(true);
0066     d->splitter->setChildrenCollapsible(false);
0067 
0068     // d->sideContainer holds all the actual content
0069     d->sideContainer = new QWidget(d->splitter);
0070     d->sideContainer->setMinimumWidth(90);
0071     d->sideContainer->setMaximumWidth(600);
0072     d->vlay = new QVBoxLayout(d->sideContainer);
0073     d->vlay->setContentsMargins(0, 0, 0, 0);
0074 
0075     d->viewChooserTabs = new QTabWidget(d->sideContainer);
0076     d->viewChooserTabs->setDocumentMode(true);
0077     d->vlay->addWidget(d->viewChooserTabs);
0078 
0079     connect(d->splitter, &QSplitter::splitterMoved, this, &Sidebar::splitterMoved);
0080 }
0081 
0082 Sidebar::~Sidebar()
0083 {
0084     delete d;
0085 }
0086 
0087 int Sidebar::addItem(QWidget *widget, const QIcon &icon, const QString &text)
0088 {
0089     if (!widget) {
0090         return -1;
0091     }
0092 
0093     widget->setParent(d->viewChooserTabs);
0094     d->viewChooserTabs->addTab(widget, icon, text);
0095     const int thisTabIndex = d->viewChooserTabs->count() - 1;
0096     // Hide all text and use large icons
0097     d->viewChooserTabs->setTabText(thisTabIndex, QString());
0098     d->viewChooserTabs->setIconSize(QSize(22, 22));
0099     d->viewChooserTabs->setTabToolTip(thisTabIndex, text);
0100     return thisTabIndex;
0101 }
0102 
0103 void Sidebar::setMainWidget(QWidget *widget)
0104 {
0105     delete d->sideWidget;
0106     d->sideWidget = widget;
0107     if (d->sideWidget) {
0108         // setting the splitter as parent for the widget automatically plugs it
0109         // into the splitter, neat!
0110         d->sideWidget->setParent(d->splitter);
0111         setFocusProxy(widget);
0112 
0113         if (!d->splitterSizesSet) {
0114             QList<int> splitterSizes = Okular::Settings::splitterSizes();
0115             if (splitterSizes.isEmpty()) {
0116                 // the first time use 1/10 for the panel and 9/10 for the pageView
0117                 splitterSizes.push_back(50);
0118                 splitterSizes.push_back(500);
0119             }
0120             d->splitter->setSizes(splitterSizes);
0121             d->splitterSizesSet = true;
0122         }
0123     }
0124 }
0125 
0126 void Sidebar::setBottomWidget(QWidget *widget)
0127 {
0128     delete d->bottomWidget;
0129     d->bottomWidget = widget;
0130     if (d->bottomWidget) {
0131         d->bottomWidget->setParent(this);
0132         d->vlay->addWidget(d->bottomWidget);
0133     }
0134 }
0135 
0136 void Sidebar::setCurrentItem(QWidget *widget)
0137 {
0138     d->viewChooserTabs->setCurrentWidget(widget);
0139 }
0140 
0141 QWidget *Sidebar::currentItem() const
0142 {
0143     if (d->viewChooserTabs->currentIndex() == -1) {
0144         return nullptr;
0145     }
0146 
0147     return d->viewChooserTabs->currentWidget();
0148 }
0149 
0150 void Sidebar::setSidebarVisibility(bool visible)
0151 {
0152     d->sideContainer->setHidden(!visible);
0153 }
0154 
0155 bool Sidebar::isSidebarVisible() const
0156 {
0157     return !d->sideContainer->isHidden();
0158 }
0159 
0160 void Sidebar::moveSplitter(int sideWidgetSize)
0161 {
0162     QList<int> splitterSizeList = d->splitter->sizes();
0163     const int total = splitterSizeList.at(0) + splitterSizeList.at(1);
0164     splitterSizeList.replace(0, total - sideWidgetSize);
0165     splitterSizeList.replace(1, sideWidgetSize);
0166     d->splitter->setSizes(splitterSizeList);
0167 }
0168 
0169 QWidget *Sidebar::getSideContainer() const
0170 {
0171     return d->sideContainer;
0172 }
0173 
0174 void Sidebar::splitterMoved(int /*pos*/, int index)
0175 {
0176     // if the side panel has been resized, save splitter sizes
0177     if (index == 1) {
0178         saveSplitterSize();
0179     }
0180 }
0181 
0182 void Sidebar::saveSplitterSize() const
0183 {
0184     Okular::Settings::setSplitterSizes(d->splitter->sizes());
0185     Okular::Settings::self()->save();
0186 }
0187 
0188 void Sidebar::dragEnterEvent(QDragEnterEvent *event)
0189 {
0190     event->setAccepted(event->mimeData()->hasUrls());
0191 }
0192 
0193 void Sidebar::dropEvent(QDropEvent *event)
0194 {
0195     const QList<QUrl> list = KUrlMimeData::urlsFromMimeData(event->mimeData());
0196     Q_EMIT urlsDropped(list);
0197 }