KXmlGui

ktoolbar.cpp
1/*
2 This file is part of the KDE libraries
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
17#include <QAction>
18#include <QActionGroup>
19#include <QApplication>
20#include <QDomElement>
21#include <QDrag>
22#include <QFrame>
23#include <QLayout>
24#include <QMenu>
25#include <QMimeData>
26#include <QMouseEvent>
27#include <QPointer>
28#ifdef WITH_QTDBUS
29#include <QDBusConnection>
30#include <QDBusMessage>
31#endif
32
33#include <KAuthorized>
34#include <KConfig>
35#include <KConfigGroup>
36#include <KIconTheme>
37#include <KLocalizedString>
38#include <KSharedConfig>
39#include <KStandardActions>
40#include <KToggleAction>
41#include <KToolBarPopupAction>
42
43#include "kactioncollection.h"
44#include "kedittoolbar.h"
45#include "kxmlguifactory.h"
46#include "kxmlguiwindow.h"
47
48#include "ktoolbarhelper_p.h"
49
50#include <algorithm>
51
52/*
53 Toolbar settings (e.g. icon size or toolButtonStyle)
54 =====================================================
55
56 We have the following stack of settings (in order of priority) :
57 - user-specified settings (loaded/saved in KConfig)
58 - developer-specified settings in the XMLGUI file (if using xmlgui) (cannot change at runtime)
59 - KDE-global default (user-configurable; can change at runtime)
60 and when switching between kparts, they are saved as xml in memory,
61 which, in the unlikely case of no-kmainwindow-autosaving, could be
62 different from the user-specified settings saved in KConfig and would have
63 priority over it.
64
65 So, in summary, without XML:
66 Global config / User settings (loaded/saved in kconfig)
67 and with XML:
68 Global config / App-XML attributes / User settings (loaded/saved in kconfig)
69
70 And all those settings (except the KDE-global defaults) have to be stored in memory
71 since we cannot retrieve them at random points in time, not knowing the xml document
72 nor config file that holds these settings. Hence the iconSizeSettings and toolButtonStyleSettings arrays.
73
74 For instance, if you change the KDE-global default, whether this makes a change
75 on a given toolbar depends on whether there are settings at Level_AppXML or Level_UserSettings.
76 Only if there are no settings at those levels, should the change of KDEDefault make a difference.
77*/
78enum SettingLevel { Level_KDEDefault, Level_AppXML, Level_UserSettings, NSettingLevels };
79enum { Unset = -1 };
80
81class KToolBarPrivate
82{
83public:
84 KToolBarPrivate(KToolBar *qq)
85 : q(qq)
86 , isMainToolBar(false)
87 , unlockedMovable(true)
88 , contextOrient(nullptr)
89 , contextMode(nullptr)
90 , contextSize(nullptr)
91 , contextButtonTitle(nullptr)
92 , contextShowText(nullptr)
93 , contextButtonAction(nullptr)
94 , contextTop(nullptr)
95 , contextLeft(nullptr)
96 , contextRight(nullptr)
97 , contextBottom(nullptr)
98 , contextIcons(nullptr)
99 , contextTextRight(nullptr)
100 , contextText(nullptr)
101 , contextTextUnder(nullptr)
102 , contextConfigureAction(nullptr)
103 , contextToolBarAction(nullptr)
104 , contextLockAction(nullptr)
105 , dropIndicatorAction(nullptr)
106 , context(nullptr)
107 , dragAction(nullptr)
108 {
109 }
110
111 void slotAppearanceChanged();
112 void slotContextAboutToShow();
113 void slotContextAboutToHide();
114 void slotContextLeft();
115 void slotContextRight();
116 void slotContextShowText();
117 void slotContextTop();
118 void slotContextBottom();
119 void slotContextIcons();
120 void slotContextText();
121 void slotContextTextRight();
122 void slotContextTextUnder();
123 void slotContextIconSize(QAction *action);
124 void slotLockToolBars(bool lock);
125
126 void init(bool readConfig = true, bool isMainToolBar = false);
127 QString getPositionAsString() const;
128 QMenu *contextMenu(const QPoint &globalPos);
129 void setLocked(bool locked);
130 void adjustSeparatorVisibility();
131 void loadKDESettings();
132 void applyCurrentSettings();
133
134 QAction *findAction(const QString &actionName, KXMLGUIClient **client = nullptr) const;
135
136 static Qt::ToolButtonStyle toolButtonStyleFromString(const QString &style);
137 static QString toolButtonStyleToString(Qt::ToolButtonStyle);
138 static Qt::ToolBarArea positionFromString(const QString &position);
139 static Qt::ToolButtonStyle toolButtonStyleSetting();
140
141 KToolBar *const q;
142 bool isMainToolBar : 1;
143 bool unlockedMovable : 1;
144 static bool s_editable;
145 static bool s_locked;
146
147 QSet<KXMLGUIClient *> xmlguiClients;
148
149 QMenu *contextOrient;
150 QMenu *contextMode;
151 QMenu *contextSize;
152
153 QAction *contextButtonTitle;
154 QAction *contextShowText;
155 QAction *contextButtonAction;
156 QAction *contextTop;
157 QAction *contextLeft;
158 QAction *contextRight;
159 QAction *contextBottom;
160 QAction *contextIcons;
161 QAction *contextTextRight;
162 QAction *contextText;
163 QAction *contextTextUnder;
164 QAction *contextConfigureAction; // nullptr if not in context
165 QAction *contextToolBarAction; // nullptr if not in context
166 KToggleAction *contextLockAction;
167
168 struct ContextIconInfo {
169 QAction *iconAction = nullptr;
170 int iconSize = 0;
171 };
172
173 std::vector<ContextIconInfo> m_contextIconSizes;
174
175 class IntSetting
176 {
177 public:
178 IntSetting()
179 {
180 for (int &value : values) {
181 value = Unset;
182 }
183 }
184 int currentValue() const
185 {
186 int val = Unset;
187 for (int value : values) {
188 if (value != Unset) {
189 val = value;
190 }
191 }
192 return val;
193 }
194 // Default value as far as the user is concerned is kde-global + app-xml.
195 // If currentValue()==defaultValue() then nothing to write into kconfig.
196 int defaultValue() const
197 {
198 int val = Unset;
199 for (int level = 0; level < Level_UserSettings; ++level) {
200 if (values[level] != Unset) {
201 val = values[level];
202 }
203 }
204 return val;
205 }
206 QString toString() const
207 {
208 QString str;
209 for (int value : values) {
210 str += QString::number(value) + QLatin1Char(' ');
211 }
212 return str;
213 }
214 int &operator[](int index)
215 {
216 return values[index];
217 }
218
219 private:
220 int values[NSettingLevels];
221 };
222 IntSetting iconSizeSettings;
223 IntSetting toolButtonStyleSettings; // either Qt::ToolButtonStyle or -1, hence "int".
224
225 QList<QAction *> actionsBeingDragged;
226 QAction *dropIndicatorAction;
227
228 QMenu *context;
229 QAction *dragAction;
230 QPoint dragStartPosition;
231};
232
233bool KToolBarPrivate::s_editable = false;
234bool KToolBarPrivate::s_locked = true;
235
236void KToolBarPrivate::init(bool readConfig, bool _isMainToolBar)
237{
238 isMainToolBar = _isMainToolBar;
239 loadKDESettings();
240
241 // also read in our configurable settings (for non-xmlgui toolbars)
242 if (readConfig) {
243 KConfigGroup cg(KSharedConfig::openConfig(), QString());
244 q->applySettings(cg);
245 }
246
247 if (q->mainWindow()) {
248 // Get notified when settings change
254 }
255
256 if (!KAuthorized::authorize(QStringLiteral("movable_toolbars"))) {
257 q->setMovable(false);
258 } else {
259 q->setMovable(!KToolBar::toolBarsLocked());
260 }
261
262 q->toggleViewAction()->setEnabled(KAuthorized::authorizeAction(QStringLiteral("options_show_toolbar")));
263
264 QObject::connect(q, &QToolBar::movableChanged, q, &KToolBar::slotMovableChanged);
265
266 q->setAcceptDrops(true);
267
268#ifdef WITH_QTDBUS
270 .connect(QString(), QStringLiteral("/KToolBar"), QStringLiteral("org.kde.KToolBar"), QStringLiteral("styleChanged"), q, SLOT(slotAppearanceChanged()));
271#endif
273 slotAppearanceChanged();
274 });
275}
276
277QString KToolBarPrivate::getPositionAsString() const
278{
279 if (!q->mainWindow()) {
280 return QStringLiteral("None");
281 }
282 // get all of the stuff to save
283 switch (q->mainWindow()->toolBarArea(const_cast<KToolBar *>(q))) {
285 return QStringLiteral("Bottom");
287 return QStringLiteral("Left");
289 return QStringLiteral("Right");
291 default:
292 return QStringLiteral("Top");
293 }
294}
295
296QMenu *KToolBarPrivate::contextMenu(const QPoint &globalPos)
297{
298 if (!context) {
299 context = new QMenu(q);
300 context->setIcon(QIcon::fromTheme(QStringLiteral("configure-toolbars")));
301 context->setTitle(i18nc("@title:menu", "Toolbar Settings"));
302
303 contextButtonTitle = context->addSection(i18nc("@title:menu", "Show Text"));
304 contextShowText = context->addAction(QString(), q, [this]() {
305 slotContextShowText();
306 });
307
308 context->addSection(i18nc("@title:menu", "Toolbar Settings"));
309
310 contextOrient = new QMenu(i18nc("Toolbar orientation", "Orientation"), context);
311
312 contextTop = contextOrient->addAction(i18nc("toolbar position string", "Top"), q, [this]() {
313 slotContextTop();
314 });
315 contextTop->setChecked(true);
316 contextLeft = contextOrient->addAction(i18nc("toolbar position string", "Left"), q, [this]() {
317 slotContextLeft();
318 });
319 contextRight = contextOrient->addAction(i18nc("toolbar position string", "Right"), q, [this]() {
320 slotContextRight();
321 });
322 contextBottom = contextOrient->addAction(i18nc("toolbar position string", "Bottom"), q, [this]() {
323 slotContextBottom();
324 });
325
326 QActionGroup *positionGroup = new QActionGroup(contextOrient);
327 const auto orientActions = contextOrient->actions();
328 for (QAction *action : orientActions) {
329 action->setActionGroup(positionGroup);
330 action->setCheckable(true);
331 }
332
333 contextMode = new QMenu(i18n("Text Position"), context);
334
335 contextIcons = contextMode->addAction(i18nc("@item:inmenu", "Icons Only"), q, [this]() {
336 slotContextIcons();
337 });
338 contextText = contextMode->addAction(i18nc("@item:inmenu", "Text Only"), q, [this]() {
339 slotContextText();
340 });
341 contextTextRight = contextMode->addAction(i18nc("@item:inmenu", "Text Alongside Icons"), q, [this]() {
342 slotContextTextRight();
343 });
344 contextTextUnder = contextMode->addAction(i18nc("@item:inmenu", "Text Under Icons"), q, [this]() {
345 slotContextTextUnder();
346 });
347
348 QActionGroup *textGroup = new QActionGroup(contextMode);
349 const auto modeActions = contextMode->actions();
350 for (QAction *action : modeActions) {
351 action->setActionGroup(textGroup);
352 action->setCheckable(true);
353 }
354
355 contextSize = new QMenu(i18n("Icon Size"), context);
356
357 auto *act = contextSize->addAction(i18nc("@item:inmenu Icon size", "Default"));
358 q->connect(act, &QAction::triggered, q, [this, act]() {
359 slotContextIconSize(act);
360 });
361 m_contextIconSizes.push_back({act, iconSizeSettings.defaultValue()});
362
363 // Query the current theme for available sizes
364 KIconTheme *theme = KIconLoader::global()->theme();
365 QList<int> avSizes;
366 if (theme) {
367 avSizes = theme->querySizes(isMainToolBar ? KIconLoader::MainToolbar : KIconLoader::Toolbar);
368 }
369
370 std::sort(avSizes.begin(), avSizes.end());
371
372 if (avSizes.count() < 10) {
373 // Fixed or threshold type icons
374 for (int it : std::as_const(avSizes)) {
375 QString text;
376 if (it < 19) {
377 text = i18n("Small (%1x%2)", it, it);
378 } else if (it < 25) {
379 text = i18n("Medium (%1x%2)", it, it);
380 } else if (it < 35) {
381 text = i18n("Large (%1x%2)", it, it);
382 } else {
383 text = i18n("Huge (%1x%2)", it, it);
384 }
385
386 auto *act = contextSize->addAction(text);
387 q->connect(act, &QAction::triggered, q, [this, act]() {
388 slotContextIconSize(act);
389 });
390 m_contextIconSizes.push_back({act, it});
391 }
392 } else {
393 // Scalable icons.
394 const int progression[] = {16, 22, 32, 48, 64, 96, 128, 192, 256};
395
396 for (int p : progression) {
397 for (int it : std::as_const(avSizes)) {
398 if (it >= p) {
399 QString text;
400 if (it < 19) {
401 text = i18n("Small (%1x%2)", it, it);
402 } else if (it < 25) {
403 text = i18n("Medium (%1x%2)", it, it);
404 } else if (it < 35) {
405 text = i18n("Large (%1x%2)", it, it);
406 } else {
407 text = i18n("Huge (%1x%2)", it, it);
408 }
409
410 auto *act = contextSize->addAction(text);
411 q->connect(act, &QAction::triggered, q, [this, act]() {
412 slotContextIconSize(act);
413 });
414 m_contextIconSizes.push_back({act, it});
415 break;
416 }
417 }
418 }
419 }
420
421 QActionGroup *sizeGroup = new QActionGroup(contextSize);
422 const auto sizeActions = contextSize->actions();
423 for (QAction *action : sizeActions) {
424 action->setActionGroup(sizeGroup);
425 action->setCheckable(true);
426 }
427
428 if (!q->toolBarsLocked() && !q->isMovable()) {
429 unlockedMovable = false;
430 }
431
432 delete contextLockAction;
433 contextLockAction = new KToggleAction(QIcon::fromTheme(QStringLiteral("system-lock-screen")), i18n("Lock Toolbar Positions"), q);
434 contextLockAction->setChecked(q->toolBarsLocked());
435 QObject::connect(contextLockAction, &KToggleAction::toggled, q, [this](bool checked) {
436 slotLockToolBars(checked);
437 });
438
439 // Now add the actions to the menu
440 context->addMenu(contextMode);
441 context->addMenu(contextSize);
442 context->addMenu(contextOrient);
443 context->addSeparator();
444
445 QObject::connect(context, &QMenu::aboutToShow, q, [this]() {
446 slotContextAboutToShow();
447 });
448 }
449
450 contextButtonAction = q->actionAt(q->mapFromGlobal(globalPos));
451 if (contextButtonAction) {
452 contextShowText->setText(contextButtonAction->text());
453 contextShowText->setIcon(contextButtonAction->icon());
454 contextShowText->setCheckable(true);
455 }
456
457 contextOrient->menuAction()->setVisible(!q->toolBarsLocked());
458 // Unplugging a submenu from abouttohide leads to the popupmenu floating around
459 // So better simply call that code from after exec() returns (DF)
460 // connect(context, SIGNAL(aboutToHide()), this, SLOT(slotContextAboutToHide()));
461
462 // For tool buttons with delay popup or menu button popup (split button)
463 // show the actions of that button for ease of access.
464 // (no need to wait for the menu to open or aim at the arrow)
465 if (auto *contextToolButton = qobject_cast<QToolButton *>(q->widgetForAction(contextButtonAction))) {
466 if (contextToolButton->popupMode() == QToolButton::DelayedPopup || contextToolButton->popupMode() == QToolButton::MenuButtonPopup) {
467 auto *actionMenu = contextButtonAction->menu();
468
469 if (!actionMenu) {
470 if (auto *toolBarPopupAction = qobject_cast<KToolBarPopupAction *>(contextButtonAction)) {
471 actionMenu = toolBarPopupAction->popupMenu();
472 }
473 }
474
475 if (actionMenu) {
476 // In case it is populated on demand
477 Q_EMIT actionMenu->aboutToShow();
478
479 auto *contextMenu = new QMenu(q);
480 contextMenu->setAttribute(Qt::WA_DeleteOnClose);
481
482 const auto actions = actionMenu->actions();
483 if (!actions.isEmpty()) {
484 for (QAction *action : actions) {
485 contextMenu->addAction(action);
486 }
487
488 // Now add the configure actions as submenu
489 contextMenu->addSeparator();
490 contextMenu->addMenu(context);
491 return contextMenu;
492 }
493 }
494 }
495 }
496
497 return context;
498}
499
500void KToolBarPrivate::setLocked(bool locked)
501{
502 if (unlockedMovable) {
503 q->setMovable(!locked);
504 }
505}
506
507void KToolBarPrivate::adjustSeparatorVisibility()
508{
509 bool visibleNonSeparator = false;
510 int separatorToShow = -1;
511
512 for (int index = 0; index < q->actions().count(); ++index) {
513 QAction *action = q->actions().at(index);
514 if (action->isSeparator()) {
515 if (visibleNonSeparator) {
516 separatorToShow = index;
517 visibleNonSeparator = false;
518 } else {
519 action->setVisible(false);
520 }
521 } else if (!visibleNonSeparator) {
522 if (action->isVisible()) {
523 visibleNonSeparator = true;
524 if (separatorToShow != -1) {
525 q->actions().at(separatorToShow)->setVisible(true);
526 separatorToShow = -1;
527 }
528 }
529 }
530 }
531
532 if (separatorToShow != -1) {
533 q->actions().at(separatorToShow)->setVisible(false);
534 }
535}
536
537Qt::ToolButtonStyle KToolBarPrivate::toolButtonStyleFromString(const QString &_style)
538{
539 QString style = _style.toLower();
540 if (style == QLatin1String("textbesideicon") || style == QLatin1String("icontextright")) {
542 } else if (style == QLatin1String("textundericon") || style == QLatin1String("icontextbottom")) {
544 } else if (style == QLatin1String("textonly")) {
546 } else {
548 }
549}
550
551QString KToolBarPrivate::toolButtonStyleToString(Qt::ToolButtonStyle style)
552{
553 switch (style) {
555 default:
556 return QStringLiteral("IconOnly");
558 return QStringLiteral("TextBesideIcon");
560 return QStringLiteral("TextOnly");
562 return QStringLiteral("TextUnderIcon");
563 }
564}
565
566Qt::ToolBarArea KToolBarPrivate::positionFromString(const QString &position)
567{
569 if (position == QLatin1String("left")) {
570 newposition = Qt::LeftToolBarArea;
571 } else if (position == QLatin1String("bottom")) {
572 newposition = Qt::BottomToolBarArea;
573 } else if (position == QLatin1String("right")) {
574 newposition = Qt::RightToolBarArea;
575 } else if (position == QLatin1String("none")) {
576 newposition = Qt::NoToolBarArea;
577 }
578 return newposition;
579}
580
581// Global setting was changed
582void KToolBarPrivate::slotAppearanceChanged()
583{
584 loadKDESettings();
585 applyCurrentSettings();
586}
587
588Qt::ToolButtonStyle KToolBarPrivate::toolButtonStyleSetting()
589{
590 KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("Toolbar style"));
591 const QString fallback = KToolBarPrivate::toolButtonStyleToString(Qt::ToolButtonTextBesideIcon);
592 return KToolBarPrivate::toolButtonStyleFromString(group.readEntry("ToolButtonStyle", fallback));
593}
594
595void KToolBarPrivate::loadKDESettings()
596{
597 iconSizeSettings[Level_KDEDefault] = q->iconSizeDefault();
598
599 if (isMainToolBar) {
600 toolButtonStyleSettings[Level_KDEDefault] = toolButtonStyleSetting();
601 } else {
602 const QString fallBack = toolButtonStyleToString(Qt::ToolButtonTextBesideIcon);
603 /**
604 TODO: if we get complaints about text beside icons on small screens,
605 try the following code out on such systems - aseigo.
606 // if we are on a small screen with a non-landscape ratio, then
607 // we revert to text under icons since width is probably not our
608 // friend in such cases
609 QDesktopWidget *desktop = QApplication::desktop();
610 QRect screenGeom = desktop->screenGeometry(desktop->primaryScreen());
611 qreal ratio = screenGeom.width() / qreal(screenGeom.height());
612
613 if (screenGeom.width() < 1024 && ratio <= 1.4) {
614 fallBack = "TextUnderIcon";
615 }
616 **/
617
618 KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("Toolbar style"));
619 const QString value = group.readEntry("ToolButtonStyleOtherToolbars", fallBack);
620 toolButtonStyleSettings[Level_KDEDefault] = KToolBarPrivate::toolButtonStyleFromString(value);
621 }
622}
623
624// Call this after changing something in d->iconSizeSettings or d->toolButtonStyleSettings
625void KToolBarPrivate::applyCurrentSettings()
626{
627 // qCDebug(DEBUG_KXMLGUI) << q->objectName() << "iconSizeSettings:" << iconSizeSettings.toString() << "->" << iconSizeSettings.currentValue();
628 const int currentIconSize = iconSizeSettings.currentValue();
629 q->setIconSize(QSize(currentIconSize, currentIconSize));
630 // qCDebug(DEBUG_KXMLGUI) << q->objectName() << "toolButtonStyleSettings:" << toolButtonStyleSettings.toString() << "->" <<
631 // toolButtonStyleSettings.currentValue();
632 q->setToolButtonStyle(static_cast<Qt::ToolButtonStyle>(toolButtonStyleSettings.currentValue()));
633
634 // And remember to save the new look later
635 KMainWindow *kmw = q->mainWindow();
636 if (kmw) {
637 kmw->setSettingsDirty();
638 }
639}
640
641QAction *KToolBarPrivate::findAction(const QString &actionName, KXMLGUIClient **clientOut) const
642{
643 for (KXMLGUIClient *client : xmlguiClients) {
644 QAction *action = client->actionCollection()->action(actionName);
645 if (action) {
646 if (clientOut) {
647 *clientOut = client;
648 }
649 return action;
650 }
651 }
652 return nullptr;
653}
654
655void KToolBarPrivate::slotContextAboutToShow()
656{
657 /**
658 * The idea here is to reuse the "static" part of the menu to save time.
659 * But the "Toolbars" action is dynamic (can be a single action or a submenu)
660 * and ToolBarHandler::setupActions() deletes it, so better not keep it around.
661 * So we currently plug/unplug the last two actions of the menu.
662 * Another way would be to keep around the actions and plug them all into a (new each time) popupmenu.
663 */
664
665 KXmlGuiWindow *kmw = qobject_cast<KXmlGuiWindow *>(q->mainWindow());
666
667 // try to find "configure toolbars" action
669 QAction *configureAction = findAction(actionName);
670 if (!configureAction && kmw) {
671 configureAction = kmw->actionCollection()->action(actionName);
672 }
673 contextConfigureAction = configureAction;
674 if (configureAction) {
675 context->addAction(configureAction);
676 }
677
678 context->addAction(contextLockAction);
679
680 contextToolBarAction = nullptr;
681 if (kmw) {
683 // Only allow hiding a toolbar if the action is also plugged somewhere else (e.g. menubar)
684 QAction *tbAction = kmw->toolBarMenuAction();
685 if (!q->toolBarsLocked() && tbAction) {
686 // this compiles to less code than `for (QObject *object : tbAction->associatedObjects()) {`
687 const QList<QObject *> associatedObjects = tbAction->associatedObjects();
688 for (QObject *object : associatedObjects) {
689 if (qobject_cast<QWidget *>(object)) {
690 contextToolBarAction = tbAction;
691 context->addAction(tbAction);
692 break;
693 }
694 }
695 }
696 }
697
698 KEditToolBar::setGlobalDefaultToolBar(q->QObject::objectName());
699
700 // Check the actions that should be checked
701 switch (q->toolButtonStyle()) {
703 default:
704 contextIcons->setChecked(true);
705 break;
707 contextTextRight->setChecked(true);
708 break;
710 contextText->setChecked(true);
711 break;
713 contextTextUnder->setChecked(true);
714 break;
715 }
716
717 auto it = std::find_if(m_contextIconSizes.cbegin(), m_contextIconSizes.cend(), [this](const ContextIconInfo &info) {
718 return info.iconSize == q->iconSize().width();
719 });
720 if (it != m_contextIconSizes.cend()) {
721 it->iconAction->setChecked(true);
722 }
723
724 switch (q->mainWindow()->toolBarArea(q)) {
726 contextBottom->setChecked(true);
727 break;
729 contextLeft->setChecked(true);
730 break;
732 contextRight->setChecked(true);
733 break;
734 default:
736 contextTop->setChecked(true);
737 break;
738 }
739
740 const bool showButtonSettings = contextButtonAction //
741 && !contextShowText->text().isEmpty() //
742 && contextTextRight->isChecked();
743 contextButtonTitle->setVisible(showButtonSettings);
744 contextShowText->setVisible(showButtonSettings);
745 if (showButtonSettings) {
746 contextShowText->setChecked(contextButtonAction->priority() >= QAction::NormalPriority);
747 }
748}
749
750void KToolBarPrivate::slotContextAboutToHide()
751{
752 // We have to unplug whatever slotContextAboutToShow plugged into the menu.
753 if (contextConfigureAction) {
754 context->removeAction(contextConfigureAction);
755 contextConfigureAction = nullptr;
756 }
757 if (contextToolBarAction) {
758 context->removeAction(contextToolBarAction);
759 contextToolBarAction = nullptr;
760 }
761 context->removeAction(contextLockAction);
762}
763
764void KToolBarPrivate::slotContextLeft()
765{
766 q->mainWindow()->addToolBar(Qt::LeftToolBarArea, q);
767}
768
769void KToolBarPrivate::slotContextRight()
770{
771 q->mainWindow()->addToolBar(Qt::RightToolBarArea, q);
772}
773
774void KToolBarPrivate::slotContextShowText()
775{
776 Q_ASSERT(contextButtonAction);
777 const QAction::Priority priority = contextShowText->isChecked() ? QAction::NormalPriority : QAction::LowPriority;
778 contextButtonAction->setPriority(priority);
779
780 // Find to which xml file and componentData the action belongs to
781 QString componentName;
782 QString filename;
783 KXMLGUIClient *client;
784 if (findAction(contextButtonAction->objectName(), &client)) {
785 componentName = client->componentName();
786 filename = client->xmlFile();
787 }
788 if (filename.isEmpty()) {
789 componentName = QCoreApplication::applicationName();
790 filename = componentName + QLatin1String("ui.rc");
791 }
792
793 // Save the priority state of the action
794 const QString configFile = KXMLGUIFactory::readConfigFile(filename, componentName);
795
796 QDomDocument document;
797 document.setContent(configFile);
798 QDomElement elem = KXMLGUIFactory::actionPropertiesElement(document);
799 QDomElement actionElem = KXMLGUIFactory::findActionByName(elem, contextButtonAction->objectName(), true);
800 actionElem.setAttribute(QStringLiteral("priority"), priority);
801 KXMLGUIFactory::saveConfigFile(document, filename, componentName);
802}
803
804void KToolBarPrivate::slotContextTop()
805{
806 q->mainWindow()->addToolBar(Qt::TopToolBarArea, q);
807}
808
809void KToolBarPrivate::slotContextBottom()
810{
811 q->mainWindow()->addToolBar(Qt::BottomToolBarArea, q);
812}
813
814void KToolBarPrivate::slotContextIcons()
815{
816 q->setToolButtonStyle(Qt::ToolButtonIconOnly);
817 toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
818}
819
820void KToolBarPrivate::slotContextText()
821{
822 q->setToolButtonStyle(Qt::ToolButtonTextOnly);
823 toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
824}
825
826void KToolBarPrivate::slotContextTextUnder()
827{
828 q->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
829 toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
830}
831
832void KToolBarPrivate::slotContextTextRight()
833{
834 q->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
835 toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
836}
837
838void KToolBarPrivate::slotContextIconSize(QAction *action)
839{
840 if (action) {
841 auto it = std::find_if(m_contextIconSizes.cbegin(), m_contextIconSizes.cend(), [action](const ContextIconInfo &info) {
842 return info.iconAction == action;
843 });
844 if (it != m_contextIconSizes.cend()) {
845 q->setIconDimensions(it->iconSize);
846 }
847 }
848}
849
850void KToolBarPrivate::slotLockToolBars(bool lock)
851{
852 q->setToolBarsLocked(lock);
853}
854
855KToolBar::KToolBar(QWidget *parent, bool isMainToolBar, bool readConfig)
857 , d(new KToolBarPrivate(this))
858{
859 d->init(readConfig, isMainToolBar);
860
861 // KToolBar is auto-added to the top area of the main window if parent is a QMainWindow
863 mw->addToolBar(this);
864 }
865}
866
869 , d(new KToolBarPrivate(this))
870{
872 // mainToolBar -> isMainToolBar = true -> buttonStyle is configurable
873 // others -> isMainToolBar = false -> ### hardcoded default for buttonStyle !!! should be configurable? -> hidden key added
874 d->init(readConfig, (objectName == QLatin1String("mainToolBar")));
875
876 // KToolBar is auto-added to the top area of the main window if parent is a QMainWindow
878 mw->addToolBar(this);
879 }
880}
881
882KToolBar::KToolBar(const QString &objectName, QMainWindow *parent, Qt::ToolBarArea area, bool newLine, bool isMainToolBar, bool readConfig)
884 , d(new KToolBarPrivate(this))
885{
887 d->init(readConfig, isMainToolBar);
888
889 if (newLine) {
891 }
892
893 mainWindow()->addToolBar(area, this);
894
895 if (newLine) {
897 }
898}
899
901{
902 delete d->contextLockAction;
903}
904
906{
907 Q_ASSERT(!cg.name().isEmpty());
908
909 const int currentIconSize = iconSize().width();
910 // qCDebug(DEBUG_KXMLGUI) << objectName() << currentIconSize << d->iconSizeSettings.toString() << "defaultValue=" << d->iconSizeSettings.defaultValue();
911 if (!cg.hasDefault("IconSize") && currentIconSize == d->iconSizeSettings.defaultValue()) {
912 cg.revertToDefault("IconSize");
913 d->iconSizeSettings[Level_UserSettings] = Unset;
914 } else {
915 cg.writeEntry("IconSize", currentIconSize);
916 d->iconSizeSettings[Level_UserSettings] = currentIconSize;
917 }
918
919 const Qt::ToolButtonStyle currentToolButtonStyle = toolButtonStyle();
920 if (!cg.hasDefault("ToolButtonStyle") && currentToolButtonStyle == d->toolButtonStyleSettings.defaultValue()) {
921 cg.revertToDefault("ToolButtonStyle");
922 d->toolButtonStyleSettings[Level_UserSettings] = Unset;
923 } else {
924 cg.writeEntry("ToolButtonStyle", d->toolButtonStyleToString(currentToolButtonStyle));
925 d->toolButtonStyleSettings[Level_UserSettings] = currentToolButtonStyle;
926 }
927}
928
930{
931 d->xmlguiClients << client;
932}
933
935{
936 d->xmlguiClients.remove(client);
937}
938
939void KToolBar::contextMenuEvent(QContextMenuEvent *event)
940{
941 if (mainWindow()) {
942 QPointer<KToolBar> guard(this);
943 const QPoint globalPos = event->globalPos();
944 d->contextMenu(globalPos)->exec(globalPos);
945
946 // "Configure Toolbars" recreates toolbars, so we might not exist anymore.
947 if (guard) {
948 d->slotContextAboutToHide();
949 }
950 return;
951 }
952
954}
955
957{
958 QMainWindow *mw = mainWindow();
959 if (!mw) {
960 return;
961 }
962
963 {
964 const QString &i18nText = KToolbarHelper::i18nToolBarName(element);
965 if (!i18nText.isEmpty()) {
966 setWindowTitle(i18nText);
967 }
968 }
969
970 /*
971 This method is called in order to load toolbar settings from XML.
972 However this can be used in two rather different cases:
973 - for the initial loading of the app's XML. In that case the settings
974 are only the defaults (Level_AppXML), the user's KConfig settings will override them
975
976 - for later re-loading when switching between parts in KXMLGUIFactory.
977 In that case the XML contains the final settings, not the defaults.
978 We do need the defaults, and the toolbar might have been completely
979 deleted and recreated meanwhile. So we store the app-default settings
980 into the XML.
981 */
982 bool loadingAppDefaults = true;
983 if (element.hasAttribute(QStringLiteral("tempXml"))) {
984 // this isn't the first time, so the app-xml defaults have been saved into the (in-memory) XML
985 loadingAppDefaults = false;
986 const QString iconSizeDefault = element.attribute(QStringLiteral("iconSizeDefault"));
987 if (!iconSizeDefault.isEmpty()) {
988 d->iconSizeSettings[Level_AppXML] = iconSizeDefault.toInt();
989 }
990 const QString toolButtonStyleDefault = element.attribute(QStringLiteral("toolButtonStyleDefault"));
991 if (!toolButtonStyleDefault.isEmpty()) {
992 d->toolButtonStyleSettings[Level_AppXML] = d->toolButtonStyleFromString(toolButtonStyleDefault);
993 }
994 } else {
995 // loading app defaults
996 bool newLine = false;
997 QString attrNewLine = element.attribute(QStringLiteral("newline")).toLower();
998 if (!attrNewLine.isEmpty()) {
999 newLine = (attrNewLine == QLatin1String("true"));
1000 }
1001 if (newLine && mw) {
1002 mw->insertToolBarBreak(this);
1003 }
1004 }
1005
1006 int newIconSize = -1;
1007 if (element.hasAttribute(QStringLiteral("iconSize"))) {
1008 bool ok;
1009 newIconSize = element.attribute(QStringLiteral("iconSize")).trimmed().toInt(&ok);
1010 if (!ok) {
1011 newIconSize = -1;
1012 }
1013 }
1014 if (newIconSize != -1) {
1015 d->iconSizeSettings[loadingAppDefaults ? Level_AppXML : Level_UserSettings] = newIconSize;
1016 }
1017
1018 const QString newToolButtonStyle = element.attribute(QStringLiteral("iconText"));
1019 if (!newToolButtonStyle.isEmpty()) {
1020 d->toolButtonStyleSettings[loadingAppDefaults ? Level_AppXML : Level_UserSettings] = d->toolButtonStyleFromString(newToolButtonStyle);
1021 }
1022
1023 bool hidden = false;
1024 {
1025 QString attrHidden = element.attribute(QStringLiteral("hidden")).toLower();
1026 if (!attrHidden.isEmpty()) {
1027 hidden = (attrHidden == QLatin1String("true"));
1028 }
1029 }
1030
1032 {
1033 QString attrPosition = element.attribute(QStringLiteral("position")).toLower();
1034 if (!attrPosition.isEmpty()) {
1035 pos = KToolBarPrivate::positionFromString(attrPosition);
1036 }
1037 }
1038 if (pos != Qt::NoToolBarArea) {
1039 mw->addToolBar(pos, this);
1040 }
1041
1042 setVisible(!hidden);
1043
1044 d->applyCurrentSettings();
1045}
1046
1047// Called when switching between xmlgui clients, in order to find any unsaved settings
1048// again when switching back to the current xmlgui client.
1050{
1051 Q_ASSERT(!current.isNull());
1052
1053 current.setAttribute(QStringLiteral("tempXml"), QStringLiteral("true"));
1054
1055 current.setAttribute(QStringLiteral("noMerge"), QStringLiteral("1"));
1056 current.setAttribute(QStringLiteral("position"), d->getPositionAsString().toLower());
1057 current.setAttribute(QStringLiteral("hidden"), isHidden() ? QStringLiteral("true") : QStringLiteral("false"));
1058
1059 const int currentIconSize = iconSize().width();
1060 if (currentIconSize == d->iconSizeSettings.defaultValue()) {
1061 current.removeAttribute(QStringLiteral("iconSize"));
1062 } else {
1063 current.setAttribute(QStringLiteral("iconSize"), iconSize().width());
1064 }
1065
1066 if (toolButtonStyle() == d->toolButtonStyleSettings.defaultValue()) {
1067 current.removeAttribute(QStringLiteral("iconText"));
1068 } else {
1069 current.setAttribute(QStringLiteral("iconText"), d->toolButtonStyleToString(toolButtonStyle()));
1070 }
1071
1072 // Note: if this method is used by more than KXMLGUIBuilder, e.g. to save XML settings to *disk*,
1073 // then the stuff below shouldn't always be done. This is not the case currently though.
1074 if (d->iconSizeSettings[Level_AppXML] != Unset) {
1075 current.setAttribute(QStringLiteral("iconSizeDefault"), d->iconSizeSettings[Level_AppXML]);
1076 }
1077 if (d->toolButtonStyleSettings[Level_AppXML] != Unset) {
1078 const Qt::ToolButtonStyle bs = static_cast<Qt::ToolButtonStyle>(d->toolButtonStyleSettings[Level_AppXML]);
1079 current.setAttribute(QStringLiteral("toolButtonStyleDefault"), d->toolButtonStyleToString(bs));
1080 }
1081}
1082
1083// called by KMainWindow::applyMainWindowSettings to read from the user settings
1085{
1086 Q_ASSERT(!cg.name().isEmpty());
1087
1088 if (cg.hasKey("IconSize")) {
1089 d->iconSizeSettings[Level_UserSettings] = cg.readEntry("IconSize", 0);
1090 }
1091 if (cg.hasKey("ToolButtonStyle")) {
1092 d->toolButtonStyleSettings[Level_UserSettings] = d->toolButtonStyleFromString(cg.readEntry("ToolButtonStyle", QString()));
1093 }
1094
1095 d->applyCurrentSettings();
1096}
1097
1099{
1100 return qobject_cast<KMainWindow *>(const_cast<QObject *>(parent()));
1101}
1102
1104{
1106 d->iconSizeSettings[Level_UserSettings] = size;
1107}
1108
1113
1114void KToolBar::slotMovableChanged(bool movable)
1115{
1116 if (movable && !KAuthorized::authorize(QStringLiteral("movable_toolbars"))) {
1117 setMovable(false);
1118 }
1119}
1120
1121void KToolBar::dragEnterEvent(QDragEnterEvent *event)
1122{
1123 if (toolBarsEditable() && event->proposedAction() & (Qt::CopyAction | Qt::MoveAction)
1124 && event->mimeData()->hasFormat(QStringLiteral("application/x-kde-action-list"))) {
1125 QByteArray data = event->mimeData()->data(QStringLiteral("application/x-kde-action-list"));
1126
1127 QDataStream stream(data);
1128
1129 QStringList actionNames;
1130
1131 stream >> actionNames;
1132
1133 const auto allCollections = KActionCollection::allCollections();
1134 for (const QString &actionName : std::as_const(actionNames)) {
1135 for (KActionCollection *ac : allCollections) {
1136 QAction *newAction = ac->action(actionName);
1137 if (newAction) {
1138 d->actionsBeingDragged.append(newAction);
1139 break;
1140 }
1141 }
1142 }
1143
1144 if (!d->actionsBeingDragged.isEmpty()) {
1145 QAction *overAction = actionAt(event->position().toPoint());
1146
1147 QFrame *dropIndicatorWidget = new QFrame(this);
1148 dropIndicatorWidget->resize(8, height() - 4);
1149 dropIndicatorWidget->setFrameShape(QFrame::VLine);
1150 dropIndicatorWidget->setLineWidth(3);
1151
1152 d->dropIndicatorAction = insertWidget(overAction, dropIndicatorWidget);
1153
1154 insertAction(overAction, d->dropIndicatorAction);
1155
1156 event->acceptProposedAction();
1157 return;
1158 }
1159 }
1160
1162}
1163
1164void KToolBar::dragMoveEvent(QDragMoveEvent *event)
1165{
1166 if (toolBarsEditable()) {
1167 Q_FOREVER {
1168 if (d->dropIndicatorAction) {
1169 QAction *overAction = nullptr;
1170 const auto actions = this->actions();
1171 for (QAction *action : actions) {
1172 // want to make it feel that half way across an action you're dropping on the other side of it
1173 QWidget *widget = widgetForAction(action);
1174 if (event->position().toPoint().x() < widget->pos().x() + (widget->width() / 2)) {
1175 overAction = action;
1176 break;
1177 }
1178 }
1179
1180 if (overAction != d->dropIndicatorAction) {
1181 // Check to see if the indicator is already in the right spot
1182 int dropIndicatorIndex = actions.indexOf(d->dropIndicatorAction);
1183 if (dropIndicatorIndex + 1 < actions.count()) {
1184 if (actions.at(dropIndicatorIndex + 1) == overAction) {
1185 break;
1186 }
1187 } else if (!overAction) {
1188 break;
1189 }
1190
1191 insertAction(overAction, d->dropIndicatorAction);
1192 }
1193
1194 event->accept();
1195 return;
1196 }
1197 break;
1198 }
1199 }
1200
1202}
1203
1204void KToolBar::dragLeaveEvent(QDragLeaveEvent *event)
1205{
1206 // Want to clear this even if toolBarsEditable was changed mid-drag (unlikely)
1207 delete d->dropIndicatorAction;
1208 d->dropIndicatorAction = nullptr;
1209 d->actionsBeingDragged.clear();
1210
1211 if (toolBarsEditable()) {
1212 event->accept();
1213 return;
1214 }
1215
1217}
1218
1219void KToolBar::dropEvent(QDropEvent *event)
1220{
1221 if (toolBarsEditable()) {
1222 for (QAction *action : std::as_const(d->actionsBeingDragged)) {
1223 if (actions().contains(action)) {
1224 removeAction(action);
1225 }
1226 insertAction(d->dropIndicatorAction, action);
1227 }
1228 }
1229
1230 // Want to clear this even if toolBarsEditable was changed mid-drag (unlikely)
1231 delete d->dropIndicatorAction;
1232 d->dropIndicatorAction = nullptr;
1233 d->actionsBeingDragged.clear();
1234
1235 if (toolBarsEditable()) {
1236 event->accept();
1237 return;
1238 }
1239
1241}
1242
1243void KToolBar::mousePressEvent(QMouseEvent *event)
1244{
1245 if (toolBarsEditable() && event->button() == Qt::LeftButton) {
1246 if (QAction *action = actionAt(event->position().toPoint())) {
1247 d->dragAction = action;
1248 d->dragStartPosition = event->position().toPoint();
1249 event->accept();
1250 return;
1251 }
1252 }
1253
1255}
1256
1257void KToolBar::mouseMoveEvent(QMouseEvent *event)
1258{
1259 if (!toolBarsEditable() || !d->dragAction) {
1261 return;
1262 }
1263
1264 if ((event->position().toPoint() - d->dragStartPosition).manhattanLength() < QApplication::startDragDistance()) {
1265 event->accept();
1266 return;
1267 }
1268
1269 QDrag *drag = new QDrag(this);
1270 QMimeData *mimeData = new QMimeData;
1271
1272 QByteArray data;
1273 {
1274 QDataStream stream(&data, QIODevice::WriteOnly);
1275
1276 QStringList actionNames;
1277 actionNames << d->dragAction->objectName();
1278
1279 stream << actionNames;
1280 }
1281
1282 mimeData->setData(QStringLiteral("application/x-kde-action-list"), data);
1283
1284 drag->setMimeData(mimeData);
1285
1286 Qt::DropAction dropAction = drag->exec(Qt::MoveAction);
1287
1288 if (dropAction == Qt::MoveAction) {
1289 // Only remove from this toolbar if it was moved to another toolbar
1290 // Otherwise the receiver moves it.
1291 if (drag->target() != this) {
1292 removeAction(d->dragAction);
1293 }
1294 }
1295
1296 d->dragAction = nullptr;
1297 event->accept();
1298}
1299
1300void KToolBar::mouseReleaseEvent(QMouseEvent *event)
1301{
1302 // Want to clear this even if toolBarsEditable was changed mid-drag (unlikely)
1303 if (d->dragAction) {
1304 d->dragAction = nullptr;
1305 event->accept();
1306 return;
1307 }
1308
1310}
1311
1313{
1314 // Generate context menu events for disabled buttons too...
1315 if (event->type() == QEvent::MouseButtonPress) {
1316 QMouseEvent *me = static_cast<QMouseEvent *>(event);
1317 if (me->buttons() & Qt::RightButton) {
1318 if (QWidget *ww = qobject_cast<QWidget *>(watched)) {
1319 if (ww->parent() == this && !ww->isEnabled()) {
1322 }
1323 }
1324 }
1325
1326 } else if (event->type() == QEvent::ParentChange) {
1327 // Make sure we're not leaving stale event filters around,
1328 // when a child is reparented somewhere else
1329 if (QWidget *ww = qobject_cast<QWidget *>(watched)) {
1330 if (!this->isAncestorOf(ww)) {
1331 // New parent is not a subwidget - remove event filter
1332 ww->removeEventFilter(this);
1333 const auto children = ww->findChildren<QWidget *>();
1334 for (QWidget *child : children) {
1335 child->removeEventFilter(this);
1336 }
1337 }
1338 }
1339 }
1340
1341 // Redirect mouse events to the toolbar when drag + drop editing is enabled
1342 if (toolBarsEditable()) {
1343 if (QWidget *ww = qobject_cast<QWidget *>(watched)) {
1344 switch (event->type()) {
1346 QMouseEvent *me = static_cast<QMouseEvent *>(event);
1347 QMouseEvent newEvent(me->type(),
1348 mapFromGlobal(ww->mapToGlobal(me->position().toPoint())),
1349 me->globalPosition().toPoint(),
1350 me->button(),
1351 me->buttons(),
1352 me->modifiers());
1353 mousePressEvent(&newEvent);
1354 return true;
1355 }
1356 case QEvent::MouseMove: {
1357 QMouseEvent *me = static_cast<QMouseEvent *>(event);
1358 QMouseEvent newEvent(me->type(),
1359 mapFromGlobal(ww->mapToGlobal(me->position().toPoint())),
1360 me->globalPosition().toPoint(),
1361 me->button(),
1362 me->buttons(),
1363 me->modifiers());
1364 mouseMoveEvent(&newEvent);
1365 return true;
1366 }
1368 QMouseEvent *me = static_cast<QMouseEvent *>(event);
1369 QMouseEvent newEvent(me->type(),
1370 mapFromGlobal(ww->mapToGlobal(me->position().toPoint())),
1371 me->globalPosition().toPoint(),
1372 me->button(),
1373 me->buttons(),
1374 me->modifiers());
1375 mouseReleaseEvent(&newEvent);
1376 return true;
1377 }
1378 default:
1379 break;
1380 }
1381 }
1382 }
1383
1384 return QToolBar::eventFilter(watched, event);
1385}
1386
1387void KToolBar::actionEvent(QActionEvent *event)
1388{
1389 if (event->type() == QEvent::ActionRemoved) {
1390 QWidget *widget = widgetForAction(event->action());
1391 if (widget) {
1392 widget->removeEventFilter(this);
1393
1394 const auto children = widget->findChildren<QWidget *>();
1395 for (QWidget *child : children) {
1396 child->removeEventFilter(this);
1397 }
1398 }
1399 }
1400
1402
1403 if (event->type() == QEvent::ActionAdded) {
1404 QWidget *widget = widgetForAction(event->action());
1405 if (widget) {
1406 widget->installEventFilter(this);
1407
1408 const auto children = widget->findChildren<QWidget *>();
1409 for (QWidget *child : children) {
1410 child->installEventFilter(this);
1411 }
1412 // Center widgets that do not have any use for more space. See bug 165274
1413 if (!(widget->sizePolicy().horizontalPolicy() & QSizePolicy::GrowFlag)
1414 // ... but do not center when using text besides icon in vertical toolbar. See bug 243196
1416 const int index = layout()->indexOf(widget);
1417 if (index != -1) {
1419 }
1420 }
1421 }
1422 }
1423
1424 d->adjustSeparatorVisibility();
1425}
1426
1428{
1429 return KToolBarPrivate::s_editable;
1430}
1431
1433{
1434 if (KToolBarPrivate::s_editable != editable) {
1435 KToolBarPrivate::s_editable = editable;
1436 }
1437}
1438
1440{
1441 if (KToolBarPrivate::s_locked != locked) {
1442 KToolBarPrivate::s_locked = locked;
1443
1444 const auto windows = KMainWindow::memberList();
1445 for (KMainWindow *mw : windows) {
1446 const auto toolbars = mw->findChildren<KToolBar *>();
1447 for (KToolBar *toolbar : toolbars) {
1448 toolbar->d->setLocked(locked);
1449 }
1450 }
1451 }
1452}
1453
1455{
1456 return KToolBarPrivate::s_locked;
1457}
1458
1460{
1461#ifdef WITH_QTDBUS
1462 QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KToolBar"), QStringLiteral("org.kde.KToolBar"), QStringLiteral("styleChanged"));
1464#endif
1465}
1466
1467#include "moc_ktoolbar.cpp"
static const QList< KActionCollection * > & allCollections()
Access the list of all action collections in existence for this app.
QAction * action(int index) const
Return the QAction* at position index in the action collection.
static Q_INVOKABLE bool authorize(const QString &action)
static Q_INVOKABLE bool authorizeAction(const QString &action)
QString name() const
void revertToDefault(const char *key, WriteConfigFlags pFlag=WriteConfigFlags())
bool hasDefault(const char *key) const
bool hasKey(const char *key) const
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
QString readEntry(const char *key, const char *aDefault=nullptr) const
static void setGlobalDefaultToolBar(const QString &toolBarName)
Sets the default toolbar which will be auto-selected for all KEditToolBar instances.
int currentSize(KIconLoader::Group group) const
static KIconLoader * global()
KIconTheme * theme() const
void iconLoaderSettingsChanged()
QList< int > querySizes(KIconLoader::Group group) const
KMainWindow represents a top-level main window.
Definition kmainwindow.h:60
void setSettingsDirty()
Tell the main window that it should save its settings when being closed.
static QList< KMainWindow * > memberList()
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
static void emitToolbarStyleChanged()
Emits a D-Bus signal to tell all toolbars in all applications, that the user settings have changed.
void addXMLGUIClient(KXMLGUIClient *client)
Adds an XML gui client that uses this toolbar.
Definition ktoolbar.cpp:929
static bool toolBarsEditable()
Returns whether the toolbars are currently editable (drag & drop of actions).
static bool toolBarsLocked()
Returns whether the toolbars are locked (i.e., moving of the toobars disallowed).
static void setToolBarsEditable(bool editable)
Enable or disable toolbar editing via drag & drop of actions.
void applySettings(const KConfigGroup &cg)
Read the toolbar settings from group cg and apply them.
KMainWindow * mainWindow() const
Returns the main window that this toolbar is docked with.
void loadState(const QDomElement &element)
Load state from an XML.
Definition ktoolbar.cpp:956
static void setToolBarsLocked(bool locked)
Allows you to lock and unlock all toolbars (i.e., disallow/allow moving of the toobars).
void saveState(QDomElement &element) const
Save state into an XML.
bool eventFilter(QObject *watched, QEvent *event) override
Reimplemented to support context menu activation on disabled tool buttons.
KToolBar(QWidget *parent, bool isMainToolBar=false, bool readConfig=true)
Constructor.
Definition ktoolbar.cpp:855
void removeXMLGUIClient(KXMLGUIClient *client)
Removes an XML gui client that uses this toolbar.
Definition ktoolbar.cpp:934
~KToolBar() override
Destroys the toolbar.
Definition ktoolbar.cpp:900
void setIconDimensions(int size)
Convenience function to set icon size.
void saveSettings(KConfigGroup &cg)
Save the toolbar settings to group cg.
Definition ktoolbar.cpp:905
int iconSizeDefault() const
Returns the default size for this type of toolbar.
A KXMLGUIClient can be used with KXMLGUIFactory to create a GUI from actions and an XML document,...
virtual QString xmlFile() const
This will return the name of the XML file as set by setXMLFile().
virtual QString componentName() const
virtual KActionCollection * actionCollection() const
Retrieves the entire action collection for the GUI client.
static QString readConfigFile(const QString &filename, const QString &componentName=QString())
static bool saveConfigFile(const QDomDocument &doc, const QString &filename, const QString &componentName=QString())
static QDomElement actionPropertiesElement(QDomDocument &doc)
static QDomElement findActionByName(QDomElement &elem, const QString &sName, bool create)
QAction * toolBarMenuAction()
void setupToolbarMenuActions()
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QStringView level(QStringView ifopt)
QString name(StandardAction id)
QList< QObject * > associatedObjects() const const
bool isSeparator() const const
void toggled(bool checked)
void triggered(bool checked)
void setVisible(bool)
void postEvent(QObject *receiver, QEvent *event, int priority)
bool connect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot)
bool send(const QDBusMessage &message) const const
QDBusConnection sessionBus()
QDBusMessage createSignal(const QString &path, const QString &interface, const QString &name)
ParseResult setContent(QAnyStringView text, ParseOptions options)
QString attribute(const QString &name, const QString &defValue) const const
bool hasAttribute(const QString &name) const const
void removeAttribute(const QString &name)
void setAttribute(const QString &name, const QString &value)
bool isNull() const const
Qt::DropAction exec(Qt::DropActions supportedActions)
void setMimeData(QMimeData *data)
QObject * target() const const
MouseButtonPress
Type type() const const
void setFrameShape(Shape)
void setLineWidth(int)
QIcon fromTheme(const QString &name)
Qt::KeyboardModifiers modifiers() const const
virtual int indexOf(const QLayoutItem *layoutItem) const const
virtual QLayoutItem * itemAt(int index) const const=0
void setAlignment(Qt::Alignment alignment)
iterator begin()
qsizetype count() const const
iterator end()
QToolBar * addToolBar(const QString &title)
void addToolBarBreak(Qt::ToolBarArea area)
void insertToolBarBreak(QToolBar *before)
void aboutToShow()
QAction * actionAt(const QPoint &pt) const const
void setData(const QString &mimeType, const QByteArray &data)
QObject(QObject *parent)
const QObjectList & children() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool eventFilter(QObject *watched, QEvent *event)
QList< T > findChildren(Qt::FindChildOptions options) const const
void installEventFilter(QObject *filterObj)
QObject * parent() const const
T qobject_cast(QObject *object)
void removeEventFilter(QObject *obj)
void setObjectName(QAnyStringView name)
QPoint toPoint() const const
Qt::MouseButton button() const const
Qt::MouseButtons buttons() const const
QPointF globalPosition() const const
QPointF position() const const
bool isEmpty() const const
QString number(double n, char format, int precision)
void push_back(QChar ch)
int toInt(bool *ok, int base) const const
QString toLower() const const
QString trimmed() const const
AlignJustify
CopyAction
LeftButton
Vertical
ToolBarArea
ToolButtonStyle
WA_DeleteOnClose
QToolBar(QWidget *parent)
QAction * actionAt(const QPoint &p) const const
virtual void actionEvent(QActionEvent *event) override
void allowedAreasChanged(Qt::ToolBarAreas allowedAreas)
virtual bool event(QEvent *event) override
void iconSizeChanged(const QSize &iconSize)
QAction * insertWidget(QAction *before, QWidget *widget)
void movableChanged(bool movable)
void orientationChanged(Qt::Orientation orientation)
void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle)
QWidget * widgetForAction(QAction *action) const const
QWidget(QWidget *parent, Qt::WindowFlags f)
QList< QAction * > actions() const const
virtual void contextMenuEvent(QContextMenuEvent *event)
virtual void dragEnterEvent(QDragEnterEvent *event)
virtual void dragLeaveEvent(QDragLeaveEvent *event)
virtual void dragMoveEvent(QDragMoveEvent *event)
virtual void dropEvent(QDropEvent *event)
void insertAction(QAction *before, QAction *action)
bool isAncestorOf(const QWidget *child) const const
bool isHidden() const const
QLayout * layout() const const
QPoint mapFromGlobal(const QPoint &pos) const const
virtual void mouseMoveEvent(QMouseEvent *event)
virtual void mousePressEvent(QMouseEvent *event)
virtual void mouseReleaseEvent(QMouseEvent *event)
void removeAction(QAction *action)
virtual void setVisible(bool visible)
void setWindowTitle(const QString &)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri May 2 2025 12:05:44 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.