Warning, file /office/calligra/libs/widgets/KoToolBox.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 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public License 0017 * along with this library; see the file COPYING.LIB. If not, write to 0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "KoToolBox_p.h" 0023 #include "KoToolBoxLayout_p.h" 0024 #include "KoToolBoxButton_p.h" 0025 0026 #include <QButtonGroup> 0027 #include <QToolButton> 0028 #include <QStyleOptionFrameV3> 0029 #include <QPainter> 0030 #include <QHash> 0031 #include <QApplication> 0032 #include <QStyle> 0033 #include <QTimer> 0034 #include <QMenu> 0035 #include <QAction> 0036 0037 #include <klocalizedstring.h> 0038 #include <WidgetsDebug.h> 0039 #include <kconfiggroup.h> 0040 #include <ksharedconfig.h> 0041 0042 #include <KoCanvasController.h> 0043 #include <KoShapeLayer.h> 0044 0045 #define BUTTON_MARGIN 10 0046 0047 static int buttonSize(int screen) 0048 { 0049 QRect rc = qApp->desktop()->screenGeometry(screen); 0050 if (rc.width() <= 1024) { 0051 return 12; 0052 } 0053 else if (rc.width() <= 1377) { 0054 return 14; 0055 } 0056 else if (rc.width() <= 1920 ) { 0057 return 16; 0058 } 0059 else { 0060 return 22; 0061 } 0062 } 0063 0064 class KoToolBox::Private 0065 { 0066 public: 0067 Private() 0068 : layout(0) 0069 , buttonGroup(0) 0070 , floating(false) 0071 , contextSize(0) 0072 { 0073 } 0074 0075 void addSection(Section *section, const QString &name); 0076 0077 QList<QToolButton*> buttons; 0078 QMap<QString, Section*> sections; 0079 KoToolBoxLayout *layout; 0080 QButtonGroup *buttonGroup; 0081 QHash<QToolButton*, QString> visibilityCodes; 0082 bool floating; 0083 QMap<QAction*,int> contextIconSizes; 0084 QMenu* contextSize; 0085 Qt::Orientation orientation; 0086 }; 0087 0088 void KoToolBox::Private::addSection(Section *section, const QString &name) 0089 { 0090 section->setName(name); 0091 layout->addSection(section); 0092 sections.insert(name, section); 0093 } 0094 0095 KoToolBox::KoToolBox() 0096 : d(new Private) 0097 { 0098 d->layout = new KoToolBoxLayout(this); 0099 // add defaults 0100 d->addSection(new Section(this), "main"); 0101 d->addSection(new Section(this), "dynamic"); 0102 0103 d->buttonGroup = new QButtonGroup(this); 0104 setLayout(d->layout); 0105 foreach(KoToolAction *toolAction, KoToolManager::instance()->toolActionList()) { 0106 addButton(toolAction); 0107 } 0108 0109 // Update visibility of buttons 0110 setButtonsVisible(QList<QString>()); 0111 0112 connect(KoToolManager::instance(), SIGNAL(changedTool(KoCanvasController*,int)), 0113 this, SLOT(setActiveTool(KoCanvasController*,int))); 0114 connect(KoToolManager::instance(), SIGNAL(currentLayerChanged(const KoCanvasController*,const KoShapeLayer*)), 0115 this, SLOT(setCurrentLayer(const KoCanvasController*,const KoShapeLayer*))); 0116 connect(KoToolManager::instance(), SIGNAL(toolCodesSelected(QList<QString>)), this, SLOT(setButtonsVisible(QList<QString>))); 0117 connect(KoToolManager::instance(), 0118 SIGNAL(addedTool(KoToolAction*,KoCanvasController*)), 0119 this, SLOT(toolAdded(KoToolAction*,KoCanvasController*))); 0120 0121 } 0122 0123 KoToolBox::~KoToolBox() 0124 { 0125 delete d; 0126 } 0127 0128 void KoToolBox::addButton(KoToolAction *toolAction) 0129 { 0130 KoToolBoxButton *button = new KoToolBoxButton(toolAction, this); 0131 0132 d->buttons << button; 0133 0134 int toolbuttonSize = buttonSize(qApp->desktop()->screenNumber(this)); 0135 KConfigGroup cfg = KSharedConfig::openConfig()->group("KoToolBox"); 0136 int iconSize = cfg.readEntry("iconSize", toolbuttonSize); 0137 button->setIconSize(QSize(iconSize, iconSize)); 0138 foreach (Section *section, d->sections) { 0139 section->setButtonSize(QSize(iconSize + BUTTON_MARGIN, iconSize + BUTTON_MARGIN)); 0140 } 0141 0142 QString sectionToBeAddedTo; 0143 const QString section = toolAction->section(); 0144 if (section.contains(qApp->applicationName())) { 0145 sectionToBeAddedTo = "main"; 0146 } else if (section.contains("main")) { 0147 sectionToBeAddedTo = "main"; 0148 } else if (section.contains("dynamic")) { 0149 sectionToBeAddedTo = "dynamic"; 0150 } else { 0151 sectionToBeAddedTo = section; 0152 } 0153 0154 Section *sectionWidget = d->sections.value(sectionToBeAddedTo); 0155 if (sectionWidget == 0) { 0156 sectionWidget = new Section(this); 0157 d->addSection(sectionWidget, sectionToBeAddedTo); 0158 } 0159 sectionWidget->addButton(button, toolAction->priority()); 0160 0161 d->buttonGroup->addButton(button, toolAction->buttonGroupId()); 0162 0163 d->visibilityCodes.insert(button, toolAction->visibilityCode()); 0164 } 0165 0166 void KoToolBox::setActiveTool(KoCanvasController *canvas, int id) 0167 { 0168 Q_UNUSED(canvas); 0169 0170 QAbstractButton *button = d->buttonGroup->button(id); 0171 if (button) { 0172 button->setChecked(true); 0173 (qobject_cast<KoToolBoxButton*>(button))->setHighlightColor(); 0174 } 0175 else { 0176 warnWidgets << "KoToolBox::setActiveTool(" << id << "): no such button found"; 0177 } 0178 } 0179 0180 void KoToolBox::setButtonsVisible(const QList<QString> &codes) 0181 { 0182 foreach(QToolButton *button, d->visibilityCodes.keys()) { 0183 QString code = d->visibilityCodes.value(button); 0184 0185 if (code.startsWith(QLatin1String("flake/"))) { 0186 continue; 0187 } 0188 0189 if (code.endsWith( QLatin1String( "/always"))) { 0190 button->setVisible(true); 0191 button->setEnabled( true ); 0192 } 0193 else if (code.isEmpty()) { 0194 button->setVisible(true); 0195 button->setEnabled( codes.count() != 0 ); 0196 } 0197 else { 0198 button->setVisible( codes.contains(code) ); 0199 } 0200 } 0201 layout()->invalidate(); 0202 update(); 0203 } 0204 0205 void KoToolBox::setCurrentLayer(const KoCanvasController *canvas, const KoShapeLayer *layer) 0206 { 0207 Q_UNUSED(canvas); 0208 const bool enabled = layer == nullptr || (layer->isEditable() && layer->isVisible()); 0209 foreach (QToolButton *button, d->visibilityCodes.keys()) { 0210 if (d->visibilityCodes[button].endsWith( QLatin1String( "/always") ) ) { 0211 continue; 0212 } 0213 button->setEnabled(enabled); 0214 } 0215 } 0216 0217 void KoToolBox::paintEvent(QPaintEvent *) 0218 { 0219 QPainter painter(this); 0220 0221 const QList<Section*> sections = d->sections.values(); 0222 QList<Section*>::const_iterator iterator = sections.begin(); 0223 int halfSpacing = layout()->spacing(); 0224 if (halfSpacing > 0) { 0225 halfSpacing /= 2; 0226 } 0227 while(iterator != sections.end()) { 0228 Section *section = *iterator; 0229 QStyleOption styleoption; 0230 styleoption.palette = palette(); 0231 0232 if (section->separators() & Section::SeparatorTop) { 0233 int y = section->y() - halfSpacing; 0234 styleoption.state = QStyle::State_None; 0235 styleoption.rect = QRect(section->x(), y-1, section->width(), 2); 0236 0237 style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &styleoption, &painter); 0238 } 0239 0240 if (section->separators() & Section::SeparatorLeft) { 0241 int x = section->x() - halfSpacing; 0242 styleoption.state = QStyle::State_Horizontal; 0243 styleoption.rect = QRect(x-1, section->y(), 2, section->height()); 0244 0245 style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &styleoption, &painter); 0246 } 0247 0248 ++iterator; 0249 } 0250 0251 painter.end(); 0252 } 0253 0254 void KoToolBox::setOrientation(Qt::Orientation orientation) 0255 { 0256 d->orientation = orientation; 0257 d->layout->setOrientation(orientation); 0258 QTimer::singleShot(0, this, SLOT(update())); 0259 foreach(Section* section, d->sections) { 0260 section->setOrientation(orientation); 0261 } 0262 } 0263 0264 void KoToolBox::setFloating(bool v) 0265 { 0266 d->floating = v; 0267 } 0268 0269 void KoToolBox::toolAdded(KoToolAction *toolAction, KoCanvasController *canvas) 0270 { 0271 Q_UNUSED(canvas); 0272 addButton(toolAction); 0273 setButtonsVisible(QList<QString>()); 0274 0275 } 0276 0277 void KoToolBox::slotContextIconSize() 0278 { 0279 QAction* action = qobject_cast<QAction*>(sender()); 0280 if (action && d->contextIconSizes.contains(action)) { 0281 const int iconSize = d->contextIconSizes.value(action); 0282 0283 KConfigGroup cfg = KSharedConfig::openConfig()->group("KoToolBox"); 0284 cfg.writeEntry("iconSize", iconSize); 0285 0286 foreach(QToolButton *button, d->buttons) { 0287 button->setIconSize(QSize(iconSize, iconSize)); 0288 } 0289 0290 foreach(Section *section, d->sections) { 0291 section->setButtonSize(QSize(iconSize + BUTTON_MARGIN, iconSize + BUTTON_MARGIN)); 0292 } 0293 0294 } 0295 } 0296 0297 void KoToolBox::contextMenuEvent(QContextMenuEvent *event) 0298 { 0299 0300 int toolbuttonSize = buttonSize(qApp->desktop()->screenNumber(this)); 0301 0302 if (!d->contextSize) { 0303 0304 d->contextSize = new QMenu(i18n("Icon Size"), this); 0305 d->contextIconSizes.insert(d->contextSize->addAction(i18nc("@item:inmenu Icon size", "Default"), 0306 this, SLOT(slotContextIconSize())), 0307 toolbuttonSize); 0308 0309 QList<int> sizes; 0310 sizes << 12 << 14 << 16 << 22 << 32 << 48 << 64; //<< 96 << 128 << 192 << 256; 0311 foreach(int i, sizes) { 0312 d->contextIconSizes.insert(d->contextSize->addAction(i18n("%1x%2", i, i), this, SLOT(slotContextIconSize())), i); 0313 } 0314 0315 QActionGroup *sizeGroup = new QActionGroup(d->contextSize); 0316 foreach (QAction *action, d->contextSize->actions()) { 0317 action->setActionGroup(sizeGroup); 0318 action->setCheckable(true); 0319 } 0320 } 0321 KConfigGroup cfg = KSharedConfig::openConfig()->group("KoToolBox"); 0322 toolbuttonSize = cfg.readEntry("iconSize", toolbuttonSize); 0323 0324 QMapIterator< QAction*, int > it = d->contextIconSizes; 0325 while (it.hasNext()) { 0326 it.next(); 0327 if (it.value() == toolbuttonSize) { 0328 it.key()->setChecked(true); 0329 break; 0330 } 0331 } 0332 0333 d->contextSize->exec(event->globalPos()); 0334 } 0335 KoToolBoxLayout *KoToolBox::toolBoxLayout() const 0336 { 0337 return d->layout; 0338 } 0339 0340 #include "moc_KoToolBoxScrollArea_p.cpp"