src/qt3support/widgets/q3mainwindow.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 "q3mainwindow.h"
       
    43 #ifndef QT_NO_MAINWINDOW
       
    44 
       
    45 #include "qapplication.h"
       
    46 #include "qbitmap.h"
       
    47 #include "qcursor.h"
       
    48 #include "qdatetime.h"
       
    49 #include "q3dockarea.h"
       
    50 #include "qevent.h"
       
    51 #include "qlayout.h"
       
    52 #include "qmap.h"
       
    53 #include "qmenubar.h"
       
    54 #include "qpainter.h"
       
    55 #include "q3popupmenu.h"
       
    56 #include "q3scrollview.h"
       
    57 #include "qstatusbar.h"
       
    58 #include "qstringlist.h"
       
    59 #include "qstyle.h"
       
    60 #include "qstyleoption.h"
       
    61 #include "qtimer.h"
       
    62 #include "q3toolbar.h"
       
    63 #include "qtooltip.h"
       
    64 #include "qwhatsthis.h"
       
    65 #ifdef Q_WS_MAC
       
    66 #  include <private/qt_mac_p.h>
       
    67 #endif
       
    68 
       
    69 #include <private/q3mainwindow_p.h>
       
    70 
       
    71 QT_BEGIN_NAMESPACE
       
    72 
       
    73 class QHideDock;
       
    74 
       
    75 /* Q3MainWindowLayout, respects widthForHeight layouts (like the left
       
    76   and right docks are)
       
    77 */
       
    78 
       
    79 class Q3MainWindowLayout : public QLayout
       
    80 {
       
    81     Q_OBJECT
       
    82 
       
    83 public:
       
    84     Q3MainWindowLayout(Q3MainWindow *mw);
       
    85     ~Q3MainWindowLayout() {}
       
    86 
       
    87     void addItem(QLayoutItem *);
       
    88     void setLeftDock(Q3DockArea *l);
       
    89     void setRightDock(Q3DockArea *r);
       
    90     void setCentralWidget(QWidget *w);
       
    91     bool hasHeightForWidth() const { return false; }
       
    92     QSize sizeHint() const;
       
    93     QSize minimumSize() const;
       
    94     QLayoutItem *itemAt(int) const { return 0; } //###
       
    95     QLayoutItem *takeAt(int) { return 0; } //###
       
    96     int count() const { return 0; } //###
       
    97 
       
    98 protected:
       
    99     void setGeometry(const QRect &r) {
       
   100         QLayout::setGeometry(r);
       
   101         layoutItems(r);
       
   102     }
       
   103 
       
   104 private:
       
   105     int layoutItems(const QRect&, bool testonly = false);
       
   106     int extraPixels() const;
       
   107 
       
   108     Q3DockArea *left, *right;
       
   109     QWidget *central;
       
   110     Q3MainWindow *mainWindow;
       
   111 
       
   112 };
       
   113 
       
   114 QSize Q3MainWindowLayout::sizeHint() const
       
   115 {
       
   116     int w = 0;
       
   117     int h = 0;
       
   118 
       
   119     if (left) {
       
   120         w += left->sizeHint().width();
       
   121         h = qMax(h, left->sizeHint().height());
       
   122     }
       
   123     if (right) {
       
   124         w += right->sizeHint().width();
       
   125         h = qMax(h, right->sizeHint().height());
       
   126     }
       
   127     if (central) {
       
   128         w += central->sizeHint().width();
       
   129         int diff = extraPixels();
       
   130         h = qMax(h, central->sizeHint().height() + diff);
       
   131     }
       
   132     return QSize(w, h);
       
   133 }
       
   134 
       
   135 QSize Q3MainWindowLayout::minimumSize() const
       
   136 {
       
   137     int w = 0;
       
   138     int h = 0;
       
   139 
       
   140     if (left) {
       
   141         QSize ms = left->minimumSizeHint().expandedTo(left->minimumSize());
       
   142         w += ms.width();
       
   143         h = qMax(h, ms.height());
       
   144     }
       
   145     if (right) {
       
   146         QSize ms = right->minimumSizeHint().expandedTo(right->minimumSize());
       
   147         w += ms.width();
       
   148         h = qMax(h, ms.height());
       
   149     }
       
   150     if (central) {
       
   151         QSize min = central->minimumSize().isNull() ?
       
   152                     central->minimumSizeHint() : central->minimumSize();
       
   153         w += min.width();
       
   154         int diff = extraPixels();
       
   155         h = qMax(h, min.height() + diff);
       
   156     }
       
   157     return QSize(w, h);
       
   158 }
       
   159 
       
   160 Q3MainWindowLayout::Q3MainWindowLayout(Q3MainWindow *mw)
       
   161     : left(0), right(0), central(0)
       
   162 {
       
   163     mainWindow = mw;
       
   164 }
       
   165 
       
   166 void Q3MainWindowLayout::setLeftDock(Q3DockArea *l)
       
   167 {
       
   168     left = l;
       
   169 }
       
   170 
       
   171 void Q3MainWindowLayout::setRightDock(Q3DockArea *r)
       
   172 {
       
   173     right = r;
       
   174 }
       
   175 
       
   176 void Q3MainWindowLayout::setCentralWidget(QWidget *w)
       
   177 {
       
   178     central = w;
       
   179 }
       
   180 
       
   181 int Q3MainWindowLayout::layoutItems(const QRect &r, bool testonly)
       
   182 {
       
   183     if (!left && !central && !right)
       
   184         return 0;
       
   185 
       
   186     int wl = 0, wr = 0;
       
   187     if (left)
       
   188         wl = ((Q3DockAreaLayout*)left->QWidget::layout())->widthForHeight(r.height());
       
   189     if (right)
       
   190         wr = ((Q3DockAreaLayout*)right->QWidget::layout())->widthForHeight(r.height());
       
   191     int w = r.width() - wr - wl;
       
   192     if (w < 0)
       
   193         w = 0;
       
   194 
       
   195     int diff = extraPixels();
       
   196     if (!testonly) {
       
   197         QRect g(geometry());
       
   198         if (left)
       
   199             left->setGeometry(QRect(g.x(), g.y() + diff, wl, r.height() - diff));
       
   200         if (right)
       
   201             right->setGeometry(QRect(g.x() + g.width() - wr, g.y() + diff, wr, r.height() - diff));
       
   202         if (central)
       
   203             central->setGeometry(g.x() + wl, g.y() + diff, w, r.height() - diff);
       
   204     }
       
   205 
       
   206     w = wl + wr;
       
   207     if (central)
       
   208         w += central->minimumSize().width();
       
   209     return w;
       
   210 }
       
   211 
       
   212 int Q3MainWindowLayout::extraPixels() const
       
   213 {
       
   214     if (mainWindow->d_func()->topDock->isEmpty() &&
       
   215          !(mainWindow->d_func()->leftDock->isEmpty() &&
       
   216            mainWindow->d_func()->rightDock->isEmpty())) {
       
   217         return 2;
       
   218     } else {
       
   219         return 0;
       
   220     }
       
   221 }
       
   222 
       
   223 void Q3MainWindowLayout::addItem(QLayoutItem * /* item */)
       
   224 {
       
   225 }
       
   226 
       
   227 /*
       
   228   QHideToolTip and QHideDock - minimized dock
       
   229 */
       
   230 
       
   231 #if 0
       
   232 class QHideToolTip : public QToolTip
       
   233 {
       
   234 public:
       
   235     QHideToolTip(QWidget *parent) : QToolTip(parent) {}
       
   236 
       
   237     void maybeTip(const QPoint &pos);
       
   238 };
       
   239 #endif
       
   240 
       
   241 
       
   242 class QHideDock : public QWidget
       
   243 {
       
   244     Q_OBJECT
       
   245 
       
   246 public:
       
   247     QHideDock(Q3MainWindow *parent) : QWidget(parent, "qt_hide_dock") {
       
   248         hide();
       
   249         setFixedHeight(style()->pixelMetric(QStyle::PM_DockWidgetHandleExtent, 0, this) + 3);
       
   250         pressedHandle = -1;
       
   251         pressed = false;
       
   252         setMouseTracking(true);
       
   253         win = parent;
       
   254 #if 0
       
   255         tip = new QHideToolTip(this);
       
   256 #endif
       
   257     }
       
   258     ~QHideDock()
       
   259     {
       
   260 #if 0
       
   261         delete tip;
       
   262 #endif
       
   263     }
       
   264 
       
   265 protected:
       
   266     void paintEvent(QPaintEvent *e) {
       
   267         QObjectList childList = children();
       
   268         if (childList.isEmpty())
       
   269             return;
       
   270         QPainter p(this);
       
   271         p.setClipRegion(e->rect());
       
   272         p.fillRect(e->rect(), palette().brush(QPalette::Window));
       
   273         int x = 0;
       
   274         for (int i = 0; i < childList.size(); ++i) {
       
   275             QObject *o = childList.at(i);
       
   276             Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
       
   277             if (!dw || !dw->isVisible())
       
   278                 continue;
       
   279             QStyleOptionQ3DockWindow opt;
       
   280             opt.rect.setRect(x, 0, 30, 10);
       
   281             opt.palette = palette();
       
   282             opt.docked = dw->area();
       
   283             opt.closeEnabled = dw->isCloseEnabled();
       
   284             opt.state = QStyle::State_None;
       
   285             if (i == pressedHandle)
       
   286                 opt.state |= QStyle::State_On;
       
   287 
       
   288             style()->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p, this);
       
   289             x += 30;
       
   290         }
       
   291     }
       
   292 
       
   293     void mousePressEvent(QMouseEvent *e) {
       
   294         pressed = true;
       
   295         QObjectList childList = children();
       
   296         if (childList.isEmpty())
       
   297             return;
       
   298         mouseMoveEvent(e);
       
   299         pressedHandle = -1;
       
   300 
       
   301         if (e->button() == Qt::RightButton && win->isDockMenuEnabled()) {
       
   302             // ### TODO: HideDock menu
       
   303         } else {
       
   304             mouseMoveEvent(e);
       
   305         }
       
   306     }
       
   307 
       
   308     void mouseMoveEvent(QMouseEvent *e) {
       
   309         QObjectList childList = children();
       
   310         if (childList.isEmpty())
       
   311             return;
       
   312         if (!pressed)
       
   313             return;
       
   314         int x = 0;
       
   315         if (e->y() >= 0 && e->y() <= height()) {
       
   316             for (int i = 0; i < childList.size(); ++i) {
       
   317                 QObject *o = childList.at(i);
       
   318                 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
       
   319                 if (!dw || !dw->isVisible())
       
   320                     continue;
       
   321                 if (e->x() >= x && e->x() <= x + 30) {
       
   322                     int old = pressedHandle;
       
   323                     pressedHandle = i;
       
   324                     if (pressedHandle != old)
       
   325                         repaint();
       
   326                     return;
       
   327                 }
       
   328                 x += 30;
       
   329             }
       
   330         }
       
   331         int old = pressedHandle;
       
   332         pressedHandle = -1;
       
   333         if (old != -1)
       
   334             repaint();
       
   335     }
       
   336 
       
   337     void mouseReleaseEvent(QMouseEvent *e) {
       
   338         pressed = false;
       
   339         if (pressedHandle == -1)
       
   340             return;
       
   341         QObjectList childList = children();
       
   342         if (childList.isEmpty())
       
   343             return;
       
   344         if (e->button() == Qt::LeftButton) {
       
   345             if (e->y() >= 0 && e->y() <= height()) {
       
   346                 QObject *o = childList.at(pressedHandle);
       
   347                 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
       
   348                 if (dw) {
       
   349                     dw->show();
       
   350                     dw->dock();
       
   351                 }
       
   352             }
       
   353         }
       
   354         pressedHandle = -1;
       
   355         repaint();
       
   356     }
       
   357 
       
   358     bool eventFilter(QObject *o, QEvent *e) {
       
   359         if (o == this || !o->isWidgetType())
       
   360             return QWidget::eventFilter(o, e);
       
   361         if (e->type() == QEvent::HideToParent ||
       
   362              e->type() == QEvent::ShowToParent)
       
   363             updateState();
       
   364         return QWidget::eventFilter(o, e);
       
   365     }
       
   366 
       
   367     void updateState() {
       
   368         bool visible = true;
       
   369         QObjectList childList = children();
       
   370         if (childList.isEmpty())
       
   371             return;
       
   372         for (int i = 0; i < childList.size(); ++i) {
       
   373             QObject *o = childList.at(i);
       
   374             Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
       
   375             if (!dw)
       
   376                 continue;
       
   377             if (dw->isHidden()) {
       
   378                 visible = false;
       
   379                 continue;
       
   380             }
       
   381             if (!dw->isVisible())
       
   382                 continue;
       
   383             visible = true;
       
   384             break;
       
   385         }
       
   386 
       
   387         if (visible)
       
   388             show();
       
   389         else
       
   390             hide();
       
   391         win->triggerLayout(false);
       
   392         update();
       
   393     }
       
   394 
       
   395     void childEvent(QChildEvent *e) {
       
   396         QWidget::childEvent(e);
       
   397         if (e->type() == QEvent::ChildInserted)
       
   398             e->child()->installEventFilter(this);
       
   399         else
       
   400             e->child()->removeEventFilter(this);
       
   401         updateState();
       
   402     }
       
   403 
       
   404 private:
       
   405     Q3MainWindow *win;
       
   406     int pressedHandle;
       
   407     bool pressed;
       
   408 #if 0
       
   409     QHideToolTip *tip;
       
   410     friend class QHideToolTip;
       
   411 #endif
       
   412 };
       
   413 
       
   414 #if 0
       
   415 void QHideToolTip::maybeTip(const QPoint &pos)
       
   416 {
       
   417     if (!parentWidget())
       
   418         return;
       
   419     QHideDock *dock = (QHideDock*)parentWidget();
       
   420 
       
   421     QObjectList dchilds = dock->children();
       
   422     if (dchilds.isEmpty())
       
   423         return;
       
   424     int x = 0;
       
   425     for (int i = 0; i < dchilds.size(); ++i) {
       
   426         QObject *o = dchilds.at(i);
       
   427         Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
       
   428         if (!dw || !dw->isVisible())
       
   429             continue;
       
   430         if (pos.x() >= x && pos.x() <= x + 30) {
       
   431             Q3DockWindow *dw = (Q3DockWindow*)o;
       
   432             if (!dw->windowTitle().isEmpty())
       
   433                 tip(QRect(x, 0, 30, dock->height()), dw->windowTitle());
       
   434             return;
       
   435         }
       
   436         x += 30;
       
   437     }
       
   438 }
       
   439 #endif
       
   440 
       
   441 /*!
       
   442     \class Q3MainWindow
       
   443     \brief The Q3MainWindow class provides a main application window,
       
   444     with a menu bar, dock windows (e.g. for toolbars), and a status
       
   445     bar.
       
   446 
       
   447     \compat
       
   448 
       
   449     Main windows are most often used to provide menus, toolbars and a
       
   450     status bar around a large central widget, such as a text edit,
       
   451     drawing canvas or QWorkspace (for MDI applications). Q3MainWindow
       
   452     is usually subclassed since this makes it easier to encapsulate
       
   453     the central widget, menus and toolbars as well as the window's
       
   454     state. Subclassing makes it possible to create the slots that are
       
   455     called when the user clicks menu items or toolbar buttons.
       
   456 
       
   457     We'll briefly review adding menu items and
       
   458     toolbar buttons then describe the facilities of Q3MainWindow
       
   459     itself.
       
   460 
       
   461     \snippet doc/src/snippets/code/src_qt3support_widgets_q3mainwindow.cpp 0
       
   462 
       
   463     Q3MainWindows may be created in their own right as shown above.
       
   464     The central widget is set with setCentralWidget(). Popup menus can
       
   465     be added to the default menu bar, widgets can be added to the
       
   466     status bar, toolbars and dock windows can be added to any of the
       
   467     dock areas.
       
   468 
       
   469     The main window will take care of the dock areas, and the geometry
       
   470     of the central widget, but all other aspects of the central widget
       
   471     are left to you. Q3MainWindow automatically detects the creation of
       
   472     a menu bar or status bar if you specify the Q3MainWindow as parent,
       
   473     or you can use the provided menuBar() and statusBar() functions.
       
   474     The functions menuBar() and statusBar() create a suitable widget
       
   475     if one doesn't exist, and update the window's layout to make
       
   476     space.
       
   477 
       
   478     New dock windows and toolbars can be added to a Q3MainWindow using
       
   479     addDockWindow(). Qt::Dock windows can be moved using moveDockWindow()
       
   480     and removed with removeDockWindow(). Q3MainWindow allows default
       
   481     dock window (toolbar) docking in all its dock areas (\c Top, \c
       
   482     Left, \c Right, \c Bottom). You can use setDockEnabled() to
       
   483     enable and disable docking areas for dock windows. When adding or
       
   484     moving dock windows you can specify their 'edge' (dock area). The
       
   485     currently available edges are: \c Top, \c Left, \c Right, \c
       
   486     Bottom, \c Minimized (effectively a 'hidden' dock area) and \c
       
   487     TornOff (floating). See \l Qt::Dock for an explanation of these
       
   488     areas. Note that the *ToolBar functions are included for backward
       
   489     compatibility; all new code should use the *DockWindow functions.
       
   490     QToolbar is a subclass of Q3DockWindow so all functions that work
       
   491     with dock windows work on toolbars in the same way.
       
   492 
       
   493     \target dwm
       
   494     If the user clicks the close button, then the dock window is
       
   495     hidden. A dock window can be hidden or unhidden by the user by
       
   496     right clicking a dock area and clicking the name of the relevant
       
   497     dock window on the pop up dock window menu. This menu lists the
       
   498     names of every dock window; visible dock windows have a tick
       
   499     beside their names. The dock window menu is created automatically
       
   500     as required by createDockWindowMenu(). Since it may not always be
       
   501     appropriate for a dock window to appear on this menu the
       
   502     setAppropriate() function is used to inform the main window
       
   503     whether or not the dock window menu should include a particular
       
   504     dock window. Double clicking a dock window handle (usually on the
       
   505     left-hand side of the dock window) undocks (floats) the dock
       
   506     window. Double clicking a floating dock window's title bar will
       
   507     dock the floating dock window. (See also
       
   508     \l{Q3MainWindow::DockWindows}.)
       
   509 
       
   510     Some functions change the appearance of a Q3MainWindow globally:
       
   511     \list
       
   512     \i Q3DockWindow::setHorizontalStretchable() and
       
   513     Q3DockWindow::setVerticalStretchable() are used to make specific dock
       
   514     windows or toolbars stretchable.
       
   515     \i setUsesBigPixmaps() is used to set whether tool buttons should
       
   516     draw small or large pixmaps (see QIcon for more information).
       
   517     \i setUsesTextLabel() is used to set whether tool buttons
       
   518     should display a textual label in addition to pixmaps
       
   519     (see QToolButton for more information).
       
   520     \endlist
       
   521 
       
   522     The user can drag dock windows into any enabled docking area. Qt::Dock
       
   523     windows can also be dragged \e within a docking area, for example
       
   524     to rearrange the order of some toolbars. Qt::Dock windows can also be
       
   525     dragged outside any docking area (undocked or 'floated'). Being
       
   526     able to drag dock windows can be enabled (the default) and
       
   527     disabled using setDockWindowsMovable().
       
   528 
       
   529     The \c Minimized edge is a hidden dock area. If this dock area is
       
   530     enabled the user can hide (minimize) a dock window or show (restore)
       
   531     a minimized dock window by clicking the dock window handle. If the
       
   532     user hovers the mouse cursor over one of the handles, the caption of
       
   533     the dock window is displayed in a tool tip (see
       
   534     Q3DockWindow::windowTitle() or Q3ToolBar::label()), so if you enable the
       
   535     \c Minimized dock area, it is best to specify a meaningful caption
       
   536     or label for each dock window. To minimize a dock window
       
   537     programmatically use moveDockWindow() with an edge of \c Minimized.
       
   538 
       
   539     Qt::Dock windows are moved transparently by default, i.e. during the
       
   540     drag an outline rectangle is drawn on the screen representing the
       
   541     position of the dock window as it moves. If you want the dock
       
   542     window to be shown normally whilst it is moved use
       
   543     setOpaqueMoving().
       
   544 
       
   545     The location of a dock window, i.e. its dock area and position
       
   546     within the dock area, can be determined by calling getLocation().
       
   547     Movable dock windows can be lined up to minimize wasted space with
       
   548     lineUpDockWindows(). Pointers to the dock areas are available from
       
   549     topDock(), leftDock(), rightDock() and bottomDock(). A customize
       
   550     menu item is added to the pop up dock window menu if
       
   551     isCustomizable() returns true; it returns false by default.
       
   552     Reimplement isCustomizable() and customize() if you want to offer
       
   553     this extra menu item, for example, to allow the user to change
       
   554     settings relating to the main window and its toolbars and dock
       
   555     windows.
       
   556 
       
   557     The main window's menu bar is fixed (at the top) by default. If
       
   558     you want a movable menu bar, create a QMenuBar as a stretchable
       
   559     widget inside its own movable dock window and restrict this dock
       
   560     window to only live within the \c Top or \c Bottom dock:
       
   561 
       
   562     \snippet doc/src/snippets/code/src_qt3support_widgets_q3mainwindow.cpp 1
       
   563 
       
   564     An application with multiple dock windows can choose to save the
       
   565     current dock window layout in order to restore it later, e.g. in
       
   566     the next session. You can do this by using the streaming operators
       
   567     for Q3MainWindow.
       
   568 
       
   569     To save the layout and positions of all the dock windows do this:
       
   570 
       
   571     \snippet doc/src/snippets/code/src_qt3support_widgets_q3mainwindow.cpp 2
       
   572 
       
   573     To restore the dock window positions and sizes (normally when the
       
   574     application is next started), do the following:
       
   575 
       
   576     \snippet doc/src/snippets/code/src_qt3support_widgets_q3mainwindow.cpp 3
       
   577 
       
   578     The QSettings class can be used in conjunction with the streaming
       
   579     operators to store the application's settings.
       
   580 
       
   581     Q3MainWindow's management of dock windows and toolbars is done
       
   582     transparently behind-the-scenes by Q3DockArea.
       
   583 
       
   584     For multi-document interfaces (MDI), use a QWorkspace as the
       
   585     central widget.
       
   586 
       
   587     Adding dock windows, e.g. toolbars, to Q3MainWindow's dock areas is
       
   588     straightforward. If the supplied dock areas are not sufficient for
       
   589     your application we suggest that you create a QWidget subclass and
       
   590     add your own dock areas (see \l Q3DockArea) to the subclass since
       
   591     Q3MainWindow provides functionality specific to the standard dock
       
   592     areas it provides.
       
   593 
       
   594     \sa Q3ToolBar Q3DockWindow QStatusBar QAction QMenuBar Q3PopupMenu QDialog
       
   595 */
       
   596 
       
   597 /*!
       
   598     \enum Q3MainWindow::DockWindows
       
   599 
       
   600     Right-clicking a dock area will pop-up the dock window menu
       
   601     (createDockWindowMenu() is called automatically). When called in
       
   602     code you can specify what items should appear on the menu with
       
   603     this enum.
       
   604 
       
   605     \value OnlyToolBars The menu will list all the toolbars, but not
       
   606     any other dock windows.
       
   607 
       
   608     \value NoToolBars The menu will list dock windows but not
       
   609     toolbars.
       
   610 
       
   611     \value AllDockWindows The menu will list all toolbars and other
       
   612     dock windows. (This is the default.)
       
   613 */
       
   614 
       
   615 /*!
       
   616     \fn void Q3MainWindow::addToolBar(Q3DockWindow *dockWindow,
       
   617     Qt::Dock position, bool newLine);
       
   618 
       
   619     Adds a new toolbar to the \a dockWindow. The toolbar is placed in
       
   620     the given \a position. If \a newLine is true the toolbar is put on
       
   621     a new line.
       
   622 */
       
   623 
       
   624 /*!
       
   625     \fn void Q3MainWindow::addToolBar(Q3DockWindow *dockWindow, const
       
   626     QString &label, Qt::Dock position, bool newLine)
       
   627     \overload
       
   628 
       
   629     The toolbar has the caption \a label and is placed in the given \a
       
   630     position.
       
   631 */
       
   632 
       
   633 /*!
       
   634     \fn void Q3MainWindow::moveToolBar(Q3DockWindow *dockWindow, Qt::Dock position);
       
   635 
       
   636     Moves the given \a dockWindow into the given \a position.
       
   637 */
       
   638 
       
   639 /*!
       
   640     \fn void Q3MainWindow::moveToolBar(Q3DockWindow *dockWindow,
       
   641     Qt::Dock position, bool nl, int index, int extraOffset)
       
   642     \overload
       
   643 
       
   644     The \a dockWindow is made the \a{index}-th item in the toolbar,
       
   645     moved over by \a extraOffset. If \a nl is true, the dock window is
       
   646     put on a new line.
       
   647 */
       
   648 
       
   649 /*!
       
   650     \fn void Q3MainWindow::removeToolBar(Q3DockWindow *dockWindow);
       
   651 
       
   652     Removes the toolbar from the given \a dockWindow.
       
   653 */
       
   654 
       
   655 /*!
       
   656     \fn void Q3MainWindow::lineUpToolBars(bool keepNewLines);
       
   657 
       
   658     Lines up the toolbars. Line breaks are preserved if \a
       
   659     keepNewLines is true.
       
   660 */
       
   661 
       
   662 /*!
       
   663     \fn void Q3MainWindow::toolBarPositionChanged(Q3ToolBar *toolbar);
       
   664 
       
   665     This signal is emitted when a \a toolbar is moved.
       
   666 */
       
   667 
       
   668 /*!
       
   669     \fn bool Q3MainWindow::toolBarsMovable() const
       
   670 
       
   671     Returns true if the window allows its toolbars to be moved; otherwise
       
   672     returns false.
       
   673 */
       
   674 
       
   675 /*!
       
   676     \fn void Q3MainWindow::setToolBarsMovable(bool b)
       
   677     If \a b is true the tool bars can be moved.
       
   678 */
       
   679 
       
   680 /*!
       
   681     Constructs an empty main window. The \a parent, \a name and widget
       
   682     flags \a f, are passed on to the QWidget constructor.
       
   683 
       
   684     By default, the widget flags are set to Qt::WType_TopLevel rather
       
   685     than 0 as they are with QWidget. If you don't want your
       
   686     Q3MainWindow to be a top level widget then you will need to set \a
       
   687     f to 0.
       
   688 */
       
   689 
       
   690 Q3MainWindow::Q3MainWindow(QWidget * parent, const char * name, Qt::WindowFlags f)
       
   691     : QWidget(*new Q3MainWindowPrivate, parent, f)
       
   692 {
       
   693     Q_D(Q3MainWindow);
       
   694     setObjectName(QLatin1String(name));
       
   695 #ifdef Q_WS_MAC
       
   696     d->opaque = true;
       
   697 #else
       
   698     d->opaque = false;
       
   699 #endif
       
   700     installEventFilter(this);
       
   701     d->topDock = new Q3DockArea(Qt::Horizontal, Q3DockArea::Normal, this, "qt_top_dock");
       
   702     d->topDock->installEventFilter(this);
       
   703     d->bottomDock = new Q3DockArea(Qt::Horizontal, Q3DockArea::Reverse, this, "qt_bottom_dock");
       
   704     d->bottomDock->installEventFilter(this);
       
   705     d->leftDock = new Q3DockArea(Qt::Vertical, Q3DockArea::Normal, this, "qt_left_dock");
       
   706     d->leftDock->installEventFilter(this);
       
   707     d->rightDock = new Q3DockArea(Qt::Vertical, Q3DockArea::Reverse, this, "qt_right_dock");
       
   708     d->rightDock->installEventFilter(this);
       
   709     d->hideDock = new QHideDock(this);
       
   710 }
       
   711 
       
   712 
       
   713 /*!
       
   714     Destroys the object and frees any allocated resources.
       
   715 */
       
   716 
       
   717 Q3MainWindow::~Q3MainWindow()
       
   718 {
       
   719     delete layout();
       
   720 }
       
   721 
       
   722 #ifndef QT_NO_MENUBAR
       
   723 /*!
       
   724     Sets this main window to use the menu bar \a newMenuBar.
       
   725 
       
   726     The existing menu bar (if any) is deleted along with its contents.
       
   727 
       
   728     \sa menuBar()
       
   729 */
       
   730 
       
   731 void Q3MainWindow::setMenuBar(QMenuBar * newMenuBar)
       
   732 {
       
   733     Q_D(Q3MainWindow);
       
   734     if (!newMenuBar)
       
   735         return;
       
   736     if (d->mb)
       
   737         delete d->mb;
       
   738     d->mb = newMenuBar;
       
   739     d->mb->installEventFilter(this);
       
   740     triggerLayout();
       
   741 }
       
   742 
       
   743 
       
   744 /*!
       
   745     Returns the menu bar for this window.
       
   746 
       
   747     If there isn't one, then menuBar() creates an empty menu bar.
       
   748 
       
   749     \sa statusBar()
       
   750 */
       
   751 
       
   752 QMenuBar * Q3MainWindow::menuBar() const
       
   753 {
       
   754     Q_D(const Q3MainWindow);
       
   755     if (d->mb)
       
   756         return d->mb;
       
   757 
       
   758     QObjectList l = queryList("QMenuBar", 0, false, false);
       
   759     QMenuBar * b;
       
   760     if (l.size()) {
       
   761         b = static_cast<QMenuBar *>(l.at(0));
       
   762     } else {
       
   763         b = new QMenuBar((Q3MainWindow *)this);
       
   764         b->setObjectName(QLatin1String("automatic menu bar"));
       
   765         b->show();
       
   766     }
       
   767     d->mb = b;
       
   768     d->mb->installEventFilter(const_cast<Q3MainWindow *>(this));
       
   769     ((Q3MainWindow *)this)->triggerLayout();
       
   770     return b;
       
   771 }
       
   772 #endif // QT_NO_MENUBAR
       
   773 
       
   774 /*!
       
   775     Sets this main window to use the status bar \a newStatusBar.
       
   776 
       
   777     The existing status bar (if any) is deleted along with its
       
   778     contents.
       
   779 
       
   780     Note that \a newStatusBar \e must be a child of this main window,
       
   781     and that it is not automatically displayed. If you call this
       
   782     function after show(), you will probably also need to call
       
   783     newStatusBar->show().
       
   784 
       
   785     \sa setMenuBar() statusBar()
       
   786 */
       
   787 
       
   788 void Q3MainWindow::setStatusBar(QStatusBar * newStatusBar)
       
   789 {
       
   790     Q_D(Q3MainWindow);
       
   791     if (!newStatusBar || newStatusBar == d->sb)
       
   792         return;
       
   793     if (d->sb)
       
   794         delete d->sb;
       
   795     d->sb = newStatusBar;
       
   796 #if 0
       
   797     // ### this code can cause unnecessary creation of a tool tip group
       
   798     connect(toolTipGroup(), SIGNAL(showTip(QString)),
       
   799              d->sb, SLOT(showMessage(QString)));
       
   800     connect(toolTipGroup(), SIGNAL(removeTip()),
       
   801              d->sb, SLOT(clearMessage()));
       
   802 #endif
       
   803     d->sb->installEventFilter(this);
       
   804     triggerLayout();
       
   805 }
       
   806 
       
   807 
       
   808 /*!
       
   809     Returns this main window's status bar. If there isn't one,
       
   810     statusBar() creates an empty status bar, and if necessary a tool
       
   811     tip group too.
       
   812 
       
   813     \sa menuBar()
       
   814 */
       
   815 
       
   816 QStatusBar * Q3MainWindow::statusBar() const
       
   817 {
       
   818     Q_D(const Q3MainWindow);
       
   819     if (d->sb)
       
   820         return d->sb;
       
   821 
       
   822     QObjectList l = queryList("QStatusBar", 0, false, false);
       
   823     QStatusBar * s;
       
   824     if (l.size()) {
       
   825         s = (QStatusBar *)l.at(0);
       
   826     } else {
       
   827         s = new QStatusBar((Q3MainWindow *)this, "automatic status bar");
       
   828         s->show();
       
   829     }
       
   830     ((Q3MainWindow *)this)->setStatusBar(s);
       
   831     ((Q3MainWindow *)this)->triggerLayout(true);
       
   832     return s;
       
   833 }
       
   834 
       
   835 
       
   836 #if 0
       
   837 /*!
       
   838     Sets this main window to use the tool tip group \a
       
   839     newToolTipGroup.
       
   840 
       
   841     The existing tool tip group (if any) is deleted along with its
       
   842     contents. All the tool tips connected to it lose the ability to
       
   843     display the group texts.
       
   844 
       
   845     \sa menuBar()
       
   846 */
       
   847 
       
   848 void Q3MainWindow::setToolTipGroup(QToolTipGroup * newToolTipGroup)
       
   849 {
       
   850     Q_D(Q3MainWindow);
       
   851     if (!newToolTipGroup || newToolTipGroup == d->ttg)
       
   852         return;
       
   853     if (d->ttg)
       
   854         delete d->ttg;
       
   855     d->ttg = newToolTipGroup;
       
   856 
       
   857     connect(toolTipGroup(), SIGNAL(showTip(QString)),
       
   858             statusBar(), SLOT(showMessage(QString)));
       
   859     connect(toolTipGroup(), SIGNAL(removeTip()),
       
   860             statusBar(), SLOT(clearMessage()));
       
   861 }
       
   862 
       
   863 
       
   864 /*!
       
   865     Returns this main window's tool tip group. If there isn't one,
       
   866     toolTipGroup() creates an empty tool tip group.
       
   867 
       
   868     \sa menuBar() statusBar()
       
   869 */
       
   870 QToolTipGroup * Q3MainWindow::toolTipGroup() const
       
   871 {
       
   872     Q_D(const Q3MainWindow);
       
   873     if (d->ttg)
       
   874         return d->ttg;
       
   875 
       
   876     QToolTipGroup * t = new QToolTipGroup((Q3MainWindow*)this,
       
   877                                            "automatic tool tip group");
       
   878     ((Q3MainWindowPrivate*)d)->ttg = t;
       
   879     return t;
       
   880 }
       
   881 #endif
       
   882 
       
   883 
       
   884 /*!
       
   885     If \a enable is true then users can dock windows in the \a dock
       
   886     area. If \a enable is false users cannot dock windows in the \a
       
   887     dock dock area.
       
   888 
       
   889     Users can dock (drag) dock windows into any enabled dock area.
       
   890 */
       
   891 
       
   892 void Q3MainWindow::setDockEnabled(Qt::Dock dock, bool enable)
       
   893 {
       
   894     d_func()->docks.insert(dock, enable);
       
   895 }
       
   896 
       
   897 
       
   898 /*!
       
   899     Returns true if the \a dock dock area is enabled, i.e. it can
       
   900     accept user dragged dock windows; otherwise returns false.
       
   901 
       
   902     \sa setDockEnabled()
       
   903 */
       
   904 
       
   905 bool Q3MainWindow::isDockEnabled(Qt::Dock dock) const
       
   906 {
       
   907     return d_func()->docks[dock];
       
   908 }
       
   909 
       
   910 /*!
       
   911     \overload
       
   912 
       
   913     Returns true if dock area \a area is enabled, i.e. it can accept
       
   914     user dragged dock windows; otherwise returns false.
       
   915 
       
   916     \sa setDockEnabled()
       
   917 */
       
   918 
       
   919 bool Q3MainWindow::isDockEnabled(Q3DockArea *area) const
       
   920 {
       
   921     Q_D(const Q3MainWindow);
       
   922     if (area == d->leftDock)
       
   923         return d->docks[Qt::DockLeft];
       
   924     if (area == d->rightDock)
       
   925         return d->docks[Qt::DockRight];
       
   926     if (area == d->topDock)
       
   927         return d->docks[Qt::DockTop];
       
   928     if (area == d->bottomDock)
       
   929         return d->docks[Qt::DockBottom];
       
   930     return false;
       
   931 }
       
   932 
       
   933 /*!
       
   934     \overload
       
   935 
       
   936     If \a enable is true then users can dock the \a dw dock window in
       
   937     the \a dock area. If \a enable is false users cannot dock the \a
       
   938     dw dock window in the \a dock area.
       
   939 
       
   940     In general users can dock (drag) dock windows into any enabled
       
   941     dock area. Using this function particular dock areas can be
       
   942     enabled (or disabled) as docking points for particular dock
       
   943     windows.
       
   944 */
       
   945 
       
   946 
       
   947 void Q3MainWindow::setDockEnabled(Q3DockWindow *dw, Qt::Dock dock, bool enable)
       
   948 {
       
   949     Q_D(Q3MainWindow);
       
   950     if (!d->dockWindows.contains(dw)) {
       
   951         d->dockWindows.append(dw);
       
   952         connect(dw, SIGNAL(placeChanged(Q3DockWindow::Place)),
       
   953                  this, SLOT(slotPlaceChanged()));
       
   954     }
       
   955     QString s;
       
   956     s.sprintf("%p_%d", (void*)dw, (int)dock);
       
   957     if (enable)
       
   958         d->disabledDocks.removeAll(s);
       
   959     else if (!d->disabledDocks.contains(s))
       
   960         d->disabledDocks << s;
       
   961     switch (dock) {
       
   962         case Qt::DockTop:
       
   963             topDock()->setAcceptDockWindow(dw, enable);
       
   964             break;
       
   965         case Qt::DockLeft:
       
   966             leftDock()->setAcceptDockWindow(dw, enable);
       
   967             break;
       
   968         case Qt::DockRight:
       
   969             rightDock()->setAcceptDockWindow(dw, enable);
       
   970             break;
       
   971         case Qt::DockBottom:
       
   972             bottomDock()->setAcceptDockWindow(dw, enable);
       
   973             break;
       
   974         default:
       
   975             break;
       
   976     }
       
   977 }
       
   978 
       
   979 /*!
       
   980     \overload
       
   981 
       
   982     Returns true if dock area \a area is enabled for the dock window
       
   983     \a dw; otherwise returns false.
       
   984 
       
   985     \sa setDockEnabled()
       
   986 */
       
   987 
       
   988 bool Q3MainWindow::isDockEnabled(Q3DockWindow *dw, Q3DockArea *area) const
       
   989 {
       
   990     Q_D(const Q3MainWindow);
       
   991     if (!isDockEnabled(area))
       
   992         return false;
       
   993     Qt::Dock dock;
       
   994     if (area == d->leftDock)
       
   995         dock = Qt::DockLeft;
       
   996     else if (area == d->rightDock)
       
   997         dock = Qt::DockRight;
       
   998     else if (area == d->topDock)
       
   999         dock = Qt::DockTop;
       
  1000     else if (area == d->bottomDock)
       
  1001         dock = Qt::DockBottom;
       
  1002     else
       
  1003         return false;
       
  1004     return isDockEnabled(dw, dock);
       
  1005 }
       
  1006 
       
  1007 /*!
       
  1008     \overload
       
  1009 
       
  1010     Returns true if dock area \a dock is enabled for the dock window
       
  1011     \a tb; otherwise returns false.
       
  1012 
       
  1013     \sa setDockEnabled()
       
  1014 */
       
  1015 
       
  1016 bool Q3MainWindow::isDockEnabled(Q3DockWindow *tb, Qt::Dock dock) const
       
  1017 {
       
  1018     if (!isDockEnabled(dock))
       
  1019         return false;
       
  1020     QString s;
       
  1021     s.sprintf("%p_%d", (void*)tb, (int)dock);
       
  1022     return !d_func()->disabledDocks.contains(s);
       
  1023 }
       
  1024 
       
  1025 
       
  1026 
       
  1027 /*!
       
  1028     Adds \a dockWindow to the \a edge dock area.
       
  1029 
       
  1030     If \a newLine is false (the default) then the \a dockWindow is
       
  1031     added at the end of the \a edge. For vertical edges the end is at
       
  1032     the bottom, for horizontal edges (including \c Minimized) the end
       
  1033     is at the right. If \a newLine is true a new line of dock windows
       
  1034     is started with \a dockWindow as the first (left-most and
       
  1035     top-most) dock window.
       
  1036 
       
  1037     If \a dockWindow is managed by another main window, it is first
       
  1038     removed from that window.
       
  1039 */
       
  1040 
       
  1041 void Q3MainWindow::addDockWindow(Q3DockWindow *dockWindow,
       
  1042                               Qt::Dock edge, bool newLine)
       
  1043 {
       
  1044     Q_D(Q3MainWindow);
       
  1045 #if defined (Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
       
  1046     extern WindowPtr qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
       
  1047     if(isWindow() && edge == Qt::DockTop) {
       
  1048         d->createWinId();
       
  1049         ChangeWindowAttributes(qt_mac_window_for(this), kWindowToolbarButtonAttribute, 0);
       
  1050     }
       
  1051 #endif
       
  1052     moveDockWindow(dockWindow, edge);
       
  1053     dockWindow->setNewLine(newLine);
       
  1054     if (!d->dockWindows.contains(dockWindow)) {
       
  1055         d->dockWindows.append(dockWindow);
       
  1056         connect(dockWindow, SIGNAL(placeChanged(Q3DockWindow::Place)),
       
  1057                  this, SLOT(slotPlaceChanged()));
       
  1058         dockWindow->installEventFilter(this);
       
  1059     }
       
  1060     dockWindow->setOpaqueMoving(d->opaque);
       
  1061 }
       
  1062 
       
  1063 
       
  1064 /*!
       
  1065     \overload
       
  1066 
       
  1067     Adds \a dockWindow to the dock area with label \a label.
       
  1068 
       
  1069     If \a newLine is false (the default) the \a dockWindow is added at
       
  1070     the end of the \a edge. For vertical edges the end is at the
       
  1071     bottom, for horizontal edges (including \c Minimized) the end is
       
  1072     at the right. If \a newLine is true a new line of dock windows is
       
  1073     started with \a dockWindow as the first (left-most and top-most)
       
  1074     dock window.
       
  1075 
       
  1076     If \a dockWindow is managed by another main window, it is first
       
  1077     removed from that window.
       
  1078 */
       
  1079 
       
  1080 void Q3MainWindow::addDockWindow(Q3DockWindow * dockWindow, const QString &label,
       
  1081                               Qt::Dock edge, bool newLine)
       
  1082 {
       
  1083     addDockWindow(dockWindow, edge, newLine);
       
  1084 #ifndef QT_NO_TOOLBAR
       
  1085     Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(dockWindow);
       
  1086     if (tb)
       
  1087         tb->setLabel(label);
       
  1088 #endif
       
  1089 }
       
  1090 
       
  1091 /*!
       
  1092     Moves \a dockWindow to the end of the \a edge.
       
  1093 
       
  1094     For vertical edges the end is at the bottom, for horizontal edges
       
  1095     (including \c Minimized) the end is at the right.
       
  1096 
       
  1097     If \a dockWindow is managed by another main window, it is first
       
  1098     removed from that window.
       
  1099 */
       
  1100 
       
  1101 void Q3MainWindow::moveDockWindow(Q3DockWindow * dockWindow, Qt::Dock edge)
       
  1102 {
       
  1103     Q_D(Q3MainWindow);
       
  1104     Qt::Orientation oo = dockWindow->orientation();
       
  1105     switch (edge) {
       
  1106     case Qt::DockTop:
       
  1107         if (dockWindow->area() != d->topDock)
       
  1108             dockWindow->removeFromDock(false);
       
  1109         d->topDock->moveDockWindow(dockWindow);
       
  1110         emit dockWindowPositionChanged(dockWindow);
       
  1111         break;
       
  1112     case Qt::DockBottom:
       
  1113         if (dockWindow->area() != d->bottomDock)
       
  1114             dockWindow->removeFromDock(false);
       
  1115         d->bottomDock->moveDockWindow(dockWindow);
       
  1116         emit dockWindowPositionChanged(dockWindow);
       
  1117         break;
       
  1118     case Qt::DockRight:
       
  1119         if (dockWindow->area() != d->rightDock)
       
  1120             dockWindow->removeFromDock(false);
       
  1121         d->rightDock->moveDockWindow(dockWindow);
       
  1122         emit dockWindowPositionChanged(dockWindow);
       
  1123         break;
       
  1124     case Qt::DockLeft:
       
  1125         if (dockWindow->area() != d->leftDock)
       
  1126             dockWindow->removeFromDock(false);
       
  1127         d->leftDock->moveDockWindow(dockWindow);
       
  1128         emit dockWindowPositionChanged(dockWindow);
       
  1129         break;
       
  1130     case Qt::DockTornOff:
       
  1131         dockWindow->undock();
       
  1132         break;
       
  1133     case Qt::DockMinimized:
       
  1134         dockWindow->undock(d->hideDock);
       
  1135         break;
       
  1136     case Qt::DockUnmanaged:
       
  1137         break;
       
  1138     }
       
  1139 
       
  1140     if (oo != dockWindow->orientation())
       
  1141         dockWindow->setOrientation(dockWindow->orientation());
       
  1142 }
       
  1143 
       
  1144 /*!
       
  1145     \overload
       
  1146 
       
  1147     Moves \a dockWindow to position \a index within the \a edge dock
       
  1148     area.
       
  1149 
       
  1150     Any dock windows with positions \a index or higher have their
       
  1151     position number incremented and any of these on the same line are
       
  1152     moved right (down for vertical dock areas) to make room.
       
  1153 
       
  1154     If \a nl is true, a new dock window line is created below the line
       
  1155     in which the moved dock window appears and the moved dock window,
       
  1156     with any others with higher positions on the same line, is moved
       
  1157     to this new line.
       
  1158 
       
  1159     The \a extraOffset is the space to put between the left side of
       
  1160     the dock area (top side for vertical dock areas) and the dock
       
  1161     window. (This is mostly used for restoring dock windows to the
       
  1162     positions the user has dragged them to.)
       
  1163 
       
  1164     If \a dockWindow is managed by another main window, it is first
       
  1165     removed from that window.
       
  1166 */
       
  1167 
       
  1168 void Q3MainWindow::moveDockWindow(Q3DockWindow * dockWindow, Qt::Dock edge, bool nl, int index, int extraOffset)
       
  1169 {
       
  1170     Q_D(Q3MainWindow);
       
  1171     Qt::Orientation oo = dockWindow->orientation();
       
  1172 
       
  1173     dockWindow->setNewLine(nl);
       
  1174     dockWindow->setOffset(extraOffset);
       
  1175     switch (edge) {
       
  1176     case Qt::DockTop:
       
  1177         if (dockWindow->area() != d->topDock)
       
  1178             dockWindow->removeFromDock(false);
       
  1179         d->topDock->moveDockWindow(dockWindow, index);
       
  1180         break;
       
  1181     case Qt::DockBottom:
       
  1182         if (dockWindow->area() != d->bottomDock)
       
  1183             dockWindow->removeFromDock(false);
       
  1184         d->bottomDock->moveDockWindow(dockWindow, index);
       
  1185         break;
       
  1186     case Qt::DockRight:
       
  1187         if (dockWindow->area() != d->rightDock)
       
  1188             dockWindow->removeFromDock(false);
       
  1189         d->rightDock->moveDockWindow(dockWindow, index);
       
  1190         break;
       
  1191     case Qt::DockLeft:
       
  1192         if (dockWindow->area() != d->leftDock)
       
  1193             dockWindow->removeFromDock(false);
       
  1194         d->leftDock->moveDockWindow(dockWindow, index);
       
  1195         break;
       
  1196     case Qt::DockTornOff:
       
  1197         dockWindow->undock();
       
  1198         break;
       
  1199     case Qt::DockMinimized:
       
  1200         dockWindow->undock(d->hideDock);
       
  1201         break;
       
  1202     case Qt::DockUnmanaged:
       
  1203         break;
       
  1204     }
       
  1205 
       
  1206     if (oo != dockWindow->orientation())
       
  1207         dockWindow->setOrientation(dockWindow->orientation());
       
  1208 }
       
  1209 
       
  1210 /*!
       
  1211     Removes \a dockWindow from the main window's docking area,
       
  1212     provided \a dockWindow is non-null and managed by this main
       
  1213     window.
       
  1214 */
       
  1215 
       
  1216 void Q3MainWindow::removeDockWindow(Q3DockWindow * dockWindow)
       
  1217 {
       
  1218     Q_D(Q3MainWindow);
       
  1219 
       
  1220 #if defined (Q_WS_MAC) && !defined (QT_MAC_USE_COCOA)
       
  1221     extern WindowPtr qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
       
  1222     if(isWindow() && dockWindow->area() == topDock() && !dockWindows(Qt::DockTop).count())
       
  1223         ChangeWindowAttributes(qt_mac_window_for(this), 0, kWindowToolbarButtonAttribute);
       
  1224 #endif
       
  1225 
       
  1226     dockWindow->hide();
       
  1227     d->dockWindows.removeAll(dockWindow);
       
  1228     disconnect(dockWindow, SIGNAL(placeChanged(Q3DockWindow::Place)),
       
  1229                 this, SLOT(slotPlaceChanged()));
       
  1230     dockWindow->removeEventFilter(this);
       
  1231 }
       
  1232 
       
  1233 /*!
       
  1234     Sets up the geometry management of the window. It is called
       
  1235     automatically when needed, so you shouldn't need to call it.
       
  1236 */
       
  1237 
       
  1238 void Q3MainWindow::setUpLayout()
       
  1239 {
       
  1240     Q_D(Q3MainWindow);
       
  1241 #ifndef QT_NO_MENUBAR
       
  1242     if (!d->mb) {
       
  1243         // slightly evil hack here.  reconsider this
       
  1244         QObjectList l = queryList("QMenuBar", 0, false, false);
       
  1245         if (l.size())
       
  1246             d->mb = menuBar();
       
  1247     }
       
  1248 #endif
       
  1249     if (!d->sb) {
       
  1250         // as above.
       
  1251         QObjectList l = queryList("QStatusBar", 0, false, false);
       
  1252         if (l.size())
       
  1253             d->sb = statusBar();
       
  1254     }
       
  1255 
       
  1256     if (!d->tll) {
       
  1257         d->tll = new QBoxLayout(this, QBoxLayout::Down);
       
  1258         d->tll->setResizeMode(minimumSize().isNull() ? QLayout::Minimum : QLayout::FreeResize);
       
  1259         d->mwl = new Q3MainWindowLayout(this);
       
  1260     } else {
       
  1261         d->tll->setMenuBar(0);
       
  1262         QLayoutItem *item;
       
  1263         while ((item = d->tll->takeAt(0))) {
       
  1264             if (item != d->mwl)
       
  1265                 delete item;
       
  1266         }
       
  1267     }
       
  1268 
       
  1269 #ifndef QT_NO_MENUBAR
       
  1270     if (d->mb && d->mb->isVisibleTo(this)) {
       
  1271         d->tll->setMenuBar(d->mb);
       
  1272         if (style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this))
       
  1273             d->tll->addSpacing(d->movable ? 1 : 2);
       
  1274     }
       
  1275 #endif
       
  1276 
       
  1277     d->tll->addWidget(d->hideDock);
       
  1278     if(d->topDock->parentWidget() == this)
       
  1279         d->tll->addWidget(d->topDock);
       
  1280 
       
  1281     Q3MainWindowLayout *mwl = d->mwl;
       
  1282     d->tll->addItem(mwl);
       
  1283     d->tll->setStretchFactor(mwl, 1);
       
  1284 
       
  1285     if(d->leftDock->parentWidget() == this)
       
  1286         mwl->setLeftDock(d->leftDock);
       
  1287     if (centralWidget())
       
  1288         mwl->setCentralWidget(centralWidget());
       
  1289     if(d->rightDock->parentWidget() == this)
       
  1290         mwl->setRightDock(d->rightDock);
       
  1291 
       
  1292     if(d->bottomDock->parentWidget() == this)
       
  1293         d->tll->addWidget(d->bottomDock);
       
  1294 
       
  1295     if (d->sb && d->sb->parentWidget() == this) {
       
  1296         d->tll->addWidget(d->sb, 0);
       
  1297         // make the sb stay on top of tool bars if there isn't enough space
       
  1298         d->sb->raise();
       
  1299     }
       
  1300 }
       
  1301 
       
  1302 /*! \reimp */
       
  1303 void Q3MainWindow::setVisible(bool visible)
       
  1304 {
       
  1305     Q_D(Q3MainWindow);
       
  1306     if (visible) {
       
  1307         if (!d->tll)
       
  1308             setUpLayout();
       
  1309 
       
  1310         // show all floating dock windows not explicitly hidden
       
  1311         if (!isVisible()) {
       
  1312             for (int i = 0; i < d->dockWindows.size(); ++i) {
       
  1313                 Q3DockWindow *dw = d->dockWindows.at(i);
       
  1314                 if (dw->isWindow() && !dw->isVisible() && !dw->testAttribute(Qt::WA_WState_Hidden)) {
       
  1315                     reinterpret_cast<Q3MainWindow *>(dw)->setAttribute(Qt::WA_WState_Hidden);
       
  1316                     dw->show();
       
  1317                 }
       
  1318             }
       
  1319         }
       
  1320     } else if (isVisible()) {
       
  1321         for (int i = 0; i < d->dockWindows.size(); ++i) {
       
  1322             Q3DockWindow *dw = d->dockWindows.at(i);
       
  1323             if (dw->isWindow() && dw->isVisible()) {
       
  1324                 dw->hide(); // implicit hide, so clear forcehide
       
  1325                 reinterpret_cast<Q3MainWindow *>(dw)->setAttribute(Qt::WA_WState_Hidden, false);
       
  1326             }
       
  1327         }
       
  1328     }
       
  1329     QWidget::setVisible(visible);
       
  1330 }
       
  1331 
       
  1332 
       
  1333 /*!  \reimp */
       
  1334 QSize Q3MainWindow::sizeHint() const
       
  1335 {
       
  1336     Q3MainWindow* that = (Q3MainWindow*) this;
       
  1337     // Workaround: because d->tll get's deleted in
       
  1338     // totalSizeHint->polish->sendPostedEvents->childEvent->triggerLayout
       
  1339     QApplication::sendPostedEvents(that, QEvent::ChildInserted);
       
  1340     if (!that->d_func()->tll)
       
  1341         that->setUpLayout();
       
  1342     return that->d_func()->tll->totalSizeHint();
       
  1343 }
       
  1344 
       
  1345 /*!  \reimp */
       
  1346 QSize Q3MainWindow::minimumSizeHint() const
       
  1347 {
       
  1348     Q_D(const Q3MainWindow);
       
  1349     if (!d->tll) {
       
  1350         Q3MainWindow* that = (Q3MainWindow*) this;
       
  1351         that->setUpLayout();
       
  1352     }
       
  1353     return d->tll->totalMinimumSize();
       
  1354 }
       
  1355 
       
  1356 /*!
       
  1357     Sets the central widget for this main window to \a w.
       
  1358 
       
  1359     The central widget is surrounded by the left, top, right and
       
  1360     bottom dock areas. The menu bar is above the top dock area.
       
  1361 
       
  1362     \sa centralWidget()
       
  1363 */
       
  1364 
       
  1365 void Q3MainWindow::setCentralWidget(QWidget * w)
       
  1366 {
       
  1367     Q_D(Q3MainWindow);
       
  1368     if (d->mc)
       
  1369         d->mc->removeEventFilter(this);
       
  1370     d->mc = w;
       
  1371     if (d->mc)
       
  1372         d->mc->installEventFilter(this);
       
  1373     triggerLayout();
       
  1374 }
       
  1375 
       
  1376 
       
  1377 /*!
       
  1378     Returns a pointer to the main window's central widget.
       
  1379 
       
  1380     The central widget is surrounded by the left, top, right and
       
  1381     bottom dock areas. The menu bar is above the top dock area.
       
  1382 
       
  1383     \sa setCentralWidget()
       
  1384 */
       
  1385 
       
  1386 QWidget * Q3MainWindow::centralWidget() const
       
  1387 {
       
  1388     return d_func()->mc;
       
  1389 }
       
  1390 
       
  1391 
       
  1392 /*! \reimp */
       
  1393 
       
  1394 void Q3MainWindow::paintEvent(QPaintEvent *)
       
  1395 {
       
  1396     Q_D(Q3MainWindow);
       
  1397     if (d->mb &&
       
  1398         style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this)) {
       
  1399         QPainter p(this);
       
  1400         int y = d->mb->height() + 1;
       
  1401         QStyleOption opt(0, QStyleOption::SO_Default);
       
  1402         opt.rect.setRect(0, y, width(), 1);
       
  1403         opt.palette = palette();
       
  1404         opt.state = QStyle::State_Sunken;
       
  1405         style()->drawPrimitive(QStyle::PE_Q3Separator, &opt, &p, this);
       
  1406     }
       
  1407 }
       
  1408 
       
  1409 
       
  1410 bool Q3MainWindow::dockMainWindow(QObject *dock) const
       
  1411 {
       
  1412     while (dock) {
       
  1413         if (dock->parent() &&
       
  1414             dock->parent() == const_cast<Q3MainWindow*>(this))
       
  1415             return true;
       
  1416         if (qobject_cast<Q3MainWindow*>(dock->parent()))
       
  1417             return false;
       
  1418         dock = dock->parent();
       
  1419     }
       
  1420     return false;
       
  1421 }
       
  1422 
       
  1423 /*!
       
  1424     \reimp
       
  1425 */
       
  1426 
       
  1427 bool Q3MainWindow::eventFilter(QObject* o, QEvent *e)
       
  1428 {
       
  1429     Q_D(Q3MainWindow);
       
  1430     if (e->type() == QEvent::Show && o == this) {
       
  1431         if (!d->tll)
       
  1432             setUpLayout();
       
  1433         d->tll->activate();
       
  1434     } else if (e->type() == QEvent::ContextMenu && d->dockMenu &&
       
  1435                 ((qobject_cast<Q3DockArea*>(o) && dockMainWindow(o)) || o == d->hideDock || o == d->mb)) {
       
  1436         if (showDockMenu(((QMouseEvent*)e)->globalPos())) {
       
  1437             ((QContextMenuEvent*)e)->accept();
       
  1438             return true;
       
  1439         }
       
  1440     }
       
  1441 
       
  1442     return QWidget::eventFilter(o, e);
       
  1443 }
       
  1444 
       
  1445 
       
  1446 /*!
       
  1447     Monitors events, received in \a e, to ensure the layout is updated.
       
  1448 */
       
  1449 void Q3MainWindow::childEvent(QChildEvent* e)
       
  1450 {
       
  1451     Q_D(Q3MainWindow);
       
  1452     if (e->type() == QEvent::ChildRemoved) {
       
  1453         if (e->child() == 0 ||
       
  1454              !e->child()->isWidgetType() ||
       
  1455              ((QWidget*)e->child())->isWindow()) {
       
  1456             // nothing
       
  1457         } else if (e->child() == d->sb) {
       
  1458             d->sb = 0;
       
  1459             triggerLayout();
       
  1460         } else if (e->child() == d->mb) {
       
  1461             d->mb = 0;
       
  1462             triggerLayout();
       
  1463         } else if (e->child() == d->mc) {
       
  1464             d->mc = 0;
       
  1465             d->mwl->setCentralWidget(0);
       
  1466             triggerLayout();
       
  1467         } else if (qobject_cast<Q3DockWindow*>(e->child())) {
       
  1468             removeDockWindow((Q3DockWindow *)(e->child()));
       
  1469             d->appropriate.remove((Q3DockWindow*)e->child());
       
  1470             triggerLayout();
       
  1471         }
       
  1472     } else if (e->type() == QEvent::ChildInserted && !d->sb) {
       
  1473         d->sb = qobject_cast<QStatusBar*>(e->child());
       
  1474         if (d->sb) {
       
  1475             if (d->tll) {
       
  1476                 if (!d->tll->findWidget(d->sb))
       
  1477                     d->tll->addWidget(d->sb);
       
  1478             } else {
       
  1479                 triggerLayout();
       
  1480             }
       
  1481         }
       
  1482     }
       
  1483 }
       
  1484 
       
  1485 /*!
       
  1486     \reimp
       
  1487 */
       
  1488 
       
  1489 bool Q3MainWindow::event(QEvent * e)
       
  1490 {
       
  1491     Q_D(Q3MainWindow);
       
  1492 #ifndef QT_NO_STATUSTIP
       
  1493     if (e->type() == QEvent::StatusTip) {
       
  1494         if (d->sb) {
       
  1495             d->sb->showMessage(static_cast<QStatusTipEvent*>(e)->tip());
       
  1496             return true;
       
  1497         }
       
  1498     }
       
  1499 #endif
       
  1500     if (e->type() == QEvent::ToolBarChange) {
       
  1501         // Keep compatibility with the Qt 3 main window, use the real main window
       
  1502         // or reimplement if you want proper handling.
       
  1503         int deltaH = 0;
       
  1504         Q3DockArea *area = topDock();
       
  1505         if (area->width() >= area->height()) {
       
  1506             deltaH = area->sizeHint().height();
       
  1507             if (!area->isVisible()) {
       
  1508                 area->show();
       
  1509             } else {
       
  1510                 area->hide();
       
  1511                 deltaH = -deltaH;
       
  1512             }
       
  1513         }
       
  1514 
       
  1515         if (deltaH) {
       
  1516             QApplication::sendPostedEvents(this, QEvent::LayoutRequest);
       
  1517             resize(width(), height() + deltaH);
       
  1518         }
       
  1519         return true;
       
  1520     }
       
  1521     if (e->type() == QEvent::ChildRemoved && ((QChildEvent*)e)->child() == d->mc) {
       
  1522         d->mc->removeEventFilter(this);
       
  1523         d->mc = 0;
       
  1524         d->mwl->setCentralWidget(0);
       
  1525     }
       
  1526 
       
  1527     if (e->type() == QEvent::MenubarUpdated) {
       
  1528         QMenubarUpdatedEvent * const event = static_cast<QMenubarUpdatedEvent *>(e);
       
  1529         if (event->menuBar() && event->menuBar()->parent() == this) {
       
  1530             triggerLayout();
       
  1531             update();
       
  1532         }
       
  1533     }
       
  1534     return QWidget::event(e);
       
  1535 }
       
  1536 
       
  1537 
       
  1538 /*!
       
  1539     \property Q3MainWindow::usesBigPixmaps
       
  1540     \brief whether big pixmaps are enabled
       
  1541 
       
  1542     If false (the default), the tool buttons will use small pixmaps;
       
  1543     otherwise big pixmaps will be used.
       
  1544 
       
  1545     Tool buttons and other widgets that wish to respond to this
       
  1546     setting are responsible for reading the correct state on startup,
       
  1547     and for connecting to the main window's widget's
       
  1548     pixmapSizeChanged() signal.
       
  1549 */
       
  1550 
       
  1551 bool Q3MainWindow::usesBigPixmaps() const
       
  1552 {
       
  1553     return d_func()->ubp;
       
  1554 }
       
  1555 
       
  1556 void Q3MainWindow::setUsesBigPixmaps(bool enable)
       
  1557 {
       
  1558     Q_D(Q3MainWindow);
       
  1559     if (enable == (bool)d->ubp)
       
  1560         return;
       
  1561 
       
  1562     d->ubp = enable;
       
  1563     emit pixmapSizeChanged(enable);
       
  1564 
       
  1565     QObjectList l = queryList("QLayout");
       
  1566     for (int i = 0; i < l.size(); ++i)
       
  1567             static_cast<QLayout *>(l.at(i))->activate();
       
  1568 }
       
  1569 
       
  1570 /*!
       
  1571     \property Q3MainWindow::usesTextLabel
       
  1572     \brief whether text labels for toolbar buttons are enabled
       
  1573 
       
  1574     If disabled (the default), the tool buttons will not use text
       
  1575     labels. If enabled, text labels will be used.
       
  1576 
       
  1577     Tool buttons and other widgets that wish to respond to this
       
  1578     setting are responsible for reading the correct state on startup,
       
  1579     and for connecting to the main window's widget's
       
  1580     usesTextLabelChanged() signal.
       
  1581 
       
  1582     \sa QToolButton::setUsesTextLabel()
       
  1583 */
       
  1584 
       
  1585 bool Q3MainWindow::usesTextLabel() const
       
  1586 {
       
  1587     return d_func()->utl;
       
  1588 }
       
  1589 
       
  1590 
       
  1591 void Q3MainWindow::setUsesTextLabel(bool enable)
       
  1592 {
       
  1593     Q_D(Q3MainWindow);
       
  1594     if (enable == (bool)d->utl)
       
  1595         return;
       
  1596 
       
  1597     d->utl = enable;
       
  1598     emit usesTextLabelChanged(enable);
       
  1599 
       
  1600     QObjectList l = queryList("QLayout");
       
  1601     for (int i = 0; i < l.size(); ++i)
       
  1602             static_cast<QLayout *>(l.at(i))->activate();
       
  1603     triggerLayout(false);
       
  1604 }
       
  1605 
       
  1606 
       
  1607 /*!
       
  1608     \fn void Q3MainWindow::pixmapSizeChanged(bool b)
       
  1609 
       
  1610     This signal is emitted whenever the setUsesBigPixmaps() is called
       
  1611     with a value different to the current setting. The new value is
       
  1612     passed in \a b. All widgets that should respond to such changes,
       
  1613     e.g. toolbar buttons, must connect to this signal.
       
  1614 */
       
  1615 
       
  1616 /*!
       
  1617     \fn void Q3MainWindow::usesTextLabelChanged(bool b)
       
  1618 
       
  1619     This signal is emitted whenever the setUsesTextLabel() is called
       
  1620     with a value different to the current setting. The new value is
       
  1621     passed in \a b. All widgets that should respond to such changes,
       
  1622     e.g. toolbar buttons, must connect to this signal.
       
  1623 */
       
  1624 
       
  1625 /*!
       
  1626     \fn void Q3MainWindow::dockWindowPositionChanged(Q3DockWindow *dockWindow)
       
  1627 
       
  1628     This signal is emitted when the \a dockWindow has changed its
       
  1629     position. A change in position occurs when a dock window is moved
       
  1630     within its dock area or moved to another dock area (including the
       
  1631     \c Minimized and \c TearOff dock areas).
       
  1632 
       
  1633     \sa getLocation()
       
  1634 */
       
  1635 
       
  1636 void Q3MainWindow::setRightJustification(bool enable)
       
  1637 {
       
  1638     Q_D(Q3MainWindow);
       
  1639     if (enable == (bool)d->justify)
       
  1640         return;
       
  1641     d->justify = enable;
       
  1642     triggerLayout(true);
       
  1643 }
       
  1644 
       
  1645 
       
  1646 /*!
       
  1647     \property Q3MainWindow::rightJustification
       
  1648     \brief whether the main window right-justifies its dock windows
       
  1649 
       
  1650     If disabled (the default), stretchable dock windows are expanded,
       
  1651     and non-stretchable dock windows are given the minimum space they
       
  1652     need. Since most dock windows are not stretchable, this usually
       
  1653     results in an unjustified right edge (or unjustified bottom edge
       
  1654     for a vertical dock area). If enabled, the main window will
       
  1655     right-justify its dock windows.
       
  1656 
       
  1657     \sa Q3DockWindow::setVerticalStretchable(), Q3DockWindow::setHorizontalStretchable()
       
  1658 */
       
  1659 
       
  1660 bool Q3MainWindow::rightJustification() const
       
  1661 {
       
  1662     return d_func()->justify;
       
  1663 }
       
  1664 
       
  1665 /*! \internal
       
  1666  */
       
  1667 
       
  1668 void Q3MainWindow::triggerLayout(bool deleteLayout)
       
  1669 {
       
  1670     Q_D(Q3MainWindow);
       
  1671     if (deleteLayout || !d->tll)
       
  1672         setUpLayout();
       
  1673     QApplication::postEvent(this, new QEvent(QEvent::LayoutHint));
       
  1674 }
       
  1675 
       
  1676 /*!
       
  1677     Enters 'What's This?' mode and returns immediately.
       
  1678 
       
  1679     This is the same as QWhatsThis::enterWhatsThisMode(), but
       
  1680     implemented as a main window object's slot. This way it can easily
       
  1681     be used for popup menus, for example:
       
  1682 
       
  1683     \snippet doc/src/snippets/code/src_qt3support_widgets_q3mainwindow.cpp 4
       
  1684 
       
  1685     \sa Q3WhatsThis::enterWhatsThisMode()
       
  1686 */
       
  1687 void Q3MainWindow::whatsThis()
       
  1688 {
       
  1689 #ifndef QT_NO_WHATSTHIS
       
  1690     QWhatsThis::enterWhatsThisMode();
       
  1691 #endif
       
  1692 }
       
  1693 
       
  1694 /*!
       
  1695     Finds the location of the dock window \a dw.
       
  1696 
       
  1697     If the \a dw dock window is found in the main window the function
       
  1698     returns true and populates the \a dock variable with the dw's dock
       
  1699     area and the \a index with the dw's position within the dock area.
       
  1700     It also sets \a nl to true if the \a dw begins a new line
       
  1701     (otherwise false), and \a extraOffset with the dock window's offset.
       
  1702 
       
  1703     If the \a dw dock window is not found then the function returns
       
  1704     false and the state of \a dock, \a index, \a nl and \a extraOffset
       
  1705     is undefined.
       
  1706 
       
  1707     If you want to save and restore dock window positions then use
       
  1708     operator>>() and operator<<().
       
  1709 */
       
  1710 
       
  1711 bool Q3MainWindow::getLocation(Q3DockWindow *dw, Qt::Dock &dock, int &index, bool &nl, int &extraOffset) const
       
  1712 {
       
  1713     Q_D(const Q3MainWindow);
       
  1714     dock = Qt::DockTornOff;
       
  1715     if (d->topDock->hasDockWindow(dw, &index))
       
  1716         dock = Qt::DockTop;
       
  1717     else if (d->bottomDock->hasDockWindow(dw, &index))
       
  1718         dock = Qt::DockBottom;
       
  1719     else if (d->leftDock->hasDockWindow(dw, &index))
       
  1720         dock = Qt::DockLeft;
       
  1721     else if (d->rightDock->hasDockWindow(dw, &index))
       
  1722         dock = Qt::DockRight;
       
  1723     else if (dw->parentWidget() == d->hideDock) {
       
  1724         index = 0;
       
  1725         dock = Qt::DockMinimized;
       
  1726     } else {
       
  1727         index = 0;
       
  1728     }
       
  1729     nl = dw->newLine();
       
  1730     extraOffset = dw->offset();
       
  1731     return true;
       
  1732 }
       
  1733 
       
  1734 #ifndef QT_NO_TOOLBAR
       
  1735 /*!
       
  1736     Returns a list of all the toolbars which are in the \a dock dock
       
  1737     area, regardless of their state.
       
  1738 
       
  1739     For example, the \c TornOff dock area may contain closed toolbars
       
  1740     but these are returned along with the visible toolbars.
       
  1741 
       
  1742     \sa dockWindows()
       
  1743 */
       
  1744 
       
  1745 QList<Q3ToolBar *> Q3MainWindow::toolBars(Qt::Dock dock) const
       
  1746 {
       
  1747     QList<Q3DockWindow *> lst = dockWindows(dock);
       
  1748     QList<Q3ToolBar *> tbl;
       
  1749     for (int i = 0; i < lst.size(); ++i) {
       
  1750         Q3ToolBar *tb = qobject_cast<Q3ToolBar *>(lst.at(i));
       
  1751         if (tb)
       
  1752             tbl.append(tb);
       
  1753     }
       
  1754     return tbl;
       
  1755 }
       
  1756 #endif
       
  1757 
       
  1758 /*!
       
  1759     Returns a list of all the dock windows which are in the \a dock
       
  1760     dock area, regardless of their state.
       
  1761 
       
  1762     For example, the Qt::DockTornOff dock area may contain closed dock
       
  1763     windows but these are returned along with the visible dock
       
  1764     windows.
       
  1765 */
       
  1766 
       
  1767 QList<Q3DockWindow *> Q3MainWindow::dockWindows(Qt::Dock dock) const
       
  1768 {
       
  1769     Q_D(const Q3MainWindow);
       
  1770     QList<Q3DockWindow *> lst;
       
  1771     switch (dock) {
       
  1772     case Qt::DockTop:
       
  1773         return d->topDock->dockWindowList();
       
  1774     case Qt::DockBottom:
       
  1775         return d->bottomDock->dockWindowList();
       
  1776     case Qt::DockLeft:
       
  1777         return d->leftDock->dockWindowList();
       
  1778     case Qt::DockRight:
       
  1779         return d->rightDock->dockWindowList();
       
  1780     case Qt::DockTornOff: {
       
  1781         for (int i = 0; i < d->dockWindows.size(); ++i) {
       
  1782             Q3DockWindow *w = d->dockWindows.at(i);
       
  1783             if (!w->area() && w->place() == Q3DockWindow::OutsideDock)
       
  1784                 lst.append(w);
       
  1785         }
       
  1786     }
       
  1787     return lst;
       
  1788     case Qt::DockMinimized: {
       
  1789         QObjectList childList = d->hideDock->children();
       
  1790         for (int i = 0; i < childList.size(); ++i) {
       
  1791             Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(childList.at(i));
       
  1792             if (dw)
       
  1793                 lst.append(dw);
       
  1794         }
       
  1795     }
       
  1796     return lst;
       
  1797     default:
       
  1798         break;
       
  1799     }
       
  1800     return lst;
       
  1801 }
       
  1802 
       
  1803 /*!
       
  1804     \overload
       
  1805 
       
  1806     Returns the list of dock windows which belong to this main window,
       
  1807     regardless of which dock area they are in or what their state is,
       
  1808     (e.g. irrespective of whether they are visible or not).
       
  1809 */
       
  1810 
       
  1811 QList<Q3DockWindow *> Q3MainWindow::dockWindows() const
       
  1812 {
       
  1813     return d_func()->dockWindows;
       
  1814 }
       
  1815 
       
  1816 void Q3MainWindow::setDockWindowsMovable(bool enable)
       
  1817 {
       
  1818     Q_D(Q3MainWindow);
       
  1819     d->movable = enable;
       
  1820     QObjectList l = queryList("Q3DockWindow");
       
  1821     for (int i = 0; i < l.size(); ++i)
       
  1822         static_cast<Q3DockWindow*>(l.at(i))->setMovingEnabled(enable);
       
  1823 }
       
  1824 
       
  1825 /*!
       
  1826     \property Q3MainWindow::dockWindowsMovable
       
  1827     \brief whether the dock windows are movable
       
  1828 
       
  1829     If true (the default), the user will be able to move movable dock
       
  1830     windows from one Q3MainWindow dock area to another, including the
       
  1831     \c TearOff area (i.e. where the dock window floats freely as a
       
  1832     window in its own right), and the \c Minimized area (where only
       
  1833     the dock window's handle is shown below the menu bar). Movable
       
  1834     dock windows can also be moved within Q3MainWindow dock areas, i.e.
       
  1835     to rearrange them within a dock area.
       
  1836 
       
  1837     If false the user will not be able to move any dock windows.
       
  1838 
       
  1839     By default dock windows are moved transparently (i.e. only an
       
  1840     outline rectangle is shown during the drag), but this setting can
       
  1841     be changed with setOpaqueMoving().
       
  1842 
       
  1843     \sa setDockEnabled(), setOpaqueMoving()
       
  1844 */
       
  1845 
       
  1846 bool Q3MainWindow::dockWindowsMovable() const
       
  1847 {
       
  1848     return d_func()->movable;
       
  1849 }
       
  1850 
       
  1851 void Q3MainWindow::setOpaqueMoving(bool b)
       
  1852 {
       
  1853     Q_D(Q3MainWindow);
       
  1854     d->opaque = b;
       
  1855     QObjectList l = queryList("Q3DockWindow");
       
  1856     for (int i = 0; i < l.size(); ++i)
       
  1857         static_cast<Q3DockWindow*>(l.at(i))->setOpaqueMoving(b);
       
  1858 }
       
  1859 
       
  1860 /*!
       
  1861     \property Q3MainWindow::opaqueMoving
       
  1862     \brief whether dock windows are moved opaquely
       
  1863 
       
  1864     If true the dock windows of the main window are shown opaquely
       
  1865     (i.e. it shows the toolbar as it looks when docked) whilst it is
       
  1866     being moved. If false (the default) they are shown transparently,
       
  1867     (i.e. as an outline rectangle).
       
  1868 
       
  1869     \warning Opaque moving of toolbars and dockwindows is known to
       
  1870     have several problems. We recommend avoiding the use of this
       
  1871     feature for the time being. We intend fixing the problems in a
       
  1872     future release.
       
  1873 */
       
  1874 
       
  1875 bool Q3MainWindow::opaqueMoving() const
       
  1876 {
       
  1877     return d_func()->opaque;
       
  1878 }
       
  1879 
       
  1880 /*!
       
  1881     This function will line up dock windows within the visible dock
       
  1882     areas (\c Top, \c Left, \c Right and \c Bottom) as compactly as
       
  1883     possible.
       
  1884 
       
  1885     If \a keepNewLines is true, all dock windows stay on their
       
  1886     original lines. If \a keepNewLines is false then newlines may be
       
  1887     removed to achieve the most compact layout possible.
       
  1888 
       
  1889     The method only works if dockWindowsMovable() returns true.
       
  1890 */
       
  1891 
       
  1892 void Q3MainWindow::lineUpDockWindows(bool keepNewLines)
       
  1893 {
       
  1894     Q_D(const Q3MainWindow);
       
  1895     if (!dockWindowsMovable())
       
  1896         return;
       
  1897     d->topDock->lineUp(keepNewLines);
       
  1898     d->leftDock->lineUp(keepNewLines);
       
  1899     d->rightDock->lineUp(keepNewLines);
       
  1900     d->bottomDock->lineUp(keepNewLines);
       
  1901 }
       
  1902 
       
  1903 /*!
       
  1904     Returns true, if the dock window menu is enabled; otherwise
       
  1905     returns false.
       
  1906 
       
  1907     The menu lists the (appropriate()) dock windows (which may be
       
  1908     shown or hidden), and has a "Line Up Dock Windows" menu item. It
       
  1909     will also have a "Customize" menu item if isCustomizable() returns
       
  1910     true.
       
  1911 
       
  1912     \sa setDockEnabled(), lineUpDockWindows() appropriate()
       
  1913     setAppropriate()
       
  1914 */
       
  1915 
       
  1916 bool Q3MainWindow::isDockMenuEnabled() const
       
  1917 {
       
  1918     return d_func()->dockMenu;
       
  1919 }
       
  1920 
       
  1921 /*!
       
  1922     If \a b is true, then right clicking on a dock window or dock area
       
  1923     will pop up the dock window menu. If \a b is false, right clicking
       
  1924     a dock window or dock area will not pop up the menu.
       
  1925 
       
  1926     The menu lists the (appropriate()) dock windows (which may be
       
  1927     shown or hidden), and has a "Line Up Dock Windows" item. It will
       
  1928     also have a "Customize" menu item if isCustomizable() returns
       
  1929     true.
       
  1930 
       
  1931     \sa lineUpDockWindows(), isDockMenuEnabled()
       
  1932 */
       
  1933 
       
  1934 void Q3MainWindow::setDockMenuEnabled(bool b)
       
  1935 {
       
  1936     d_func()->dockMenu = b;
       
  1937 }
       
  1938 
       
  1939 /*!
       
  1940     Creates the dock window menu which contains all toolbars (if \a
       
  1941     dockWindows is \c OnlyToolBars), all dock windows (if \a
       
  1942     dockWindows is \c NoToolBars) or all toolbars and dock windows (if
       
  1943     \a dockWindows is \c AllDockWindows - the default).
       
  1944 
       
  1945     This function is called internally when necessary, e.g. when the
       
  1946     user right clicks a dock area (providing isDockMenuEnabled()
       
  1947     returns true). You can reimplement this function if you wish to
       
  1948     customize the behavior.
       
  1949 
       
  1950     The menu items representing the toolbars and dock windows are
       
  1951     checkable. The visible dock windows are checked and the hidden
       
  1952     dock windows are unchecked. The user can click a menu item to
       
  1953     change its state (show or hide the dock window).
       
  1954 
       
  1955     The list and the state are always kept up-to-date.
       
  1956 
       
  1957     Toolbars and dock windows which are not appropriate in the current
       
  1958     context (see setAppropriate()) are not listed in the menu.
       
  1959 
       
  1960     The menu also has a menu item for lining up the dock windows.
       
  1961 
       
  1962     If isCustomizable() returns true, a Customize menu item is added
       
  1963     to the menu, which if clicked will call customize(). The
       
  1964     isCustomizable() function we provide returns false and customize()
       
  1965     does nothing, so they must be reimplemented in a subclass to be
       
  1966     useful.
       
  1967 */
       
  1968 
       
  1969 Q3PopupMenu *Q3MainWindow::createDockWindowMenu(DockWindows dockWindows) const
       
  1970 {
       
  1971     Q_D(const Q3MainWindow);
       
  1972     QObjectList l = queryList("Q3DockWindow");
       
  1973     if (l.isEmpty())
       
  1974         return 0;
       
  1975 
       
  1976     Q3PopupMenu *menu = new Q3PopupMenu((Q3MainWindow*)this);
       
  1977     menu->setObjectName(QLatin1String("qt_customize_menu"));
       
  1978     d->dockWindowModes.replace( menu, dockWindows );
       
  1979     menu->setCheckable(true);
       
  1980     connect( menu, SIGNAL(aboutToShow()), this, SLOT(menuAboutToShow()) );
       
  1981     return menu;
       
  1982 }
       
  1983 
       
  1984 /*!
       
  1985     This slot is called from the aboutToShow() signal of the default
       
  1986     dock menu of the mainwindow. The default implementation
       
  1987     initializes the menu with all dock windows and toolbars in this
       
  1988     slot.
       
  1989 */
       
  1990 
       
  1991 void Q3MainWindow::menuAboutToShow()
       
  1992 {
       
  1993     Q_D(Q3MainWindow);
       
  1994     Q3PopupMenu *menu = (Q3PopupMenu*)sender();
       
  1995     menu->clear();
       
  1996 
       
  1997     DockWindows dockWindows;
       
  1998     {
       
  1999         QMap<Q3PopupMenu*, DockWindows>::Iterator it = d->dockWindowModes.find( menu );
       
  2000         if ( it == d->dockWindowModes.end() )
       
  2001             return;
       
  2002         dockWindows = (*it);
       
  2003     }
       
  2004 
       
  2005     QObjectList l = queryList("Q3DockWindow");
       
  2006     bool empty = true;
       
  2007     if (!l.isEmpty()) {
       
  2008         if (dockWindows == AllDockWindows || dockWindows == NoToolBars) {
       
  2009             for (int i = 0; i < l.size(); ++i) {
       
  2010                 Q3DockWindow *dw = (Q3DockWindow*)l.at(i);
       
  2011                 if (!appropriate(dw) || qobject_cast<Q3ToolBar*>(dw) || !dockMainWindow(dw))
       
  2012                     continue;
       
  2013                 QString label = dw->windowTitle();
       
  2014                 if (!label.isEmpty()) {
       
  2015                     QAction *act = menu->addAction(label);
       
  2016                     act->setCheckable(true);
       
  2017                     act->setChecked(dw->isVisible());
       
  2018                     QObject::connect(act, SIGNAL(triggered()), dw, SLOT(toggleVisible()));
       
  2019                     empty = false;
       
  2020                 }
       
  2021             }
       
  2022         }
       
  2023         if (!empty) {
       
  2024             menu->addSeparator();
       
  2025             empty = true;
       
  2026         }
       
  2027 #ifndef QT_NO_TOOLBAR
       
  2028         if (dockWindows == AllDockWindows || dockWindows == OnlyToolBars) {
       
  2029             for (int i = 0; i < l.size(); ++i) {
       
  2030                 Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(l.at(i));
       
  2031                 if (!tb || !appropriate(tb) || !dockMainWindow(tb))
       
  2032                     continue;
       
  2033                 QString label = tb->label();
       
  2034                 if (!label.isEmpty()) {
       
  2035                     QAction *act = menu->addAction(label);
       
  2036                     act->setCheckable(true);
       
  2037                     act->setChecked(tb->isVisible());
       
  2038                     QObject::connect(act, SIGNAL(triggered()), tb, SLOT(toggleVisible()));
       
  2039                     empty = false;
       
  2040                 }
       
  2041             }
       
  2042         }
       
  2043 #endif
       
  2044     }
       
  2045     if (!empty) {
       
  2046         menu->addSeparator();
       
  2047         empty = true;
       
  2048     }
       
  2049 
       
  2050     if (dockWindowsMovable())
       
  2051         menu->addAction(tr("Line up"), this, SLOT(doLineUp()));
       
  2052     if (isCustomizable())
       
  2053         menu->addAction(tr("Customize..."), this, SLOT(customize()));
       
  2054 }
       
  2055 
       
  2056 
       
  2057 /*!
       
  2058     Shows the dock menu at the position \a globalPos. The menu lists
       
  2059     the dock windows so that they can be shown (or hidden), lined up,
       
  2060     and possibly customized. Returns true if the menu is shown;
       
  2061     otherwise returns false.
       
  2062 
       
  2063     If you want a custom menu, reimplement this function. You can
       
  2064     create the menu from scratch or call createDockWindowMenu() and
       
  2065     modify the result.
       
  2066 
       
  2067     The default implementation uses the dock window menu which gets
       
  2068     created by createDockWindowMenu(). You can reimplement
       
  2069     createDockWindowMenu() if you want to use your own specialized
       
  2070     popup menu.
       
  2071 */
       
  2072 
       
  2073 bool Q3MainWindow::showDockMenu(const QPoint &globalPos)
       
  2074 {
       
  2075     Q_D(Q3MainWindow);
       
  2076     if (!d->dockMenu)
       
  2077         return false;
       
  2078 
       
  2079     if(Q3PopupMenu *ret = createDockWindowMenu()) {
       
  2080         ret->exec(globalPos);
       
  2081         delete ret;
       
  2082         return true;
       
  2083     }
       
  2084     return false;
       
  2085 }
       
  2086 
       
  2087 void Q3MainWindow::slotPlaceChanged()
       
  2088 {
       
  2089     QObject* obj = (QObject*)sender();
       
  2090     Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(obj);
       
  2091     if (dw)
       
  2092         emit dockWindowPositionChanged(dw);
       
  2093 #ifndef QT_NO_TOOLBAR
       
  2094     Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(obj);
       
  2095     if (tb)
       
  2096         emit toolBarPositionChanged(tb);
       
  2097 #endif
       
  2098 }
       
  2099 
       
  2100 /*!
       
  2101     \internal
       
  2102     For internal use of Q3DockWindow only.
       
  2103  */
       
  2104 
       
  2105 Q3DockArea *Q3MainWindow::dockingArea(const QPoint &p)
       
  2106 {
       
  2107     Q_D(Q3MainWindow);
       
  2108     int mh = d->mb ? d->mb->height() : 0;
       
  2109     int sh = d->sb ? d->sb->height() : 0;
       
  2110     if (p.x() >= -5 && p.x() <= 100 && p.y() > mh && p.y() - height() - sh)
       
  2111         return d->leftDock;
       
  2112     if (p.x() >= width() - 100 && p.x() <= width() + 5 && p.y() > mh && p.y() - height() - sh)
       
  2113         return d->rightDock;
       
  2114     if (p.y() >= -5 && p.y() < mh + 100 && p.x() >= 0 && p.x() <= width())
       
  2115         return d->topDock;
       
  2116     if (p.y() >= height() - sh - 100 && p.y() <= height() + 5 && p.x() >= 0 && p.x() <= width())
       
  2117         return d->bottomDock;
       
  2118     return 0;
       
  2119 }
       
  2120 
       
  2121 /*!
       
  2122     Returns true if \a dw is a dock window known to the main window;
       
  2123     otherwise returns false.
       
  2124 */
       
  2125 
       
  2126 bool Q3MainWindow::hasDockWindow(Q3DockWindow *dw)
       
  2127 {
       
  2128     return d_func()->dockWindows.contains(dw);
       
  2129 }
       
  2130 
       
  2131 /*!
       
  2132     Returns the \c Left dock area
       
  2133 
       
  2134     \sa rightDock() topDock() bottomDock()
       
  2135 */
       
  2136 
       
  2137 Q3DockArea *Q3MainWindow::leftDock() const
       
  2138 {
       
  2139     return d_func()->leftDock;
       
  2140 }
       
  2141 
       
  2142 /*!
       
  2143     Returns the \c Right dock area
       
  2144 
       
  2145     \sa leftDock() topDock() bottomDock()
       
  2146 */
       
  2147 
       
  2148 Q3DockArea *Q3MainWindow::rightDock() const
       
  2149 {
       
  2150     return d_func()->rightDock;
       
  2151 }
       
  2152 
       
  2153 /*!
       
  2154     Returns the \c Top dock area
       
  2155 
       
  2156     \sa bottomDock() leftDock() rightDock()
       
  2157 */
       
  2158 
       
  2159 Q3DockArea *Q3MainWindow::topDock() const
       
  2160 {
       
  2161     return d_func()->topDock;
       
  2162 }
       
  2163 
       
  2164 /*!
       
  2165     Returns a pointer the \c Bottom dock area
       
  2166 
       
  2167     \sa topDock() leftDock() rightDock()
       
  2168 */
       
  2169 
       
  2170 Q3DockArea *Q3MainWindow::bottomDock() const
       
  2171 {
       
  2172     return d_func()->bottomDock;
       
  2173 }
       
  2174 
       
  2175 /*!
       
  2176     This function is called when the user clicks the Customize menu
       
  2177     item on the dock window menu.
       
  2178 
       
  2179     The customize menu item will only appear if isCustomizable()
       
  2180     returns true (it returns false by default).
       
  2181 
       
  2182     The function is intended, for example, to provide the user with a
       
  2183     means of telling the application that they wish to customize the
       
  2184     main window, dock windows or dock areas.
       
  2185 
       
  2186     The default implementation does nothing and the Customize menu
       
  2187     item is not shown on the right-click menu by default. If you want
       
  2188     the item to appear then reimplement isCustomizable() to return
       
  2189     true, and reimplement this function to do whatever you want.
       
  2190 
       
  2191     \sa isCustomizable()
       
  2192 */
       
  2193 
       
  2194 void Q3MainWindow::customize()
       
  2195 {
       
  2196 }
       
  2197 
       
  2198 /*!
       
  2199     Returns true if the dock area dock window menu includes the
       
  2200     Customize menu item (which calls customize() when clicked).
       
  2201     Returns false by default, i.e. the popup menu will not contain a
       
  2202     Customize menu item. You will need to reimplement this function
       
  2203     and set it to return true if you wish the user to be able to see
       
  2204     the dock window menu.
       
  2205 
       
  2206     \sa customize()
       
  2207 */
       
  2208 
       
  2209 bool Q3MainWindow::isCustomizable() const
       
  2210 {
       
  2211     return false;
       
  2212 }
       
  2213 
       
  2214 /*!
       
  2215     Returns true if it is appropriate to include a menu item for the
       
  2216     \a dw dock window in the dock window menu; otherwise returns
       
  2217     false.
       
  2218 
       
  2219     The user is able to change the state (show or hide) a dock window
       
  2220     that has a menu item by clicking the item.
       
  2221 
       
  2222     Call setAppropriate() to indicate whether or not a particular dock
       
  2223     window should appear on the popup menu.
       
  2224 
       
  2225     \sa setAppropriate()
       
  2226 */
       
  2227 
       
  2228 bool Q3MainWindow::appropriate(Q3DockWindow *dw) const
       
  2229 {
       
  2230     Q_D(const Q3MainWindow);
       
  2231     QMap<Q3DockWindow*, bool>::ConstIterator it = d->appropriate.find(dw);
       
  2232     if (it == d->appropriate.end())
       
  2233         return true;
       
  2234     return *it;
       
  2235 }
       
  2236 
       
  2237 /*!
       
  2238     Use this function to control whether or not the \a dw dock
       
  2239     window's caption should appear as a menu item on the dock window
       
  2240     menu that lists the dock windows.
       
  2241 
       
  2242     If \a a is true then the \a dw will appear as a menu item on the
       
  2243     dock window menu. The user is able to change the state (show or
       
  2244     hide) a dock window that has a menu item by clicking the item;
       
  2245     depending on the state of your application, this may or may not be
       
  2246     appropriate. If \a a is false the \a dw will not appear on the
       
  2247     popup menu.
       
  2248 
       
  2249     \sa showDockMenu() isCustomizable() customize()
       
  2250 */
       
  2251 
       
  2252 void Q3MainWindow::setAppropriate(Q3DockWindow *dw, bool a)
       
  2253 {
       
  2254     d_func()->appropriate.insert(dw, a);
       
  2255 }
       
  2256 
       
  2257 #ifndef QT_NO_TEXTSTREAM
       
  2258 static void saveDockArea(QTextStream &ts, Q3DockArea *a)
       
  2259 {
       
  2260     QList<Q3DockWindow *> l = a->dockWindowList();
       
  2261     for (int i = 0; i < l.size(); ++i) {
       
  2262         Q3DockWindow *dw = l.at(i);
       
  2263         ts << QString(dw->windowTitle());
       
  2264         ts << ',';
       
  2265     }
       
  2266     ts << endl;
       
  2267     ts << *a;
       
  2268 }
       
  2269 
       
  2270 /*!
       
  2271     \relates Q3MainWindow
       
  2272 
       
  2273     Writes the layout (sizes and positions) of the dock windows in the
       
  2274     dock areas of the Q3MainWindow \a mainWindow, including \c
       
  2275     Minimized and \c TornOff dock windows, to the text stream \a ts.
       
  2276 
       
  2277     This can be used, for example, in conjunction with QSettings to
       
  2278     save the user's layout when the \a mainWindow receives a
       
  2279     close event.
       
  2280 
       
  2281     \sa QWidget::closeEvent()
       
  2282 */
       
  2283 
       
  2284 QTextStream &operator<<(QTextStream &ts, const Q3MainWindow &mainWindow)
       
  2285 {
       
  2286     QList<Q3DockWindow *> l = mainWindow.dockWindows(Qt::DockMinimized);
       
  2287     for (int i = 0; i < l.size(); ++i) {
       
  2288         Q3DockWindow *dw = l.at(i);
       
  2289         ts << dw->windowTitle();
       
  2290         ts << ',';
       
  2291     }
       
  2292     ts << endl;
       
  2293 
       
  2294     l = mainWindow.dockWindows(Qt::DockTornOff);
       
  2295     for (int i = 0; i < l.size(); ++i) {
       
  2296         Q3DockWindow *dw = l.at(i);
       
  2297         ts << dw->windowTitle();
       
  2298         ts << ',';
       
  2299     }
       
  2300     ts << endl;
       
  2301     for (int i = 0; i < l.size(); ++i) {
       
  2302         Q3DockWindow *dw = l.at(i);
       
  2303         ts << '[' << dw->windowTitle() << ','
       
  2304            << (int)dw->geometry().x() << ','
       
  2305            << (int)dw->geometry().y() << ','
       
  2306            << (int)dw->geometry().width() << ','
       
  2307            << (int)dw->geometry().height() << ','
       
  2308            << (int)dw->isVisible() << ']';
       
  2309     }
       
  2310     ts << endl;
       
  2311 
       
  2312     saveDockArea(ts, mainWindow.topDock());
       
  2313     saveDockArea(ts, mainWindow.bottomDock());
       
  2314     saveDockArea(ts, mainWindow.rightDock());
       
  2315     saveDockArea(ts, mainWindow.leftDock());
       
  2316     return ts;
       
  2317 }
       
  2318 
       
  2319 static void loadDockArea(const QStringList &names, Q3DockArea *a, Qt::Dock dl, QList<Q3DockWindow *> &l, Q3MainWindow *mw, QTextStream &ts)
       
  2320 {
       
  2321     for (QStringList::ConstIterator it = names.begin(); it != names.end(); ++it) {
       
  2322         for (int i = 0; i < l.size(); ++i) {
       
  2323             Q3DockWindow *dw = l.at(i);
       
  2324             if (dw->windowTitle() == *it) {
       
  2325                 mw->addDockWindow(dw, dl);
       
  2326                 break;
       
  2327             }
       
  2328         }
       
  2329     }
       
  2330     if (a) {
       
  2331         ts >> *a;
       
  2332     } else if (dl == Qt::DockTornOff) {
       
  2333         QString s = ts.readLine();
       
  2334         enum State { Pre, Name, X, Y, Width, Height, Visible, Post };
       
  2335         int state = Pre;
       
  2336         QString name, x, y, w, h, visible;
       
  2337         QChar c;
       
  2338         for (int i = 0; i < (int)s.length(); ++i) {
       
  2339             c = s[i];
       
  2340             if (state == Pre && c == QLatin1Char('[')) {
       
  2341                 state++;
       
  2342                 continue;
       
  2343             }
       
  2344             if (c == QLatin1Char(',') &&
       
  2345                  (state == Name || state == X || state == Y || state == Width || state == Height)) {
       
  2346                 state++;
       
  2347                 continue;
       
  2348             }
       
  2349             if (state == Visible && c == QLatin1Char(']')) {
       
  2350                 for (int i = 0; i < l.size(); ++i) {
       
  2351                     Q3DockWindow *dw = l.at(i);
       
  2352                     if (QString(dw->windowTitle()) == name) {
       
  2353                         if (!qobject_cast<Q3ToolBar*>(dw))
       
  2354                             dw->setGeometry(x.toInt(), y.toInt(), w.toInt(), h.toInt());
       
  2355                         else
       
  2356                             dw->setGeometry(x.toInt(), y.toInt(), dw->width(), dw->height());
       
  2357                         if (!(bool)visible.toInt())
       
  2358                             dw->hide();
       
  2359                         else
       
  2360                             dw->show();
       
  2361                         break;
       
  2362                     }
       
  2363                 }
       
  2364 
       
  2365                 name = x = y = w = h = visible = QLatin1String("");
       
  2366 
       
  2367                 state = Pre;
       
  2368                 continue;
       
  2369             }
       
  2370             if (state == Name)
       
  2371                 name += c;
       
  2372             else if (state == X)
       
  2373                 x += c;
       
  2374             else if (state == Y)
       
  2375                 y += c;
       
  2376             else if (state == Width)
       
  2377                 w += c;
       
  2378             else if (state == Height)
       
  2379                 h += c;
       
  2380             else if (state == Visible)
       
  2381                 visible += c;
       
  2382         }
       
  2383     }
       
  2384 }
       
  2385 
       
  2386 /*!
       
  2387     \relates Q3MainWindow
       
  2388 
       
  2389     Reads the layout (sizes and positions) of the dock windows in the
       
  2390     dock areas of the Q3MainWindow \a mainWindow from the text stream,
       
  2391     \a ts, including \c Minimized and \c TornOff dock windows.
       
  2392     Restores the dock windows and dock areas to these sizes and
       
  2393     positions. The layout information must be in the format produced
       
  2394     by operator<<().
       
  2395 
       
  2396     This can be used, for example, in conjunction with QSettings to
       
  2397     restore the user's layout.
       
  2398 */
       
  2399 
       
  2400 QTextStream &operator>>(QTextStream &ts, Q3MainWindow &mainWindow)
       
  2401 {
       
  2402     QList<Q3DockWindow *> l = mainWindow.dockWindows();
       
  2403 
       
  2404     QString s = ts.readLine();
       
  2405     QStringList names = s.split(QLatin1Char(','));
       
  2406     loadDockArea(names, 0, Qt::DockMinimized, l, &mainWindow, ts);
       
  2407 
       
  2408     s = ts.readLine();
       
  2409     names = s.split(QLatin1Char(','));
       
  2410     loadDockArea(names, 0, Qt::DockTornOff, l, &mainWindow, ts);
       
  2411 
       
  2412     int i = 0;
       
  2413     Q3DockArea *areas[] = { mainWindow.topDock(), mainWindow.bottomDock(), mainWindow.rightDock(), mainWindow.leftDock() };
       
  2414     for (int dl = (int)Qt::DockTop; dl != (int)Qt::DockMinimized; ++dl, ++i) {
       
  2415         s = ts.readLine();
       
  2416         names = s.split(QLatin1Char(','));
       
  2417         loadDockArea(names, areas[i], (Qt::Dock)dl, l, &mainWindow, ts);
       
  2418     }
       
  2419     return ts;
       
  2420 }
       
  2421 #endif
       
  2422 
       
  2423 QT_END_NAMESPACE
       
  2424 
       
  2425 #include "q3mainwindow.moc"
       
  2426 
       
  2427 #endif