source: tspsg/src/3rdparty/qttoolbardialog-2.2_1-opensource/src/qttoolbardialog.cpp @ 019894f5ef

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