Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qttoolbardialog.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6#include "ui_qttoolbardialog.h"
7
8#include <QtWidgets/qmainwindow.h>
9#include <QtWidgets/qpushbutton.h>
10#include <QtWidgets/qtoolbar.h>
11
12#include <QtGui/qaction.h>
13#include <QtGui/qevent.h>
14
15#include <QtCore/qmap.h>
16#include <QtCore/qhash.h>
17#include <QtCore/qset.h>
18
19#include <algorithm>
20
21QT_BEGIN_NAMESPACE
22
23using namespace Qt::StringLiterals;
24
26
28{
30public:
33
34 void setMainWindow(QMainWindow *mainWindow);
35 QMainWindow *mainWindow() const;
36
37 void addCategory(const QString &category);
38 bool hasCategory(const QString &category) const;
40 QList<QAction *> categoryActions(const QString &category) const;
41 QString actionCategory(QAction *action) const;
42
43 // only non-separator
44 void addAction(QAction *action, const QString &category);
45
46 void removeAction(QAction *action);
47
48 QSet<QAction *> actions() const;
49 bool isWidgetAction(QAction *action) const;
50
51 /*
52 Adds (registers) toolBar. Adds (registers) actions that already exists in toolBar.
53 Remembers toolbar and its actions as a default.
54 */
55 void addDefaultToolBar(QToolBar *toolBar, const QString &category);
56
57 void removeDefaultToolBar(QToolBar *toolBar);
58 // NULL on action list means separator.
60 bool isDefaultToolBar(QToolBar *toolBar) const;
61
62 QToolBar *createToolBar(const QString &toolBarName);
63 void deleteToolBar(QToolBar *toolBar); // only those which were created, not added
64
65 QList<QAction *> actions(QToolBar *toolBar) const;
66
67 void setToolBars(const QHash<QToolBar *, QList<QAction *>> &actions);
68 void setToolBar(QToolBar *toolBar, const QList<QAction *> &actions);
69
71 QByteArray saveState(int version = 0) const;
72 bool restoreState(const QByteArray &state, int version = 0);
73
74public slots:
75
78
81 void toolBarRemoved(QToolBar *toolBar);
82
83 /*
84 If QToolBarWidgetAction was in another tool bar and is inserted into
85 this toolBar, toolBarChanged is first emitted for other toolbar - without
86 that action. (Another approach may be that user first must call setToolBar
87 without that action for old tool bar)
88 */
89 void toolBarChanged(QToolBar *toolBar, const QList<QAction *> &actions);
90
91private:
92 QScopedPointer<QtFullToolBarManagerPrivate> d_ptr;
95};
96
98{
99 class QtFullToolBarManager *q_ptr;
100 Q_DECLARE_PUBLIC(QtFullToolBarManager)
101
102public:
103
105 void removeWidgetActions(const QHash<QToolBar *, QList<QAction *>> &actions);
106
107 enum {
111 };
112
113 void saveState(QDataStream &stream) const;
114 bool restoreState(QDataStream &stream) const;
115 QToolBar *findDefaultToolBar(const QString &objectName) const;
116 QAction *findAction(const QString &actionName) const;
117
118 QToolBar *toolBarByName(const QString &toolBarName) const;
119
122
127
132
133 QMainWindow *theMainWindow{nullptr};
134};
135
136QToolBar *QtFullToolBarManagerPrivate::toolBarWidgetAction(QAction *action) const
137{
138 return widgetActions.value(action, nullptr);
139}
140
141void QtFullToolBarManagerPrivate::removeWidgetActions(const QHash<QToolBar *, QList<QAction *>>
142 &actions)
143{
144 auto itToolBar = actions.constBegin();
145 while (itToolBar != actions.constEnd()) {
146 QToolBar *toolBar = itToolBar.key();
147 auto newActions = toolBars.value(toolBar);
148 auto newActionsWithSeparators = toolBarsWithSeparators.value(toolBar);
149
150 QList<QAction *> removedActions;
151 const auto actionList = itToolBar.value();
152 for (QAction *action : actionList) {
153 if (newActions.contains(action) && toolBarWidgetAction(action) == toolBar) {
154 newActions.removeAll(action);
155 newActionsWithSeparators.removeAll(action);
156 removedActions.append(action);
157 }
158 }
159
160 //emit q_ptr->toolBarChanged(toolBar, newActions);
161
162 toolBars.insert(toolBar, newActions);
163 toolBarsWithSeparators.insert(toolBar, newActionsWithSeparators);
164 for (QAction *oldAction : std::as_const(removedActions)) {
165 widgetActions.insert(oldAction, 0);
166 actionToToolBars[oldAction].removeAll(toolBar);
167 }
168
169 ++itToolBar;
170 }
171}
172
173void QtFullToolBarManagerPrivate::saveState(QDataStream &stream) const
174{
175 stream << (uchar) ToolBarMarker;
176 stream << defaultToolBars.size();
177 auto itToolBar = defaultToolBars.constBegin();
178 while (itToolBar != defaultToolBars.constEnd()) {
179 QToolBar *tb = itToolBar.key();
180 if (tb->objectName().isEmpty()) {
181 qWarning("QtToolBarManager::saveState(): 'objectName' not set for QToolBar "
182 "%p '%s', using 'windowTitle' instead",
183 tb, tb->windowTitle().toLocal8Bit().constData());
184 stream << tb->windowTitle();
185 } else {
186 stream << tb->objectName();
187 }
188
189 const auto actions = toolBars.value(tb);
190 stream << actions.size();
191 for (QAction *action : actions) {
192 if (action) {
193 if (action->objectName().isEmpty()) {
194 qWarning("QtToolBarManager::saveState(): 'objectName' not set for QAction "
195 "%p '%s', using 'text' instead",
196 action, action->text().toLocal8Bit().constData());
197 stream << action->text();
198 } else {
199 stream << action->objectName();
200 }
201 } else {
202 stream << QString();
203 }
204 }
205 ++itToolBar;
206 }
207
208
209 stream << (uchar) CustomToolBarMarker;
210 stream << toolBars.size() - defaultToolBars.size();
211 itToolBar = toolBars.constBegin();
212 while (itToolBar != toolBars.constEnd()) {
213 QToolBar *tb = itToolBar.key();
214 if (!defaultToolBars.contains(tb)) {
215 stream << tb->objectName();
216 stream << tb->windowTitle();
217
218 stream << toolBars[tb].size();
219
220 const auto actions = toolBars.value(tb);
221 for (QAction *action : actions) {
222 if (action) {
223 if (action->objectName().isEmpty()) {
224 qWarning("QtToolBarManager::saveState(): 'objectName' not set for QAction "
225 "%p '%s', using 'text' instead",
226 action, action->text().toLocal8Bit().constData());
227 stream << action->text();
228 } else {
229 stream << action->objectName();
230 }
231 } else {
232 stream << QString();
233 }
234 }
235 }
236 ++itToolBar;
237 }
238}
239
240bool QtFullToolBarManagerPrivate::restoreState(QDataStream &stream) const
241{
242 uchar tmarker = 0;
243 stream >> tmarker;
244 if (tmarker != ToolBarMarker)
245 return false;
246
247 int toolBars = 0;
248 stream >> toolBars;
249 for (int i = 0; i < toolBars; i++) {
250 QString objectName;
251 stream >> objectName;
252 int actionCount = 0;
253 stream >> actionCount;
254 QList<QAction *> actions;
255 for (int j = 0; j < actionCount; j++) {
256 QString actionName;
257 stream >> actionName;
258
259 if (actionName.isEmpty())
260 actions.append(nullptr);
261 else {
262 QAction *action = findAction(actionName);
263 if (action)
264 actions.append(action);
265 }
266 }
267
268 QToolBar *toolBar = findDefaultToolBar(objectName);
269 if (toolBar)
270 q_ptr->setToolBar(toolBar, actions);
271 }
272
273
274
275 uchar ctmarker = 0;
276 stream >> ctmarker;
277 if (ctmarker != CustomToolBarMarker)
278 return false;
279
280 auto oldCustomToolBars = customToolBars;
281
282 stream >> toolBars;
283 for (int i = 0; i < toolBars; i++) {
284 QString objectName;
285 QString toolBarName;
286 int actionCount = 0;
287 stream >> objectName;
288 stream >> toolBarName;
289 stream >> actionCount;
290 QList<QAction *> actions;
291 for (int j = 0; j < actionCount; j++) {
292 QString actionName;
293 stream >> actionName;
294
295 if (actionName.isEmpty())
296 actions.append(nullptr);
297 else {
298 QAction *action = findAction(actionName);
299 if (action)
300 actions.append(action);
301 }
302 }
303
304 QToolBar *toolBar = toolBarByName(objectName);
305 if (toolBar) {
306 toolBar->setWindowTitle(toolBarName);
307 oldCustomToolBars.removeAll(toolBar);
308 }
309 else
310 toolBar = q_ptr->createToolBar(toolBarName);
311 if (toolBar) {
312 toolBar->setObjectName(objectName);
313 q_ptr->setToolBar(toolBar, actions);
314 }
315 }
316 for (QToolBar *toolBar : std::as_const(oldCustomToolBars))
317 q_ptr->deleteToolBar(toolBar);
318 return true;
319}
320
321QToolBar *QtFullToolBarManagerPrivate::findDefaultToolBar(const QString &objectName) const
322{
323 auto itToolBar = defaultToolBars.constBegin();
324 while (itToolBar != defaultToolBars.constEnd()) {
325 QToolBar *tb = itToolBar.key();
326 if (tb->objectName() == objectName)
327 return tb;
328
329 ++itToolBar;
330 }
331
332 qWarning("QtToolBarManager::restoreState(): cannot find a QToolBar named "
333 "'%s', trying to match using 'windowTitle' instead.",
334 objectName.toLocal8Bit().constData());
335
336 itToolBar = defaultToolBars.constBegin();
337 while (itToolBar != defaultToolBars.constEnd()) {
338 QToolBar *tb = itToolBar.key();
339 if (tb->windowTitle() == objectName)
340 return tb;
341
342 ++itToolBar;
343 }
344 qWarning("QtToolBarManager::restoreState(): cannot find a QToolBar with "
345 "matching 'windowTitle' (looking for '%s').",
346 objectName.toLocal8Bit().constData());
347
348 return nullptr;
349}
350
351QAction *QtFullToolBarManagerPrivate::findAction(const QString &actionName) const
352{
353 auto it =
354 std::find_if(allActions.cbegin(), allActions.cend(),
355 [&actionName] (const QAction *a) { return a->objectName() == actionName; });
356 if (it != allActions.cend())
357 return *it;
358 qWarning("QtToolBarManager::restoreState(): cannot find a QAction named "
359 "'%s', trying to match using 'text' instead.",
360 actionName.toLocal8Bit().constData());
361
362 it = std::find_if(allActions.cbegin(), allActions.cend(),
363 [&actionName] (const QAction *a) { return a->text() == actionName; });
364 if (it != allActions.cend())
365 return *it;
366 qWarning("QtToolBarManager::restoreState(): cannot find a QAction with "
367 "matching 'text' (looking for '%s').",
368 actionName.toLocal8Bit().constData());
369
370 return nullptr;
371}
372
373QToolBar *QtFullToolBarManagerPrivate::toolBarByName(const QString &toolBarName) const
374{
375 auto itToolBar = toolBars.constBegin();
376 while (itToolBar != toolBars.constEnd()) {
377 QToolBar *toolBar = itToolBar.key();
378 if (toolBar->objectName() == toolBarName)
379 return toolBar;
380
381 ++itToolBar;
382 }
383 return nullptr;
384}
385
386//////////////////////////////
387
388QtFullToolBarManager::QtFullToolBarManager(QObject *parent)
389 : QObject(parent), d_ptr(new QtFullToolBarManagerPrivate)
390{
391 d_ptr->q_ptr = this;
392}
393
395
396void QtFullToolBarManager::setMainWindow(QMainWindow *mainWindow)
397{
398 d_ptr->theMainWindow = mainWindow;
399}
400
401QMainWindow *QtFullToolBarManager::mainWindow() const
402{
403 return d_ptr->theMainWindow;
404}
405
406void QtFullToolBarManager::addCategory(const QString &category)
407{
408 d_ptr->categoryToActions[category] = QList<QAction *>();
409}
410
411bool QtFullToolBarManager::hasCategory(const QString &category) const
412{
413 return d_ptr->categoryToActions.contains(category);
414}
415
417{
418 return d_ptr->categoryToActions.keys();
419}
420
421QList<QAction *> QtFullToolBarManager::categoryActions(const QString &category) const
422{
423 const auto it = d_ptr->categoryToActions.constFind(category);
424 if (it != d_ptr->categoryToActions.constEnd())
425 return it.value();
426 return {};
427}
428
430{
431 return d_ptr->actionToCategory.value(action, {});
432}
433
434void QtFullToolBarManager::addAction(QAction *action, const QString &category)
435{
436 if (!action)
437 return;
438 if (action->isSeparator())
439 return;
440 if (d_ptr->allActions.contains(action))
441 return;
442 if (qstrcmp(action->metaObject()->className(), "QToolBarWidgetAction") == 0)
443 d_ptr->widgetActions.insert(action, 0);
444 else
445 d_ptr->regularActions.insert(action);
446 d_ptr->allActions.insert(action);
447 d_ptr->categoryToActions[category].append(action);
448 d_ptr->actionToCategory[action] = category;
449}
450
451void QtFullToolBarManager::removeAction(QAction *action)
452{
453 if (!d_ptr->allActions.contains(action))
454 return;
455
456 const auto toolBars = d_ptr->actionToToolBars[action];
457 for (QToolBar *toolBar : toolBars) {
458 d_ptr->toolBars[toolBar].removeAll(action);
459 d_ptr->toolBarsWithSeparators[toolBar].removeAll(action);
460
461 toolBar->removeAction(action);
462 }
463
464 auto itDefault = d_ptr->defaultToolBars.constBegin();
465 while (itDefault != d_ptr->defaultToolBars.constEnd()) {
466 if (itDefault.value().contains(action))
467 d_ptr->defaultToolBars[itDefault.key()].removeAll(action);
468
469 itDefault++;
470 }
471
472 d_ptr->allActions.remove(action);
473 d_ptr->widgetActions.remove(action);
474 d_ptr->regularActions.remove(action);
475 d_ptr->actionToToolBars.remove(action);
476
477 QString category = d_ptr->actionToCategory.value(action);
478 d_ptr->actionToCategory.remove(action);
479 d_ptr->categoryToActions[category].removeAll(action);
480
481 if (d_ptr->categoryToActions[category].isEmpty())
482 d_ptr->categoryToActions.remove(category);
483}
484
486{
487 return d_ptr->allActions;
488}
489
490bool QtFullToolBarManager::isWidgetAction(QAction *action) const
491{
492 return d_ptr->widgetActions.contains(action);
493}
494
495void QtFullToolBarManager::addDefaultToolBar(QToolBar *toolBar, const QString &category)
496{
497 if (!toolBar)
498 return;
499 if (d_ptr->toolBars.contains(toolBar))
500 return;
501 // could be also checked if toolBar belongs to mainwindow
502
503 QList<QAction *> newActionsWithSeparators;
504 QList<QAction *> newActions;
505 const auto actions = toolBar->actions();
506 for (QAction *action : actions) {
507 addAction(action, category);
508 if (d_ptr->widgetActions.contains(action))
509 d_ptr->widgetActions.insert(action, toolBar);
510 newActionsWithSeparators.append(action);
511 if (action->isSeparator())
512 action = nullptr;
513 else
514 d_ptr->actionToToolBars[action].append(toolBar);
515 newActions.append(action);
516 }
517 d_ptr->defaultToolBars.insert(toolBar, newActions);
518 //Below could be done by call setToolBar() if we want signal emission here.
519 d_ptr->toolBars.insert(toolBar, newActions);
520 d_ptr->toolBarsWithSeparators.insert(toolBar, newActionsWithSeparators);
521}
522
524{
525 if (!d_ptr->defaultToolBars.contains(toolBar))
526 return;
527
528 const auto defaultActions = d_ptr->defaultToolBars[toolBar];
529 setToolBar(toolBar, QList<QAction *>());
530 for (QAction *action : defaultActions)
531 removeAction(action);
532
533 d_ptr->toolBars.remove(toolBar);
534 d_ptr->toolBarsWithSeparators.remove(toolBar);
535 d_ptr->defaultToolBars.remove(toolBar);
536
537 for (QAction *action : defaultActions) {
538 if (action)
539 toolBar->insertAction(nullptr, action);
540 else
541 toolBar->insertSeparator(nullptr);
542 }
543}
544
546{
547 return d_ptr->defaultToolBars;
548}
549
550bool QtFullToolBarManager::isDefaultToolBar(QToolBar *toolBar) const
551{
552 if (d_ptr->defaultToolBars.contains(toolBar))
553 return true;
554 return false;
555}
556
557QToolBar *QtFullToolBarManager::createToolBar(const QString &toolBarName)
558{
559 if (!mainWindow())
560 return nullptr;
561 auto *toolBar = new QToolBar(toolBarName, mainWindow());
562 int i = 1;
563 const QString prefix = "_Custom_Toolbar_%1"_L1;
564 QString name = prefix.arg(i);
565 while (d_ptr->toolBarByName(name))
566 name = prefix.arg(++i);
567 toolBar->setObjectName(name);
568 mainWindow()->addToolBar(toolBar);
569 d_ptr->customToolBars.append(toolBar);
570 d_ptr->toolBars.insert(toolBar, QList<QAction *>());
571 d_ptr->toolBarsWithSeparators.insert(toolBar, QList<QAction *>());
572 return toolBar;
573}
574
575void QtFullToolBarManager::deleteToolBar(QToolBar *toolBar)
576{
577 if (!d_ptr->toolBars.contains(toolBar))
578 return;
579 if (d_ptr->defaultToolBars.contains(toolBar))
580 return;
581 setToolBar(toolBar, QList<QAction *>());
582 d_ptr->customToolBars.removeAll(toolBar);
583 d_ptr->toolBars.remove(toolBar);
584 d_ptr->toolBarsWithSeparators.remove(toolBar);
585 delete toolBar;
586}
587
588QList<QAction *> QtFullToolBarManager::actions(QToolBar *toolBar) const
589{
590 if (d_ptr->toolBars.contains(toolBar))
591 return d_ptr->toolBars.value(toolBar);
592 return {};
593}
594
595void QtFullToolBarManager::setToolBars(const QHash<QToolBar *, QList<QAction *>> &actions)
596{
597 auto it = actions.constBegin();
598 while (it != actions.constEnd()) {
599 setToolBar(it.key(), it.value());
600 ++it;
601 }
602}
603
604void QtFullToolBarManager::setToolBar(QToolBar *toolBar, const QList<QAction *> &actions)
605{
606 if (!toolBar)
607 return;
608 if (!d_ptr->toolBars.contains(toolBar))
609 return;
610
611 if (actions == d_ptr->toolBars[toolBar])
612 return;
613
614 QHash<QToolBar *, QList<QAction *>> toRemove;
615
616 QList<QAction *> newActions;
617 for (QAction *action : actions) {
618 if (!action || (!newActions.contains(action) && d_ptr->allActions.contains(action)))
619 newActions.append(action);
620
621 QToolBar *oldToolBar = d_ptr->toolBarWidgetAction(action);
622 if (oldToolBar && oldToolBar != toolBar)
623 toRemove[oldToolBar].append(action);
624 }
625
626 d_ptr->removeWidgetActions(toRemove);
627
628 const auto oldActions = d_ptr->toolBarsWithSeparators.value(toolBar);
629 for (QAction *action : oldActions) {
630 /*
631 When addDefaultToolBar() separator actions could be checked if they are
632 inserted in other toolbars - if yes then create new one.
633 */
634 if (d_ptr->toolBarWidgetAction(action) == toolBar)
635 d_ptr->widgetActions.insert(action, 0);
636 toolBar->removeAction(action);
637 if (action->isSeparator())
638 delete action;
639 else
640 d_ptr->actionToToolBars[action].removeAll(toolBar);
641 }
642
643 QList<QAction *> newActionsWithSeparators;
644 for (QAction *action : std::as_const(newActions)) {
645 QAction *newAction = nullptr;
646 if (!action)
647 newAction = toolBar->insertSeparator(nullptr);
648 if (d_ptr->allActions.contains(action)) {
649 toolBar->insertAction(nullptr, action);
650 newAction = action;
651 d_ptr->actionToToolBars[action].append(toolBar);
652 }
653 newActionsWithSeparators.append(newAction);
654 }
655 d_ptr->toolBars.insert(toolBar, newActions);
656 d_ptr->toolBarsWithSeparators.insert(toolBar, newActionsWithSeparators);
657}
658
660{
661 return d_ptr->toolBars;
662}
663
664void QtFullToolBarManager::resetToolBar(QToolBar *toolBar)
665{
666 if (!isDefaultToolBar(toolBar))
667 return;
668 setToolBar(toolBar, defaultToolBars().value(toolBar));
669}
670
672{
673 setToolBars(defaultToolBars());
674 const auto oldCustomToolBars = d_ptr->customToolBars;
675 for (QToolBar *tb : oldCustomToolBars)
676 deleteToolBar(tb);
677}
678
680{
681 QByteArray data;
682 QDataStream stream(&data, QIODevice::WriteOnly);
684 stream << version;
685 d_ptr->saveState(stream);
686 return data;
687}
688
689bool QtFullToolBarManager::restoreState(const QByteArray &state, int version)
690{
691 QByteArray sd = state;
692 QDataStream stream(&sd, QIODevice::ReadOnly);
693 int marker = 0, v = 0;
694 stream >> marker;
695 stream >> v;
696 if (marker != QtFullToolBarManagerPrivate::VersionMarker || v != version)
697 return false;
698 return d_ptr->restoreState(stream);
699}
700
701
703{
704 class QtToolBarManager *q_ptr;
705 Q_DECLARE_PUBLIC(QtToolBarManager)
706public:
708};
709
710//////////////////////////////////////
711
712/*! \class QtToolBarManager
713 \internal
714 \inmodule QtDesigner
715 \since 4.4
716
717 \brief The QtToolBarManager class provides toolbar management for
718 main windows.
719
720 The QtToolBarManager is typically used with a QtToolBarDialog
721 which allows the user to customize the toolbars for a given main
722 window. The QtToolBarDialog class's functionality is controlled by
723 an instance of the QtToolBarManager class, and the main window is
724 specified using the QtToolBarManager class's setMainWindow()
725 function.
726
727 The currently specified main window can be retrieved using the
728 mainWindow() function.
729
730 The toolbar manager holds lists of the given main window's actions
731 and toolbars, and can add actions and toolbars to these
732 lists using the addAction() and addToolBar() functions
733 respectively. The actions can in addition be categorized
734 acccording to the user's preferences. The toolbar manager can also
735 remove custom actions and toolbars using the removeAction() and
736 removeToolBar() functions.
737
738 Finally, the QtToolBarManager is able to save the customized state
739 of its toolbars using the saveState() function as well as restore
740 the toolbars' saved state using restoreState() function.
741
742 \sa QtToolBarDialog
743*/
744
745/*!
746 Creates a toolbar manager with the given \a parent.
747*/
748QtToolBarManager::QtToolBarManager(QObject *parent)
749 : QObject(parent), d_ptr(new QtToolBarManagerPrivate)
750{
751 d_ptr->q_ptr = this;
752
753 d_ptr->manager = new QtFullToolBarManager(this);
754}
755
756/*!
757 Destroys the toolbar manager.
758*/
760
761/*!
762 Sets the main window upon which the toolbar manager operates, to
763 be the given \a mainWindow.
764*/
765void QtToolBarManager::setMainWindow(QMainWindow *mainWindow)
766{
767 d_ptr->manager->setMainWindow(mainWindow);
768}
769
770/*!
771 Returns the main window associated this toolbar manager.
772*/
773QMainWindow *QtToolBarManager::mainWindow() const
774{
775 return d_ptr->manager->mainWindow();
776}
777
778/*!
779 Adds the given \a action to the given \a category in the manager's
780 list of actions. If the \a category doesn't exist it is created.
781 Only non separator actions can be added. If the action is already
782 added to the list, the function doesn't do anything.
783
784 \sa removeAction()
785*/
786void QtToolBarManager::addAction(QAction *action, const QString &category)
787{
788 d_ptr->manager->addAction(action, category);
789}
790
791/*!
792 Removes the specified \a action from the manager's list of
793 actions. The action is also removed from all the registered
794 toolbars. If the specified \a action is the only action in its
795 category, that category is removed as well.
796
797 \sa addAction()
798*/
799void QtToolBarManager::removeAction(QAction *action)
800{
801 d_ptr->manager->removeAction(action);
802}
803
804/*!
805 Adds the given \a toolBar to the manager's toolbar list.
806
807 All the \a toolBar's actions are automatically added to the given
808 \a category in the manager's list of actions if they're not
809 already there. The manager remembers which toolbar the actions
810 belonged to, so, when the \a toolBar is removed, its actions will
811 be removed as well.
812
813 Custom toolbars are created with the main window returned by
814 the mainWindow() function, as its parent.
815
816 \sa removeToolBar()
817*/
818void QtToolBarManager::addToolBar(QToolBar *toolBar, const QString &category)
819{
820 d_ptr->manager->addDefaultToolBar(toolBar, category);
821}
822
823/*!
824 Removes the specified \a toolBar from the manager's list. All the
825 actions that existed in the specified \a toolBar when it was
826 added are removed as well.
827
828 \sa addToolBar()
829*/
830void QtToolBarManager::removeToolBar(QToolBar *toolBar)
831{
832 d_ptr->manager->removeDefaultToolBar(toolBar);
833}
834
835/*!
836 Returns the manager's toolbar list.
837*/
839{
840 return d_ptr->manager->toolBarsActions().keys();
841}
842
843/*
844void QtToolBarManager::resetToolBar(QToolBar *toolBar)
845{
846 d_ptr->manager->resetToolBar(toolBar);
847}
848
849void QtToolBarManager::resetAllToolBars()
850{
851 d_ptr->manager->resetAllToolBars();
852}
853*/
854
855/*!
856 Saves the state of the toolbar manager's toolbars. The \a version
857 number is stored as part of the data.
858
859 Identifies all the QToolBar and QAction objects by their object
860 name property. Ensure that this property is unique for each
861 QToolBar and QAction that you add using the QtToolBarManager.
862
863 Returns an identifier for the state which can be passed along with
864 the version number to the restoreState() function to restore the
865 saved state.
866
867 \sa restoreState()
868*/
870{
871 return d_ptr->manager->saveState(version);
872}
873
874/*!
875 Restores the saved state of the toolbar manager's toolbars. The
876 \a version number is compared with the version number of the
877 stored \a state.
878
879 Returns true if the version numbers are matching and the toolbar
880 manager's state is restored; otherwise the toolbar manager's state
881 is left unchanged and the function returns false.
882
883 Note that the state of the toolbar manager's toolbars should be
884 restored before restoring the state of the main window's toolbars
885 and dockwidgets using the QMainWindow::restoreState() function. In
886 that way the restoreState() function can create the custom
887 toolbars before the QMainWindow::restoreState() function restores
888 the custom toolbars' positions.
889
890 \sa saveState()
891*/
892bool QtToolBarManager::restoreState(const QByteArray &state, int version)
893{
894 return d_ptr->manager->restoreState(state, version);
895}
896
897//////////////////////
898
900public:
901 ToolBarItem() : tb(nullptr) {}
902 ToolBarItem(QToolBar *toolBar) : tb(toolBar) {}
903 ToolBarItem(QToolBar *toolBar, const QString &toolBarName)
904 : tb(toolBar), tbName(toolBarName) {}
905 ToolBarItem(const QString &toolBarName) : tb(nullptr), tbName(toolBarName) {}
906 QToolBar *toolBar() const
907 { return tb; }
908 void setToolBar(QToolBar *toolBar)
909 { tb = toolBar; }
911 { return tbName; }
912 void setToolBarName(const QString &toolBarName)
913 { tbName = toolBarName; }
914private:
915 QToolBar *tb;
916 QString tbName;
917};
918
920 QtToolBarDialog *q_ptr = nullptr;
921 Q_DECLARE_PUBLIC(QtToolBarDialog)
922public:
924 ToolBarItem *createItem(const QString &toolBarName);
926
930 void okClicked();
933 void upClicked();
938 void toolBarRenamed(QListWidgetItem *item);
939 void currentActionChanged(QTreeWidgetItem *current);
940 void currentToolBarChanged(QListWidgetItem *current);
941 void currentToolBarActionChanged(QListWidgetItem *current);
942
944 bool isDefaultToolBar(ToolBarItem *item) const;
946 void clearOld();
947 void fillNew();
953
955
956 // static
960
961 // dynamic
965
966 // dynamic
969
972
975};
976
977ToolBarItem *QtToolBarDialogPrivate::createItem(QToolBar *toolBar)
978{
979 if (!toolBar)
980 return nullptr;
981 auto *item = new ToolBarItem(toolBar, toolBar->windowTitle());
982 allToolBarItems.insert(item);
983 return item;
984}
985
986ToolBarItem *QtToolBarDialogPrivate::createItem(const QString &toolBarName)
987{
988 auto *item = new ToolBarItem(toolBarName);
989 allToolBarItems.insert(item);
990 return item;
991}
992
994{
995 if (!allToolBarItems.contains(item))
996 return;
997 allToolBarItems.remove(item);
998 delete item;
999}
1000
1002{
1003 ui.actionTree->clear();
1004 ui.toolBarList->clear();
1005 ui.currentToolBarList->clear();
1006 ui.removeButton->setEnabled(false);
1007 ui.newButton->setEnabled(false);
1008 ui.upButton->setEnabled(false);
1009 ui.downButton->setEnabled(false);
1010 ui.leftButton->setEnabled(false);
1011 ui.rightButton->setEnabled(false);
1012
1013 actionToItem.clear();
1014 itemToAction.clear();
1015 toolBarToItem.clear();
1016 itemToToolBar.clear();
1017 actionToCurrentItem.clear();
1018 currentItemToAction.clear();
1019 widgetActionToToolBar.clear();
1020 toolBarToWidgetActions.clear();
1021
1022 toolBarItems.clear();
1023 currentState.clear();
1024 createdItems.clear();
1025 removedItems.clear();
1026 qDeleteAll(allToolBarItems);
1027 allToolBarItems.clear();
1028
1029 currentToolBar = nullptr;
1030 currentAction = nullptr;
1031}
1032
1034{
1035 if (!toolBarManager)
1036 return;
1037
1038 auto *item = new QTreeWidgetItem(ui.actionTree);
1039 item->setText(0, separatorText);
1040 ui.actionTree->setCurrentItem(item);
1041 currentAction = item;
1042 actionToItem.insert(0, item);
1043 itemToAction.insert(item, 0);
1044 const QStringList categories = toolBarManager->categories();
1045 for (const QString &category : categories) {
1046 auto *categoryItem = new QTreeWidgetItem(ui.actionTree);
1047 categoryItem->setText(0, category);
1048 const auto actions = toolBarManager->categoryActions(category);
1049 for (QAction *action : actions) {
1050 item = new QTreeWidgetItem(categoryItem);
1051 item->setText(0, action->text());
1052 item->setIcon(0, action->icon());
1053 item->setTextAlignment(0, Qt::Alignment(Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic));
1054 actionToItem.insert(action, item);
1055 itemToAction.insert(item, action);
1056 if (toolBarManager->isWidgetAction(action)) {
1057 item->setData(0, Qt::ForegroundRole, QColor(Qt::blue));
1058 widgetActionToToolBar.insert(action, 0);
1059 }
1060 item->setFlags(item->flags() | Qt::ItemIsDragEnabled);
1061 }
1062 categoryItem->setExpanded(true);
1063 }
1064 //ui.actionTree->sortItems(0, Qt::AscendingOrder);
1065
1066 const auto toolBars = toolBarManager->toolBarsActions();
1067 auto it = toolBars.constBegin();
1068 while (it != toolBars.constEnd()) {
1069 QToolBar *toolBar = it.key();
1070 ToolBarItem *tbItem = createItem(toolBar);
1071 toolBarItems.insert(toolBar, tbItem);
1072 auto *item = new QListWidgetItem(toolBar->windowTitle(), ui.toolBarList);
1073 toolBarToItem.insert(tbItem, item);
1074 itemToToolBar.insert(item, tbItem);
1075 const auto actions = it.value();
1076 for (QAction *action : actions) {
1077 if (toolBarManager->isWidgetAction(action)) {
1078 widgetActionToToolBar.insert(action, tbItem);
1079 toolBarToWidgetActions[tbItem].insert(action);
1080 }
1081 }
1082 currentState.insert(tbItem, actions);
1083 if (it == toolBars.constBegin())
1084 ui.toolBarList->setCurrentItem(item);
1085 if (isDefaultToolBar(tbItem))
1086 item->setData(Qt::ForegroundRole, QColor(Qt::darkGreen));
1087 else
1088 item->setFlags(item->flags() | Qt::ItemIsEditable);
1089
1090 ++it;
1091 }
1092 ui.toolBarList->sortItems();
1094}
1095
1097{
1098 if (!item)
1099 return false;
1100 if (!item->toolBar())
1101 return false;
1103}
1104
1106{
1107 bool newEnabled = false;
1108 bool removeEnabled = false;
1109 bool renameEnabled = false;
1110 bool upEnabled = false;
1111 bool downEnabled = false;
1112 bool leftEnabled = false;
1113 bool rightEnabled = false;
1114
1115 if (toolBarManager) {
1116 newEnabled = true;
1117 removeEnabled = !isDefaultToolBar(currentToolBar);
1118 renameEnabled = removeEnabled;
1119 QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
1120 if (currentToolBarAction) {
1121 int row = ui.currentToolBarList->row(currentToolBarAction);
1122 upEnabled = row > 0;
1123 downEnabled = row < ui.currentToolBarList->count() - 1;
1124 leftEnabled = true;
1125 }
1126 if (currentAction && currentToolBar)
1127 rightEnabled = true;
1128 }
1129 ui.newButton->setEnabled(newEnabled);
1130 ui.removeButton->setEnabled(removeEnabled);
1131 ui.renameButton->setEnabled(renameEnabled);
1132 ui.upButton->setEnabled(upEnabled);
1133 ui.downButton->setEnabled(downEnabled);
1134 ui.leftButton->setEnabled(leftEnabled);
1135 ui.rightButton->setEnabled(rightEnabled);
1136}
1137
1139{
1140 QString toolBarName = QtToolBarDialog::tr("Custom Toolbar"); // = QInputDialog::getString();
1141 // produce unique name
1142 ToolBarItem *item = createItem(toolBarName);
1143 currentState.insert(item, QList<QAction *>());
1144 createdItems.insert(item);
1145 auto *i = new QListWidgetItem(toolBarName, ui.toolBarList);
1146 i->setFlags(i->flags() | Qt::ItemIsEditable);
1147 ui.toolBarList->setCurrentItem(i);
1148 itemToToolBar.insert(i, item);
1149 toolBarToItem.insert(item, i);
1150 ui.toolBarList->sortItems();
1151 ui.toolBarList->setCurrentItem(i);
1152 currentToolBarChanged(i);
1154}
1155
1157{
1158 if (!item)
1159 return;
1161 return;
1162 if (!toolBarToItem.contains(item))
1163 return;
1164 QListWidgetItem *i = toolBarToItem.value(item);
1165 bool wasCurrent = false;
1166 if (i == ui.toolBarList->currentItem())
1167 wasCurrent = true;
1168 int row = ui.toolBarList->row(i);
1169 const auto itToolBar = toolBarToWidgetActions.find(item);
1170 if (itToolBar != toolBarToWidgetActions.end()) {
1171 for (QAction *action : std::as_const(itToolBar.value()))
1172 widgetActionToToolBar.insert(action, 0);
1173 toolBarToWidgetActions.erase(itToolBar);
1174 }
1175
1176 currentState.remove(item);
1177 createdItems.remove(item);
1178 toolBarToItem.remove(item);
1179 itemToToolBar.remove(i);
1180 delete i;
1181 if (item->toolBar())
1182 removedItems.insert(item);
1183 else
1184 deleteItem(item);
1185 if (wasCurrent) {
1186 if (row == ui.toolBarList->count())
1187 row--;
1188 if (row < 0)
1189 ;
1190 else
1191 ui.toolBarList->setCurrentRow(row);
1192 }
1194}
1195
1197{
1198 QListWidgetItem *i = ui.toolBarList->currentItem();
1199 if (!i)
1200 return;
1201 ToolBarItem *item = itemToToolBar.value(i);
1202 removeToolBar(item);
1203}
1204
1206{
1207 const auto defaultToolBars = toolBarManager->defaultToolBars();
1208 auto itToolBar = defaultToolBars.constBegin();
1209 while (itToolBar != defaultToolBars.constEnd()) {
1210 QToolBar *toolBar = itToolBar.key();
1211 ToolBarItem *toolBarItem = toolBarItems.value(toolBar);
1212
1213 const auto tbwit = toolBarToWidgetActions.find(toolBarItem);
1214 if (tbwit != toolBarToWidgetActions.end()) {
1215 for (QAction *action : std::as_const(tbwit.value()))
1216 widgetActionToToolBar.insert(action, 0);
1217 toolBarToWidgetActions.erase(tbwit);
1218 }
1219
1220 currentState.remove(toolBarItem);
1221
1222 for (QAction *action : itToolBar.value()) {
1223 if (toolBarManager->isWidgetAction(action)) {
1224 ToolBarItem *otherToolBar = widgetActionToToolBar.value(action);
1225 if (otherToolBar) {
1226 toolBarToWidgetActions[otherToolBar].remove(action);
1227 currentState[otherToolBar].removeAll(action);
1228 }
1229 widgetActionToToolBar.insert(action, toolBarItem);
1230 toolBarToWidgetActions[toolBarItem].insert(action);
1231 }
1232 }
1233 currentState.insert(toolBarItem, itToolBar.value());
1234
1235 ++itToolBar;
1236 }
1237 currentToolBarChanged(toolBarToItem.value(currentToolBar));
1238
1239 const auto toolBars = currentState.keys();
1240 for (ToolBarItem *tb : toolBars)
1241 removeToolBar(tb);
1242}
1243
1245{
1247 q_ptr->accept();
1248}
1249
1251{
1252 const auto toolBars = currentState;
1253 auto itToolBar = toolBars.constBegin();
1254 while (itToolBar != toolBars.constEnd()) {
1255 ToolBarItem *item = itToolBar.key();
1256 QToolBar *toolBar = item->toolBar();
1257 if (toolBar) {
1258 toolBarManager->setToolBar(toolBar, itToolBar.value());
1259 toolBar->setWindowTitle(item->toolBarName());
1260 }
1261
1262 ++itToolBar;
1263 }
1264
1265 const QSet<ToolBarItem *> toRemove = removedItems;
1266 for (ToolBarItem *item : toRemove) {
1267 QToolBar *toolBar = item->toolBar();
1268 removedItems.remove(item);
1269 currentState.remove(item);
1270 deleteItem(item);
1271 if (toolBar)
1272 toolBarManager->deleteToolBar(toolBar);
1273 }
1274
1275 const QSet<ToolBarItem *> toCreate = createdItems;
1276 for (ToolBarItem *item : toCreate) {
1277 QString toolBarName = item->toolBarName();
1278 createdItems.remove(item);
1279 const auto actions = currentState.value(item);
1280 QToolBar *toolBar = toolBarManager->createToolBar(toolBarName);
1281 item->setToolBar(toolBar);
1282 toolBarManager->setToolBar(toolBar, actions);
1283 }
1284}
1285
1287{
1288 QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
1289 if (!currentToolBarAction)
1290 return;
1291 int row = ui.currentToolBarList->row(currentToolBarAction);
1292 if (row == 0)
1293 return;
1294 ui.currentToolBarList->takeItem(row);
1295 int newRow = row - 1;
1296 ui.currentToolBarList->insertItem(newRow, currentToolBarAction);
1297 auto actions = currentState.value(currentToolBar);
1298 QAction *action = actions.at(row);
1299 actions.removeAt(row);
1300 actions.insert(newRow, action);
1301 currentState.insert(currentToolBar, actions);
1302 ui.currentToolBarList->setCurrentItem(currentToolBarAction);
1304}
1305
1307{
1308 QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
1309 if (!currentToolBarAction)
1310 return;
1311 int row = ui.currentToolBarList->row(currentToolBarAction);
1312 if (row == ui.currentToolBarList->count() - 1)
1313 return;
1314 ui.currentToolBarList->takeItem(row);
1315 int newRow = row + 1;
1316 ui.currentToolBarList->insertItem(newRow, currentToolBarAction);
1317 auto actions = currentState.value(currentToolBar);
1318 QAction *action = actions.at(row);
1319 actions.removeAt(row);
1320 actions.insert(newRow, action);
1321 currentState.insert(currentToolBar, actions);
1322 ui.currentToolBarList->setCurrentItem(currentToolBarAction);
1324}
1325
1327{
1328 QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
1329 if (!currentToolBarAction)
1330 return;
1331 int row = ui.currentToolBarList->row(currentToolBarAction);
1332 currentState[currentToolBar].removeAt(row);
1333 QAction *action = currentItemToAction.value(currentToolBarAction);
1334 if (widgetActionToToolBar.contains(action)) {
1335 ToolBarItem *item = widgetActionToToolBar.value(action);
1336 if (item == currentToolBar) { // have to be
1337 toolBarToWidgetActions[item].remove(action);
1338 if (toolBarToWidgetActions[item].isEmpty())
1339 toolBarToWidgetActions.remove(item);
1340 }
1341 widgetActionToToolBar.insert(action, 0);
1342 }
1343 if (action)
1344 actionToCurrentItem.remove(action);
1345 currentItemToAction.remove(currentToolBarAction);
1346 delete currentToolBarAction;
1347 if (row == ui.currentToolBarList->count())
1348 row--;
1349 if (row >= 0) {
1350 QListWidgetItem *item = ui.currentToolBarList->item(row);
1351 ui.currentToolBarList->setCurrentItem(item);
1352 }
1354}
1355
1357{
1358 if (!currentAction)
1359 return;
1360 if (!currentToolBar)
1361 return;
1362 QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
1363
1364 QAction *action = itemToAction.value(currentAction);
1365 QListWidgetItem *item = nullptr;
1366 if (action) {
1367 if (currentState[currentToolBar].contains(action)) {
1368 item = actionToCurrentItem.value(action);
1369 if (item == currentToolBarAction)
1370 return;
1371 int row = ui.currentToolBarList->row(item);
1372 ui.currentToolBarList->takeItem(row);
1373 currentState[currentToolBar].removeAt(row);
1374 // only reorder here
1375 } else {
1376 item = new QListWidgetItem(action->text());
1377 item->setIcon(action->icon());
1378 item->setTextAlignment(Qt::Alignment(Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic));
1379 currentItemToAction.insert(item, action);
1380 actionToCurrentItem.insert(action, item);
1381 if (widgetActionToToolBar.contains(action)) {
1382 item->setData(Qt::ForegroundRole, QColor(Qt::blue));
1383 ToolBarItem *toolBar = widgetActionToToolBar.value(action);
1384 if (toolBar) {
1385 currentState[toolBar].removeAll(action);
1386 toolBarToWidgetActions[toolBar].remove(action);
1387 if (toolBarToWidgetActions[toolBar].isEmpty())
1388 toolBarToWidgetActions.remove(toolBar);
1389 }
1390 widgetActionToToolBar.insert(action, currentToolBar);
1391 toolBarToWidgetActions[currentToolBar].insert(action);
1392 }
1393 }
1394 } else {
1395 item = new QListWidgetItem(separatorText);
1396 currentItemToAction.insert(item, 0);
1397 }
1398
1399 int row = ui.currentToolBarList->count();
1400 if (currentToolBarAction) {
1401 row = ui.currentToolBarList->row(currentToolBarAction) + 1;
1402 }
1403 ui.currentToolBarList->insertItem(row, item);
1404 currentState[currentToolBar].insert(row, action);
1405 ui.currentToolBarList->setCurrentItem(item);
1406
1408}
1409
1411{
1412 if (!currentToolBar)
1413 return;
1414
1415 QListWidgetItem *item = toolBarToItem.value(currentToolBar);
1416 ui.toolBarList->editItem(item);
1417}
1418
1419void QtToolBarDialogPrivate::toolBarRenamed(QListWidgetItem *item)
1420{
1421 if (!currentToolBar)
1422 return;
1423
1424 ToolBarItem *tbItem = itemToToolBar.value(item);
1425 if (!tbItem)
1426 return;
1427 tbItem->setToolBarName(item->text());
1428 //ui.toolBarList->sortItems();
1429}
1430
1431void QtToolBarDialogPrivate::currentActionChanged(QTreeWidgetItem *current)
1432{
1433 if (itemToAction.contains(current))
1434 currentAction = current;
1435 else
1436 currentAction = nullptr;
1438}
1439
1440void QtToolBarDialogPrivate::currentToolBarChanged(QListWidgetItem *current)
1441{
1442 currentToolBar = itemToToolBar.value(current);
1443 ui.currentToolBarList->clear();
1444 actionToCurrentItem.clear();
1445 currentItemToAction.clear();
1447 if (!currentToolBar) {
1448 return;
1449 }
1450 const auto actions = currentState.value(currentToolBar);
1451 QListWidgetItem *first = nullptr;
1452 for (QAction *action : actions) {
1453 QString actionName = separatorText;
1454 if (action)
1455 actionName = action->text();
1456 auto *item = new QListWidgetItem(actionName, ui.currentToolBarList);
1457 if (action) {
1458 item->setIcon(action->icon());
1459 item->setTextAlignment(Qt::Alignment(Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic));
1460 actionToCurrentItem.insert(action, item);
1461 if (widgetActionToToolBar.contains(action))
1462 item->setData(Qt::ForegroundRole, QColor(Qt::blue));
1463 }
1464 currentItemToAction.insert(item, action);
1465 if (!first)
1466 first = item;
1467 }
1468 if (first)
1469 ui.currentToolBarList->setCurrentItem(first);
1470}
1471
1473{
1475}
1476
1478{
1479 // just nothing
1480 q_ptr->reject();
1481}
1482
1483//////////////////////
1484/*
1485class FeedbackItemDelegate : public QItemDelegate
1486{
1487 Q_OBJECT
1488public:
1489 FeedbackItemDelegate(QObject *parent = 0) : QItemDelegate(parent) { }
1490
1491 virtual void paint(QPainter *painter, const QStyleOptionViewItem &option,
1492 const QModelIndex & index) const;
1493 virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
1494};
1495
1496void FeedbackItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
1497 const QModelIndex &index) const
1498{
1499 if ()
1500 painter->save();
1501 QRect r = option.rect;
1502 float yCentral = r.height() / 2.0;
1503 float margin = 2.0;
1504 float arrowWidth = 5.0;
1505 float width = 20;
1506 qDebug("rect: x %d, y %d, w %d, h %d", r.x(), r.y(), r.width(), r.height());
1507 QLineF lineBase(0.0 + margin, r.y() + yCentral, width - margin, r.y() + yCentral);
1508 QLineF lineArrowLeft(width - margin - arrowWidth, r.y() + yCentral - arrowWidth,
1509 width - margin, r.y() + yCentral);
1510 QLineF lineArrowRight(width - margin - arrowWidth, r.y() + yCentral + arrowWidth,
1511 width - margin, r.y() + yCentral);
1512 painter->drawLine(lineBase);
1513 painter->drawLine(lineArrowLeft);
1514 painter->drawLine(lineArrowRight);
1515 painter->translate(QPoint(width, 0));
1516 QItemDelegate::paint(painter, option, index);
1517 painter->restore();
1518}
1519
1520QSize FeedbackItemDelegate::sizeHint(const QStyleOptionViewItem &option,
1521 const QModelIndex &index) const
1522{
1523 //return QItemDelegate::sizeHint(option, index);
1524 QSize s = QItemDelegate::sizeHint(option, index);
1525 s.setWidth(s.width() - 20);
1526 return s;
1527}
1528
1529class QtToolBarListWidget : public QListWidget
1530{
1531 Q_OBJECT
1532public:
1533 QtToolBarListWidget(QWidget *parent) : QListWidget(parent), actionDrag(false) {}
1534
1535protected:
1536 void startDrag(Qt::DropActions supportedActions);
1537
1538 void dragEnterEvent(QDragEnterEvent *event);
1539 void dragMoveEvent(QDragMoveEvent *event);
1540 void dragLeaveEvent(QDragLeaveEvent *);
1541 void dropEvent(QDropEvent *event);
1542
1543 void setDragAction(const QString *action) { actionName = action; }
1544private:
1545 QPersistentModelIndex lastDropIndicator;
1546 QString actionName;
1547 bool actionDrag;
1548};
1549
1550void QtToolBarListWidget::startDrag(Qt::DropActions supportedActions)
1551{
1552 QListWidgetItem *item = currentItem();
1553 if (item) {
1554 actionName = QString();
1555 emit aboutToDrag(item);
1556 if (!actionName.isEmpty()) {
1557 QDrag *drag = new QDrag(this);
1558 QMimeData *data = new QMimeData;
1559 data->setData("action", actionName.toLocal8Bit().constData());
1560 drag->setMimeData(data);
1561 drag->exec(supportedActions);
1562 }
1563 }
1564}
1565
1566void QtToolBarListWidget::dragEnterEvent(QDragEnterEvent *event)
1567{
1568 const QMimeData *mime = event->mimeData();
1569 actionDrag = mime->hasFormat("action");
1570 if (actionDrag)
1571 event->accept();
1572 else
1573 event->ignore();
1574}
1575
1576void QtToolBarListWidget::dragMoveEvent(QDragMoveEvent *event)
1577{
1578 event->ignore();
1579 if (actionDrag) {
1580 QPoint p = event->pos();
1581 QListWidgetItem *item = itemAt(p);
1582 Indicator indic = QtToolBarListWidget::None;
1583 if (item) {
1584 QRect rect = visualItemRect(item);
1585 if (p.y() - rect.top() < rect.height() / 2)
1586 indic = QtToolBarListWidget::Above;
1587 else
1588 indic = QtToolBarListWidget::Below;
1589 }
1590 setIndicator(item, indic);
1591 event->accept();
1592 }
1593}
1594
1595void QtToolBarListWidget::dragLeaveEvent(QDragLeaveEvent *)
1596{
1597 if (actionDrag) {
1598 actionDrag = false;
1599 setIndicator(item, QtToolBarListWidget::None);
1600 }
1601}
1602
1603void QtToolBarListWidget::dropEvent(QDropEvent *event)
1604{
1605 if (actionDrag) {
1606 QListWidgetItem *item = indicatorItem();
1607 Indicator indic = indicator();
1608 QByteArray array = event->mimeData()->data("action");
1609 QDataStream stream(&array, QIODevice::ReadOnly);
1610 QString action;
1611 stream >> action;
1612 emit actionDropped(action, item, );
1613
1614 actionDrag = false;
1615 setIndicator(item, QtToolBarListWidget::None);
1616 }
1617}
1618*/
1619
1620/*! \class QtToolBarDialog
1621 \internal
1622 \inmodule QtDesigner
1623 \since 4.4
1624
1625 \brief The QtToolBarDialog class provides a dialog for customizing
1626 toolbars.
1627
1628 QtToolBarDialog allows the user to customize the toolbars for a
1629 given main window.
1630
1631 \image qttoolbardialog.png
1632
1633 The dialog lets the users add, rename and remove custom toolbars.
1634 Note that built-in toolbars are marked with a green color, and
1635 cannot be removed or renamed.
1636
1637 The users can also add and remove actions from the toolbars. An
1638 action can be added to many toolbars, but a toolbar can only
1639 contain one instance of each action. Actions that contains a
1640 widget are marked with a blue color in the list of actions, and
1641 can only be added to one single toolbar.
1642
1643 Finally, the users can add separators to the toolbars.
1644
1645 The original toolbars can be restored by clicking the \gui
1646 {Restore all} button. All custom toolbars will then be removed,
1647 and all built-in toolbars will be restored to their original state.
1648
1649 The QtToolBarDialog class's functionality is controlled by an
1650 instance of the QtToolBarManager class, and the main window is
1651 specified using the QtToolBarManager::setMainWindow() function.
1652
1653 All you need to do to use QtToolBarDialog is to specify an
1654 QtToolBarManager instance and call the QDialog::exec() slot:
1655
1656 \snippet doc/src/snippets/code/tools_shared_qttoolbardialog_qttoolbardialog.cpp 0
1657
1658 \sa QtToolBarManager
1659*/
1660
1661/*!
1662 Creates a toolbar dialog with the given \a parent and the specified
1663 window \a flags.
1664*/
1665QtToolBarDialog::QtToolBarDialog(QWidget *parent, Qt::WindowFlags flags)
1666 : QDialog(parent, flags), d_ptr(new QtToolBarDialogPrivate)
1667{
1668 d_ptr->q_ptr = this;
1669 d_ptr->ui.setupUi(this);
1670 d_ptr->separatorText = tr("< S E P A R A T O R >");
1671
1672 d_ptr->ui.actionTree->setColumnCount(1);
1673 d_ptr->ui.actionTree->setRootIsDecorated(false);
1674 d_ptr->ui.actionTree->header()->hide();
1675
1676 d_ptr->ui.upButton->setIcon(QIcon(":/qt-project.org/qttoolbardialog/images/up.png"_L1));
1677 d_ptr->ui.downButton->setIcon(QIcon(":/qt-project.org/qttoolbardialog/images/down.png"_L1));
1678 d_ptr->ui.leftButton->setIcon(QIcon(":/qt-project.org/qttoolbardialog/images/back.png"_L1));
1679 d_ptr->ui.rightButton->setIcon(QIcon(":/qt-project.org/qttoolbardialog/images/forward.png"_L1));
1680 d_ptr->ui.newButton->setIcon(QIcon(":/qt-project.org/qttoolbardialog/images/plus.png"_L1));
1681 d_ptr->ui.removeButton->setIcon(QIcon(":/qt-project.org/qttoolbardialog/images/minus.png"_L1));
1682
1683 connect(d_ptr->ui.newButton, &QAbstractButton::clicked, this, [this] { d_ptr->newClicked(); });
1684 connect(d_ptr->ui.removeButton, &QAbstractButton::clicked, this, [this] { d_ptr->removeClicked(); });
1685 connect(d_ptr->ui.renameButton, &QAbstractButton::clicked, this, [this] { d_ptr->renameClicked(); });
1686 connect(d_ptr->ui.upButton, &QAbstractButton::clicked, this, [this] { d_ptr->upClicked(); });
1687 connect(d_ptr->ui.downButton, &QAbstractButton::clicked, this, [this] { d_ptr->downClicked(); });
1688 connect(d_ptr->ui.leftButton, &QAbstractButton::clicked, this, [this] { d_ptr->leftClicked(); });
1689 connect(d_ptr->ui.rightButton, &QAbstractButton::clicked, this, [this] { d_ptr->rightClicked(); });
1690
1691 connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::RestoreDefaults),
1692 &QAbstractButton::clicked, this, [this] { d_ptr->defaultClicked(); });
1693 connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::Ok),
1694 &QAbstractButton::clicked, this, [this] { d_ptr->okClicked(); });
1695 connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::Apply),
1696 &QAbstractButton::clicked, this, [this] { d_ptr->applyClicked(); });
1697 connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::Cancel),
1698 &QAbstractButton::clicked, this, [this] { d_ptr->cancelClicked(); });
1699
1700 connect(d_ptr->ui.actionTree, &QTreeWidget::currentItemChanged,
1701 this, [this](QTreeWidgetItem *current) { d_ptr->currentActionChanged(current); });
1702 connect(d_ptr->ui.currentToolBarList, &QListWidget::currentItemChanged,
1703 this, [this](QListWidgetItem *current) { d_ptr->currentToolBarActionChanged(current); });
1704 connect(d_ptr->ui.toolBarList, &QListWidget::currentItemChanged,
1705 this, [this](QListWidgetItem *current) { d_ptr->currentToolBarChanged(current); });
1706
1707 connect(d_ptr->ui.actionTree, &QTreeWidget::itemDoubleClicked,
1708 this, [this] { d_ptr->rightClicked(); });
1709 connect(d_ptr->ui.currentToolBarList, &QListWidget::itemDoubleClicked,
1710 this, [this] { d_ptr->leftClicked(); });
1711 connect(d_ptr->ui.toolBarList, &QListWidget::itemChanged,
1712 this, [this](QListWidgetItem *current) { d_ptr->toolBarRenamed(current); });
1713}
1714
1715/*!
1716 Destroys the toolbar dialog.
1717*/
1719{
1720 d_ptr->clearOld();
1721}
1722
1723/*!
1724 Connects the toolbar dialog to the given \a toolBarManager. Then,
1725 when exec() is called, the toolbar dialog will operate using the
1726 given \a toolBarManager.
1727*/
1729{
1730 if (d_ptr->toolBarManager == toolBarManager->d_ptr->manager)
1731 return;
1732 if (isVisible())
1733 d_ptr->clearOld();
1734 d_ptr->toolBarManager = toolBarManager->d_ptr->manager;
1735 if (isVisible())
1736 d_ptr->fillNew();
1737}
1738
1739/*!
1740 \reimp
1741*/
1742void QtToolBarDialog::showEvent(QShowEvent *event)
1743{
1744 if (!event->spontaneous())
1745 d_ptr->fillNew();
1746}
1747
1748/*!
1749 \reimp
1750*/
1751void QtToolBarDialog::hideEvent(QHideEvent *event)
1752{
1753 if (!event->spontaneous())
1754 d_ptr->clearOld();
1755}
1756
1757QT_END_NAMESPACE
1758
1759#include "moc_qttoolbardialog_p.cpp"
1760#include "qttoolbardialog.moc"
QToolBar * findDefaultToolBar(const QString &objectName) const
QHash< QToolBar *, QList< QAction * > > toolBars
QHash< QAction *, QList< QToolBar * > > actionToToolBars
void removeWidgetActions(const QHash< QToolBar *, QList< QAction * > > &actions)
QHash< QAction *, QToolBar * > widgetActions
bool restoreState(QDataStream &stream) const
QList< QToolBar * > customToolBars
QToolBar * toolBarByName(const QString &toolBarName) const
QHash< QToolBar *, QList< QAction * > > toolBarsWithSeparators
QHash< QAction *, QString > actionToCategory
void saveState(QDataStream &stream) const
QAction * findAction(const QString &actionName) const
QHash< QToolBar *, QList< QAction * > > defaultToolBars
bool isDefaultToolBar(QToolBar *toolBar) const
void toolBarRemoved(QToolBar *toolBar)
QList< QAction * > actions(QToolBar *toolBar) const
bool hasCategory(const QString &category) const
void deleteToolBar(QToolBar *toolBar)
QToolBar * createToolBar(const QString &toolBarName)
void removeAction(QAction *action)
void setToolBar(QToolBar *toolBar, const QList< QAction * > &actions)
~QtFullToolBarManager() override
void addCategory(const QString &category)
QHash< QToolBar *, QList< QAction * > > toolBarsActions() const
bool restoreState(const QByteArray &state, int version=0)
QSet< QAction * > actions() const
bool isWidgetAction(QAction *action) const
void setToolBars(const QHash< QToolBar *, QList< QAction * > > &actions)
void addAction(QAction *action, const QString &category)
void removeDefaultToolBar(QToolBar *toolBar)
QMainWindow * mainWindow() const
void toolBarChanged(QToolBar *toolBar, const QList< QAction * > &actions)
QString actionCategory(QAction *action) const
QHash< QToolBar *, QList< QAction * > > defaultToolBars() const
QByteArray saveState(int version=0) const
void addDefaultToolBar(QToolBar *toolBar, const QString &category)
void setMainWindow(QMainWindow *mainWindow)
QStringList categories() const
QList< QAction * > categoryActions(const QString &category) const
QHash< QListWidgetItem *, ToolBarItem * > itemToToolBar
void currentActionChanged(QTreeWidgetItem *current)
QtFullToolBarManager * toolBarManager
QTreeWidgetItem * currentAction
bool isDefaultToolBar(ToolBarItem *item) const
Ui::QtToolBarDialog ui
QHash< ToolBarItem *, QSet< QAction * > > toolBarToWidgetActions
void removeToolBar(ToolBarItem *item)
ToolBarItem * createItem(const QString &toolBarName)
QSet< ToolBarItem * > allToolBarItems
QHash< QAction *, QTreeWidgetItem * > actionToItem
void currentToolBarActionChanged(QListWidgetItem *current)
QSet< ToolBarItem * > removedItems
QSet< ToolBarItem * > createdItems
QHash< QAction *, ToolBarItem * > widgetActionToToolBar
void toolBarRenamed(QListWidgetItem *item)
void deleteItem(ToolBarItem *item)
QHash< QTreeWidgetItem *, QAction * > itemToAction
QHash< QToolBar *, ToolBarItem * > toolBarItems
QHash< ToolBarItem *, QListWidgetItem * > toolBarToItem
QHash< QAction *, QListWidgetItem * > actionToCurrentItem
void currentToolBarChanged(QListWidgetItem *current)
QHash< QListWidgetItem *, QAction * > currentItemToAction
QHash< ToolBarItem *, QList< QAction * > > currentState
The QtToolBarDialog class provides a dialog for customizing toolbars.
void hideEvent(QHideEvent *event) override
\reimp
~QtToolBarDialog() override
Destroys the toolbar dialog.
void showEvent(QShowEvent *event) override
\reimp
void setToolBarManager(QtToolBarManager *toolBarManager)
Connects the toolbar dialog to the given toolBarManager.
The QtToolBarManager class provides toolbar management for main windows.
void removeAction(QAction *action)
Removes the specified action from the manager's list of actions.
~QtToolBarManager() override
Destroys the toolbar manager.
QMainWindow * mainWindow() const
Returns the main window associated this toolbar manager.
QList< QToolBar * > toolBars() const
Returns the manager's toolbar list.
void removeToolBar(QToolBar *toolBar)
Removes the specified toolBar from the manager's list.
QByteArray saveState(int version=0) const
Saves the state of the toolbar manager's toolbars.
void setMainWindow(QMainWindow *mainWindow)
Sets the main window upon which the toolbar manager operates, to be the given mainWindow.
QString toolBarName() const
ToolBarItem(QToolBar *toolBar)
void setToolBarName(const QString &toolBarName)
ToolBarItem(QToolBar *toolBar, const QString &toolBarName)
void setToolBar(QToolBar *toolBar)
QToolBar * toolBar() const
ToolBarItem(const QString &toolBarName)