src/qt3support/widgets/q3toolbar.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/qt3support/widgets/q3toolbar.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,840 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3toolbar.h"
+#ifndef QT_NO_TOOLBAR
+
+#include "q3mainwindow.h"
+#include "qapplication.h"
+#include "q3combobox.h"
+#include "qcursor.h"
+#include "qdesktopwidget.h"
+#include "qdrawutil.h"
+#include "qevent.h"
+#include "qframe.h"
+#include "qlayout.h"
+#include "qmap.h"
+#include "qpainter.h"
+#include "q3popupmenu.h"
+#include "qstyle.h"
+#include "qstyleoption.h"
+#include "qtimer.h"
+#include "qtoolbutton.h"
+#include "qtooltip.h"
+
+QT_BEGIN_NAMESPACE
+
+static const char * const arrow_v_xpm[] = {
+    "7 9 3 1",
+    "            c None",
+    ".            c #000000",
+    "+            c none",
+    ".+++++.",
+    "..+++..",
+    "+..+..+",
+    "++...++",
+    ".++.++.",
+    "..+++..",
+    "+..+..+",
+    "++...++",
+    "+++.+++"};
+
+static const char * const arrow_h_xpm[] = {
+    "9 7 3 1",
+    "            c None",
+    ".            c #000000",
+    "+            c none",
+    "..++..+++",
+    "+..++..++",
+    "++..++..+",
+    "+++..++..",
+    "++..++..+",
+    "+..++..++",
+    "..++..+++"};
+
+class Q3ToolBarExtensionWidget;
+
+class Q3ToolBarPrivate
+{
+public:
+    Q3ToolBarPrivate() : moving(false), checkingExtension(false) {
+    }
+
+    bool moving;
+    bool checkingExtension;
+    Q3ToolBarExtensionWidget *extension;
+    Q3PopupMenu *extensionPopup;
+
+    QMap<QAction *, QWidget *> actions;
+};
+
+
+class Q3ToolBarSeparator : public QWidget
+{
+    Q_OBJECT
+public:
+    Q3ToolBarSeparator(Qt::Orientation, Q3ToolBar *parent, const char* name=0);
+
+    QSize sizeHint() const;
+    Qt::Orientation orientation() const { return orient; }
+public slots:
+    void setOrientation(Qt::Orientation);
+protected:
+    void changeEvent(QEvent *);
+    void paintEvent(QPaintEvent *);
+
+private:
+    Qt::Orientation orient;
+};
+
+class Q3ToolBarExtensionWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    Q3ToolBarExtensionWidget(QWidget *w);
+    void setOrientation(Qt::Orientation o);
+    QToolButton *button() const { return tb; }
+
+protected:
+    void resizeEvent(QResizeEvent *e) {
+        QWidget::resizeEvent(e);
+        layOut();
+    }
+
+private:
+    void layOut();
+    QToolButton *tb;
+    Qt::Orientation orient;
+
+};
+
+Q3ToolBarExtensionWidget::Q3ToolBarExtensionWidget(QWidget *w)
+    : QWidget(w, "qt_dockwidget_internal")
+{
+    tb = new QToolButton(this, "qt_toolbar_ext_button");
+    tb->setAutoRaise(true);
+    setOrientation(Qt::Horizontal);
+    setAutoFillBackground(true);
+}
+
+void Q3ToolBarExtensionWidget::setOrientation(Qt::Orientation o)
+{
+    orient = o;
+    if (orient == Qt::Horizontal)
+        tb->setIcon(QPixmap((const char **)arrow_h_xpm));
+    else
+        tb->setIcon(QPixmap((const char **)arrow_v_xpm));
+    layOut();
+}
+
+void Q3ToolBarExtensionWidget::layOut()
+{
+    tb->setGeometry(2, 2, width() - 4, height() - 4);
+}
+
+Q3ToolBarSeparator::Q3ToolBarSeparator(Qt::Orientation o , Q3ToolBar *parent,
+                                     const char* name)
+    : QWidget(parent, name)
+{
+    connect(parent, SIGNAL(orientationChanged(Qt::Orientation)),
+             this, SLOT(setOrientation(Qt::Orientation)));
+    setOrientation(o);
+    setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
+}
+
+
+
+void Q3ToolBarSeparator::setOrientation(Qt::Orientation o)
+{
+    orient = o;
+}
+
+void Q3ToolBarSeparator::changeEvent(QEvent *ev)
+{
+    if(ev->type() == QEvent::StyleChange)
+        setOrientation(orient);
+    QWidget::changeEvent(ev);
+}
+
+static QStyleOption getStyleOption(const Q3ToolBarSeparator *tbs)
+{
+    QStyleOption opt(0);
+    opt.rect = tbs->rect();
+    opt.palette = tbs->palette();
+    if (tbs->orientation() == Qt::Horizontal)
+        opt.state = QStyle::State_Horizontal;
+    else
+        opt.state = QStyle::State_None;
+    return opt;
+}
+
+QSize Q3ToolBarSeparator::sizeHint() const
+{
+    QStyleOption opt = getStyleOption(this);
+    int extent = style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, this);
+    if (orient == Qt::Horizontal)
+        return QSize(extent, 0);
+    else
+        return QSize(0, extent);
+}
+
+void Q3ToolBarSeparator::paintEvent(QPaintEvent *)
+{
+    QPainter p(this);
+    QStyleOption opt = getStyleOption(this);
+    style()->drawPrimitive(QStyle::PE_Q3DockWindowSeparator, &opt, &p, this);
+}
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "q3toolbar.moc"
+QT_END_INCLUDE_NAMESPACE
+
+
+/*!
+    \class Q3ToolBar
+    \brief The Q3ToolBar class provides a movable panel containing
+    widgets such as tool buttons.
+
+    \compat
+
+    A toolbar is a panel that contains a set of controls, usually
+    represented by small icons. It's purpose is to provide quick
+    access to frequently used commands or options. Within a
+    Q3MainWindow the user can drag toolbars within and between the
+    \link Q3DockArea dock areas\endlink. Toolbars can also be dragged
+    out of any dock area to float freely as top-level windows.
+
+    Q3ToolBar is a specialization of QDockWindow, and so provides all
+    the functionality of a QDockWindow.
+
+    To use Q3ToolBar you simply create a Q3ToolBar as a child of a
+    Q3MainWindow, create a number of QToolButton widgets (or other
+    widgets) in left to right (or top to bottom) order and call
+    addSeparator() when you want a separator. When a toolbar is
+    floated the caption used is the label given in the constructor
+    call. This can be changed with setLabel().
+
+    You may use most widgets within a toolbar, with QToolButton and
+    QComboBox being the most common. But note that the toolbar's
+    actions must be \l {Q3Action}s.
+
+    If you create a new widget on an already visible Q3ToolBar, this
+    widget will automatically become visible without needing a show()
+    call. (This differs from every other Qt widget container. We
+    recommend calling show() anyway since we hope to fix this anomaly
+    in a future release.)
+
+    Q3ToolBars, like QDockWindows, are located in \l{Q3DockArea}s or
+    float as top-level windows. Q3MainWindow provides four Q3DockAreas
+    (top, left, right and bottom). When you create a new toolbar (as
+    in the example above) as a child of a Q3MainWindow the toolbar will
+    be added to the top dock area. You can move it to another dock
+    area (or float it) by calling Q3MainWindow::moveDockWindow(). Dock
+    areas lay out their windows in lines.
+
+    If the main window is resized so that the area occupied by the
+    toolbar is too small to show all its widgets a little arrow button
+    (which looks like a right-pointing chevron, '&#187;') will appear
+    at the right or bottom of the toolbar depending on its
+    orientation. Clicking this button pops up a menu that shows the
+    'overflowing' items. QToolButtons are represented in the menu using
+    their textLabel property, other QAbstractButton subclasses are represented
+    using their text property, and QComboBoxes are represented as submenus,
+    with the caption text being used in the submenu item.
+
+    Usually a toolbar will get precisely the space it needs. However,
+    with setHorizontalStretchable(), setVerticalStretchable() or
+    setStretchableWidget() you can tell the main window to expand the
+    toolbar to fill all available space in the specified orientation.
+
+    The toolbar arranges its buttons either horizontally or vertically
+    (see orientation() for details). Generally, Q3DockArea will set the
+    orientation correctly for you, but you can set it yourself with
+    setOrientation() and track any changes by connecting to the
+    orientationChanged() signal.
+
+    You can use the clear() method to remove all items from a toolbar.
+
+    \img qdockwindow.png Toolbar (dock window)
+    \caption A floating QToolbar (dock window)
+
+    \sa QToolButton Q3MainWindow
+*/
+
+/*!
+    Constructs an empty toolbar.
+
+    The toolbar is called \a name and is a child of \a parent and is
+    managed by \a parent. It is initially located in dock area \a dock
+    and is labeled \a label. If \a newLine is true the toolbar will be
+    placed on a new line in the dock area.
+*/
+
+Q3ToolBar::Q3ToolBar(const QString &label,
+                    Q3MainWindow * parent, Qt::ToolBarDock dock,
+                    bool newLine, const char * name)
+    : Q3DockWindow(InDock, parent, name, 0, true)
+{
+    mw = parent;
+    init();
+
+    if (parent)
+        parent->addToolBar(this, label, dock, newLine);
+}
+
+
+/*!
+    Constructs an empty horizontal toolbar.
+
+    The toolbar is called \a name and is a child of \a parent and is
+    managed by \a mainWindow. The \a label and \a newLine parameters
+    are passed straight to Q3MainWindow::addDockWindow(). \a name and
+    the widget flags \a f are passed on to the Q3DockWindow constructor.
+
+    Use this constructor if you want to create torn-off (undocked,
+    floating) toolbars or toolbars in the \link QStatusBar status
+    bar\endlink.
+*/
+
+Q3ToolBar::Q3ToolBar(const QString &label, Q3MainWindow * mainWindow,
+                    QWidget * parent, bool newLine, const char * name,
+                    Qt::WindowFlags f)
+    : Q3DockWindow(InDock, parent, name, f, true)
+{
+    mw = mainWindow;
+    init();
+
+    setParent(parent);
+
+    if (mainWindow)
+        mainWindow->addToolBar(this, label, Qt::DockUnmanaged, newLine);
+}
+
+
+/*!
+    \overload
+
+    Constructs an empty toolbar called \a name, with parent \a parent,
+    in its \a parent's top dock area, without any label and without
+    requiring a newline.
+*/
+
+Q3ToolBar::Q3ToolBar(Q3MainWindow * parent, const char * name)
+    : Q3DockWindow(InDock, parent, name, 0, true)
+{
+    mw = parent;
+    init();
+
+    if (parent)
+        parent->addToolBar(this, QString(), Qt::DockTop);
+}
+
+/*!
+    \internal
+
+  Common initialization code. Requires that \c mw and \c o are set.
+  Does not call Q3MainWindow::addDockWindow().
+*/
+void Q3ToolBar::init()
+{
+    d = new Q3ToolBarPrivate;
+    d->extension = 0;
+    d->extensionPopup = 0;
+    sw = 0;
+
+    setBackgroundRole(QPalette::Button);
+    setFocusPolicy(Qt::NoFocus);
+    setFrameStyle(QFrame::ToolBarPanel | QFrame::Raised);
+}
+
+/*!
+    Destructor.
+*/
+
+Q3ToolBar::~Q3ToolBar()
+{
+    delete d;
+}
+
+/*!
+    \reimp
+*/
+
+void Q3ToolBar::setOrientation(Qt::Orientation o)
+{
+    Q3DockWindow::setOrientation(o);
+    if (d->extension)
+        d->extension->setOrientation(o);
+    QObjectList childList = children();
+    for (int i = 0; i < childList.size(); ++i) {
+        Q3ToolBarSeparator* w = qobject_cast<Q3ToolBarSeparator*>(childList.at(i));
+        if (w)
+            w->setOrientation(o);
+    }
+}
+
+/*!
+    Adds a separator to the right/bottom of the toolbar.
+*/
+
+void Q3ToolBar::addSeparator()
+{
+    (void) new Q3ToolBarSeparator(orientation(), this, "toolbar separator");
+}
+
+/*!
+  \internal
+*/
+
+void Q3ToolBar::styleChange(QStyle &oldStyle)
+{
+    Q3DockWindow::styleChange(oldStyle);
+}
+
+
+/*!
+    \reimp
+*/
+void Q3ToolBar::setVisible(bool visible)
+{
+    Q3DockWindow::setVisible(visible);
+    if (mw)
+        mw->triggerLayout(false);
+    if (visible)
+        checkForExtension(size());
+}
+
+/*!
+    Returns a pointer to the Q3MainWindow which manages this toolbar.
+*/
+
+Q3MainWindow * Q3ToolBar::mainWindow() const
+{
+    return mw;
+}
+
+
+/*!
+    Sets the widget \a w to be expanded if this toolbar is requested
+    to stretch.
+
+    The request to stretch might occur because Q3MainWindow
+    right-justifies the dock area the toolbar is in, or because this
+    toolbar's isVerticalStretchable() or isHorizontalStretchable() is
+    set to true.
+
+    If you call this function and the toolbar is not yet stretchable,
+    setStretchable() is called.
+
+    \sa Q3MainWindow::setRightJustification(), setVerticalStretchable(),
+    setHorizontalStretchable()
+*/
+
+void Q3ToolBar::setStretchableWidget(QWidget * w)
+{
+    sw = w;
+    boxLayout()->setStretchFactor(w, 1);
+
+    if (!isHorizontalStretchable() && !isVerticalStretchable()) {
+        if (orientation() == Qt::Horizontal)
+            setHorizontalStretchable(true);
+        else
+            setVerticalStretchable(true);
+    }
+}
+
+
+/*!
+    \reimp
+*/
+
+bool Q3ToolBar::event(QEvent * e)
+{
+    bool r =  Q3DockWindow::event(e);
+    // After the event filters have dealt with it, do our stuff.
+    if (e->type() == QEvent::ChildInserted) {
+        QObject * child = ((QChildEvent*)e)->child();
+        if (child && child->isWidgetType() && !((QWidget*)child)->isWindow()
+             && child->parent() == this
+            && QLatin1String("qt_dockwidget_internal") != child->objectName()) {
+            boxLayout()->addWidget((QWidget*)child);
+            QLayoutItem *item = boxLayout()->itemAt(boxLayout()->indexOf((QWidget*)child));
+            if (QToolButton *button = qobject_cast<QToolButton*>(child)) {
+                item->setAlignment(Qt::AlignHCenter);
+                button->setFocusPolicy(Qt::NoFocus);
+                if (mw) {
+                    QObject::connect(mw, SIGNAL(pixmapSizeChanged(bool)),
+                                     button, SLOT(setUsesBigPixmap(bool)));
+                    button->setUsesBigPixmap(mw->usesBigPixmaps());
+                    QObject::connect(mw, SIGNAL(usesTextLabelChanged(bool)),
+                                     child, SLOT(setUsesTextLabel(bool)));
+                    button->setUsesTextLabel(mw->usesTextLabel());
+                }
+                button->setAutoRaise(true);
+            }
+            if (isVisible()) {
+                // toolbar compatibility: we auto show widgets that
+                // are not explicitly hidden
+                if (((QWidget*)child)->testAttribute(Qt::WA_WState_Hidden)
+                    && !((QWidget*)child)->testAttribute(Qt::WA_WState_ExplicitShowHide))
+                    ((QWidget*)child)->show();
+                checkForExtension(size());
+            }
+        }
+        if (child && child->isWidgetType() && ((QWidget*)child) == sw)
+            boxLayout()->setStretchFactor((QWidget*)child, 1);
+    } else if (e->type() == QEvent::Show) {
+        layout()->activate();
+    } else if (e->type() == QEvent::LayoutHint && place() == OutsideDock) {
+        adjustSize();
+    }
+    return r;
+}
+
+
+/*!
+    \property Q3ToolBar::label
+    \brief the toolbar's label.
+
+    If the toolbar is floated the label becomes the toolbar window's
+    caption. There is no default label text.
+*/
+
+void Q3ToolBar::setLabel(const QString & label)
+{
+    l = label;
+    setWindowTitle(l);
+}
+
+QString Q3ToolBar::label() const
+{
+    return l;
+}
+
+
+/*!
+    Deletes all the toolbar's child widgets.
+*/
+
+void Q3ToolBar::clear()
+{
+    QObjectList childList = children();
+    d->extension = 0;
+    d->extensionPopup = 0; //they will both be destroyed by the following code
+    for (int i = 0; i < childList.size(); ++i) {
+        QObject *obj = childList.at(i);
+        if (obj->isWidgetType() && QLatin1String("qt_dockwidget_internal") != obj->objectName())
+            delete obj;
+    }
+}
+
+/*!
+    \internal
+*/
+
+QSize Q3ToolBar::minimumSize() const
+{
+    if (orientation() == Qt::Horizontal)
+        return QSize(0, Q3DockWindow::minimumSize().height());
+    return QSize(Q3DockWindow::minimumSize().width(), 0);
+}
+
+/*!
+    \reimp
+*/
+
+QSize Q3ToolBar::minimumSizeHint() const
+{
+    if (orientation() == Qt::Horizontal)
+        return QSize(0, Q3DockWindow::minimumSizeHint().height());
+    return QSize(Q3DockWindow::minimumSizeHint().width(), 0);
+}
+
+void Q3ToolBar::createPopup()
+{
+    if (!d->extensionPopup) {
+        d->extensionPopup = new Q3PopupMenu(this, "qt_dockwidget_internal");
+        connect(d->extensionPopup, SIGNAL(aboutToShow()), this, SLOT(createPopup()));
+    }
+
+    if (!d->extension) {
+        d->extension = new Q3ToolBarExtensionWidget(this);
+        d->extension->setOrientation(orientation());
+        d->extension->button()->setPopup(d->extensionPopup);
+        d->extension->button()->setPopupMode(QToolButton::InstantPopup);
+    }
+
+    d->extensionPopup->clear();
+
+    // delete submenus
+    QObjectList popups = d->extensionPopup->queryList("Q3PopupMenu", 0, false, true);
+    while (!popups.isEmpty())
+        delete popups.takeFirst();
+
+    QObjectList childlist = queryList("QWidget", 0, false, true);
+    bool hide = false;
+    bool doHide = false;
+    int id;
+    for (int i = 0; i < childlist.size(); ++i) {
+        QObject *obj = childlist.at(i);
+        if (!obj->isWidgetType() || obj == d->extension->button() || obj == d->extensionPopup
+            || QLatin1String("qt_dockwidget_internal") == obj->objectName()) {
+            continue;
+        }
+        int j = 2;
+        QWidget *w = (QWidget*)obj;
+        if (qobject_cast<Q3ComboBox*>(w))
+            j = 1;
+        hide = false;
+
+        const int padding = 4; // extra pixels added by the layout hierarchy
+        QPoint p(mapTo(this, w->geometry().bottomRight()));
+        if (orientation() == Qt::Horizontal) {
+            if ((p.x() > (doHide ? width() - d->extension->width() / j - padding : width() - padding))
+                || (p.x() > parentWidget()->width() - d->extension->width()))
+                hide = true;
+        } else {
+            if ((p.y() > (doHide ? height()- d->extension->height() / j - padding : height() - padding))
+                || (p.y() > parentWidget()->height() - d->extension->height()))
+                hide = true;
+        }
+        if (hide && w->isVisible()) {
+            doHide = true;
+            if (qobject_cast<QToolButton*>(w)) {
+                QToolButton *b = (QToolButton*)w;
+                QString s = b->textLabel();
+                if (s.isEmpty())
+                    s = b->text();
+                if (b->popup() && b->popupDelay() == 0)
+                    id = d->extensionPopup->insertItem(b->iconSet(), s, b->popup());
+                else
+                    id = d->extensionPopup->insertItem(b->iconSet(), s, b, SLOT(click())) ;
+                if (b->isToggleButton())
+                    d->extensionPopup->setItemChecked(id, b->isOn());
+                if (!b->isEnabled())
+                    d->extensionPopup->setItemEnabled(id, false);
+            } else if (qobject_cast<QAbstractButton*>(w)) {
+                QAbstractButton *b = (QAbstractButton*)w;
+                QString s = b->text();
+                if (s.isEmpty())
+                    s = QLatin1String("");
+                if (b->pixmap())
+                    id = d->extensionPopup->insertItem(*b->pixmap(), s, b, SLOT(click()));
+                else
+                    id = d->extensionPopup->insertItem(s, b, SLOT(click()));
+                if (b->isToggleButton())
+                    d->extensionPopup->setItemChecked(id, b->isOn());
+                if (!b->isEnabled())
+                    d->extensionPopup->setItemEnabled(id, false);
+#ifndef QT_NO_COMBOBOX
+            } else if (qobject_cast<Q3ComboBox*>(w)) {
+                Q3ComboBox *c = (Q3ComboBox*)w;
+                if (c->count() != 0) {
+                    QString s = c->windowTitle();
+                    if (s.isEmpty())
+                        s = c->currentText();
+                    int maxItems = 0;
+                    Q3PopupMenu *cp = new Q3PopupMenu(d->extensionPopup);
+                    cp->setEnabled(c->isEnabled());
+                    d->extensionPopup->insertItem(s, cp);
+                    connect(cp, SIGNAL(activated(int)), c, SLOT(internalActivate(int)));
+                    for (int i = 0; i < c->count(); ++i) {
+                        QString tmp = c->text(i);
+                        cp->insertItem(tmp, i);
+                        if (c->currentText() == tmp)
+                            cp->setItemChecked(i, true);
+                        if (!maxItems) {
+                            if (cp->actions().count() == 10) {
+                                int h = cp->sizeHint().height();
+                                maxItems = QApplication::desktop()->height() * 10 / h;
+                            }
+                        } else if (cp->actions().count() >= maxItems - 1) {
+                            Q3PopupMenu* sp = new Q3PopupMenu(d->extensionPopup);
+                            cp->insertItem(tr("More..."), sp);
+                            cp = sp;
+                            connect(cp, SIGNAL(activated(int)), c, SLOT(internalActivate(int)));
+                        }
+                    }
+                }
+#endif //QT_NO_COMBOBOX
+            }
+        }
+    }
+}
+
+/*!
+    \reimp
+*/
+
+void Q3ToolBar::resizeEvent(QResizeEvent *e)
+{
+    Q3DockWindow::resizeEvent(e);
+    checkForExtension(e->size());
+}
+
+/*!
+    \internal
+
+    This function is called when an action is triggered. The relevant
+    information is passed in the event \a e.
+*/
+void Q3ToolBar::actionEvent(QActionEvent *e)
+{
+    if (e->type() == QEvent::ActionAdded) {
+        QAction *a = e->action();
+        QWidget *w;
+        if (a->isSeparator()) {
+            w = new Q3ToolBarSeparator(orientation(), this, "toolbar separator");
+        } else {
+            QToolButton* btn = new QToolButton(this);
+            btn->setDefaultAction(a);
+            w = btn;
+        }
+        d->actions.insert(a, w);
+    } else if (e->type() == QEvent::ActionRemoved) {
+        QAction *a = e->action();
+        delete d->actions.take(a);
+    }
+}
+
+
+void Q3ToolBar::checkForExtension(const QSize &sz)
+{
+    if (!isVisible())
+        return;
+
+    if (d->checkingExtension)
+        return;
+    d->checkingExtension = true;
+
+    bool tooSmall;
+    if (orientation() == Qt::Horizontal)
+        tooSmall = sz.width() < sizeHint().width();
+    else
+        tooSmall = sz.height() < sizeHint().height();
+
+    if (tooSmall) {
+        createPopup();
+        if (d->extensionPopup->actions().count()) {
+            // parentWidget()->width() used since the Q3ToolBar width
+            // will never be less than minimumSize()
+            if (orientation() == Qt::Horizontal)
+                d->extension->setGeometry((parentWidget() ? parentWidget()->width() : width()) - 20,
+                                          1, 20, height() - 2);
+            else
+                d->extension->setGeometry(1, (parentWidget() ? parentWidget()->height() : height()) - 20,
+                                          width() - 2, 20);
+            d->extension->show();
+            d->extension->raise();
+        } else {
+            delete d->extension;
+            d->extension = 0;
+            delete d->extensionPopup;
+            d->extensionPopup = 0;
+        }
+    } else {
+        delete d->extension;
+        d->extension = 0;
+        delete d->extensionPopup;
+        d->extensionPopup = 0;
+    }
+    d->checkingExtension = false;
+}
+
+
+/*!
+    \internal
+*/
+
+void Q3ToolBar::setMinimumSize(int, int)
+{
+}
+
+/* from chaunsee:
+
+1.  Tool Bars should contain only high-frequency functions.  Avoid putting
+things like About and Exit on a tool bar unless they are frequent functions.
+
+2.  All tool bar buttons must have some keyboard access method (it can be a
+menu or shortcut key or a function in a dialog box that can be accessed
+through the keyboard).
+
+3.  Make tool bar functions as efficient as possible (the common example is to
+Print in Microsoft applications, it doesn't bring up the Print dialog box, it
+prints immediately to the default printer).
+
+4.  Avoid turning tool bars into graphical menu bars.  To me, a tool bar should
+be efficient. Once you make almost all the items in a tool bar into graphical
+pull-down menus, you start to lose efficiency.
+
+5.  Make sure that adjacent icons are distinctive. There are some tool bars
+where you see a group of 4-5 icons that represent related functions, but they
+are so similar that you can't differentiate among them.         These tool bars are
+often a poor attempt at a "common visual language".
+
+6.  Use any de facto standard icons of your platform (for windows use the
+cut, copy and paste icons provided in dev kits rather than designing your
+own).
+
+7.  Avoid putting a highly destructive tool bar button (delete database) by a
+safe, high-frequency button (Find) -- this will yield 1-0ff errors).
+
+8.  Tooltips in many Microsoft products simply reiterate the menu text even
+when that is not explanatory.  Consider making your tooltips slightly more
+verbose and explanatory than the corresponding menu item.
+
+9.  Keep the tool bar as stable as possible when you click on different
+objects. Consider disabling tool bar buttons if they are used in most, but not
+all contexts.
+
+10.  If you have multiple tool bars (like the Microsoft MMC snap-ins have),
+put the most stable tool bar to at the left with less stable ones to the
+right. This arrangement (stable to less stable) makes the tool bar somewhat
+more predictable.
+
+11.  Keep a single tool bar to fewer than 20 items divided into 4-7 groups of
+items.
+*/
+
+QT_END_NAMESPACE
+
+#endif