source: tspsg/src/3rdparty/qttoolbardialog-2.2_1-opensource/src/qttoolbardialog.cpp @ 7a39458d16

appveyorimgbotreadme
Last change on this file since 7a39458d16 was 7a39458d16, checked in by Oleksii Serdiuk, 12 years ago

A few more fixes for compatibility with Qt 5.

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