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