src/qt3support/widgets/q3toolbar.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt3Support module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "q3toolbar.h"
       
    43 #ifndef QT_NO_TOOLBAR
       
    44 
       
    45 #include "q3mainwindow.h"
       
    46 #include "qapplication.h"
       
    47 #include "q3combobox.h"
       
    48 #include "qcursor.h"
       
    49 #include "qdesktopwidget.h"
       
    50 #include "qdrawutil.h"
       
    51 #include "qevent.h"
       
    52 #include "qframe.h"
       
    53 #include "qlayout.h"
       
    54 #include "qmap.h"
       
    55 #include "qpainter.h"
       
    56 #include "q3popupmenu.h"
       
    57 #include "qstyle.h"
       
    58 #include "qstyleoption.h"
       
    59 #include "qtimer.h"
       
    60 #include "qtoolbutton.h"
       
    61 #include "qtooltip.h"
       
    62 
       
    63 QT_BEGIN_NAMESPACE
       
    64 
       
    65 static const char * const arrow_v_xpm[] = {
       
    66     "7 9 3 1",
       
    67     "            c None",
       
    68     ".            c #000000",
       
    69     "+            c none",
       
    70     ".+++++.",
       
    71     "..+++..",
       
    72     "+..+..+",
       
    73     "++...++",
       
    74     ".++.++.",
       
    75     "..+++..",
       
    76     "+..+..+",
       
    77     "++...++",
       
    78     "+++.+++"};
       
    79 
       
    80 static const char * const arrow_h_xpm[] = {
       
    81     "9 7 3 1",
       
    82     "            c None",
       
    83     ".            c #000000",
       
    84     "+            c none",
       
    85     "..++..+++",
       
    86     "+..++..++",
       
    87     "++..++..+",
       
    88     "+++..++..",
       
    89     "++..++..+",
       
    90     "+..++..++",
       
    91     "..++..+++"};
       
    92 
       
    93 class Q3ToolBarExtensionWidget;
       
    94 
       
    95 class Q3ToolBarPrivate
       
    96 {
       
    97 public:
       
    98     Q3ToolBarPrivate() : moving(false), checkingExtension(false) {
       
    99     }
       
   100 
       
   101     bool moving;
       
   102     bool checkingExtension;
       
   103     Q3ToolBarExtensionWidget *extension;
       
   104     Q3PopupMenu *extensionPopup;
       
   105 
       
   106     QMap<QAction *, QWidget *> actions;
       
   107 };
       
   108 
       
   109 
       
   110 class Q3ToolBarSeparator : public QWidget
       
   111 {
       
   112     Q_OBJECT
       
   113 public:
       
   114     Q3ToolBarSeparator(Qt::Orientation, Q3ToolBar *parent, const char* name=0);
       
   115 
       
   116     QSize sizeHint() const;
       
   117     Qt::Orientation orientation() const { return orient; }
       
   118 public slots:
       
   119     void setOrientation(Qt::Orientation);
       
   120 protected:
       
   121     void changeEvent(QEvent *);
       
   122     void paintEvent(QPaintEvent *);
       
   123 
       
   124 private:
       
   125     Qt::Orientation orient;
       
   126 };
       
   127 
       
   128 class Q3ToolBarExtensionWidget : public QWidget
       
   129 {
       
   130     Q_OBJECT
       
   131 
       
   132 public:
       
   133     Q3ToolBarExtensionWidget(QWidget *w);
       
   134     void setOrientation(Qt::Orientation o);
       
   135     QToolButton *button() const { return tb; }
       
   136 
       
   137 protected:
       
   138     void resizeEvent(QResizeEvent *e) {
       
   139         QWidget::resizeEvent(e);
       
   140         layOut();
       
   141     }
       
   142 
       
   143 private:
       
   144     void layOut();
       
   145     QToolButton *tb;
       
   146     Qt::Orientation orient;
       
   147 
       
   148 };
       
   149 
       
   150 Q3ToolBarExtensionWidget::Q3ToolBarExtensionWidget(QWidget *w)
       
   151     : QWidget(w, "qt_dockwidget_internal")
       
   152 {
       
   153     tb = new QToolButton(this, "qt_toolbar_ext_button");
       
   154     tb->setAutoRaise(true);
       
   155     setOrientation(Qt::Horizontal);
       
   156     setAutoFillBackground(true);
       
   157 }
       
   158 
       
   159 void Q3ToolBarExtensionWidget::setOrientation(Qt::Orientation o)
       
   160 {
       
   161     orient = o;
       
   162     if (orient == Qt::Horizontal)
       
   163         tb->setIcon(QPixmap((const char **)arrow_h_xpm));
       
   164     else
       
   165         tb->setIcon(QPixmap((const char **)arrow_v_xpm));
       
   166     layOut();
       
   167 }
       
   168 
       
   169 void Q3ToolBarExtensionWidget::layOut()
       
   170 {
       
   171     tb->setGeometry(2, 2, width() - 4, height() - 4);
       
   172 }
       
   173 
       
   174 Q3ToolBarSeparator::Q3ToolBarSeparator(Qt::Orientation o , Q3ToolBar *parent,
       
   175                                      const char* name)
       
   176     : QWidget(parent, name)
       
   177 {
       
   178     connect(parent, SIGNAL(orientationChanged(Qt::Orientation)),
       
   179              this, SLOT(setOrientation(Qt::Orientation)));
       
   180     setOrientation(o);
       
   181     setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
       
   182 }
       
   183 
       
   184 
       
   185 
       
   186 void Q3ToolBarSeparator::setOrientation(Qt::Orientation o)
       
   187 {
       
   188     orient = o;
       
   189 }
       
   190 
       
   191 void Q3ToolBarSeparator::changeEvent(QEvent *ev)
       
   192 {
       
   193     if(ev->type() == QEvent::StyleChange)
       
   194         setOrientation(orient);
       
   195     QWidget::changeEvent(ev);
       
   196 }
       
   197 
       
   198 static QStyleOption getStyleOption(const Q3ToolBarSeparator *tbs)
       
   199 {
       
   200     QStyleOption opt(0);
       
   201     opt.rect = tbs->rect();
       
   202     opt.palette = tbs->palette();
       
   203     if (tbs->orientation() == Qt::Horizontal)
       
   204         opt.state = QStyle::State_Horizontal;
       
   205     else
       
   206         opt.state = QStyle::State_None;
       
   207     return opt;
       
   208 }
       
   209 
       
   210 QSize Q3ToolBarSeparator::sizeHint() const
       
   211 {
       
   212     QStyleOption opt = getStyleOption(this);
       
   213     int extent = style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, this);
       
   214     if (orient == Qt::Horizontal)
       
   215         return QSize(extent, 0);
       
   216     else
       
   217         return QSize(0, extent);
       
   218 }
       
   219 
       
   220 void Q3ToolBarSeparator::paintEvent(QPaintEvent *)
       
   221 {
       
   222     QPainter p(this);
       
   223     QStyleOption opt = getStyleOption(this);
       
   224     style()->drawPrimitive(QStyle::PE_Q3DockWindowSeparator, &opt, &p, this);
       
   225 }
       
   226 
       
   227 QT_BEGIN_INCLUDE_NAMESPACE
       
   228 #include "q3toolbar.moc"
       
   229 QT_END_INCLUDE_NAMESPACE
       
   230 
       
   231 
       
   232 /*!
       
   233     \class Q3ToolBar
       
   234     \brief The Q3ToolBar class provides a movable panel containing
       
   235     widgets such as tool buttons.
       
   236 
       
   237     \compat
       
   238 
       
   239     A toolbar is a panel that contains a set of controls, usually
       
   240     represented by small icons. It's purpose is to provide quick
       
   241     access to frequently used commands or options. Within a
       
   242     Q3MainWindow the user can drag toolbars within and between the
       
   243     \link Q3DockArea dock areas\endlink. Toolbars can also be dragged
       
   244     out of any dock area to float freely as top-level windows.
       
   245 
       
   246     Q3ToolBar is a specialization of QDockWindow, and so provides all
       
   247     the functionality of a QDockWindow.
       
   248 
       
   249     To use Q3ToolBar you simply create a Q3ToolBar as a child of a
       
   250     Q3MainWindow, create a number of QToolButton widgets (or other
       
   251     widgets) in left to right (or top to bottom) order and call
       
   252     addSeparator() when you want a separator. When a toolbar is
       
   253     floated the caption used is the label given in the constructor
       
   254     call. This can be changed with setLabel().
       
   255 
       
   256     You may use most widgets within a toolbar, with QToolButton and
       
   257     QComboBox being the most common. But note that the toolbar's
       
   258     actions must be \l {Q3Action}s.
       
   259 
       
   260     If you create a new widget on an already visible Q3ToolBar, this
       
   261     widget will automatically become visible without needing a show()
       
   262     call. (This differs from every other Qt widget container. We
       
   263     recommend calling show() anyway since we hope to fix this anomaly
       
   264     in a future release.)
       
   265 
       
   266     Q3ToolBars, like QDockWindows, are located in \l{Q3DockArea}s or
       
   267     float as top-level windows. Q3MainWindow provides four Q3DockAreas
       
   268     (top, left, right and bottom). When you create a new toolbar (as
       
   269     in the example above) as a child of a Q3MainWindow the toolbar will
       
   270     be added to the top dock area. You can move it to another dock
       
   271     area (or float it) by calling Q3MainWindow::moveDockWindow(). Dock
       
   272     areas lay out their windows in lines.
       
   273 
       
   274     If the main window is resized so that the area occupied by the
       
   275     toolbar is too small to show all its widgets a little arrow button
       
   276     (which looks like a right-pointing chevron, '&#187;') will appear
       
   277     at the right or bottom of the toolbar depending on its
       
   278     orientation. Clicking this button pops up a menu that shows the
       
   279     'overflowing' items. QToolButtons are represented in the menu using
       
   280     their textLabel property, other QAbstractButton subclasses are represented
       
   281     using their text property, and QComboBoxes are represented as submenus,
       
   282     with the caption text being used in the submenu item.
       
   283 
       
   284     Usually a toolbar will get precisely the space it needs. However,
       
   285     with setHorizontalStretchable(), setVerticalStretchable() or
       
   286     setStretchableWidget() you can tell the main window to expand the
       
   287     toolbar to fill all available space in the specified orientation.
       
   288 
       
   289     The toolbar arranges its buttons either horizontally or vertically
       
   290     (see orientation() for details). Generally, Q3DockArea will set the
       
   291     orientation correctly for you, but you can set it yourself with
       
   292     setOrientation() and track any changes by connecting to the
       
   293     orientationChanged() signal.
       
   294 
       
   295     You can use the clear() method to remove all items from a toolbar.
       
   296 
       
   297     \img qdockwindow.png Toolbar (dock window)
       
   298     \caption A floating QToolbar (dock window)
       
   299 
       
   300     \sa QToolButton Q3MainWindow
       
   301 */
       
   302 
       
   303 /*!
       
   304     Constructs an empty toolbar.
       
   305 
       
   306     The toolbar is called \a name and is a child of \a parent and is
       
   307     managed by \a parent. It is initially located in dock area \a dock
       
   308     and is labeled \a label. If \a newLine is true the toolbar will be
       
   309     placed on a new line in the dock area.
       
   310 */
       
   311 
       
   312 Q3ToolBar::Q3ToolBar(const QString &label,
       
   313                     Q3MainWindow * parent, Qt::ToolBarDock dock,
       
   314                     bool newLine, const char * name)
       
   315     : Q3DockWindow(InDock, parent, name, 0, true)
       
   316 {
       
   317     mw = parent;
       
   318     init();
       
   319 
       
   320     if (parent)
       
   321         parent->addToolBar(this, label, dock, newLine);
       
   322 }
       
   323 
       
   324 
       
   325 /*!
       
   326     Constructs an empty horizontal toolbar.
       
   327 
       
   328     The toolbar is called \a name and is a child of \a parent and is
       
   329     managed by \a mainWindow. The \a label and \a newLine parameters
       
   330     are passed straight to Q3MainWindow::addDockWindow(). \a name and
       
   331     the widget flags \a f are passed on to the Q3DockWindow constructor.
       
   332 
       
   333     Use this constructor if you want to create torn-off (undocked,
       
   334     floating) toolbars or toolbars in the \link QStatusBar status
       
   335     bar\endlink.
       
   336 */
       
   337 
       
   338 Q3ToolBar::Q3ToolBar(const QString &label, Q3MainWindow * mainWindow,
       
   339                     QWidget * parent, bool newLine, const char * name,
       
   340                     Qt::WindowFlags f)
       
   341     : Q3DockWindow(InDock, parent, name, f, true)
       
   342 {
       
   343     mw = mainWindow;
       
   344     init();
       
   345 
       
   346     setParent(parent);
       
   347 
       
   348     if (mainWindow)
       
   349         mainWindow->addToolBar(this, label, Qt::DockUnmanaged, newLine);
       
   350 }
       
   351 
       
   352 
       
   353 /*!
       
   354     \overload
       
   355 
       
   356     Constructs an empty toolbar called \a name, with parent \a parent,
       
   357     in its \a parent's top dock area, without any label and without
       
   358     requiring a newline.
       
   359 */
       
   360 
       
   361 Q3ToolBar::Q3ToolBar(Q3MainWindow * parent, const char * name)
       
   362     : Q3DockWindow(InDock, parent, name, 0, true)
       
   363 {
       
   364     mw = parent;
       
   365     init();
       
   366 
       
   367     if (parent)
       
   368         parent->addToolBar(this, QString(), Qt::DockTop);
       
   369 }
       
   370 
       
   371 /*!
       
   372     \internal
       
   373 
       
   374   Common initialization code. Requires that \c mw and \c o are set.
       
   375   Does not call Q3MainWindow::addDockWindow().
       
   376 */
       
   377 void Q3ToolBar::init()
       
   378 {
       
   379     d = new Q3ToolBarPrivate;
       
   380     d->extension = 0;
       
   381     d->extensionPopup = 0;
       
   382     sw = 0;
       
   383 
       
   384     setBackgroundRole(QPalette::Button);
       
   385     setFocusPolicy(Qt::NoFocus);
       
   386     setFrameStyle(QFrame::ToolBarPanel | QFrame::Raised);
       
   387 }
       
   388 
       
   389 /*!
       
   390     Destructor.
       
   391 */
       
   392 
       
   393 Q3ToolBar::~Q3ToolBar()
       
   394 {
       
   395     delete d;
       
   396 }
       
   397 
       
   398 /*!
       
   399     \reimp
       
   400 */
       
   401 
       
   402 void Q3ToolBar::setOrientation(Qt::Orientation o)
       
   403 {
       
   404     Q3DockWindow::setOrientation(o);
       
   405     if (d->extension)
       
   406         d->extension->setOrientation(o);
       
   407     QObjectList childList = children();
       
   408     for (int i = 0; i < childList.size(); ++i) {
       
   409         Q3ToolBarSeparator* w = qobject_cast<Q3ToolBarSeparator*>(childList.at(i));
       
   410         if (w)
       
   411             w->setOrientation(o);
       
   412     }
       
   413 }
       
   414 
       
   415 /*!
       
   416     Adds a separator to the right/bottom of the toolbar.
       
   417 */
       
   418 
       
   419 void Q3ToolBar::addSeparator()
       
   420 {
       
   421     (void) new Q3ToolBarSeparator(orientation(), this, "toolbar separator");
       
   422 }
       
   423 
       
   424 /*!
       
   425   \internal
       
   426 */
       
   427 
       
   428 void Q3ToolBar::styleChange(QStyle &oldStyle)
       
   429 {
       
   430     Q3DockWindow::styleChange(oldStyle);
       
   431 }
       
   432 
       
   433 
       
   434 /*!
       
   435     \reimp
       
   436 */
       
   437 void Q3ToolBar::setVisible(bool visible)
       
   438 {
       
   439     Q3DockWindow::setVisible(visible);
       
   440     if (mw)
       
   441         mw->triggerLayout(false);
       
   442     if (visible)
       
   443         checkForExtension(size());
       
   444 }
       
   445 
       
   446 /*!
       
   447     Returns a pointer to the Q3MainWindow which manages this toolbar.
       
   448 */
       
   449 
       
   450 Q3MainWindow * Q3ToolBar::mainWindow() const
       
   451 {
       
   452     return mw;
       
   453 }
       
   454 
       
   455 
       
   456 /*!
       
   457     Sets the widget \a w to be expanded if this toolbar is requested
       
   458     to stretch.
       
   459 
       
   460     The request to stretch might occur because Q3MainWindow
       
   461     right-justifies the dock area the toolbar is in, or because this
       
   462     toolbar's isVerticalStretchable() or isHorizontalStretchable() is
       
   463     set to true.
       
   464 
       
   465     If you call this function and the toolbar is not yet stretchable,
       
   466     setStretchable() is called.
       
   467 
       
   468     \sa Q3MainWindow::setRightJustification(), setVerticalStretchable(),
       
   469     setHorizontalStretchable()
       
   470 */
       
   471 
       
   472 void Q3ToolBar::setStretchableWidget(QWidget * w)
       
   473 {
       
   474     sw = w;
       
   475     boxLayout()->setStretchFactor(w, 1);
       
   476 
       
   477     if (!isHorizontalStretchable() && !isVerticalStretchable()) {
       
   478         if (orientation() == Qt::Horizontal)
       
   479             setHorizontalStretchable(true);
       
   480         else
       
   481             setVerticalStretchable(true);
       
   482     }
       
   483 }
       
   484 
       
   485 
       
   486 /*!
       
   487     \reimp
       
   488 */
       
   489 
       
   490 bool Q3ToolBar::event(QEvent * e)
       
   491 {
       
   492     bool r =  Q3DockWindow::event(e);
       
   493     // After the event filters have dealt with it, do our stuff.
       
   494     if (e->type() == QEvent::ChildInserted) {
       
   495         QObject * child = ((QChildEvent*)e)->child();
       
   496         if (child && child->isWidgetType() && !((QWidget*)child)->isWindow()
       
   497              && child->parent() == this
       
   498             && QLatin1String("qt_dockwidget_internal") != child->objectName()) {
       
   499             boxLayout()->addWidget((QWidget*)child);
       
   500             QLayoutItem *item = boxLayout()->itemAt(boxLayout()->indexOf((QWidget*)child));
       
   501             if (QToolButton *button = qobject_cast<QToolButton*>(child)) {
       
   502                 item->setAlignment(Qt::AlignHCenter);
       
   503                 button->setFocusPolicy(Qt::NoFocus);
       
   504                 if (mw) {
       
   505                     QObject::connect(mw, SIGNAL(pixmapSizeChanged(bool)),
       
   506                                      button, SLOT(setUsesBigPixmap(bool)));
       
   507                     button->setUsesBigPixmap(mw->usesBigPixmaps());
       
   508                     QObject::connect(mw, SIGNAL(usesTextLabelChanged(bool)),
       
   509                                      child, SLOT(setUsesTextLabel(bool)));
       
   510                     button->setUsesTextLabel(mw->usesTextLabel());
       
   511                 }
       
   512                 button->setAutoRaise(true);
       
   513             }
       
   514             if (isVisible()) {
       
   515                 // toolbar compatibility: we auto show widgets that
       
   516                 // are not explicitly hidden
       
   517                 if (((QWidget*)child)->testAttribute(Qt::WA_WState_Hidden)
       
   518                     && !((QWidget*)child)->testAttribute(Qt::WA_WState_ExplicitShowHide))
       
   519                     ((QWidget*)child)->show();
       
   520                 checkForExtension(size());
       
   521             }
       
   522         }
       
   523         if (child && child->isWidgetType() && ((QWidget*)child) == sw)
       
   524             boxLayout()->setStretchFactor((QWidget*)child, 1);
       
   525     } else if (e->type() == QEvent::Show) {
       
   526         layout()->activate();
       
   527     } else if (e->type() == QEvent::LayoutHint && place() == OutsideDock) {
       
   528         adjustSize();
       
   529     }
       
   530     return r;
       
   531 }
       
   532 
       
   533 
       
   534 /*!
       
   535     \property Q3ToolBar::label
       
   536     \brief the toolbar's label.
       
   537 
       
   538     If the toolbar is floated the label becomes the toolbar window's
       
   539     caption. There is no default label text.
       
   540 */
       
   541 
       
   542 void Q3ToolBar::setLabel(const QString & label)
       
   543 {
       
   544     l = label;
       
   545     setWindowTitle(l);
       
   546 }
       
   547 
       
   548 QString Q3ToolBar::label() const
       
   549 {
       
   550     return l;
       
   551 }
       
   552 
       
   553 
       
   554 /*!
       
   555     Deletes all the toolbar's child widgets.
       
   556 */
       
   557 
       
   558 void Q3ToolBar::clear()
       
   559 {
       
   560     QObjectList childList = children();
       
   561     d->extension = 0;
       
   562     d->extensionPopup = 0; //they will both be destroyed by the following code
       
   563     for (int i = 0; i < childList.size(); ++i) {
       
   564         QObject *obj = childList.at(i);
       
   565         if (obj->isWidgetType() && QLatin1String("qt_dockwidget_internal") != obj->objectName())
       
   566             delete obj;
       
   567     }
       
   568 }
       
   569 
       
   570 /*!
       
   571     \internal
       
   572 */
       
   573 
       
   574 QSize Q3ToolBar::minimumSize() const
       
   575 {
       
   576     if (orientation() == Qt::Horizontal)
       
   577         return QSize(0, Q3DockWindow::minimumSize().height());
       
   578     return QSize(Q3DockWindow::minimumSize().width(), 0);
       
   579 }
       
   580 
       
   581 /*!
       
   582     \reimp
       
   583 */
       
   584 
       
   585 QSize Q3ToolBar::minimumSizeHint() const
       
   586 {
       
   587     if (orientation() == Qt::Horizontal)
       
   588         return QSize(0, Q3DockWindow::minimumSizeHint().height());
       
   589     return QSize(Q3DockWindow::minimumSizeHint().width(), 0);
       
   590 }
       
   591 
       
   592 void Q3ToolBar::createPopup()
       
   593 {
       
   594     if (!d->extensionPopup) {
       
   595         d->extensionPopup = new Q3PopupMenu(this, "qt_dockwidget_internal");
       
   596         connect(d->extensionPopup, SIGNAL(aboutToShow()), this, SLOT(createPopup()));
       
   597     }
       
   598 
       
   599     if (!d->extension) {
       
   600         d->extension = new Q3ToolBarExtensionWidget(this);
       
   601         d->extension->setOrientation(orientation());
       
   602         d->extension->button()->setPopup(d->extensionPopup);
       
   603         d->extension->button()->setPopupMode(QToolButton::InstantPopup);
       
   604     }
       
   605 
       
   606     d->extensionPopup->clear();
       
   607 
       
   608     // delete submenus
       
   609     QObjectList popups = d->extensionPopup->queryList("Q3PopupMenu", 0, false, true);
       
   610     while (!popups.isEmpty())
       
   611         delete popups.takeFirst();
       
   612 
       
   613     QObjectList childlist = queryList("QWidget", 0, false, true);
       
   614     bool hide = false;
       
   615     bool doHide = false;
       
   616     int id;
       
   617     for (int i = 0; i < childlist.size(); ++i) {
       
   618         QObject *obj = childlist.at(i);
       
   619         if (!obj->isWidgetType() || obj == d->extension->button() || obj == d->extensionPopup
       
   620             || QLatin1String("qt_dockwidget_internal") == obj->objectName()) {
       
   621             continue;
       
   622         }
       
   623         int j = 2;
       
   624         QWidget *w = (QWidget*)obj;
       
   625         if (qobject_cast<Q3ComboBox*>(w))
       
   626             j = 1;
       
   627         hide = false;
       
   628 
       
   629         const int padding = 4; // extra pixels added by the layout hierarchy
       
   630         QPoint p(mapTo(this, w->geometry().bottomRight()));
       
   631         if (orientation() == Qt::Horizontal) {
       
   632             if ((p.x() > (doHide ? width() - d->extension->width() / j - padding : width() - padding))
       
   633                 || (p.x() > parentWidget()->width() - d->extension->width()))
       
   634                 hide = true;
       
   635         } else {
       
   636             if ((p.y() > (doHide ? height()- d->extension->height() / j - padding : height() - padding))
       
   637                 || (p.y() > parentWidget()->height() - d->extension->height()))
       
   638                 hide = true;
       
   639         }
       
   640         if (hide && w->isVisible()) {
       
   641             doHide = true;
       
   642             if (qobject_cast<QToolButton*>(w)) {
       
   643                 QToolButton *b = (QToolButton*)w;
       
   644                 QString s = b->textLabel();
       
   645                 if (s.isEmpty())
       
   646                     s = b->text();
       
   647                 if (b->popup() && b->popupDelay() == 0)
       
   648                     id = d->extensionPopup->insertItem(b->iconSet(), s, b->popup());
       
   649                 else
       
   650                     id = d->extensionPopup->insertItem(b->iconSet(), s, b, SLOT(click())) ;
       
   651                 if (b->isToggleButton())
       
   652                     d->extensionPopup->setItemChecked(id, b->isOn());
       
   653                 if (!b->isEnabled())
       
   654                     d->extensionPopup->setItemEnabled(id, false);
       
   655             } else if (qobject_cast<QAbstractButton*>(w)) {
       
   656                 QAbstractButton *b = (QAbstractButton*)w;
       
   657                 QString s = b->text();
       
   658                 if (s.isEmpty())
       
   659                     s = QLatin1String("");
       
   660                 if (b->pixmap())
       
   661                     id = d->extensionPopup->insertItem(*b->pixmap(), s, b, SLOT(click()));
       
   662                 else
       
   663                     id = d->extensionPopup->insertItem(s, b, SLOT(click()));
       
   664                 if (b->isToggleButton())
       
   665                     d->extensionPopup->setItemChecked(id, b->isOn());
       
   666                 if (!b->isEnabled())
       
   667                     d->extensionPopup->setItemEnabled(id, false);
       
   668 #ifndef QT_NO_COMBOBOX
       
   669             } else if (qobject_cast<Q3ComboBox*>(w)) {
       
   670                 Q3ComboBox *c = (Q3ComboBox*)w;
       
   671                 if (c->count() != 0) {
       
   672                     QString s = c->windowTitle();
       
   673                     if (s.isEmpty())
       
   674                         s = c->currentText();
       
   675                     int maxItems = 0;
       
   676                     Q3PopupMenu *cp = new Q3PopupMenu(d->extensionPopup);
       
   677                     cp->setEnabled(c->isEnabled());
       
   678                     d->extensionPopup->insertItem(s, cp);
       
   679                     connect(cp, SIGNAL(activated(int)), c, SLOT(internalActivate(int)));
       
   680                     for (int i = 0; i < c->count(); ++i) {
       
   681                         QString tmp = c->text(i);
       
   682                         cp->insertItem(tmp, i);
       
   683                         if (c->currentText() == tmp)
       
   684                             cp->setItemChecked(i, true);
       
   685                         if (!maxItems) {
       
   686                             if (cp->actions().count() == 10) {
       
   687                                 int h = cp->sizeHint().height();
       
   688                                 maxItems = QApplication::desktop()->height() * 10 / h;
       
   689                             }
       
   690                         } else if (cp->actions().count() >= maxItems - 1) {
       
   691                             Q3PopupMenu* sp = new Q3PopupMenu(d->extensionPopup);
       
   692                             cp->insertItem(tr("More..."), sp);
       
   693                             cp = sp;
       
   694                             connect(cp, SIGNAL(activated(int)), c, SLOT(internalActivate(int)));
       
   695                         }
       
   696                     }
       
   697                 }
       
   698 #endif //QT_NO_COMBOBOX
       
   699             }
       
   700         }
       
   701     }
       
   702 }
       
   703 
       
   704 /*!
       
   705     \reimp
       
   706 */
       
   707 
       
   708 void Q3ToolBar::resizeEvent(QResizeEvent *e)
       
   709 {
       
   710     Q3DockWindow::resizeEvent(e);
       
   711     checkForExtension(e->size());
       
   712 }
       
   713 
       
   714 /*!
       
   715     \internal
       
   716 
       
   717     This function is called when an action is triggered. The relevant
       
   718     information is passed in the event \a e.
       
   719 */
       
   720 void Q3ToolBar::actionEvent(QActionEvent *e)
       
   721 {
       
   722     if (e->type() == QEvent::ActionAdded) {
       
   723         QAction *a = e->action();
       
   724         QWidget *w;
       
   725         if (a->isSeparator()) {
       
   726             w = new Q3ToolBarSeparator(orientation(), this, "toolbar separator");
       
   727         } else {
       
   728             QToolButton* btn = new QToolButton(this);
       
   729             btn->setDefaultAction(a);
       
   730             w = btn;
       
   731         }
       
   732         d->actions.insert(a, w);
       
   733     } else if (e->type() == QEvent::ActionRemoved) {
       
   734         QAction *a = e->action();
       
   735         delete d->actions.take(a);
       
   736     }
       
   737 }
       
   738 
       
   739 
       
   740 void Q3ToolBar::checkForExtension(const QSize &sz)
       
   741 {
       
   742     if (!isVisible())
       
   743         return;
       
   744 
       
   745     if (d->checkingExtension)
       
   746         return;
       
   747     d->checkingExtension = true;
       
   748 
       
   749     bool tooSmall;
       
   750     if (orientation() == Qt::Horizontal)
       
   751         tooSmall = sz.width() < sizeHint().width();
       
   752     else
       
   753         tooSmall = sz.height() < sizeHint().height();
       
   754 
       
   755     if (tooSmall) {
       
   756         createPopup();
       
   757         if (d->extensionPopup->actions().count()) {
       
   758             // parentWidget()->width() used since the Q3ToolBar width
       
   759             // will never be less than minimumSize()
       
   760             if (orientation() == Qt::Horizontal)
       
   761                 d->extension->setGeometry((parentWidget() ? parentWidget()->width() : width()) - 20,
       
   762                                           1, 20, height() - 2);
       
   763             else
       
   764                 d->extension->setGeometry(1, (parentWidget() ? parentWidget()->height() : height()) - 20,
       
   765                                           width() - 2, 20);
       
   766             d->extension->show();
       
   767             d->extension->raise();
       
   768         } else {
       
   769             delete d->extension;
       
   770             d->extension = 0;
       
   771             delete d->extensionPopup;
       
   772             d->extensionPopup = 0;
       
   773         }
       
   774     } else {
       
   775         delete d->extension;
       
   776         d->extension = 0;
       
   777         delete d->extensionPopup;
       
   778         d->extensionPopup = 0;
       
   779     }
       
   780     d->checkingExtension = false;
       
   781 }
       
   782 
       
   783 
       
   784 /*!
       
   785     \internal
       
   786 */
       
   787 
       
   788 void Q3ToolBar::setMinimumSize(int, int)
       
   789 {
       
   790 }
       
   791 
       
   792 /* from chaunsee:
       
   793 
       
   794 1.  Tool Bars should contain only high-frequency functions.  Avoid putting
       
   795 things like About and Exit on a tool bar unless they are frequent functions.
       
   796 
       
   797 2.  All tool bar buttons must have some keyboard access method (it can be a
       
   798 menu or shortcut key or a function in a dialog box that can be accessed
       
   799 through the keyboard).
       
   800 
       
   801 3.  Make tool bar functions as efficient as possible (the common example is to
       
   802 Print in Microsoft applications, it doesn't bring up the Print dialog box, it
       
   803 prints immediately to the default printer).
       
   804 
       
   805 4.  Avoid turning tool bars into graphical menu bars.  To me, a tool bar should
       
   806 be efficient. Once you make almost all the items in a tool bar into graphical
       
   807 pull-down menus, you start to lose efficiency.
       
   808 
       
   809 5.  Make sure that adjacent icons are distinctive. There are some tool bars
       
   810 where you see a group of 4-5 icons that represent related functions, but they
       
   811 are so similar that you can't differentiate among them.         These tool bars are
       
   812 often a poor attempt at a "common visual language".
       
   813 
       
   814 6.  Use any de facto standard icons of your platform (for windows use the
       
   815 cut, copy and paste icons provided in dev kits rather than designing your
       
   816 own).
       
   817 
       
   818 7.  Avoid putting a highly destructive tool bar button (delete database) by a
       
   819 safe, high-frequency button (Find) -- this will yield 1-0ff errors).
       
   820 
       
   821 8.  Tooltips in many Microsoft products simply reiterate the menu text even
       
   822 when that is not explanatory.  Consider making your tooltips slightly more
       
   823 verbose and explanatory than the corresponding menu item.
       
   824 
       
   825 9.  Keep the tool bar as stable as possible when you click on different
       
   826 objects. Consider disabling tool bar buttons if they are used in most, but not
       
   827 all contexts.
       
   828 
       
   829 10.  If you have multiple tool bars (like the Microsoft MMC snap-ins have),
       
   830 put the most stable tool bar to at the left with less stable ones to the
       
   831 right. This arrangement (stable to less stable) makes the tool bar somewhat
       
   832 more predictable.
       
   833 
       
   834 11.  Keep a single tool bar to fewer than 20 items divided into 4-7 groups of
       
   835 items.
       
   836 */
       
   837 
       
   838 QT_END_NAMESPACE
       
   839 
       
   840 #endif