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 }