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