Warning, file /office/calligra/libs/widgets/KoModeBox.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * Copyright (c) 2005-2009 Thomas Zander <zander@kde.org>
0003  * Copyright (c) 2009 Peter Simonsson <peter.simonsson@gmail.com>
0004  * Copyright (c) 2010 Cyrille Berger <cberger@cberger.net>
0005  * Copyright (c) 2011 C. Boemann <cbo@boemann.dk>
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 
0023 #include <algorithm>
0024 
0025 #include "KoModeBox_p.h"
0026 
0027 #include <KoCanvasControllerWidget.h>
0028 #include <KoCanvasBase.h>
0029 #include <KoToolManager.h>
0030 #include <KoShapeLayer.h>
0031 
0032 #include <kconfiggroup.h>
0033 #include <klocalizedstring.h>
0034 #include <kselectaction.h>
0035 #include <ksharedconfig.h>
0036 
0037 #include <QIcon>
0038 
0039 #include <QMap>
0040 #include <QList>
0041 #include <QHash>
0042 #include <QSet>
0043 #include <QRect>
0044 #include <QLabel>
0045 #include <QFrame>
0046 #include <QGridLayout>
0047 #include <QApplication>
0048 #include <QTabBar>
0049 #include <QStackedWidget>
0050 #include <QPainter>
0051 #include <QTextLayout>
0052 #include <QMenu>
0053 #include <QScrollBar>
0054 #include <QFontDatabase>
0055 
0056 #include <WidgetsDebug.h>
0057 
0058 class KoModeBox::Private
0059 {
0060 public:
0061     Private(KoCanvasController *c)
0062         : canvas(c->canvas())
0063         , activeId(-1)
0064         , iconTextFitted(true)
0065         , fittingIterations(0)
0066         , iconMode(IconAndText)
0067         , verticalTabsSide(TopSide)
0068         , horizontalTabsSide(LeftSide)
0069         , horizontalMode(false)
0070     {
0071     }
0072 
0073     KoCanvasBase *canvas;
0074     QGridLayout *layout;
0075     QList<KoToolAction*> toolActions; // toolActions maintained by toolmanager
0076     QList<KoToolAction*> addedToolActions; //tools in the order added to QToolBox
0077     QMap<int, QWidget *> addedWidgets;
0078     QSet<QWidget *> currentAuxWidgets;
0079     int activeId;
0080     QTabBar *tabBar;
0081     QStackedWidget *stack;
0082     bool iconTextFitted;
0083     int fittingIterations;
0084     IconMode iconMode;
0085     VerticalTabsSide verticalTabsSide;
0086     HorizontalTabsSide horizontalTabsSide;
0087     bool horizontalMode;
0088 };
0089 
0090 QString KoModeBox::applicationName;
0091 
0092 static bool compareToolActions(const KoToolAction *b1, const KoToolAction *b2)
0093 {
0094     int b1Level;
0095     int b2Level;
0096     if (b1->section().contains(KoModeBox::applicationName)) {
0097         b1Level = 0;
0098     } else if (b1->section().contains("main")) {
0099         b1Level = 1;
0100     } else {
0101         b1Level = 2;
0102     }
0103 
0104     if (b2->section().contains(KoModeBox::applicationName)) {
0105         b2Level = 0;
0106     } else if (b2->section().contains("main")) {
0107         b2Level = 1;
0108     } else {
0109         b2Level = 2;
0110     }
0111 
0112     if (b1Level == b2Level) {
0113         return b1->priority() < b2->priority();
0114     } else {
0115         return b1Level < b2Level;
0116     }
0117 }
0118 
0119 
0120 KoModeBox::KoModeBox(KoCanvasControllerWidget *canvas, const QString &appName)
0121     : QWidget()
0122     , d(new Private(canvas))
0123 {
0124     applicationName = appName;
0125 
0126     KConfigGroup cfg =  KSharedConfig::openConfig()->group("calligra");
0127     d->iconMode = (IconMode)cfg.readEntry("ModeBoxIconMode", (int)IconAndText);
0128     d->verticalTabsSide = (VerticalTabsSide)cfg.readEntry("ModeBoxVerticalTabsSide", (int)TopSide);
0129     d->horizontalTabsSide = (HorizontalTabsSide)cfg.readEntry("ModeBoxHorizontalTabsSide", (int)LeftSide);
0130 
0131     d->layout = new QGridLayout();
0132     d->stack = new QStackedWidget();
0133 
0134     d->tabBar = new QTabBar();
0135     setIconSize();
0136     d->tabBar->setExpanding(d->horizontalMode);
0137     if (d->horizontalMode) {
0138         switchTabsSide(d->verticalTabsSide);
0139     } else {
0140         switchTabsSide(d->horizontalTabsSide);
0141     }
0142     d->tabBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
0143     d->layout->addWidget(d->stack, 0, 1);
0144 
0145     d->layout->setContentsMargins(0,0,0,0);
0146     setLayout(d->layout);
0147 
0148     foreach(KoToolAction *toolAction, KoToolManager::instance()->toolActionList()) {
0149         addToolAction(toolAction);
0150     }
0151 
0152     std::sort(d->toolActions.begin(), d->toolActions.end(), compareToolActions);
0153 
0154     // Update visibility of toolActions
0155     updateShownTools(QList<QString>());
0156 
0157     d->tabBar->setContextMenuPolicy(Qt::CustomContextMenu);
0158     connect(d->tabBar, SIGNAL(currentChanged(int)), this, SLOT(toolSelected(int)));
0159     connect(d->tabBar, SIGNAL(customContextMenuRequested(QPoint)), SLOT(slotContextMenuRequested(QPoint)));
0160 
0161     connect(KoToolManager::instance(), SIGNAL(changedTool(KoCanvasController*,int)),
0162             this, SLOT(setActiveTool(KoCanvasController*,int)));
0163     connect(KoToolManager::instance(), SIGNAL(currentLayerChanged(const KoCanvasController*,const KoShapeLayer*)),
0164             this, SLOT(setCurrentLayer(const KoCanvasController*,const KoShapeLayer*)));
0165     connect(KoToolManager::instance(), SIGNAL(toolCodesSelected(QList<QString>)), this, SLOT(updateShownTools(QList<QString>)));
0166     connect(KoToolManager::instance(),
0167             SIGNAL(addedTool(KoToolAction*,KoCanvasController*)),
0168             this, SLOT(toolAdded(KoToolAction*,KoCanvasController*)));
0169 
0170     connect(canvas, SIGNAL(toolOptionWidgetsChanged(QList<QPointer<QWidget>>)),
0171          this, SLOT(setOptionWidgets(QList<QPointer<QWidget>>)));
0172 }
0173 
0174 KoModeBox::~KoModeBox()
0175 {
0176     delete d;
0177 }
0178 
0179 void KoModeBox::addToolAction(KoToolAction *toolAction)
0180 {
0181     d->toolActions.append(toolAction);
0182 }
0183 
0184 void KoModeBox::locationChanged(Qt::DockWidgetArea area)
0185 {
0186     resize(0,0);
0187     switch(area) {
0188         case Qt::TopDockWidgetArea:
0189         case Qt::BottomDockWidgetArea:
0190             d->horizontalMode = true;
0191             d->layout->removeWidget(d->stack);
0192             d->layout->addWidget(d->stack, 1, 0);
0193             d->layout->setColumnStretch(1, 0);
0194             d->layout->setRowStretch(1, 100);
0195             break;
0196         case Qt::LeftDockWidgetArea:
0197         case Qt::RightDockWidgetArea:
0198             d->horizontalMode = false;
0199             d->layout->removeWidget(d->stack);
0200             d->layout->addWidget(d->stack, 0, 1);
0201             d->layout->setColumnStretch(1, 100);
0202             d->layout->setRowStretch(1, 0);
0203             break;
0204         default:
0205             break;
0206     }
0207     d->layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
0208     d->layout->invalidate();
0209 
0210     setIconSize();
0211     d->tabBar->setExpanding(d->horizontalMode);
0212     if (d->horizontalMode) {
0213         switchTabsSide(d->verticalTabsSide);
0214     } else {
0215         switchTabsSide(d->horizontalTabsSide);
0216     }
0217 }
0218 
0219 void KoModeBox::setActiveTool(KoCanvasController *canvas, int id)
0220 {
0221     if (canvas->canvas() == d->canvas) {
0222         // Clear the minimumSize instigated by the previous tool
0223         // The new minimumSize will be set in updateShownTools()
0224         if (d->addedWidgets.contains(d->activeId)) {
0225             ScrollArea *sa = qobject_cast<ScrollArea *>(d->addedWidgets[d->activeId]->parentWidget()->parentWidget());
0226             sa->setMinimumWidth(0);
0227             sa->setMinimumHeight(0);
0228         }
0229 
0230         d->activeId = id;
0231         d->tabBar->blockSignals(true);
0232         int i = 0;
0233         foreach (KoToolAction *toolAction, d->addedToolActions) {
0234             if (toolAction->buttonGroupId() == d->activeId) {
0235                 d->tabBar->setCurrentIndex(i);
0236                 d->stack->setCurrentIndex(i);
0237                 break;
0238             }
0239             ++i;
0240         }
0241         d->tabBar->blockSignals(false);
0242         return;
0243     }
0244 }
0245 
0246 QIcon KoModeBox::createTextIcon(KoToolAction *toolAction) const
0247 {
0248     Q_ASSERT(!d->horizontalMode);
0249 
0250     QSize iconSize = d->tabBar->iconSize();
0251     QFont smallFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
0252     qreal pointSize = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont).pointSizeF();
0253     smallFont.setPointSizeF(pointSize);
0254     // This must be a QImage, as drawing to a QPixmap outside the
0255     // UI thread will cause sporadic crashes.
0256     QImage pm(iconSize, QImage::Format_ARGB32_Premultiplied);
0257     pm.fill(Qt::transparent);
0258     QPainter p(&pm);
0259     if (d->horizontalTabsSide == LeftSide ) {
0260         p.rotate(90);
0261         p.translate(0,-iconSize.width());
0262     } else {
0263         p.rotate(-90);
0264         p.translate(-iconSize.height(),0);
0265     }
0266 
0267     QIcon::fromTheme(toolAction->iconName()).paint(&p, 0, 0, iconSize.height(), 22);
0268 
0269     QTextLayout textLayout(toolAction->iconText(), smallFont, p.device());
0270     QTextOption option = QTextOption(Qt::AlignTop | Qt::AlignHCenter);
0271     option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
0272     textLayout.setTextOption(option);
0273     textLayout.beginLayout();
0274     qreal height = 0;
0275     while (1) {
0276         QTextLine line = textLayout.createLine();
0277         if (!line.isValid())
0278             break;
0279 
0280         line.setLineWidth(iconSize.height());
0281         line.setPosition(QPointF(0, height));
0282         height += line.height();
0283     }
0284     textLayout.endLayout();
0285 
0286     if (textLayout.lineCount() > 2) {
0287         iconSize.setHeight(iconSize.height() + 8);
0288         d->tabBar->setIconSize(iconSize);
0289         d->iconTextFitted = false;
0290     } else if (height > iconSize.width() - 22) {
0291         iconSize.setWidth(22 + height);
0292         d->tabBar->setIconSize(iconSize);
0293         d->iconTextFitted = false;
0294     }
0295 
0296     p.setFont(smallFont);
0297     p.setPen(palette().text().color());
0298     textLayout.draw(&p, QPoint(0, 22));
0299     p.end();
0300 
0301     return QIcon(QPixmap::fromImage(pm));
0302 }
0303 
0304 QIcon KoModeBox::createSimpleIcon(KoToolAction *toolAction) const
0305 {
0306     QSize iconSize = d->tabBar->iconSize();
0307 
0308     // This must be a QImage, as drawing to a QPixmap outside the
0309     // UI thread will cause sporadic crashes.
0310     QImage pm(iconSize, QImage::Format_ARGB32_Premultiplied);
0311     pm.fill(Qt::transparent);
0312     QPainter p(&pm);
0313     if (!d->horizontalMode) {
0314         if (d->horizontalTabsSide == LeftSide ) {
0315             p.rotate(90);
0316             p.translate(0,-iconSize.width());
0317         } else {
0318             p.rotate(-90);
0319             p.translate(-iconSize.height(),0);
0320         }
0321     }
0322 
0323     QIcon::fromTheme(toolAction->iconName()).paint(&p, 0, 0, iconSize.height(), iconSize.width());
0324 
0325     return QIcon(QPixmap::fromImage(pm));
0326 }
0327 
0328 void KoModeBox::addItem(KoToolAction *toolAction)
0329 {
0330     QWidget *oldwidget = d->addedWidgets[toolAction->buttonGroupId()];
0331     QWidget *widget;
0332 
0333     // We need to create a new widget in all cases as QToolBox seems to crash if we reuse
0334     // a widget (even though the item had been removed)
0335     QLayout *layout;
0336     if (!oldwidget) {
0337         layout = new QGridLayout();
0338     } else {
0339         layout = oldwidget->layout();
0340     }
0341     widget = new QWidget();
0342     widget->setLayout(layout);
0343     layout->setContentsMargins(0,0,0,0);
0344     layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
0345     d->addedWidgets[toolAction->buttonGroupId()] = widget;
0346 
0347     // Create a rotated icon with text
0348     if (d->iconMode == IconAndText) {
0349         if (d->horizontalMode) {
0350             d->tabBar->addTab(QIcon::fromTheme(toolAction->iconName()), toolAction->iconText());
0351         } else {
0352             d->tabBar->addTab(createTextIcon(toolAction), QString());
0353         }
0354     } else {
0355         int index = d->tabBar->addTab(createSimpleIcon(toolAction), QString());
0356         d->tabBar->setTabToolTip(index, toolAction->toolTip());
0357     }
0358     d->tabBar->blockSignals(false);
0359     ScrollArea *sa = new ScrollArea();
0360     if (d->horizontalMode) {
0361         sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0362         sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0363     } else {
0364         sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0365         sa->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0366     }
0367     sa->setWidgetResizable(true);
0368     sa->setContentsMargins(0,0,0,0);
0369     sa->setWidget(widget);
0370     sa->setFrameShape(QFrame::NoFrame);
0371     sa->setFocusPolicy(Qt::NoFocus);
0372     d->stack->addWidget(sa);
0373     d->addedToolActions.append(toolAction);
0374 }
0375 
0376 void KoModeBox::updateShownTools(const QList<QString> &codes)
0377 {
0378     if (d->iconTextFitted) {
0379         d->fittingIterations = 0;
0380     }
0381     d->iconTextFitted = true;
0382 
0383     d->tabBar->blockSignals(true);
0384 
0385     while (d->tabBar->count()) {
0386         d->tabBar->removeTab(0);
0387         d->stack->removeWidget(d->stack->widget(0));
0388     }
0389 
0390     d->addedToolActions.clear();
0391 
0392     int newIndex = -1;
0393     foreach (KoToolAction *toolAction, d->toolActions) {
0394         const QString toolCodes = toolAction->visibilityCode();
0395         if (toolAction->buttonGroupId() == d->activeId) {
0396             newIndex = d->addedToolActions.length();
0397         }
0398         if (toolAction->section().contains(applicationName)) {
0399             addItem(toolAction);
0400             continue;
0401         } else if (!toolAction->section().contains("dynamic")
0402             && !toolAction->section().contains("main")) {
0403             continue;
0404         }
0405         if (toolCodes.startsWith(QLatin1String("flake/"))) {
0406             addItem(toolAction);
0407             continue;
0408         }
0409 
0410         if (toolCodes.endsWith( QLatin1String( "/always"))) {
0411             addItem(toolAction);
0412             continue;
0413         } else if (toolCodes.isEmpty() && codes.count() != 0) {
0414             addItem(toolAction);
0415             continue;
0416         } else {
0417            foreach (const QString &shapeCode, codes) {
0418                 if (toolCodes.contains(shapeCode)) {
0419                     addItem(toolAction);
0420                     break;
0421                 }
0422            }
0423         }
0424     }
0425     if (newIndex != -1) {
0426         d->tabBar->setCurrentIndex(newIndex);
0427         d->stack->setCurrentIndex(newIndex);
0428     }
0429     d->tabBar->blockSignals(false);
0430 
0431     if (!d->iconTextFitted &&  d->fittingIterations++ < 8) {
0432         updateShownTools(codes);
0433     }
0434     d->iconTextFitted = true;
0435 }
0436 
0437 void KoModeBox::setOptionWidgets(const QList<QPointer<QWidget> > &optionWidgetList)
0438 {
0439     if (! d->addedWidgets.contains(d->activeId)) return;
0440 
0441     // For some reason we need to set some attr on our placeholder widget here
0442     // eventhough these settings should be default
0443     // Otherwise Sheets' celltool's optionwidget looks ugly
0444     d->addedWidgets[d->activeId]->setAutoFillBackground(false);
0445     d->addedWidgets[d->activeId]->setBackgroundRole(QPalette::NoRole);
0446 
0447     qDeleteAll(d->currentAuxWidgets);
0448     d->currentAuxWidgets.clear();
0449 
0450     int cnt = 0;
0451     QGridLayout *layout = (QGridLayout *)d->addedWidgets[d->activeId]->layout();
0452     // need to unstretch row/column that have previously been stretched
0453     layout->setRowStretch(layout->rowCount()-1, 0);
0454     layout->setRowStretch(layout->columnCount()-1, 0);
0455     layout->setColumnStretch(0, 0);
0456     layout->setColumnStretch(1, 0);
0457     layout->setColumnStretch(2, 0);
0458     layout->setRowStretch(0, 0);
0459     layout->setRowStretch(1, 0);
0460     layout->setRowStretch(2, 0);
0461 
0462     if (d->horizontalMode) {
0463         layout->setRowStretch(0, 1);
0464         layout->setRowStretch(1, 2);
0465         layout->setRowStretch(2, 1);
0466         layout->setHorizontalSpacing(2);
0467         layout->setVerticalSpacing(0);
0468         foreach(QWidget *widget, optionWidgetList) {
0469             if (!widget->windowTitle().isEmpty()) {
0470                 QLabel *l;
0471                 layout->addWidget(l = new QLabel(widget->windowTitle()), 0, cnt, 1, 1, Qt::AlignLeft);
0472                 d->currentAuxWidgets.insert(l);
0473             }
0474             layout->addWidget(widget, 1, cnt++, 2, 1);
0475             widget->show();
0476             if (widget != optionWidgetList.last()) {
0477                 QFrame *s;
0478                 layout->addWidget(s = new QFrame(), 1, cnt, 1, 1, Qt::AlignHCenter);
0479                 layout->setColumnMinimumWidth(cnt++, 16);
0480                 s->setFrameStyle(QFrame::VLine | QFrame::Sunken);
0481                 d->currentAuxWidgets.insert(s);
0482                 ++cnt;
0483             }
0484             layout->setColumnStretch(cnt, 100);
0485         }
0486     } else {
0487         layout->setColumnStretch(0, 1);
0488         layout->setColumnStretch(1, 2);
0489         layout->setColumnStretch(2, 1);
0490         layout->setHorizontalSpacing(0);
0491         layout->setVerticalSpacing(2);
0492         int specialCount = 0;
0493         foreach(QWidget *widget, optionWidgetList) {
0494             if (!widget->windowTitle().isEmpty()) {
0495                 QLabel *l;
0496                 layout->addWidget(l = new QLabel(widget->windowTitle()), cnt++, 0, 1, 3, Qt::AlignHCenter);
0497                 d->currentAuxWidgets.insert(l);
0498             }
0499             layout->addWidget(widget, cnt++, 0, 1, 3);
0500             QLayout *subLayout = widget->layout();
0501             if (subLayout) {
0502                 for (int i = 0; i < subLayout->count(); ++i) {
0503                     QWidget *spacerWidget = subLayout->itemAt(i)->widget();
0504                     if (spacerWidget && spacerWidget->objectName().contains("SpecialSpacer")) {
0505                         specialCount++;
0506                     }
0507                 }
0508             }
0509             widget->show();
0510             if (widget != optionWidgetList.last()) {
0511                 QFrame *s;
0512                 layout->addWidget(s = new QFrame(), cnt, 1, 1, 1);
0513                 layout->setRowMinimumHeight(cnt++, 16);
0514                 s->setFrameStyle(QFrame::HLine | QFrame::Sunken);
0515                 d->currentAuxWidgets.insert(s);
0516             }
0517         }
0518         if (specialCount == optionWidgetList.count()) {
0519             layout->setRowStretch(cnt, 100);
0520         }
0521     }
0522 }
0523 
0524 void ScrollArea::showEvent(QShowEvent *e)
0525 {
0526     QScrollArea::showEvent(e);
0527     if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) {
0528         setMinimumWidth(widget()->minimumSizeHint().width() + (verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0));
0529     } else {
0530         setMinimumHeight(widget()->minimumSizeHint().height() + (horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0));
0531     }
0532 }
0533 
0534 void KoModeBox::setCurrentLayer(const KoCanvasController *canvas, const KoShapeLayer *layer)
0535 {
0536     Q_UNUSED(canvas);
0537     Q_UNUSED(layer);
0538     //Since targeted application don't use this we won't bother implementing
0539 }
0540 
0541 void KoModeBox::setCanvas(KoCanvasBase *canvas)
0542 {
0543     KoCanvasControllerWidget *ccwidget;
0544 
0545     if (d->canvas) {
0546         ccwidget = dynamic_cast<KoCanvasControllerWidget *>(d->canvas->canvasController());
0547         disconnect(ccwidget, SIGNAL(toolOptionWidgetsChanged(QList<QPointer<QWidget>>)),
0548                     this, SLOT(setOptionWidgets(QList<QPointer<QWidget>>)));
0549     }
0550 
0551     d->canvas = canvas;
0552 
0553     ccwidget = dynamic_cast<KoCanvasControllerWidget *>(d->canvas->canvasController());
0554     connect(
0555         ccwidget, SIGNAL(toolOptionWidgetsChanged(QList<QPointer<QWidget>>)),
0556          this, SLOT(setOptionWidgets(QList<QPointer<QWidget>>)));
0557 }
0558 
0559 void KoModeBox::unsetCanvas()
0560 {
0561     d->canvas = 0;
0562 }
0563 
0564 void KoModeBox::toolAdded(KoToolAction *toolAction, KoCanvasController *canvas)
0565 {
0566     if (canvas->canvas() == d->canvas) {
0567         addToolAction(toolAction);
0568 
0569         std::stable_sort(d->toolActions.begin(), d->toolActions.end(), compareToolActions);
0570 
0571         updateShownTools(QList<QString>());
0572     }
0573 }
0574 
0575 void KoModeBox::toolSelected(int index)
0576 {
0577     if (index != -1) {
0578         d->addedToolActions.at(index)->trigger();
0579     }
0580 }
0581 
0582 void KoModeBox::slotContextMenuRequested(const QPoint &pos)
0583 {
0584     QMenu menu;
0585     KSelectAction* textAction = new KSelectAction(i18n("Text"), &menu);
0586     connect(textAction, SIGNAL(triggered(int)), SLOT(switchIconMode(int)));
0587     menu.addAction(textAction);
0588     textAction->addAction(i18n("Icon and Text"));
0589     textAction->addAction(i18n("Icon only"));
0590     textAction->setCurrentItem(d->iconMode);
0591 
0592     KSelectAction* buttonPositionAction = new KSelectAction(i18n("Tabs side"), &menu);
0593     connect(buttonPositionAction, SIGNAL(triggered(int)), SLOT(switchTabsSide(int)));
0594     menu.addAction(buttonPositionAction);
0595     if (d->horizontalMode) {
0596         buttonPositionAction->addAction(i18n("Top side"));
0597         buttonPositionAction->addAction(i18n("Bottom side"));
0598         buttonPositionAction->setCurrentItem(d->verticalTabsSide);
0599     } else {
0600         buttonPositionAction->addAction(i18n("Left side"));
0601         buttonPositionAction->addAction(i18n("Right side"));
0602         buttonPositionAction->setCurrentItem(d->horizontalTabsSide);
0603     }
0604 
0605     menu.exec(d->tabBar->mapToGlobal(pos));
0606 }
0607 
0608 void KoModeBox::switchIconMode(int mode)
0609 {
0610     d->iconMode = static_cast<IconMode>(mode);
0611     setIconSize();
0612     updateShownTools(QList<QString>());
0613 
0614     KConfigGroup cfg =  KSharedConfig::openConfig()->group("calligra");
0615     cfg.writeEntry("ModeBoxIconMode", (int)d->iconMode);
0616 
0617 }
0618 
0619 void KoModeBox::switchTabsSide(int side)
0620 {
0621     if (d->horizontalMode) {
0622         d->verticalTabsSide = static_cast<VerticalTabsSide>(side);
0623         if (d->verticalTabsSide == TopSide) {
0624             d->layout->removeWidget(d->tabBar);
0625             d->tabBar->setShape(QTabBar::RoundedNorth);
0626             d->layout->addWidget(d->tabBar, 0, 0);
0627         } else {
0628             d->layout->removeWidget(d->tabBar);
0629             d->tabBar->setShape(QTabBar::RoundedSouth);
0630             d->layout->addWidget(d->tabBar, 2, 0);
0631         }
0632 
0633         KConfigGroup cfg =  KSharedConfig::openConfig()->group("calligra");
0634         cfg.writeEntry("ModeBoxVerticalTabsSide", (int)d->verticalTabsSide);
0635     } else {
0636         d->horizontalTabsSide = static_cast<HorizontalTabsSide>(side);
0637         if (d->horizontalTabsSide == LeftSide) {
0638             d->layout->removeWidget(d->tabBar);
0639             d->tabBar->setShape(QTabBar::RoundedWest);
0640             d->layout->addWidget(d->tabBar, 0, 0);
0641         } else {
0642             d->layout->removeWidget(d->tabBar);
0643             d->tabBar->setShape(QTabBar::RoundedEast);
0644             d->layout->addWidget(d->tabBar, 0, 2);
0645         }
0646 
0647         KConfigGroup cfg =  KSharedConfig::openConfig()->group("calligra");
0648         cfg.writeEntry("ModeBoxHorizontalTabsSide", (int)d->horizontalTabsSide);
0649     }
0650     updateShownTools(QList<QString>());
0651 }
0652 
0653 void KoModeBox::setIconSize() const {
0654     if (!d->horizontalMode && d->iconMode == IconAndText) {
0655         d->tabBar->setIconSize(QSize(32,64));
0656     } else {
0657         d->tabBar->setIconSize(QSize(22,22));
0658     }
0659 }