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

0.1.4.170-beta2-bb10appveyorimgbotreadme
Last change on this file since f6352492e7 was f6352492e7, checked in by Oleksii Serdiuk, 13 years ago

Last commit (r165) broke compilation with disabled PCH. Fixed.

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