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>