Warning, file /office/calligra/libs/widgets/KoToolDocker.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 * 0003 * Copyright (c) 2010-2011 C. Boemann <cbo@boemann.dk> 0004 * Copyright (c) 2005-2006 Boudewijn Rempt <boud@valdyas.org> 0005 * Copyright (c) 2006 Thomas Zander <zander@kde.org> 0006 * 0007 * This library is free software; you can redistribute it and/or 0008 * modify it under the terms of the GNU Library General Public 0009 * License as published by the Free Software Foundation; either 0010 * version 2 of the License, or (at your option) any later version. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Library General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Library General Public License 0018 * along with this library; see the file COPYING.LIB. If not, write to 0019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 * Boston, MA 02110-1301, USA. 0021 */ 0022 #include "KoToolDocker.h" 0023 0024 #include <KoDockWidgetTitleBarButton.h> 0025 #include <KoDockWidgetTitleBar.h> 0026 #include <KoIcon.h> 0027 0028 #include <klocalizedstring.h> 0029 #include <kconfiggroup.h> 0030 #include <ksharedconfig.h> 0031 0032 #include <QIcon> 0033 #include <QApplication> 0034 #include <QPointer> 0035 #include <QGridLayout> 0036 #include <QScrollArea> 0037 #include <QScrollBar> 0038 #include <QLabel> 0039 #include <QSet> 0040 #include <QAction> 0041 #include <QStyleOptionFrame> 0042 #include <QToolButton> 0043 #include <QTabWidget> 0044 0045 #include <WidgetsDebug.h> 0046 0047 class Q_DECL_HIDDEN KoToolDocker::Private 0048 { 0049 public: 0050 Private(KoToolDocker *dock) 0051 : q(dock) 0052 , tabbed(false) 0053 , tabIcon(koIcon("tab-new")) 0054 , unTabIcon(koIcon("tab-close")) 0055 { 0056 } 0057 0058 QList<QPointer<QWidget> > currentWidgetList; 0059 QSet<QWidget *> currentAuxWidgets; 0060 QScrollArea *scrollArea; 0061 QWidget *hiderWidget; // non current widgets are hidden by being children of this 0062 QWidget *housekeeperWidget; 0063 QGridLayout *housekeeperLayout; 0064 KoToolDocker *q; 0065 Qt::DockWidgetArea dockingArea; 0066 bool tabbed; 0067 QIcon tabIcon; 0068 QIcon unTabIcon; 0069 QToolButton *tabButton; 0070 0071 0072 void resetWidgets() 0073 { 0074 currentWidgetList.clear(); 0075 qDeleteAll(currentAuxWidgets); 0076 currentAuxWidgets.clear(); 0077 } 0078 0079 void recreateLayout(const QList<QPointer<QWidget> > &optionWidgetList) 0080 { 0081 foreach(QPointer<QWidget> widget, currentWidgetList) { 0082 if (!widget.isNull() && widget && hiderWidget) { 0083 widget->setParent(hiderWidget); 0084 } 0085 } 0086 qDeleteAll(currentAuxWidgets); 0087 currentAuxWidgets.clear(); 0088 0089 currentWidgetList = optionWidgetList; 0090 0091 // need to unstretch row that have previously been stretched 0092 housekeeperLayout->setRowStretch(housekeeperLayout->rowCount()-1, 0); 0093 0094 if (tabbed && currentWidgetList.size() > 1) { 0095 QTabWidget *t; 0096 housekeeperLayout->addWidget(t = new QTabWidget(), 0, 0); 0097 t->setDocumentMode(true); 0098 currentAuxWidgets.insert(t); 0099 foreach(QPointer<QWidget> widget, currentWidgetList) { 0100 if (widget.isNull() || widget->objectName().isEmpty()) { 0101 Q_ASSERT(!(widget->objectName().isEmpty())); 0102 continue; // skip this docker in release build when assert don't crash 0103 } 0104 t->addTab(widget, widget->windowTitle()); 0105 } 0106 } else { 0107 int cnt = 0; 0108 QFrame *s; 0109 QLabel *l; 0110 switch(dockingArea) { 0111 case Qt::TopDockWidgetArea: 0112 case Qt::BottomDockWidgetArea: 0113 housekeeperLayout->setHorizontalSpacing(2); 0114 housekeeperLayout->setVerticalSpacing(0); 0115 foreach(QPointer<QWidget> widget, currentWidgetList) { 0116 if (widget.isNull() || widget->objectName().isEmpty()) { 0117 continue; // skip this docker in release build when assert don't crash 0118 } 0119 if (!widget->windowTitle().isEmpty()) { 0120 housekeeperLayout->addWidget(l = new QLabel(widget->windowTitle()), 0, 2*cnt); 0121 currentAuxWidgets.insert(l); 0122 } 0123 housekeeperLayout->addWidget(widget, 1, 2*cnt); 0124 widget->show(); 0125 if (widget != currentWidgetList.last()) { 0126 housekeeperLayout->addWidget(s = new QFrame(), 0, 2*cnt+1, 2, 1); 0127 s->setFrameShape(QFrame::VLine); 0128 currentAuxWidgets.insert(s); 0129 } 0130 cnt++; 0131 } 0132 break; 0133 case Qt::LeftDockWidgetArea: 0134 case Qt::RightDockWidgetArea: { 0135 housekeeperLayout->setHorizontalSpacing(0); 0136 housekeeperLayout->setVerticalSpacing(2); 0137 int specialCount = 0; 0138 foreach(QPointer<QWidget> widget, currentWidgetList) { 0139 if (widget.isNull() || widget->objectName().isEmpty()) { 0140 Q_ASSERT(!(widget->objectName().isEmpty())); 0141 continue; // skip this docker in release build when assert don't crash 0142 } 0143 if (!widget->windowTitle().isEmpty()) { 0144 housekeeperLayout->addWidget(l = new QLabel(widget->windowTitle()), cnt++, 0); 0145 currentAuxWidgets.insert(l); 0146 } 0147 housekeeperLayout->addWidget(widget, cnt++, 0); 0148 QLayout *subLayout = widget->layout(); 0149 if (subLayout) { 0150 for (int i = 0; i < subLayout->count(); ++i) { 0151 QWidget *spacerWidget = subLayout->itemAt(i)->widget(); 0152 if (spacerWidget && spacerWidget->objectName().contains("SpecialSpacer")) { 0153 specialCount++; 0154 } 0155 } 0156 } 0157 widget->show(); 0158 if (widget != currentWidgetList.last()) { 0159 housekeeperLayout->addWidget(s = new QFrame(), cnt++, 0); 0160 s->setFrameShape(QFrame::HLine); 0161 currentAuxWidgets.insert(s); 0162 } 0163 } 0164 if (specialCount == currentWidgetList.count()) { 0165 housekeeperLayout->setRowStretch(cnt, 10000); 0166 } 0167 break; 0168 } 0169 default: 0170 break; 0171 } 0172 } 0173 housekeeperLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); 0174 housekeeperLayout->invalidate(); 0175 } 0176 0177 void locationChanged(Qt::DockWidgetArea area) 0178 { 0179 dockingArea = area; 0180 recreateLayout(currentWidgetList); 0181 } 0182 0183 void toggleTab() 0184 { 0185 if (!tabbed) { 0186 tabbed = true; 0187 tabButton->setIcon(unTabIcon); 0188 } else { 0189 tabbed = false; 0190 tabButton->setIcon(tabIcon); 0191 } 0192 recreateLayout(currentWidgetList); 0193 } 0194 }; 0195 0196 KoToolDocker::KoToolDocker(QWidget *parent) 0197 : QDockWidget(i18n("Tool Options"), parent), 0198 d(new Private(this)) 0199 { 0200 KConfigGroup cfg = KSharedConfig::openConfig()->group("DockWidget sharedtooldocker"); 0201 d->tabbed = cfg.readEntry("TabbedMode", false); 0202 0203 toggleViewAction()->setVisible(false); //should always be visible, so hide option in menu 0204 setFeatures(DockWidgetMovable|DockWidgetFloatable); 0205 setTitleBarWidget(new KoDockWidgetTitleBar(this)); 0206 0207 connect(this, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(locationChanged(Qt::DockWidgetArea))); 0208 0209 d->housekeeperWidget = new QWidget(); 0210 d->housekeeperLayout = new QGridLayout(); 0211 d->housekeeperLayout->setContentsMargins(4,4,4,0); 0212 d->housekeeperWidget->setLayout(d->housekeeperLayout); 0213 0214 d->housekeeperLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); 0215 0216 d->hiderWidget = new QWidget(d->housekeeperWidget); 0217 d->hiderWidget->setVisible(false); 0218 0219 d->scrollArea = new QScrollArea(); 0220 d->scrollArea->setWidget(d->housekeeperWidget); 0221 d->scrollArea->setFrameShape(QFrame::NoFrame); 0222 d->scrollArea->setWidgetResizable(true); 0223 d->scrollArea->setFocusPolicy(Qt::NoFocus); 0224 0225 setWidget(d->scrollArea); 0226 0227 d->tabButton = new QToolButton(this); // parent hack in toggleLock to keep it clickable 0228 d->tabButton->setIcon(d->tabIcon); 0229 d->tabButton->setToolTip(i18n("Toggles organizing the options in tabs or not")); 0230 d->tabButton->setAutoRaise(true); 0231 connect(d->tabButton, SIGNAL(clicked()), SLOT(toggleTab())); 0232 d->tabButton->resize(d->tabButton->sizeHint()); 0233 } 0234 0235 KoToolDocker::~KoToolDocker() 0236 { 0237 KConfigGroup cfg = KSharedConfig::openConfig()->group("DockWidget sharedtooldocker"); 0238 cfg.writeEntry("TabbedMode", d->tabbed); 0239 cfg.sync(); 0240 0241 delete d; 0242 } 0243 0244 bool KoToolDocker::hasOptionWidget() 0245 { 0246 return !d->currentWidgetList.isEmpty(); 0247 } 0248 0249 void KoToolDocker::setTabEnabled(bool enabled) 0250 { 0251 d->tabButton->setVisible(enabled); 0252 } 0253 0254 void KoToolDocker::setOptionWidgets(const QList<QPointer<QWidget> > &optionWidgetList) 0255 { 0256 d->recreateLayout(optionWidgetList); 0257 } 0258 0259 void KoToolDocker::resizeEvent(QResizeEvent*) 0260 { 0261 int fw = isFloating() ? style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, nullptr, this) : 0; 0262 d->tabButton->move(width() - d->tabButton->width() - d->scrollArea->verticalScrollBar()->sizeHint().width(), fw); 0263 } 0264 0265 void KoToolDocker::resetWidgets() 0266 { 0267 d->resetWidgets(); 0268 } 0269 0270 0271 void KoToolDocker::setCanvas(KoCanvasBase *canvas) 0272 { 0273 setEnabled(canvas != 0); 0274 } 0275 0276 void KoToolDocker::unsetCanvas() 0277 { 0278 setEnabled(false); 0279 } 0280 0281 //have to include this because of Q_PRIVATE_SLOT 0282 #include <moc_KoToolDocker.cpp>