Krita Source Code Documentation
Loading...
Searching...
No Matches
ktoolbar.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2
3 SPDX-FileCopyrightText: 2000 Reginald Stadlbauer (reggie@kde.org)
4 SPDX-FileCopyrightText: 1997, 1998 Stephan Kulow (coolo@kde.org)
5 SPDX-FileCopyrightText: 1997, 1998 Mark Donohoe (donohoe@kde.org)
6 SPDX-FileCopyrightText: 1997, 1998 Sven Radej (radej@kde.org)
7 SPDX-FileCopyrightText: 1997, 1998 Matthias Ettrich (ettrich@kde.org)
8 SPDX-FileCopyrightText: 1999 Chris Schlaeger (cs@kde.org)
9 SPDX-FileCopyrightText: 1999 Kurt Granroth (granroth@kde.org)
10 SPDX-FileCopyrightText: 2005-2006 Hamish Rodda (rodda@kde.org)
11
12 SPDX-License-Identifier: LGPL-2.0-only
13*/
14
15#include "ktoolbar.h"
16#include "config-xmlgui.h"
17#include <QAction>
18#include <QApplication>
19#include <QScreen>
20#include <QFrame>
21#include <QLayout>
22#include <QMenu>
23#include <QMimeData>
24#include <QDrag>
25#include <QMouseEvent>
26#include <QToolButton>
27#include <QDomElement>
28#ifdef HAVE_DBUS
29#include <QDBusConnection>
30#include <QDBusMessage>
31#endif
32#include <QDebug>
33#include <QActionGroup>
34
35#include <kconfig.h>
36#include <ksharedconfig.h>
37#ifdef HAVE_ICONTHEMES
38#include <kicontheme.h>
39#endif
40#include <klocalizedstring.h>
41#include <kstandardaction.h>
42#include <ktoggleaction.h>
43#include <kconfiggroup.h>
44
45#include "kactioncollection.h"
46#include "kedittoolbar.h"
47#include "kxmlguifactory.h"
48#include "kxmlguiwindow.h"
49
50#include <kis_icon_utils.h>
51
53
55
56/*
57 Toolbar settings (e.g. icon size or toolButtonStyle)
58 =====================================================
59
60 We have the following stack of settings (in order of priority) :
61 - user-specified settings (loaded/saved in KConfig)
62 - developer-specified settings in the XMLGUI file (if using xmlgui) (cannot change at runtime)
63 - KDE-global default (user-configurable; can change at runtime)
64 and when switching between kparts, they are saved as xml in memory,
65 which, in the unlikely case of no-kmainwindow-autosaving, could be
66 different from the user-specified settings saved in KConfig and would have
67 priority over it.
68
69 So, in summary, without XML:
70 Global config / User settings (loaded/saved in kconfig)
71 and with XML:
72 Global config / App-XML attributes / User settings (loaded/saved in kconfig)
73
74 And all those settings (except the KDE-global defaults) have to be stored in memory
75 since we cannot retrieve them at random points in time, not knowing the xml document
76 nor config file that holds these settings. Hence the iconSizeSettings and toolButtonStyleSettings arrays.
77
78 For instance, if you change the KDE-global default, whether this makes a change
79 on a given toolbar depends on whether there are settings at Level_AppXML or Level_UserSettings.
80 Only if there are no settings at those levels, should the change of KDEDefault make a difference.
81*/
84 };
85enum { Unset = -1 };
86
88{
89public:
91 : q(qq),
92 isMainToolBar(false),
93 unlockedMovable(true),
95 contextMode(0),
96 contextSize(0),
100 contextTop(0),
101 contextLeft(0),
102 contextRight(0),
103 contextBottom(0),
104 contextIcons(0),
106 contextText(0),
110 context(0),
111 dragAction(0)
112 {
113 }
114
118 void slotContextLeft();
119 void slotContextRight();
120 void slotContextShowText();
121 void slotContextTop();
122 void slotContextBottom();
123 void slotContextIcons();
124 void slotContextText();
127 void slotContextIconSize();
128 void slotLockToolBars(bool lock);
129 void slotToolButtonToggled(bool checked);
130
131
132 void init(bool readConfig = true, bool isMainToolBar = false);
133 QString getPositionAsString() const;
134 QMenu *contextMenu(const QPoint &globalPos);
135 void setLocked(bool locked);
137 void loadKDESettings();
139 void customizeButtonPalette(QToolButton *button, bool checked);
140
141 QAction *findAction(const QString &actionName, KisKXMLGUIClient **client = 0) const;
142
143 static Qt::ToolButtonStyle toolButtonStyleFromString(const QString &style);
144 static QString toolButtonStyleToString(Qt::ToolButtonStyle);
145 static Qt::ToolBarArea positionFromString(const QString &position);
146 static Qt::ToolButtonStyle toolButtonStyleSetting();
147
151 static bool s_editable;
152
153 QSet<KisKXMLGUIClient *> xmlguiClients;
154
158
162 QAction *contextTop;
163 QAction *contextLeft;
164 QAction *contextRight;
166 QAction *contextIcons;
168 QAction *contextText;
170 KToggleAction *contextLockAction;
171 QMap<QAction *, int> contextIconSizes;
172
174 {
175 public:
177 {
178 for (int level = 0; level < NSettingLevels; ++level) {
179 values[level] = Unset;
180 }
181 }
182 int currentValue() const
183 {
184 int val = Unset;
185 for (int level = 0; level < NSettingLevels; ++level) {
186 if (values[level] != Unset) {
187 val = values[level];
188 }
189 }
190 return val;
191 }
192 // Default value as far as the user is concerned is kde-global + app-xml.
193 // If currentValue()==defaultValue() then nothing to write into kconfig.
194 int defaultValue() const
195 {
196 int val = Unset;
197 for (int level = 0; level < Level_UserSettings; ++level) {
198 if (values[level] != Unset) {
199 val = values[level];
200 }
201 }
202 return val;
203 }
204 QString toString() const
205 {
206 QString str;
207 for (int level = 0; level < NSettingLevels; ++level) {
208 str += QString::number(values[level]) + QLatin1Char(' ');
209 }
210 return str;
211 }
212 int &operator[](int index)
213 {
214 return values[index];
215 }
216 private:
218 };
220 IntSetting toolButtonStyleSettings; // either Qt::ToolButtonStyle or -1, hence "int".
221
224
225 QMenu *context;
226 QAction *dragAction;
228
231};
232
234
236{
238 {
239 s_toolBarsModel->LAGER_QT(toolBarsLocked).bind(std::bind(&ToolBarsStateUpdater::updateToolbars, this, std::placeholders::_1));
240 }
241
242 void updateToolbars(bool locked) {
243 Q_FOREACH (KisKMainWindow *mw, KisKMainWindow::memberList()) {
244 Q_FOREACH (KisToolBar *toolbar, mw->findChildren<KisToolBar *>()) {
245 toolbar->d->setLocked(locked);
246 }
247 }
248 }
249};
250
252
253void KisToolBar::Private::init(bool readConfig, bool _isMainToolBar)
254{
255 isMainToolBar = _isMainToolBar;
257
258 // also read in our configurable settings (for non-xmlgui toolbars)
259 if (readConfig) {
260 KConfigGroup cg(KSharedConfig::openConfig(), QString());
261 q->applySettings(cg);
262 }
263
264 if (q->mainWindow()) {
265 // Get notified when settings change
266 connect(q, SIGNAL(allowedAreasChanged(Qt::ToolBarAreas)),
267 q->mainWindow(), SLOT(setSettingsDirty()));
268 connect(q, SIGNAL(iconSizeChanged(QSize)),
269 q->mainWindow(), SLOT(setSettingsDirty()));
270 connect(q, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
271 q->mainWindow(), SLOT(setSettingsDirty()));
272 connect(q, SIGNAL(movableChanged(bool)),
273 q->mainWindow(), SLOT(setSettingsDirty()));
274 connect(q, SIGNAL(orientationChanged(Qt::Orientation)),
275 q->mainWindow(), SLOT(setSettingsDirty()));
276 }
277
278 q->setMovable(!KisToolBar::toolBarsLocked());
279
280 connect(q, SIGNAL(movableChanged(bool)),
281 q, SLOT(slotMovableChanged(bool)));
282
283 q->setAcceptDrops(true);
284
285#ifdef HAVE_DBUS
286 QDBusConnection::sessionBus().connect(QString(), QStringLiteral("/KisToolBar"), QStringLiteral("org.kde.KisToolBar"),
287 QStringLiteral("styleChanged"), q, SLOT(slotAppearanceChanged()));
288#endif
289}
290
292{
293 // get all of the stuff to save
294 switch (q->mainWindow()->toolBarArea(const_cast<KisToolBar *>(q))) {
295 case Qt::BottomToolBarArea:
296 return QStringLiteral("Bottom");
297 case Qt::LeftToolBarArea:
298 return QStringLiteral("Left");
299 case Qt::RightToolBarArea:
300 return QStringLiteral("Right");
301 case Qt::TopToolBarArea:
302 default:
303 return QStringLiteral("Top");
304 }
305}
306
307QMenu *KisToolBar::Private::contextMenu(const QPoint &globalPos)
308{
309 if (!context) {
310 context = new QMenu(q);
311
312 contextButtonTitle = context->addSection(i18nc("@title:menu", "Show Text"));
313 contextShowText = context->addAction(QString(), q, SLOT(slotContextShowText()));
314
315 context->addSection(i18nc("@title:menu", "Toolbar Settings"));
316
317 contextOrient = new QMenu(i18nc("Toolbar orientation", "Orientation"), context);
318
319 contextTop = contextOrient->addAction(i18nc("toolbar position string", "Top"), q, SLOT(slotContextTop()));
320 contextTop->setChecked(true);
321 contextLeft = contextOrient->addAction(i18nc("toolbar position string", "Left"), q, SLOT(slotContextLeft()));
322 contextRight = contextOrient->addAction(i18nc("toolbar position string", "Right"), q, SLOT(slotContextRight()));
323 contextBottom = contextOrient->addAction(i18nc("toolbar position string", "Bottom"), q, SLOT(slotContextBottom()));
324
325 QActionGroup *positionGroup = new QActionGroup(contextOrient);
326 Q_FOREACH (QAction *action, contextOrient->actions()) {
327 action->setActionGroup(positionGroup);
328 action->setCheckable(true);
329 }
330
331 contextMode = new QMenu(i18n("Text Position"), context);
332
333 contextIcons = contextMode->addAction(i18n("Icons Only"), q, SLOT(slotContextIcons()));
334 contextText = contextMode->addAction(i18n("Text Only"), q, SLOT(slotContextText()));
335 contextTextRight = contextMode->addAction(i18n("Text Alongside Icons"), q, SLOT(slotContextTextRight()));
336 contextTextUnder = contextMode->addAction(i18n("Text Under Icons"), q, SLOT(slotContextTextUnder()));
337
338 QActionGroup *textGroup = new QActionGroup(contextMode);
339 Q_FOREACH (QAction *action, contextMode->actions()) {
340 action->setActionGroup(textGroup);
341 action->setCheckable(true);
342 }
343
344 contextSize = new QMenu(i18n("Icon Size"), context);
345
346 contextIconSizes.insert(contextSize->addAction(i18nc("@item:inmenu Icon size", "Default"), q, SLOT(slotContextIconSize())),
347 iconSizeSettings.defaultValue());
348
349 QList<int> avSizes;
350 avSizes << 16 << 22 << 24 << 32 << 48 << 64 << 128 << 256;
351
352 std::sort(avSizes.begin(), avSizes.end());
353
354 if (avSizes.count() < 10) {
355 // Fixed or threshold type icons
356 Q_FOREACH (int it, avSizes) {
357 QString text;
358 if (it < 19) {
359 text = i18n("Small (%1x%2)", it, it);
360 } else if (it < 25) {
361 text = i18n("Medium (%1x%2)", it, it);
362 } else if (it < 35) {
363 text = i18n("Large (%1x%2)", it, it);
364 } else {
365 text = i18n("Huge (%1x%2)", it, it);
366 }
367
368 // save the size in the contextIconSizes map
369 contextIconSizes.insert(contextSize->addAction(text, q, SLOT(slotContextIconSize())), it);
370 }
371 } else {
372 // Scalable icons.
373 const int progression[] = { 16, 22, 32, 48, 64, 96, 128, 192, 256 };
374
375 for (uint i = 0; i < 9; i++) {
376 Q_FOREACH (int it, avSizes) {
377 if (it >= progression[ i ]) {
378 QString text;
379 if (it < 19) {
380 text = i18n("Small (%1x%2)", it, it);
381 } else if (it < 25) {
382 text = i18n("Medium (%1x%2)", it, it);
383 } else if (it < 35) {
384 text = i18n("Large (%1x%2)", it, it);
385 } else {
386 text = i18n("Huge (%1x%2)", it, it);
387 }
388
389 // save the size in the contextIconSizes map
390 contextIconSizes.insert(contextSize->addAction(text, q, SLOT(slotContextIconSize())), it);
391 break;
392 }
393 }
394 }
395 }
396
397 QActionGroup *sizeGroup = new QActionGroup(contextSize);
398 Q_FOREACH (QAction *action, contextSize->actions()) {
399 action->setActionGroup(sizeGroup);
400 action->setCheckable(true);
401 }
402
403 if (!q->toolBarsLocked() && !q->isMovable()) {
404 unlockedMovable = false;
405 }
406
407 delete contextLockAction;
408 contextLockAction = new KToggleAction(KisIconUtils::loadIcon(QStringLiteral("system-lock-screen")), i18n("Lock Toolbar Positions"), q);
409 contextLockAction->setChecked(q->toolBarsLocked());
410 connect(contextLockAction, SIGNAL(toggled(bool)), q, SLOT(slotLockToolBars(bool)));
411
412 // Now add the actions to the menu
413 context->addMenu(contextMode);
414 context->addMenu(contextSize);
415 context->addMenu(contextOrient);
416 context->addSeparator();
417
418 connect(context, SIGNAL(aboutToShow()), q, SLOT(slotContextAboutToShow()));
419 }
420
421 contextButtonAction = q->actionAt(q->mapFromGlobal(globalPos));
422 if (contextButtonAction) {
423 contextShowText->setText(contextButtonAction->text());
424 contextShowText->setIcon(contextButtonAction->icon());
425 contextShowText->setCheckable(true);
426 }
427
428 contextOrient->menuAction()->setVisible(!q->toolBarsLocked());
429 // Unplugging a submenu from AboutToHide leads to the popupmenu floating around
430 // So better simply call that code from after exec() returns (DF)
431 //connect(context, SIGNAL(aboutToHide()), this, SLOT(slotContextAboutToHide()));
432
433 return context;
434}
435
437{
438 if (unlockedMovable) {
439 q->setMovable(!locked);
440 }
441}
442
444{
445 bool visibleNonSeparator = false;
446 int separatorToShow = -1;
447
448 for (int index = 0; index < q->actions().count(); ++index) {
449 QAction *action = q->actions()[ index ];
450 if (action->isSeparator()) {
451 if (visibleNonSeparator) {
452 separatorToShow = index;
453 visibleNonSeparator = false;
454 } else {
455 action->setVisible(false);
456 }
457 } else if (!visibleNonSeparator) {
458 if (action->isVisible()) {
459 visibleNonSeparator = true;
460 if (separatorToShow != -1) {
461 q->actions()[ separatorToShow ]->setVisible(true);
462 separatorToShow = -1;
463 }
464 }
465 }
466 }
467
468 if (separatorToShow != -1) {
469 q->actions()[ separatorToShow ]->setVisible(false);
470 }
471}
472
473Qt::ToolButtonStyle KisToolBar::Private::toolButtonStyleFromString(const QString &_style)
474{
475 QString style = _style.toLower();
476 if (style == QStringLiteral("textbesideicon") || style == QLatin1String("icontextright")) {
477 return Qt::ToolButtonTextBesideIcon;
478 } else if (style == QStringLiteral("textundericon") || style == QLatin1String("icontextbottom")) {
479 return Qt::ToolButtonTextUnderIcon;
480 } else if (style == QStringLiteral("textonly")) {
481 return Qt::ToolButtonTextOnly;
482 } else {
483 return Qt::ToolButtonIconOnly;
484 }
485}
486
487QString KisToolBar::Private::toolButtonStyleToString(Qt::ToolButtonStyle style)
488{
489 switch (style) {
490 case Qt::ToolButtonIconOnly:
491 default:
492 return QStringLiteral("IconOnly");
493 case Qt::ToolButtonTextBesideIcon:
494 return QStringLiteral("TextBesideIcon");
495 case Qt::ToolButtonTextOnly:
496 return QStringLiteral("TextOnly");
497 case Qt::ToolButtonTextUnderIcon:
498 return QStringLiteral("TextUnderIcon");
499 }
500}
501
502Qt::ToolBarArea KisToolBar::Private::positionFromString(const QString &position)
503{
504 Qt::ToolBarArea newposition = Qt::TopToolBarArea;
505 if (position == QStringLiteral("left")) {
506 newposition = Qt::LeftToolBarArea;
507 } else if (position == QStringLiteral("bottom")) {
508 newposition = Qt::BottomToolBarArea;
509 } else if (position == QStringLiteral("right")) {
510 newposition = Qt::RightToolBarArea;
511 }
512 return newposition;
513}
514
515// Global setting was changed
517{
518 loadKDESettings();
519 applyCurrentSettings();
520}
521
523{
524 KConfigGroup group(KSharedConfig::openConfig(), "Toolbar style");
525 const QString fallback = KisToolBar::Private::toolButtonStyleToString(Qt::ToolButtonTextBesideIcon);
526 return KisToolBar::Private::toolButtonStyleFromString(group.readEntry("ToolButtonStyle", fallback));
527}
528
530{
531 iconSizeSettings[Level_KDEDefault] = q->iconSizeDefault();
532
533 if (isMainToolBar) {
534 toolButtonStyleSettings[Level_KDEDefault] = toolButtonStyleSetting();
535 } else {
536 const QString fallBack = toolButtonStyleToString(Qt::ToolButtonTextBesideIcon);
537 KConfigGroup group(KSharedConfig::openConfig(), "Toolbar style");
538 const QString value = group.readEntry("ToolButtonStyleOtherToolbars", fallBack);
540 }
541}
542
543// Call this after changing something in d->iconSizeSettings or d->toolButtonStyleSettings
545{
546 //qDebug() << q->objectName() << "iconSizeSettings:" << iconSizeSettings.toString() << "->" << iconSizeSettings.currentValue();
547 const int currentIconSize = iconSizeSettings.currentValue();
548 q->setIconSize(QSize(currentIconSize, currentIconSize));
549 //qDebug() << q->objectName() << "toolButtonStyleSettings:" << toolButtonStyleSettings.toString() << "->" << toolButtonStyleSettings.currentValue();
550 q->setToolButtonStyle(static_cast<Qt::ToolButtonStyle>(toolButtonStyleSettings.currentValue()));
551
552 // And remember to save the new look later
553 KisKMainWindow *kmw = q->mainWindow();
554 if (kmw) {
555 kmw->setSettingsDirty();
556 }
557}
558
559// Krita widget style "hack" setting button palette depending on check state
561{
562 QPalette p = button->palette();
563 QColor color = q->palette().color(checked ? QPalette::Highlight : QPalette::Button);
564 p.setColor(QPalette::Button, color);
565 button->setPalette(p);
566}
567
568QAction *KisToolBar::Private::findAction(const QString &actionName, KisKXMLGUIClient **clientOut) const
569{
570 Q_FOREACH (KisKXMLGUIClient *client, xmlguiClients) {
571 QAction *action = client->actionCollection()->action(actionName);
572 if (action) {
573 if (clientOut) {
574 *clientOut = client;
575 }
576 return action;
577 }
578 }
579 return 0;
580}
581
583{
592 KXmlGuiWindow *kmw = qobject_cast<KXmlGuiWindow *>(q->mainWindow());
593
594 // try to find "configure toolbars" action
595 QAction *configureAction = 0;
596 const char *actionName;
598 configureAction = findAction(QLatin1String(actionName));
599
600 if (!configureAction && kmw) {
601 configureAction = kmw->actionCollection()->action(QLatin1String(actionName));
602 }
603
604 if (configureAction) {
605 context->addAction(configureAction);
606 }
607
608 context->addAction(contextLockAction);
609
610 if (kmw) {
612 // Only allow hiding a toolbar if the action is also plugged somewhere else (e.g. menubar)
613 QAction *tbAction = kmw->toolBarMenuAction();
614 if (!q->toolBarsLocked() && tbAction && tbAction->associatedWidgets().count() > 0) {
615 context->addAction(tbAction);
616 }
617 }
618
619 KisKEditToolBar::setGlobalDefaultToolBar(q->QObject::objectName().toLatin1().constData());
620
621 // Check the actions that should be checked
622 switch (q->toolButtonStyle()) {
623 case Qt::ToolButtonIconOnly:
624 default:
625 contextIcons->setChecked(true);
626 break;
627 case Qt::ToolButtonTextBesideIcon:
628 contextTextRight->setChecked(true);
629 break;
630 case Qt::ToolButtonTextOnly:
631 contextText->setChecked(true);
632 break;
633 case Qt::ToolButtonTextUnderIcon:
634 contextTextUnder->setChecked(true);
635 break;
636 }
637
638 QMapIterator< QAction *, int > it = contextIconSizes;
639 while (it.hasNext()) {
640 it.next();
641 if (it.value() == q->iconSize().width()) {
642 it.key()->setChecked(true);
643 break;
644 }
645 }
646
647 switch (q->mainWindow()->toolBarArea(q)) {
648 case Qt::BottomToolBarArea:
649 contextBottom->setChecked(true);
650 break;
651 case Qt::LeftToolBarArea:
652 contextLeft->setChecked(true);
653 break;
654 case Qt::RightToolBarArea:
655 contextRight->setChecked(true);
656 break;
657 default:
658 case Qt::TopToolBarArea:
659 contextTop->setChecked(true);
660 break;
661 }
662
663 const bool showButtonSettings = contextButtonAction
664 && !contextShowText->text().isEmpty()
665 && contextTextRight->isChecked();
666 contextButtonTitle->setVisible(showButtonSettings);
667 contextShowText->setVisible(showButtonSettings);
668 if (showButtonSettings) {
669 contextShowText->setChecked(contextButtonAction->priority() >= QAction::NormalPriority);
670 }
671}
672
674{
675 // We have to unplug whatever slotContextAboutToShow plugged into the menu.
676 // Unplug the toolbar menu action
677 KXmlGuiWindow *kmw = qobject_cast<KXmlGuiWindow *>(q->mainWindow());
678 if (kmw && kmw->toolBarMenuAction()) {
679 if (kmw->toolBarMenuAction()->associatedWidgets().count() > 1) {
680 context->removeAction(kmw->toolBarMenuAction());
681 }
682 }
683
684 // Unplug the configure toolbars action too, since it's afterwards anyway
685 QAction *configureAction = 0;
686 const char *actionName;
688 configureAction = findAction(QLatin1String(actionName));
689
690 if (!configureAction && kmw) {
691 configureAction = kmw->actionCollection()->action(QLatin1String(actionName));
692 }
693
694 if (configureAction) {
695 context->removeAction(configureAction);
696 }
697
698 context->removeAction(contextLockAction);
699}
700
702{
703 q->mainWindow()->addToolBar(Qt::LeftToolBarArea, q);
704}
705
707{
708 q->mainWindow()->addToolBar(Qt::RightToolBarArea, q);
709}
710
712{
713 Q_ASSERT(contextButtonAction);
714 const QAction::Priority priority = contextShowText->isChecked()
715 ? QAction::NormalPriority : QAction::LowPriority;
716 contextButtonAction->setPriority(priority);
717
718 // Find to which xml file and componentData the action belongs to
719 QString componentName;
720 QString filename;
721 KisKXMLGUIClient *client;
722 if (findAction(contextButtonAction->objectName(), &client)) {
723 componentName = client->componentName();
724 filename = client->xmlFile();
725 }
726 if (filename.isEmpty()) {
727 componentName = QCoreApplication::applicationName();
728 filename = componentName + QStringLiteral("ui.xmlgui");
729 }
730
731 // Save the priority state of the action
732 const QString configFile = KisKXMLGUIFactory::readConfigFile(filename, componentName);
733
734 QDomDocument document;
735 document.setContent(configFile);
736 QDomElement elem = KisKXMLGUIFactory::actionPropertiesElement(document);
737 QDomElement actionElem = KisKXMLGUIFactory::findActionByName(elem, contextButtonAction->objectName(), true);
738 actionElem.setAttribute(QStringLiteral("priority"), priority);
739 KisKXMLGUIFactory::saveConfigFile(document, filename, componentName);
740}
741
743{
744 q->mainWindow()->addToolBar(Qt::TopToolBarArea, q);
745}
746
748{
749 q->mainWindow()->addToolBar(Qt::BottomToolBarArea, q);
750}
751
753{
754 q->setToolButtonStyle(Qt::ToolButtonIconOnly);
755 toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
756}
757
759{
760 q->setToolButtonStyle(Qt::ToolButtonTextOnly);
761 toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
762}
763
765{
766 q->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
767 toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
768}
769
771{
772 q->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
773 toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
774}
775
777{
778 QAction *action = qobject_cast<QAction *>(q->sender());
779 if (action && contextIconSizes.contains(action)) {
780 const int iconSize = contextIconSizes.value(action);
781 q->setIconDimensions(iconSize);
782 }
783}
784
786{
787 q->setToolBarsLocked(lock);
788}
789
790// Krita widget style "hack" reacting to QToolButton toggles
792{
793 QToolButton *tb = qobject_cast<QToolButton *>(q->sender());
794 if (tb) {
795 customizeButtonPalette(tb, checked);
796 }
797}
798
799KisToolBar::KisToolBar(const QString &objectName, QWidget *parent, bool readConfig)
800 : QToolBar(parent),
801 d(new Private(this))
802{
803 setObjectName(objectName);
804 // mainToolBar -> isMainToolBar = true -> buttonStyle is configurable
805 // others -> isMainToolBar = false -> ### hardcoded default for buttonStyle !!! should be configurable? -> hidden key added
806 d->init(readConfig, objectName == QStringLiteral("mainToolBar"));
807
808 // KisToolBar is auto-added to the top area of the main window if parent is a QMainWindow
809 if (QMainWindow *mw = qobject_cast<QMainWindow *>(parent)) {
810 mw->addToolBar(this);
811 }
812}
813
815{
816 delete d->contextLockAction;
817 delete d;
818}
819
820void KisToolBar::saveSettings(KConfigGroup &cg)
821{
822 Q_ASSERT(!cg.name().isEmpty());
823
824 const int currentIconSize = iconSize().width();
825 //qDebug() << objectName() << currentIconSize << d->iconSizeSettings.toString() << "defaultValue=" << d->iconSizeSettings.defaultValue();
826 if (!cg.hasDefault("IconSize") && currentIconSize == d->iconSizeSettings.defaultValue()) {
827 cg.revertToDefault("IconSize");
829 } else {
830 cg.writeEntry("IconSize", currentIconSize);
831 d->iconSizeSettings[Level_UserSettings] = currentIconSize;
832 }
833
834 const Qt::ToolButtonStyle currentToolButtonStyle = toolButtonStyle();
835 if (!cg.hasDefault("ToolButtonStyle") && currentToolButtonStyle == d->toolButtonStyleSettings.defaultValue()) {
836 cg.revertToDefault("ToolButtonStyle");
838 } else {
839 cg.writeEntry("ToolButtonStyle", d->toolButtonStyleToString(currentToolButtonStyle));
840 d->toolButtonStyleSettings[Level_UserSettings] = currentToolButtonStyle;
841 }
842}
843
844
846{
847 d->xmlguiClients << client;
848}
849
851{
852 d->xmlguiClients.remove(client);
853}
854
855void KisToolBar::contextMenuEvent(QContextMenuEvent *event)
856{
857 QToolBar::contextMenuEvent(event);
858}
859
860void KisToolBar::loadState(const QDomElement &element)
861{
862 QMainWindow *mw = mainWindow();
863 if (!mw) {
864 return;
865 }
866
867 {
868 QDomNode textNode = element.namedItem(QStringLiteral("text"));
869 QByteArray domain;
870 QByteArray text;
871 QByteArray context;
872 if (textNode.isElement()) {
873 QDomElement textElement = textNode.toElement();
874 domain = textElement.attribute(QStringLiteral("translationDomain")).toUtf8();
875 text = textElement.text().toUtf8();
876 context = textElement.attribute(QStringLiteral("context")).toUtf8();
877 } else {
878 textNode = element.namedItem(QStringLiteral("Text"));
879 if (textNode.isElement()) {
880 QDomElement textElement = textNode.toElement();
881 domain = textElement.attribute(QStringLiteral("translationDomain")).toUtf8();
882 text = textElement.text().toUtf8();
883 context = textElement.attribute(QStringLiteral("context")).toUtf8();
884 }
885 }
886
887 if (domain.isEmpty()) {
888 domain = element.ownerDocument().documentElement().attribute(QStringLiteral("translationDomain")).toUtf8();
889 if (domain.isEmpty()) {
890 domain = KLocalizedString::applicationDomain();
891 }
892 }
893 QString i18nText;
894 if (!text.isEmpty() && !context.isEmpty()) {
895 i18nText = i18ndc(domain.constData(), context.constData(), text.constData());
896 } else if (!text.isEmpty()) {
897 i18nText = i18nd(domain.constData(), text.constData());
898 }
899
900 if (!i18nText.isEmpty()) {
901 setWindowTitle(i18nText);
902 }
903 }
904
905 /*
906 This method is called in order to load toolbar settings from XML.
907 However this can be used in two rather different cases:
908 - for the initial loading of the app's XML. In that case the settings
909 are only the defaults (Level_AppXML), the user's KConfig settings will override them
910
911 - for later re-loading when switching between parts in KisKXMLGUIFactory.
912 In that case the XML contains the final settings, not the defaults.
913 We do need the defaults, and the toolbar might have been completely
914 deleted and recreated meanwhile. So we store the app-default settings
915 into the XML.
916 */
917 bool loadingAppDefaults = true;
918 if (element.hasAttribute(QStringLiteral("tempXml"))) {
919 // this isn't the first time, so the app-xml defaults have been saved into the (in-memory) XML
920 loadingAppDefaults = false;
921 const QString iconSizeDefault = element.attribute(QStringLiteral("iconSizeDefault"));
922 if (!iconSizeDefault.isEmpty()) {
924 }
925 const QString toolButtonStyleDefault = element.attribute(QStringLiteral("toolButtonStyleDefault"));
926 if (!toolButtonStyleDefault.isEmpty()) {
928 }
929 } else {
930 // loading app defaults
931 bool newLine = false;
932 QString attrNewLine = element.attribute(QStringLiteral("newline")).toLower();
933 if (!attrNewLine.isEmpty()) {
934 newLine = attrNewLine == QStringLiteral("true");
935 }
936 if (newLine && mw) {
937 mw->insertToolBarBreak(this);
938 }
939
940 }
941
942 int newIconSize = -1;
943 if (element.hasAttribute(QStringLiteral("iconSize"))) {
944 bool ok;
945 newIconSize = element.attribute(QStringLiteral("iconSize")).trimmed().toInt(&ok);
946 if (!ok) {
947 newIconSize = -1;
948 }
949 }
950 if (newIconSize != -1) {
951 d->iconSizeSettings[loadingAppDefaults ? Level_AppXML : Level_UserSettings] = newIconSize;
952 }
953
954 const QString newToolButtonStyle = element.attribute(QStringLiteral("iconText"));
955 if (!newToolButtonStyle.isEmpty()) {
956 d->toolButtonStyleSettings[loadingAppDefaults ? Level_AppXML : Level_UserSettings] = d->toolButtonStyleFromString(newToolButtonStyle);
957 }
958
959 bool hidden = false;
960 {
961 QString attrHidden = element.attribute(QStringLiteral("hidden")).toLower();
962 if (!attrHidden.isEmpty()) {
963 hidden = attrHidden == QStringLiteral("true");
964 }
965 }
966
967 Qt::ToolBarArea pos = Qt::NoToolBarArea;
968 {
969 QString attrPosition = element.attribute(QStringLiteral("position")).toLower();
970 if (!attrPosition.isEmpty()) {
971 pos = KisToolBar::Private::positionFromString(attrPosition);
972 }
973 }
974 if (pos != Qt::NoToolBarArea) {
975 mw->addToolBar(pos, this);
976 }
977
978 setVisible(!hidden);
979
981}
982
983// Called when switching between xmlgui clients, in order to find any unsaved settings
984// again when switching back to the current xmlgui client.
985void KisToolBar::saveState(QDomElement &current) const
986{
987 Q_ASSERT(!current.isNull());
988
989 current.setAttribute(QStringLiteral("tempXml"), QLatin1String("true"));
990
991 current.setAttribute(QStringLiteral("noMerge"), QLatin1String("1"));
992 current.setAttribute(QStringLiteral("position"), d->getPositionAsString().toLower());
993 current.setAttribute(QStringLiteral("hidden"), isHidden() ? QLatin1String("true") : QLatin1String("false"));
994
995 const int currentIconSize = iconSize().width();
996 if (currentIconSize == d->iconSizeSettings.defaultValue()) {
997 current.removeAttribute(QStringLiteral("iconSize"));
998 } else {
999 current.setAttribute(QStringLiteral("iconSize"), iconSize().width());
1000 }
1001
1002 if (toolButtonStyle() == d->toolButtonStyleSettings.defaultValue()) {
1003 current.removeAttribute(QStringLiteral("iconText"));
1004 } else {
1005 current.setAttribute(QStringLiteral("iconText"), d->toolButtonStyleToString(toolButtonStyle()));
1006 }
1007
1008 // Note: if this method is used by more than KisKXMLGUIBuilder, e.g. to save XML settings to *disk*,
1009 // then the stuff below shouldn't always be done. This is not the case currently though.
1011 current.setAttribute(QStringLiteral("iconSizeDefault"), d->iconSizeSettings[Level_AppXML]);
1012 }
1014 const Qt::ToolButtonStyle bs = static_cast<Qt::ToolButtonStyle>(d->toolButtonStyleSettings[Level_AppXML]);
1015 current.setAttribute(QStringLiteral("toolButtonStyleDefault"), d->toolButtonStyleToString(bs));
1016 }
1017}
1018
1019// called by KisKMainWindow::applyMainWindowSettings to read from the user settings
1020void KisToolBar::applySettings(const KConfigGroup &cg)
1021{
1022 Q_ASSERT(!cg.name().isEmpty());
1023
1024 if (cg.hasKey("IconSize")) {
1025 d->iconSizeSettings[Level_UserSettings] = cg.readEntry("IconSize", 0);
1026 }
1027 if (cg.hasKey("ToolButtonStyle")) {
1028 d->toolButtonStyleSettings[Level_UserSettings] = d->toolButtonStyleFromString(cg.readEntry("ToolButtonStyle", QString()));
1029 }
1030
1032}
1033
1035{
1036 return qobject_cast<KisKMainWindow *>(const_cast<QObject *>(parent()));
1037}
1038
1040{
1041 QToolBar::setIconSize(QSize(size, size));
1043}
1044
1046{
1047 return 22;
1048}
1049
1051{
1052 setMovable(movable);
1053}
1054
1055void KisToolBar::dragEnterEvent(QDragEnterEvent *event)
1056{
1057 if (toolBarsEditable() && event->proposedAction() & (Qt::CopyAction | Qt::MoveAction) &&
1058 event->mimeData()->hasFormat(QStringLiteral("application/x-kde-action-list"))) {
1059 QByteArray data = event->mimeData()->data(QStringLiteral("application/x-kde-action-list"));
1060
1061 QDataStream stream(data);
1062
1063 QStringList actionNames;
1064
1065 stream >> actionNames;
1066
1067 Q_FOREACH (const QString &actionName, actionNames) {
1069 QAction *newAction = ac->action(actionName);
1070 if (newAction) {
1071 d->actionsBeingDragged.append(newAction);
1072 break;
1073 }
1074 }
1075 }
1076
1077 if (d->actionsBeingDragged.count()) {
1078 QAction *overAction = actionAt(event->pos());
1079
1080 QFrame *dropIndicatorWidget = new QFrame(this);
1081 dropIndicatorWidget->resize(8, height() - 4);
1082 dropIndicatorWidget->setFrameShape(QFrame::VLine);
1083 dropIndicatorWidget->setLineWidth(3);
1084
1085 d->dropIndicatorAction = insertWidget(overAction, dropIndicatorWidget);
1086
1087 insertAction(overAction, d->dropIndicatorAction);
1088
1089 event->acceptProposedAction();
1090 return;
1091 }
1092 }
1093
1094 QToolBar::dragEnterEvent(event);
1095}
1096
1097void KisToolBar::dragMoveEvent(QDragMoveEvent *event)
1098{
1099 if (toolBarsEditable())
1100 Q_FOREVER {
1102 {
1103 QAction *overAction = 0L;
1104 Q_FOREACH (QAction *action, actions()) {
1105 // want to make it feel that half way across an action you're dropping on the other side of it
1106 QWidget *widget = widgetForAction(action);
1107 if (event->pos().x() < widget->pos().x() + (widget->width() / 2)) {
1108 overAction = action;
1109 break;
1110 }
1111 }
1112
1113 if (overAction != d->dropIndicatorAction) {
1114 // Check to see if the indicator is already in the right spot
1115 int dropIndicatorIndex = actions().indexOf(d->dropIndicatorAction);
1116 if (dropIndicatorIndex + 1 < actions().count()) {
1117 if (actions()[ dropIndicatorIndex + 1 ] == overAction) {
1118 break;
1119 }
1120 } else if (!overAction) {
1121 break;
1122 }
1123
1124 insertAction(overAction, d->dropIndicatorAction);
1125 }
1126
1127 event->accept();
1128 return;
1129 }
1130 break;
1131 }
1132
1133 QToolBar::dragMoveEvent(event);
1134}
1135
1136void KisToolBar::dragLeaveEvent(QDragLeaveEvent *event)
1137{
1138 // Want to clear this even if toolBarsEditable was changed mid-drag (unlikely)
1139 delete d->dropIndicatorAction;
1140 d->dropIndicatorAction = 0L;
1141 d->actionsBeingDragged.clear();
1142
1143 if (toolBarsEditable()) {
1144 event->accept();
1145 return;
1146 }
1147
1148 QToolBar::dragLeaveEvent(event);
1149}
1150
1151void KisToolBar::dropEvent(QDropEvent *event)
1152{
1153 if (toolBarsEditable()) {
1154 Q_FOREACH (QAction *action, d->actionsBeingDragged) {
1155 if (actions().contains(action)) {
1156 removeAction(action);
1157 }
1158 insertAction(d->dropIndicatorAction, action);
1159 }
1160 }
1161
1162 // Want to clear this even if toolBarsEditable was changed mid-drag (unlikely)
1163 delete d->dropIndicatorAction;
1164 d->dropIndicatorAction = 0L;
1165 d->actionsBeingDragged.clear();
1166
1167 if (toolBarsEditable()) {
1168 event->accept();
1169 return;
1170 }
1171
1172 QToolBar::dropEvent(event);
1173}
1174
1175void KisToolBar::mousePressEvent(QMouseEvent *event)
1176{
1177 if (toolBarsEditable() && event->button() == Qt::LeftButton) {
1178 if (QAction *action = actionAt(event->pos())) {
1179 d->dragAction = action;
1180 d->dragStartPosition = event->pos();
1181 event->accept();
1182 return;
1183 }
1184 }
1185
1186 QToolBar::mousePressEvent(event);
1187}
1188
1189void KisToolBar::mouseMoveEvent(QMouseEvent *event)
1190{
1191 if (!toolBarsEditable() || !d->dragAction) {
1192 return QToolBar::mouseMoveEvent(event);
1193 }
1194
1195 if ((event->pos() - d->dragStartPosition).manhattanLength() < QApplication::startDragDistance()) {
1196 event->accept();
1197 return;
1198 }
1199
1200 QDrag *drag = new QDrag(this);
1201 QMimeData *mimeData = new QMimeData;
1202
1203 QByteArray data;
1204 {
1205 QDataStream stream(&data, QIODevice::WriteOnly);
1206
1207 QStringList actionNames;
1208 actionNames << d->dragAction->objectName();
1209
1210 stream << actionNames;
1211 }
1212
1213 mimeData->setData(QStringLiteral("application/x-kde-action-list"), data);
1214
1215 drag->setMimeData(mimeData);
1216
1217 Qt::DropAction dropAction = drag->exec(Qt::MoveAction);
1218
1219 if (dropAction == Qt::MoveAction)
1220 // Only remove from this toolbar if it was moved to another toolbar
1221 // Otherwise the receiver moves it.
1222 if (drag->target() != this) {
1223 removeAction(d->dragAction);
1224 }
1225
1226 d->dragAction = 0L;
1227 event->accept();
1228}
1229
1230void KisToolBar::mouseReleaseEvent(QMouseEvent *event)
1231{
1232 // Want to clear this even if toolBarsEditable was changed mid-drag (unlikely)
1233 if (d->dragAction) {
1234 d->dragAction = 0L;
1235 event->accept();
1236 return;
1237 }
1238
1239 QToolBar::mouseReleaseEvent(event);
1240}
1241
1242bool KisToolBar::eventFilter(QObject *watched, QEvent *event)
1243{
1244 // Generate context menu events for disabled buttons too...
1245 if (event->type() == QEvent::MouseButtonPress) {
1246 QMouseEvent *me = static_cast<QMouseEvent *>(event);
1247 if (me->buttons() & Qt::RightButton)
1248 if (QWidget *ww = qobject_cast<QWidget *>(watched))
1249 if (ww->parent() == this && !ww->isEnabled()) {
1250 QCoreApplication::postEvent(this, new QContextMenuEvent(QContextMenuEvent::Mouse, me->pos(), me->globalPos()));
1251 }
1252
1253 } else if (event->type() == QEvent::ParentChange) {
1254 // Make sure we're not leaving stale event filters around,
1255 // when a child is reparented somewhere else
1256 if (QWidget *ww = qobject_cast<QWidget *>(watched)) {
1257 if (!this->isAncestorOf(ww)) {
1258 // New parent is not a subwidget - remove event filter
1259 ww->removeEventFilter(this);
1260 Q_FOREACH (QWidget *child, ww->findChildren<QWidget *>()) {
1261 child->removeEventFilter(this);
1262 }
1263 }
1264 }
1265 }
1266
1267 QToolButton *tb;
1268 if ((tb = qobject_cast<QToolButton *>(watched))) {
1269 const QList<QAction *> tbActions = tb->actions();
1270 if (!tbActions.isEmpty()) {
1271 // Handle MMB on toolbar buttons
1272 if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) {
1273 QMouseEvent *me = static_cast<QMouseEvent *>(event);
1274 if (me->button() == Qt::MiddleButton /*&&
1275 act->receivers(SIGNAL(triggered(Qt::MouseButtons,Qt::KeyboardModifiers)))*/) {
1276 QAction *act = tbActions.first();
1277 if (me->type() == QEvent::MouseButtonPress) {
1278 tb->setDown(act->isEnabled());
1279 } else {
1280 tb->setDown(false);
1281 if (act->isEnabled()) {
1282 QMetaObject::invokeMethod(act, "triggered", Qt::DirectConnection,
1283 Q_ARG(Qt::MouseButtons, me->button()),
1284 Q_ARG(Qt::KeyboardModifiers, QApplication::keyboardModifiers()));
1285 }
1286 }
1287 }
1288 }
1289
1290 // CJK languages use more verbose accelerator marker: they add a Latin
1291 // letter in parenthesis, and put accelerator on that. Hence, the default
1292 // removal of ampersand only may not be enough there, instead the whole
1293 // parenthesis construct should be removed. Use KLocalizedString's method to do this.
1294 if (event->type() == QEvent::Show || event->type() == QEvent::Paint || event->type() == QEvent::EnabledChange) {
1295 QAction *act = tb->defaultAction();
1296 if (act) {
1297 const QString text = KLocalizedString::removeAcceleratorMarker(act->iconText().isEmpty() ? act->text() : act->iconText());
1298 const QString toolTip = KLocalizedString::removeAcceleratorMarker(act->toolTip());
1299 // Filtering messages requested by translators (scripting).
1300 tb->setText(i18nc("@action:intoolbar Text label of toolbar button", "%1", text));
1301 tb->setToolTip(i18nc("@info:tooltip Tooltip of toolbar button", "%1", toolTip));
1302 }
1303 }
1304 }
1305 }
1306
1307 // Redirect mouse events to the toolbar when drag + drop editing is enabled
1308 if (toolBarsEditable()) {
1309 if (QWidget *ww = qobject_cast<QWidget *>(watched)) {
1310 switch (event->type()) {
1311 case QEvent::MouseButtonPress: {
1312 QMouseEvent *me = static_cast<QMouseEvent *>(event);
1313 QMouseEvent newEvent(me->type(), mapFromGlobal(ww->mapToGlobal(me->pos())), me->globalPos(),
1314 me->button(), me->buttons(), me->modifiers());
1315 mousePressEvent(&newEvent);
1316 return true;
1317 }
1318 case QEvent::MouseMove: {
1319 QMouseEvent *me = static_cast<QMouseEvent *>(event);
1320 QMouseEvent newEvent(me->type(), mapFromGlobal(ww->mapToGlobal(me->pos())), me->globalPos(),
1321 me->button(), me->buttons(), me->modifiers());
1322 mouseMoveEvent(&newEvent);
1323 return true;
1324 }
1325 case QEvent::MouseButtonRelease: {
1326 QMouseEvent *me = static_cast<QMouseEvent *>(event);
1327 QMouseEvent newEvent(me->type(), mapFromGlobal(ww->mapToGlobal(me->pos())), me->globalPos(),
1328 me->button(), me->buttons(), me->modifiers());
1329 mouseReleaseEvent(&newEvent);
1330 return true;
1331 }
1332 default:
1333 break;
1334 }
1335 }
1336 }
1337
1338 return QToolBar::eventFilter(watched, event);
1339}
1340
1341void KisToolBar::actionEvent(QActionEvent *event)
1342{
1343 if (event->type() == QEvent::ActionRemoved) {
1344 QWidget *widget = widgetForAction(event->action());
1345 if (widget) {
1346 widget->removeEventFilter(this);
1347
1348 Q_FOREACH (QWidget *child, widget->findChildren<QWidget *>()) {
1349 child->removeEventFilter(this);
1350 }
1351 // Remove Krita's palette manipulation
1352 QToolButton *tb = qobject_cast<QToolButton *>(widget);
1353 if (tb) {
1354 tb->disconnect(this, SLOT(slotToolButtonToggled(bool)));
1355 }
1356 }
1357 }
1358
1359 QToolBar::actionEvent(event);
1360
1361 if (event->type() == QEvent::ActionAdded) {
1362 QWidget *widget = widgetForAction(event->action());
1363 if (widget) {
1364 widget->installEventFilter(this);
1365
1366 Q_FOREACH (QWidget *child, widget->findChildren<QWidget *>()) {
1367 child->installEventFilter(this);
1368 }
1369 // Center widgets that do not have any use for more space. See bug 165274
1370 if (!(widget->sizePolicy().horizontalPolicy() & QSizePolicy::GrowFlag)
1371 // ... but do not center when using text besides icon in vertical toolbar. See bug 243196
1372 && !(orientation() == Qt::Vertical && toolButtonStyle() == Qt::ToolButtonTextBesideIcon)) {
1373 const int index = layout()->indexOf(widget);
1374 if (index != -1) {
1375 layout()->itemAt(index)->setAlignment(Qt::AlignJustify);
1376 }
1377 }
1378 // NOTE: set a fixed button size, same size as the buttonsize used in kis_paintop_box
1379 // and toggle highlight color on checked buttons, same as in KisHighlightedButton
1380 QToolButton *tb = qobject_cast<QToolButton *>(widget);
1381 if (tb && event->action()->icon().isNull() == false) {
1382 d->customizeButtonPalette(tb, tb->isChecked());
1383 connect(tb, SIGNAL(toggled(bool)), this, SLOT(slotToolButtonToggled(bool)));
1384 widget->setFixedSize(32, 32);
1385 }
1386 }
1387 }
1388
1390}
1391
1396
1398{
1399 if (KisToolBar::Private::s_editable != editable) {
1401 }
1402}
1403
1405{
1406 s_toolBarsModel->settoolBarsLocked(locked);
1407}
1408
1410{
1411 return s_toolBarsModel->toolBarsLocked();
1412}
1413
1415{
1416#ifdef HAVE_DBUS
1417 QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KisToolBar"), QStringLiteral("org.kde.KisToolBar"), QStringLiteral("styleChanged"));
1418 QDBusConnection::sessionBus().send(message);
1419#endif
1420}
1421
1423{
1424 return s_toolBarsModel;
1425}
1426
1427#include "moc_ktoolbar.cpp"
float value(const T *src, size_t ch)
const Params2D p
Q_GLOBAL_STATIC(KisStoragePluginRegistry, s_instance)
unsigned int uint
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
int iconSize(qreal width, qreal height)
KDE top level main window with predefined action layout
QAction * toolBarMenuAction()
void setupToolbarMenuActions()
A container for a set of QAction objects.
static const QList< KisKActionCollection * > & allCollections()
QAction * action(int index) const
static void setGlobalDefaultToolBar(const char *toolBarName)
KDE top level main window
Definition kmainwindow.h:89
static QList< KisKMainWindow * > memberList()
void setSettingsDirty()
virtual QString xmlFile() const
virtual QString componentName() const
virtual KisKActionCollection * actionCollection() const
static QDomElement actionPropertiesElement(QDomDocument &doc)
static bool saveConfigFile(const QDomDocument &doc, const QString &filename, const QString &componentName=QString())
static QString readConfigFile(const QString &filename, const QString &componentName=QString())
static QDomElement findActionByName(QDomElement &elem, const QString &sName, bool create)
int values[NSettingLevels]
Definition ktoolbar.cpp:217
Private(KisToolBar *qq)
Definition ktoolbar.cpp:90
static Qt::ToolBarArea positionFromString(const QString &position)
Definition ktoolbar.cpp:502
QAction * contextBottom
Definition ktoolbar.cpp:165
IntSetting toolButtonStyleSettings
Definition ktoolbar.cpp:220
static bool s_editable
Definition ktoolbar.cpp:151
void slotContextAboutToHide()
Definition ktoolbar.cpp:673
QSet< KisKXMLGUIClient * > xmlguiClients
Definition ktoolbar.cpp:153
QAction * contextLeft
Definition ktoolbar.cpp:163
QAction * contextIcons
Definition ktoolbar.cpp:166
QMenu * contextMenu(const QPoint &globalPos)
Definition ktoolbar.cpp:307
QAction * contextTextUnder
Definition ktoolbar.cpp:169
QAction * contextButtonTitle
Definition ktoolbar.cpp:159
QAction * contextText
Definition ktoolbar.cpp:168
QAction * contextButtonAction
Definition ktoolbar.cpp:161
KToggleAction * contextLockAction
Definition ktoolbar.cpp:170
void customizeButtonPalette(QToolButton *button, bool checked)
Definition ktoolbar.cpp:560
void applyCurrentSettings()
Definition ktoolbar.cpp:544
void setLocked(bool locked)
Definition ktoolbar.cpp:436
QList< QAction * > actionsBeingDragged
Definition ktoolbar.cpp:222
static QString toolButtonStyleToString(Qt::ToolButtonStyle)
Definition ktoolbar.cpp:487
static ToolBarsStateUpdater s_toolBarsStateUpdater
Definition ktoolbar.cpp:251
void slotAppearanceChanged()
Definition ktoolbar.cpp:516
QAction * contextShowText
Definition ktoolbar.cpp:160
static Qt::ToolButtonStyle toolButtonStyleFromString(const QString &style)
Definition ktoolbar.cpp:473
void slotContextTextUnder()
Definition ktoolbar.cpp:764
QAction * contextTextRight
Definition ktoolbar.cpp:167
void slotLockToolBars(bool lock)
Definition ktoolbar.cpp:785
void init(bool readConfig=true, bool isMainToolBar=false)
Definition ktoolbar.cpp:253
QAction * findAction(const QString &actionName, KisKXMLGUIClient **client=0) const
Definition ktoolbar.cpp:568
QString getPositionAsString() const
Definition ktoolbar.cpp:291
void adjustSeparatorVisibility()
Definition ktoolbar.cpp:443
IntSetting iconSizeSettings
Definition ktoolbar.cpp:219
QAction * dropIndicatorAction
Definition ktoolbar.cpp:223
static Qt::ToolButtonStyle toolButtonStyleSetting()
Definition ktoolbar.cpp:522
QAction * contextRight
Definition ktoolbar.cpp:164
void slotContextAboutToShow()
Definition ktoolbar.cpp:582
QMap< QAction *, int > contextIconSizes
Definition ktoolbar.cpp:171
void slotContextTextRight()
Definition ktoolbar.cpp:770
void slotToolButtonToggled(bool checked)
Definition ktoolbar.cpp:791
Floatable toolbar with auto resize.
Definition ktoolbar.h:47
void applySettings(const KConfigGroup &cg)
static bool toolBarsEditable()
void contextMenuEvent(QContextMenuEvent *) override
Definition ktoolbar.cpp:855
void mousePressEvent(QMouseEvent *) override
void dragLeaveEvent(QDragLeaveEvent *) override
void mouseMoveEvent(QMouseEvent *) override
void mouseReleaseEvent(QMouseEvent *) override
~KisToolBar() override
Definition ktoolbar.cpp:814
static void emitToolbarStyleChanged()
Private *const d
Definition ktoolbar.h:177
void setIconDimensions(int size)
void removeXMLGUIClient(KisKXMLGUIClient *client)
Definition ktoolbar.cpp:850
void dragMoveEvent(QDragMoveEvent *) override
static bool toolBarsLocked()
static void setToolBarsLocked(bool locked)
void saveState(QDomElement &element) const
Definition ktoolbar.cpp:985
void saveSettings(KConfigGroup &cg)
Definition ktoolbar.cpp:820
void dropEvent(QDropEvent *) override
KisToolBar(const QString &objectName, QWidget *parent, bool readConfig=true)
Definition ktoolbar.cpp:799
void dragEnterEvent(QDragEnterEvent *) override
int iconSizeDefault() const
bool eventFilter(QObject *watched, QEvent *event) override
virtual void slotMovableChanged(bool movable)
static void setToolBarsEditable(bool editable)
void loadState(const QDomElement &element)
Definition ktoolbar.cpp:860
void actionEvent(QActionEvent *) override
static KisToolBarStateModel * toolBarStateModel()
void addXMLGUIClient(KisKXMLGUIClient *client)
Definition ktoolbar.cpp:845
KisKMainWindow * mainWindow() const
QString button(const QWheelEvent &ev)
@ Unset
Definition ktoolbar.cpp:85
SettingLevel
Definition ktoolbar.cpp:82
@ Level_AppXML
Definition ktoolbar.cpp:82
@ Level_UserSettings
Definition ktoolbar.cpp:82
@ NSettingLevels
Definition ktoolbar.cpp:83
@ Level_KDEDefault
Definition ktoolbar.cpp:82
const char * name(StandardAction id)
QIcon loadIcon(const QString &name)