src/gui/widgets/qmainwindow.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
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 QtGui 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 "qmainwindow.h"
       
    43 #include "qmainwindowlayout_p.h"
       
    44 
       
    45 #ifndef QT_NO_MAINWINDOW
       
    46 
       
    47 #include "qdockwidget.h"
       
    48 #include "qtoolbar.h"
       
    49 
       
    50 #include <qapplication.h>
       
    51 #include <qmenubar.h>
       
    52 #include <qstatusbar.h>
       
    53 #include <qevent.h>
       
    54 #include <qstyle.h>
       
    55 #include <qdebug.h>
       
    56 #include <qpainter.h>
       
    57 
       
    58 #include <private/qwidget_p.h>
       
    59 #include "qtoolbar_p.h"
       
    60 #include "qwidgetanimator_p.h"
       
    61 #ifdef Q_WS_MAC
       
    62 #include <private/qt_mac_p.h>
       
    63 #include <private/qt_cocoa_helpers_mac_p.h>
       
    64 QT_BEGIN_NAMESPACE
       
    65 extern OSWindowRef qt_mac_window_for(const QWidget *); // qwidget_mac.cpp
       
    66 QT_END_NAMESPACE
       
    67 #endif
       
    68 #ifdef QT_SOFTKEYS_ENABLED
       
    69 #include <private/qsoftkeymanager_p.h>
       
    70 #endif
       
    71 
       
    72 QT_BEGIN_NAMESPACE
       
    73 
       
    74 class QMainWindowPrivate : public QWidgetPrivate
       
    75 {
       
    76     Q_DECLARE_PUBLIC(QMainWindow)
       
    77 public:
       
    78     inline QMainWindowPrivate()
       
    79         : layout(0), explicitIconSize(false), toolButtonStyle(Qt::ToolButtonIconOnly)
       
    80 #ifdef Q_WS_MAC
       
    81             , useHIToolBar(false)
       
    82 #endif
       
    83 #ifdef QT_SOFTKEYS_ENABLED
       
    84             , menuBarAction(0)
       
    85 #endif
       
    86 #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
       
    87             , hasOldCursor(false) , cursorAdjusted(false)
       
    88 #endif
       
    89     { }
       
    90     QMainWindowLayout *layout;
       
    91     QSize iconSize;
       
    92     bool explicitIconSize;
       
    93     Qt::ToolButtonStyle toolButtonStyle;
       
    94 #ifdef Q_WS_MAC
       
    95     bool useHIToolBar;
       
    96 #endif
       
    97 #ifdef QT_SOFTKEYS_ENABLED
       
    98     QAction *menuBarAction;
       
    99 #endif
       
   100     void init();
       
   101     QList<int> hoverSeparator;
       
   102     QPoint hoverPos;
       
   103 
       
   104 #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
       
   105     QCursor separatorCursor(const QList<int> &path) const;
       
   106     void adjustCursor(const QPoint &pos);
       
   107     QCursor oldCursor;
       
   108     uint hasOldCursor : 1;
       
   109     uint cursorAdjusted : 1;
       
   110 #endif
       
   111 };
       
   112 
       
   113 void QMainWindowPrivate::init()
       
   114 {
       
   115     Q_Q(QMainWindow);
       
   116     layout = new QMainWindowLayout(q);
       
   117     const int metric = q->style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, q);
       
   118     iconSize = QSize(metric, metric);
       
   119     q->setAttribute(Qt::WA_Hover);
       
   120 #ifdef QT_SOFTKEYS_ENABLED
       
   121     menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, q);
       
   122     menuBarAction->setObjectName(QLatin1String("_q_menuSoftKeyAction"));
       
   123 #endif
       
   124 }
       
   125 
       
   126 /*
       
   127     The Main Window:
       
   128 
       
   129     +----------------------------------------------------------+
       
   130     | Menu Bar                                                 |
       
   131     +----------------------------------------------------------+
       
   132     | Tool Bar Area                                            |
       
   133     |   +--------------------------------------------------+   |
       
   134     |   | Dock Window Area                                 |   |
       
   135     |   |   +------------------------------------------+   |   |
       
   136     |   |   |                                          |   |   |
       
   137     |   |   | Central Widget                           |   |   |
       
   138     |   |   |                                          |   |   |
       
   139     |   |   |                                          |   |   |
       
   140     |   |   |                                          |   |   |
       
   141     |   |   |                                          |   |   |
       
   142     |   |   |                                          |   |   |
       
   143     |   |   |                                          |   |   |
       
   144     |   |   |                                          |   |   |
       
   145     |   |   |                                          |   |   |
       
   146     |   |   |                                          |   |   |
       
   147     |   |   |                                          |   |   |
       
   148     |   |   +------------------------------------------+   |   |
       
   149     |   |                                                  |   |
       
   150     |   +--------------------------------------------------+   |
       
   151     |                                                          |
       
   152     +----------------------------------------------------------+
       
   153     | Status Bar                                               |
       
   154     +----------------------------------------------------------+
       
   155 
       
   156 */
       
   157 
       
   158 /*!
       
   159     \class QMainWindow
       
   160     \brief The QMainWindow class provides a main application
       
   161            window.
       
   162     \ingroup mainwindow-classes
       
   163 
       
   164 
       
   165     \tableofcontents
       
   166 
       
   167     \section1 Qt Main Window Framework
       
   168 
       
   169     A main window provides a framework for building an
       
   170     application's user interface. Qt has QMainWindow and its \l{Main
       
   171     Window and Related Classes}{related classes} for main window
       
   172     management. QMainWindow has its own layout to which you can add
       
   173     \l{QToolBar}s, \l{QDockWidget}s, a
       
   174     QMenuBar, and a QStatusBar. The layout has a center area that can
       
   175     be occupied by any kind of widget. You can see an image of the
       
   176     layout below.
       
   177 
       
   178     \image mainwindowlayout.png
       
   179 
       
   180     \note Creating a main window without a central widget is not supported.
       
   181     You must have a central widget even if it is just a placeholder.
       
   182 
       
   183     \section1 Creating Main Window Components
       
   184 
       
   185     A central widget will typically be a standard Qt widget such
       
   186     as a QTextEdit or a QGraphicsView. Custom widgets can also be
       
   187     used for advanced applications. You set the central widget with \c
       
   188     setCentralWidget().
       
   189 
       
   190     Main windows have either a single (SDI) or multiple (MDI)
       
   191     document interface. You create MDI applications in Qt by using a
       
   192     QMdiArea as the central widget.
       
   193 
       
   194     We will now examine each of the other widgets that can be
       
   195     added to a main window. We give examples on how to create and add
       
   196     them.
       
   197 
       
   198     \section2 Creating Menus
       
   199 
       
   200     Qt implements menus in QMenu and QMainWindow keeps them in a
       
   201     QMenuBar. \l{QAction}{QAction}s are added to the menus, which
       
   202     display them as menu items.
       
   203 
       
   204     You can add new menus to the main window's menu bar by calling
       
   205     \c menuBar(), which returns the QMenuBar for the window, and then
       
   206     add a menu with QMenuBar::addMenu().
       
   207 
       
   208     QMainWindow comes with a default menu bar, but you can also
       
   209     set one yourself with \c setMenuBar(). If you wish to implement a
       
   210     custom menu bar (i.e., not use the QMenuBar widget), you can set it
       
   211     with \c setMenuWidget().
       
   212 
       
   213     An example of how to create menus follows:
       
   214 
       
   215     \snippet examples/mainwindows/application/mainwindow.cpp 26
       
   216 
       
   217     The \c createPopupMenu() function creates popup menus when the
       
   218     main window receives context menu events.  The default
       
   219     implementation generates a menu with the checkable actions from
       
   220     the dock widgets and toolbars. You can reimplement \c
       
   221     createPopupMenu() for a custom menu.
       
   222 
       
   223     \section2 Creating Toolbars
       
   224 
       
   225     Toolbars are implemented in the QToolBar class.  You add a
       
   226     toolbar to a main window with \c addToolBar().
       
   227 
       
   228     You control the initial position of toolbars by assigning them
       
   229     to a specific Qt::ToolBarArea. You can split an area by inserting
       
   230     a toolbar break - think of this as a line break in text editing -
       
   231     with \c addToolBarBreak() or \c insertToolBarBreak(). You can also
       
   232     restrict placement by the user with QToolBar::setAllowedAreas()
       
   233     and QToolBar::setMovable().
       
   234 
       
   235     The size of toolbar icons can be retrieved with \c iconSize().
       
   236     The sizes are platform dependent; you can set a fixed size with \c
       
   237     setIconSize(). You can alter the appearance of all tool buttons in
       
   238     the toolbars with \c setToolButtonStyle().
       
   239 
       
   240     An example of toolbar creation follows:
       
   241 
       
   242     \snippet examples/mainwindows/application/mainwindow.cpp 29
       
   243 
       
   244     \section2 Creating Dock Widgets
       
   245 
       
   246     Dock widgets are implemented in the QDockWidget class. A dock
       
   247     widget is a window that can be docked into the main window.  You
       
   248     add dock widgets to a main window with \c addDockWidget().
       
   249 
       
   250     There are four dock widget areas as given by the
       
   251     Qt::DockWidgetArea enum: left, right, top, and bottom. You can
       
   252     specify which dock widget area that should occupy the corners
       
   253     where the areas overlap with \c setCorner(). By default
       
   254     each area can only contain one row (vertical or horizontal) of
       
   255     dock widgets, but if you enable nesting with \c
       
   256     setDockNestingEnabled(), dock widgets can be added in either
       
   257     direction.
       
   258 
       
   259     Two dock widgets may also be stacked on top of each other. A
       
   260     QTabBar is then used to select which of the widgets that should be
       
   261     displayed.
       
   262 
       
   263     We give an example of how to create and add dock widgets to a
       
   264     main window:
       
   265 
       
   266     \snippet doc/src/snippets/mainwindowsnippet.cpp 0
       
   267 
       
   268     \section2 The Status Bar
       
   269 
       
   270     You can set a status bar with \c setStatusBar(), but one is
       
   271     created the first time \c statusBar() (which returns the main
       
   272     window's status bar) is called. See QStatusBar for information on
       
   273     how to use it.
       
   274 
       
   275     \section1 Storing State
       
   276 
       
   277     QMainWindow can store the state of its layout with \c
       
   278     saveState(); it can later be retrieved with \c restoreState(). It
       
   279     is the position and size (relative to the size of the main window)
       
   280     of the toolbars and dock widgets that are stored.
       
   281 
       
   282     \sa QMenuBar, QToolBar, QStatusBar, QDockWidget, {Application
       
   283     Example}, {Dock Widgets Example}, {MDI Example}, {SDI Example},
       
   284     {Menus Example}
       
   285 */
       
   286 
       
   287 /*!
       
   288     \fn void QMainWindow::iconSizeChanged(const QSize &iconSize)
       
   289 
       
   290     This signal is emitted when the size of the icons used in the
       
   291     window is changed. The new icon size is passed in \a iconSize.
       
   292 
       
   293     You can connect this signal to other components to help maintain
       
   294     a consistent appearance for your application.
       
   295 
       
   296     \sa setIconSize()
       
   297 */
       
   298 
       
   299 /*!
       
   300     \fn void QMainWindow::toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle)
       
   301 
       
   302     This signal is emitted when the style used for tool buttons in the
       
   303     window is changed. The new style is passed in \a toolButtonStyle.
       
   304 
       
   305     You can connect this signal to other components to help maintain
       
   306     a consistent appearance for your application.
       
   307 
       
   308     \sa setToolButtonStyle()
       
   309 */
       
   310 
       
   311 /*!
       
   312     Constructs a QMainWindow with the given \a parent and the specified
       
   313     widget \a flags.
       
   314 
       
   315     QMainWindow sets the Qt::Window flag itself, and will hence
       
   316     always be created as a top-level widget.
       
   317  */
       
   318 QMainWindow::QMainWindow(QWidget *parent, Qt::WindowFlags flags)
       
   319     : QWidget(*(new QMainWindowPrivate()), parent, flags | Qt::Window)
       
   320 {
       
   321     d_func()->init();
       
   322 }
       
   323 
       
   324 #ifdef QT3_SUPPORT
       
   325 /*!
       
   326     \obsolete
       
   327     Constructs a QMainWindow with the given \a parent, \a name, and
       
   328     with the specified widget \a flags.
       
   329  */
       
   330 QMainWindow::QMainWindow(QWidget *parent, const char *name, Qt::WindowFlags flags)
       
   331     : QWidget(*(new QMainWindowPrivate()), parent, flags | Qt::WType_TopLevel)
       
   332 {
       
   333     setObjectName(QString::fromAscii(name));
       
   334     d_func()->init();
       
   335 }
       
   336 #endif
       
   337 
       
   338 /*!
       
   339     Destroys the main window.
       
   340  */
       
   341 QMainWindow::~QMainWindow()
       
   342 { }
       
   343 
       
   344 /*! \property QMainWindow::iconSize
       
   345     \brief size of toolbar icons in this mainwindow.
       
   346 
       
   347     The default is the default tool bar icon size of the GUI style.
       
   348     Note that the icons used must be at least of this size as the
       
   349     icons are only scaled down.
       
   350 */
       
   351 
       
   352 /*!
       
   353     \property QMainWindow::dockOptions
       
   354     \brief the docking behavior of QMainWindow
       
   355     \since 4.3
       
   356 
       
   357     The default value is AnimatedDocks | AllowTabbedDocks.
       
   358 */
       
   359 
       
   360 /*!
       
   361     \enum QMainWindow::DockOption
       
   362     \since 4.3
       
   363 
       
   364     This enum contains flags that specify the docking behavior of QMainWindow.
       
   365 
       
   366     \value AnimatedDocks    Identical to the \l animated property.
       
   367 
       
   368     \value AllowNestedDocks Identical to the \l dockNestingEnabled property.
       
   369 
       
   370     \value AllowTabbedDocks The user can drop one dock widget "on top" of
       
   371                             another. The two widgets are stacked and a tab
       
   372                             bar appears for selecting which one is visible.
       
   373 
       
   374     \value ForceTabbedDocks Each dock area contains a single stack of tabbed
       
   375                             dock widgets. In other words, dock widgets cannot
       
   376                             be placed next to each other in a dock area. If
       
   377                             this option is set, AllowNestedDocks has no effect.
       
   378 
       
   379     \value VerticalTabs     The two vertical dock areas on the sides of the
       
   380                             main window show their tabs vertically. If this
       
   381                             option is not set, all dock areas show their tabs
       
   382                             at the bottom. Implies AllowTabbedDocks. See also
       
   383                             \l setTabPosition().
       
   384 
       
   385     These options only control how dock widgets may be dropped in a QMainWindow.
       
   386     They do not re-arrange the dock widgets to conform with the specified
       
   387     options. For this reason they should be set before any dock widgets
       
   388     are added to the main window. Exceptions to this are the AnimatedDocks and
       
   389     VerticalTabs options, which may be set at any time.
       
   390 */
       
   391 
       
   392 void QMainWindow::setDockOptions(DockOptions opt)
       
   393 {
       
   394     Q_D(QMainWindow);
       
   395     d->layout->setDockOptions(opt);
       
   396 }
       
   397 
       
   398 QMainWindow::DockOptions QMainWindow::dockOptions() const
       
   399 {
       
   400     Q_D(const QMainWindow);
       
   401     return d->layout->dockOptions;
       
   402 }
       
   403 
       
   404 QSize QMainWindow::iconSize() const
       
   405 { return d_func()->iconSize; }
       
   406 
       
   407 void QMainWindow::setIconSize(const QSize &iconSize)
       
   408 {
       
   409     Q_D(QMainWindow);
       
   410     QSize sz = iconSize;
       
   411     if (!sz.isValid()) {
       
   412         const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, this);
       
   413         sz = QSize(metric, metric);
       
   414     }
       
   415     if (d->iconSize != sz) {
       
   416         d->iconSize = sz;
       
   417         emit iconSizeChanged(d->iconSize);
       
   418     }
       
   419     d->explicitIconSize = iconSize.isValid();
       
   420 }
       
   421 
       
   422 /*! \property QMainWindow::toolButtonStyle
       
   423     \brief style of toolbar buttons in this mainwindow.
       
   424 
       
   425     The default is Qt::ToolButtonIconOnly.
       
   426 */
       
   427 
       
   428 Qt::ToolButtonStyle QMainWindow::toolButtonStyle() const
       
   429 { return d_func()->toolButtonStyle; }
       
   430 
       
   431 void QMainWindow::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
       
   432 {
       
   433     Q_D(QMainWindow);
       
   434     if (d->toolButtonStyle == toolButtonStyle)
       
   435         return;
       
   436     d->toolButtonStyle = toolButtonStyle;
       
   437     emit toolButtonStyleChanged(d->toolButtonStyle);
       
   438 }
       
   439 
       
   440 #ifndef QT_NO_MENUBAR
       
   441 /*!
       
   442     Returns the menu bar for the main window. This function creates
       
   443     and returns an empty menu bar if the menu bar does not exist.
       
   444 
       
   445     If you want all windows in a Mac application to share one menu
       
   446     bar, don't use this function to create it, because the menu bar
       
   447     created here will have this QMainWindow as its parent.  Instead,
       
   448     you must create a menu bar that does not have a parent, which you
       
   449     can then share among all the Mac windows. Create a parent-less
       
   450     menu bar this way:
       
   451 
       
   452     \snippet doc/src/snippets/code/src_gui_widgets_qmenubar.cpp 1
       
   453 
       
   454     \sa setMenuBar()
       
   455 */
       
   456 QMenuBar *QMainWindow::menuBar() const
       
   457 {
       
   458     QMenuBar *menuBar = qobject_cast<QMenuBar *>(d_func()->layout->menuBar());
       
   459     if (!menuBar) {
       
   460         QMainWindow *self = const_cast<QMainWindow *>(this);
       
   461         menuBar = new QMenuBar(self);
       
   462         self->setMenuBar(menuBar);
       
   463     }
       
   464     return menuBar;
       
   465 }
       
   466 
       
   467 /*!
       
   468     Sets the menu bar for the main window to \a menuBar.
       
   469 
       
   470     Note: QMainWindow takes ownership of the \a menuBar pointer and
       
   471     deletes it at the appropriate time.
       
   472 
       
   473     \sa menuBar()
       
   474 */
       
   475 void QMainWindow::setMenuBar(QMenuBar *menuBar)
       
   476 {
       
   477     Q_D(QMainWindow);
       
   478     if (d->layout->menuBar() && d->layout->menuBar() != menuBar) {
       
   479         // Reparent corner widgets before we delete the old menu bar.
       
   480         QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(d->layout->menuBar());
       
   481         if (menuBar) {
       
   482             // TopLeftCorner widget.
       
   483             QWidget *cornerWidget = oldMenuBar->cornerWidget(Qt::TopLeftCorner);
       
   484             if (cornerWidget)
       
   485                 menuBar->setCornerWidget(cornerWidget, Qt::TopLeftCorner);
       
   486             // TopRightCorner widget.
       
   487             cornerWidget = oldMenuBar->cornerWidget(Qt::TopRightCorner);
       
   488             if (cornerWidget)
       
   489                 menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner);
       
   490         }
       
   491         oldMenuBar->hide();
       
   492         oldMenuBar->deleteLater();
       
   493     }
       
   494     d->layout->setMenuBar(menuBar);
       
   495 
       
   496 #ifdef QT_SOFTKEYS_ENABLED
       
   497     if (menuBar)
       
   498         addAction(d->menuBarAction);
       
   499     else
       
   500         removeAction(d->menuBarAction);
       
   501 #endif
       
   502 }
       
   503 
       
   504 /*!
       
   505     \since 4.2
       
   506 
       
   507     Returns the menu bar for the main window. This function returns
       
   508     null if a menu bar hasn't been constructed yet.
       
   509 */
       
   510 QWidget *QMainWindow::menuWidget() const
       
   511 {
       
   512     QWidget *menuBar = d_func()->layout->menuBar();
       
   513     return menuBar;
       
   514 }
       
   515 
       
   516 /*!
       
   517     \since 4.2
       
   518 
       
   519     Sets the menu bar for the main window to \a menuBar.
       
   520 
       
   521     QMainWindow takes ownership of the \a menuBar pointer and
       
   522     deletes it at the appropriate time.
       
   523 */
       
   524 void QMainWindow::setMenuWidget(QWidget *menuBar)
       
   525 {
       
   526     Q_D(QMainWindow);
       
   527     if (d->layout->menuBar() && d->layout->menuBar() != menuBar) {
       
   528         d->layout->menuBar()->hide();
       
   529         d->layout->menuBar()->deleteLater();
       
   530     }
       
   531     d->layout->setMenuBar(menuBar);
       
   532 }
       
   533 #endif // QT_NO_MENUBAR
       
   534 
       
   535 #ifndef QT_NO_STATUSBAR
       
   536 /*!
       
   537     Returns the status bar for the main window. This function creates
       
   538     and returns an empty status bar if the status bar does not exist.
       
   539 
       
   540     \sa setStatusBar()
       
   541 */
       
   542 QStatusBar *QMainWindow::statusBar() const
       
   543 {
       
   544     QStatusBar *statusbar = d_func()->layout->statusBar();
       
   545     if (!statusbar) {
       
   546         QMainWindow *self = const_cast<QMainWindow *>(this);
       
   547         statusbar = new QStatusBar(self);
       
   548         statusbar->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
       
   549         self->setStatusBar(statusbar);
       
   550     }
       
   551     return statusbar;
       
   552 }
       
   553 
       
   554 /*!
       
   555     Sets the status bar for the main window to \a statusbar.
       
   556 
       
   557     Setting the status bar to 0 will remove it from the main window.
       
   558     Note that QMainWindow takes ownership of the \a statusbar pointer
       
   559     and deletes it at the appropriate time.
       
   560 
       
   561     \sa statusBar()
       
   562 */
       
   563 void QMainWindow::setStatusBar(QStatusBar *statusbar)
       
   564 {
       
   565     Q_D(QMainWindow);
       
   566     if (d->layout->statusBar() && d->layout->statusBar() != statusbar) {
       
   567         d->layout->statusBar()->hide();
       
   568         d->layout->statusBar()->deleteLater();
       
   569     }
       
   570     d->layout->setStatusBar(statusbar);
       
   571 }
       
   572 #endif // QT_NO_STATUSBAR
       
   573 
       
   574 /*!
       
   575     Returns the central widget for the main window. This function
       
   576     returns zero if the central widget has not been set.
       
   577 
       
   578     \sa setCentralWidget()
       
   579 */
       
   580 QWidget *QMainWindow::centralWidget() const
       
   581 { return d_func()->layout->centralWidget(); }
       
   582 
       
   583 /*!
       
   584     Sets the given \a widget to be the main window's central widget.
       
   585 
       
   586     Note: QMainWindow takes ownership of the \a widget pointer and
       
   587     deletes it at the appropriate time.
       
   588 
       
   589     \sa centralWidget()
       
   590 */
       
   591 void QMainWindow::setCentralWidget(QWidget *widget)
       
   592 {
       
   593     Q_D(QMainWindow);
       
   594     if (d->layout->centralWidget() && d->layout->centralWidget() != widget) {
       
   595         d->layout->centralWidget()->hide();
       
   596         d->layout->centralWidget()->deleteLater();
       
   597     }
       
   598     d->layout->setCentralWidget(widget);
       
   599 }
       
   600 
       
   601 #ifndef QT_NO_DOCKWIDGET
       
   602 /*!
       
   603     Sets the given dock widget \a area to occupy the specified \a
       
   604     corner.
       
   605 
       
   606     \sa corner()
       
   607 */
       
   608 void QMainWindow::setCorner(Qt::Corner corner, Qt::DockWidgetArea area)
       
   609 {
       
   610     bool valid = false;
       
   611     switch (corner) {
       
   612     case Qt::TopLeftCorner:
       
   613         valid = (area == Qt::TopDockWidgetArea || area == Qt::LeftDockWidgetArea);
       
   614         break;
       
   615     case Qt::TopRightCorner:
       
   616         valid = (area == Qt::TopDockWidgetArea || area == Qt::RightDockWidgetArea);
       
   617         break;
       
   618     case Qt::BottomLeftCorner:
       
   619         valid = (area == Qt::BottomDockWidgetArea || area == Qt::LeftDockWidgetArea);
       
   620         break;
       
   621     case Qt::BottomRightCorner:
       
   622         valid = (area == Qt::BottomDockWidgetArea || area == Qt::RightDockWidgetArea);
       
   623         break;
       
   624     }
       
   625     if (!valid)
       
   626         qWarning("QMainWindow::setCorner(): 'area' is not valid for 'corner'");
       
   627     else
       
   628         d_func()->layout->setCorner(corner, area);
       
   629 }
       
   630 
       
   631 /*!
       
   632     Returns the dock widget area that occupies the specified \a
       
   633     corner.
       
   634 
       
   635     \sa setCorner()
       
   636 */
       
   637 Qt::DockWidgetArea QMainWindow::corner(Qt::Corner corner) const
       
   638 { return d_func()->layout->corner(corner); }
       
   639 #endif
       
   640 
       
   641 #ifndef QT_NO_TOOLBAR
       
   642 
       
   643 static bool checkToolBarArea(Qt::ToolBarArea area, const char *where)
       
   644 {
       
   645     switch (area) {
       
   646     case Qt::LeftToolBarArea:
       
   647     case Qt::RightToolBarArea:
       
   648     case Qt::TopToolBarArea:
       
   649     case Qt::BottomToolBarArea:
       
   650         return true;
       
   651     default:
       
   652         break;
       
   653     }
       
   654     qWarning("%s: invalid 'area' argument", where);
       
   655     return false;
       
   656 }
       
   657 
       
   658 /*!
       
   659     Adds a toolbar break to the given \a area after all the other
       
   660     objects that are present.
       
   661 */
       
   662 void QMainWindow::addToolBarBreak(Qt::ToolBarArea area)
       
   663 {
       
   664     if (!checkToolBarArea(area, "QMainWindow::addToolBarBreak"))
       
   665         return;
       
   666     d_func()->layout->addToolBarBreak(area);
       
   667 }
       
   668 
       
   669 /*!
       
   670     Inserts a toolbar break before the toolbar specified by \a before.
       
   671 */
       
   672 void QMainWindow::insertToolBarBreak(QToolBar *before)
       
   673 { d_func()->layout->insertToolBarBreak(before); }
       
   674 
       
   675 /*!
       
   676     Removes a toolbar break previously inserted before the toolbar specified by \a before.
       
   677 */
       
   678 
       
   679 void QMainWindow::removeToolBarBreak(QToolBar *before)
       
   680 {
       
   681     Q_D(QMainWindow);
       
   682     d->layout->removeToolBarBreak(before);
       
   683 }
       
   684 
       
   685 /*!
       
   686     Adds the \a toolbar into the specified \a area in this main
       
   687     window. The \a toolbar is placed at the end of the current tool
       
   688     bar block (i.e. line). If the main window already manages \a toolbar
       
   689     then it will only move the toolbar to \a area.
       
   690 
       
   691     \sa insertToolBar() addToolBarBreak() insertToolBarBreak()
       
   692 */
       
   693 void QMainWindow::addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)
       
   694 {
       
   695     if (!checkToolBarArea(area, "QMainWindow::addToolBar"))
       
   696         return;
       
   697 
       
   698     Q_D(QMainWindow);
       
   699 
       
   700     disconnect(this, SIGNAL(iconSizeChanged(QSize)),
       
   701                toolbar, SLOT(_q_updateIconSize(QSize)));
       
   702     disconnect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
       
   703                toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
       
   704 
       
   705     if(toolbar->d_func()->state && toolbar->d_func()->state->dragging) {
       
   706         //removing a toolbar which is dragging will cause crash
       
   707 #ifndef QT_NO_DOCKWIDGET
       
   708         bool animated = isAnimated();
       
   709         setAnimated(false);
       
   710 #endif
       
   711         toolbar->d_func()->endDrag();
       
   712 #ifndef QT_NO_DOCKWIDGET
       
   713         setAnimated(animated);
       
   714 #endif
       
   715     }
       
   716 
       
   717     if (!d->layout->usesHIToolBar(toolbar)) {
       
   718         d->layout->removeWidget(toolbar);
       
   719     } else {
       
   720         d->layout->removeToolBar(toolbar);
       
   721     }
       
   722 
       
   723     toolbar->d_func()->_q_updateIconSize(d->iconSize);
       
   724     toolbar->d_func()->_q_updateToolButtonStyle(d->toolButtonStyle);
       
   725     connect(this, SIGNAL(iconSizeChanged(QSize)),
       
   726             toolbar, SLOT(_q_updateIconSize(QSize)));
       
   727     connect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
       
   728             toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
       
   729 
       
   730     d->layout->addToolBar(area, toolbar);
       
   731 }
       
   732 
       
   733 /*! \overload
       
   734     Equivalent of calling addToolBar(Qt::TopToolBarArea, \a toolbar)
       
   735 */
       
   736 void QMainWindow::addToolBar(QToolBar *toolbar)
       
   737 { addToolBar(Qt::TopToolBarArea, toolbar); }
       
   738 
       
   739 /*!
       
   740     \overload
       
   741 
       
   742     Creates a QToolBar object, setting its window title to \a title,
       
   743     and inserts it into the top toolbar area.
       
   744 
       
   745     \sa setWindowTitle()
       
   746 */
       
   747 QToolBar *QMainWindow::addToolBar(const QString &title)
       
   748 {
       
   749     QToolBar *toolBar = new QToolBar(this);
       
   750     toolBar->setWindowTitle(title);
       
   751     addToolBar(toolBar);
       
   752     return toolBar;
       
   753 }
       
   754 
       
   755 /*!
       
   756     Inserts the \a toolbar into the area occupied by the \a before toolbar
       
   757     so that it appears before it. For example, in normal left-to-right
       
   758     layout operation, this means that \a toolbar will appear to the left
       
   759     of the toolbar specified by \a before in a horizontal toolbar area.
       
   760 
       
   761     \sa insertToolBarBreak() addToolBar() addToolBarBreak()
       
   762 */
       
   763 void QMainWindow::insertToolBar(QToolBar *before, QToolBar *toolbar)
       
   764 {
       
   765     Q_D(QMainWindow);
       
   766 
       
   767     d->layout->removeToolBar(toolbar);
       
   768 
       
   769     toolbar->d_func()->_q_updateIconSize(d->iconSize);
       
   770     toolbar->d_func()->_q_updateToolButtonStyle(d->toolButtonStyle);
       
   771     connect(this, SIGNAL(iconSizeChanged(QSize)),
       
   772             toolbar, SLOT(_q_updateIconSize(QSize)));
       
   773     connect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
       
   774             toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
       
   775 
       
   776     d->layout->insertToolBar(before, toolbar);
       
   777 }
       
   778 
       
   779 /*!
       
   780     Removes the \a toolbar from the main window layout and hides
       
   781     it. Note that the \a toolbar is \e not deleted.
       
   782 */
       
   783 void QMainWindow::removeToolBar(QToolBar *toolbar)
       
   784 {
       
   785     if (toolbar) {
       
   786         d_func()->layout->removeToolBar(toolbar);
       
   787         toolbar->hide();
       
   788     }
       
   789 }
       
   790 
       
   791 /*!
       
   792     Returns the Qt::ToolBarArea for \a toolbar. If \a toolbar has not
       
   793     been added to the main window, this function returns \c
       
   794     Qt::NoToolBarArea.
       
   795 
       
   796     \sa addToolBar() addToolBarBreak() Qt::ToolBarArea
       
   797 */
       
   798 Qt::ToolBarArea QMainWindow::toolBarArea(QToolBar *toolbar) const
       
   799 { return d_func()->layout->toolBarArea(toolbar); }
       
   800 
       
   801 /*!
       
   802 
       
   803     Returns whether there is a toolbar
       
   804     break before the \a toolbar.
       
   805 
       
   806     \sa  addToolBarBreak(), insertToolBarBreak()
       
   807 */
       
   808 bool QMainWindow::toolBarBreak(QToolBar *toolbar) const
       
   809 {
       
   810     return d_func()->layout->toolBarBreak(toolbar);
       
   811 }
       
   812 
       
   813 #endif // QT_NO_TOOLBAR
       
   814 
       
   815 #ifndef QT_NO_DOCKWIDGET
       
   816 
       
   817 /*! \property QMainWindow::animated
       
   818     \brief whether manipulating dock widgets and tool bars is animated
       
   819     \since 4.2
       
   820 
       
   821     When a dock widget or tool bar is dragged over the
       
   822     main window, the main window adjusts its contents
       
   823     to indicate where the dock widget or tool bar will
       
   824     be docked if it is dropped. Setting this property
       
   825     causes QMainWindow to move its contents in a smooth
       
   826     animation. Clearing this property causes the contents
       
   827     to snap into their new positions.
       
   828 
       
   829     By default, this property is set. It may be cleared if
       
   830     the main window contains widgets which are slow at resizing
       
   831     or repainting themselves.
       
   832 
       
   833     Setting this property is identical to setting the AnimatedDocks
       
   834     option using setDockOptions().
       
   835 */
       
   836 
       
   837 bool QMainWindow::isAnimated() const
       
   838 {
       
   839     Q_D(const QMainWindow);
       
   840     return d->layout->dockOptions & AnimatedDocks;
       
   841 }
       
   842 
       
   843 void QMainWindow::setAnimated(bool enabled)
       
   844 {
       
   845     Q_D(QMainWindow);
       
   846 
       
   847     DockOptions opts = d->layout->dockOptions;
       
   848     if (enabled)
       
   849         opts |= AnimatedDocks;
       
   850     else
       
   851         opts &= ~AnimatedDocks;
       
   852 
       
   853     d->layout->setDockOptions(opts);
       
   854 }
       
   855 
       
   856 /*! \property QMainWindow::dockNestingEnabled
       
   857     \brief whether docks can be nested
       
   858     \since 4.2
       
   859 
       
   860     If this property is false, dock areas can only contain a single row
       
   861     (horizontal or vertical) of dock widgets. If this property is true,
       
   862     the area occupied by a dock widget can be split in either direction to contain
       
   863     more dock widgets.
       
   864 
       
   865     Dock nesting is only necessary in applications that contain a lot of
       
   866     dock widgets. It gives the user greater freedom in organizing their
       
   867     main window. However, dock nesting leads to more complex
       
   868     (and less intuitive) behavior when a dock widget is dragged over the
       
   869     main window, since there are more ways in which a dropped dock widget
       
   870     may be placed in the dock area.
       
   871 
       
   872     Setting this property is identical to setting the AllowNestedDocks option
       
   873     using setDockOptions().
       
   874 */
       
   875 
       
   876 bool QMainWindow::isDockNestingEnabled() const
       
   877 {
       
   878     Q_D(const QMainWindow);
       
   879     return d->layout->dockOptions & AllowNestedDocks;
       
   880 }
       
   881 
       
   882 void QMainWindow::setDockNestingEnabled(bool enabled)
       
   883 {
       
   884     Q_D(QMainWindow);
       
   885 
       
   886     DockOptions opts = d->layout->dockOptions;
       
   887     if (enabled)
       
   888         opts |= AllowNestedDocks;
       
   889     else
       
   890         opts &= ~AllowNestedDocks;
       
   891 
       
   892     d->layout->setDockOptions(opts);
       
   893 }
       
   894 
       
   895 #if 0
       
   896 /*! \property QMainWindow::verticalTabsEnabled
       
   897     \brief whether left and right dock areas use vertical tabs
       
   898     \since 4.2
       
   899 
       
   900     If this property is set to false, dock areas containing tabbed dock widgets
       
   901     display horizontal tabs, simmilar to Visual Studio.
       
   902 
       
   903     If this property is set to true, then the right and left dock areas display vertical
       
   904     tabs, simmilar to KDevelop.
       
   905 
       
   906     This property should be set before any dock widgets are added to the main window.
       
   907 */
       
   908 
       
   909 bool QMainWindow::verticalTabsEnabled() const
       
   910 {
       
   911     return d_func()->layout->verticalTabsEnabled();
       
   912 }
       
   913 
       
   914 void QMainWindow::setVerticalTabsEnabled(bool enabled)
       
   915 {
       
   916     d_func()->layout->setVerticalTabsEnabled(enabled);
       
   917 }
       
   918 #endif
       
   919 
       
   920 static bool checkDockWidgetArea(Qt::DockWidgetArea area, const char *where)
       
   921 {
       
   922     switch (area) {
       
   923     case Qt::LeftDockWidgetArea:
       
   924     case Qt::RightDockWidgetArea:
       
   925     case Qt::TopDockWidgetArea:
       
   926     case Qt::BottomDockWidgetArea:
       
   927         return true;
       
   928     default:
       
   929         break;
       
   930     }
       
   931     qWarning("%s: invalid 'area' argument", where);
       
   932     return false;
       
   933 }
       
   934 
       
   935 #ifndef QT_NO_TABBAR
       
   936 /*!
       
   937     \property QMainWindow::documentMode
       
   938     \brief whether the tab bar for tabbed dockwidgets is set to document mode.
       
   939     \since 4.5
       
   940 
       
   941     The default is false.
       
   942 
       
   943     \sa QTabBar::documentMode
       
   944 */
       
   945 bool QMainWindow::documentMode() const
       
   946 {
       
   947     return d_func()->layout->documentMode();
       
   948 }
       
   949 
       
   950 void QMainWindow::setDocumentMode(bool enabled)
       
   951 {
       
   952     d_func()->layout->setDocumentMode(enabled);
       
   953 }
       
   954 #endif // QT_NO_TABBAR
       
   955 
       
   956 #ifndef QT_NO_TABWIDGET
       
   957 /*!
       
   958     \property QMainWindow::tabShape
       
   959     \brief the tab shape used for tabbed dock widgets.
       
   960     \since 4.5
       
   961 
       
   962     The default is \l QTabWidget::Rounded.
       
   963 
       
   964     \sa setTabPosition()
       
   965 */
       
   966 QTabWidget::TabShape QMainWindow::tabShape() const
       
   967 {
       
   968     return d_func()->layout->tabShape();
       
   969 }
       
   970 
       
   971 void QMainWindow::setTabShape(QTabWidget::TabShape tabShape)
       
   972 {
       
   973     d_func()->layout->setTabShape(tabShape);
       
   974 }
       
   975 
       
   976 /*!
       
   977     \since 4.5
       
   978 
       
   979     Returns the tab position for \a area.
       
   980 
       
   981     \note The \l VerticalTabs dock option overrides the tab positions returned
       
   982     by this function.
       
   983 
       
   984     \sa setTabPosition(), tabShape()
       
   985 */
       
   986 QTabWidget::TabPosition QMainWindow::tabPosition(Qt::DockWidgetArea area) const
       
   987 {
       
   988     if (!checkDockWidgetArea(area, "QMainWindow::tabPosition"))
       
   989         return QTabWidget::South;
       
   990     return d_func()->layout->tabPosition(area);
       
   991 }
       
   992 
       
   993 /*!
       
   994     \since 4.5
       
   995 
       
   996     Sets the tab position for the given dock widget \a areas to the specified
       
   997     \a tabPosition. By default, all dock areas show their tabs at the bottom.
       
   998 
       
   999     \note The \l VerticalTabs dock option overrides the tab positions set by
       
  1000     this method.
       
  1001 
       
  1002     \sa tabPosition(), setTabShape()
       
  1003 */
       
  1004 void QMainWindow::setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition)
       
  1005 {
       
  1006     d_func()->layout->setTabPosition(areas, tabPosition);
       
  1007 }
       
  1008 #endif // QT_NO_TABWIDGET
       
  1009 
       
  1010 /*!
       
  1011     Adds the given \a dockwidget to the specified \a area.
       
  1012 */
       
  1013 void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget)
       
  1014 {
       
  1015     if (!checkDockWidgetArea(area, "QMainWindow::addDockWidget"))
       
  1016         return;
       
  1017 
       
  1018     Qt::Orientation orientation = Qt::Vertical;
       
  1019     switch (area) {
       
  1020     case Qt::TopDockWidgetArea:
       
  1021     case Qt::BottomDockWidgetArea:
       
  1022         orientation = Qt::Horizontal;
       
  1023         break;
       
  1024     default:
       
  1025         break;
       
  1026     }
       
  1027     d_func()->layout->removeWidget(dockwidget); // in case it was already in here
       
  1028     addDockWidget(area, dockwidget, orientation);
       
  1029 
       
  1030 #ifdef Q_WS_MAC     //drawer support
       
  1031     QMacCocoaAutoReleasePool pool;
       
  1032     extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
       
  1033     if (qt_mac_is_macdrawer(dockwidget)) {
       
  1034         extern bool qt_mac_set_drawer_preferred_edge(QWidget *, Qt::DockWidgetArea); //qwidget_mac.cpp
       
  1035         window()->createWinId();
       
  1036         dockwidget->window()->createWinId();
       
  1037         qt_mac_set_drawer_preferred_edge(dockwidget, area);
       
  1038         if (dockwidget->isVisible()) {
       
  1039             dockwidget->hide();
       
  1040             dockwidget->show();
       
  1041         }
       
  1042     }
       
  1043 #endif
       
  1044 }
       
  1045 
       
  1046 /*!
       
  1047     Restores the state of \a dockwidget if it is created after the call
       
  1048     to restoreState(). Returns true if the state was restored; otherwise
       
  1049     returns false.
       
  1050 
       
  1051     \sa restoreState(), saveState()
       
  1052 */
       
  1053 
       
  1054 bool QMainWindow::restoreDockWidget(QDockWidget *dockwidget)
       
  1055 {
       
  1056     return d_func()->layout->restoreDockWidget(dockwidget);
       
  1057 }
       
  1058 
       
  1059 /*!
       
  1060     Adds \a dockwidget into the given \a area in the direction
       
  1061     specified by the \a orientation.
       
  1062 */
       
  1063 void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget,
       
  1064                                 Qt::Orientation orientation)
       
  1065 {
       
  1066     if (!checkDockWidgetArea(area, "QMainWindow::addDockWidget"))
       
  1067         return;
       
  1068 
       
  1069     // add a window to an area, placing done relative to the previous
       
  1070     d_func()->layout->addDockWidget(area, dockwidget, orientation);
       
  1071 }
       
  1072 
       
  1073 /*!
       
  1074     \fn void QMainWindow::splitDockWidget(QDockWidget *first, QDockWidget *second, Qt::Orientation orientation)
       
  1075 
       
  1076     Splits the space covered by the \a first dock widget into two parts,
       
  1077     moves the \a first dock widget into the first part, and moves the
       
  1078     \a second dock widget into the second part.
       
  1079 
       
  1080     The \a orientation specifies how the space is divided: A Qt::Horizontal
       
  1081     split places the second dock widget to the right of the first; a
       
  1082     Qt::Vertical split places the second dock widget below the first.
       
  1083 
       
  1084     \e Note: if \a first is currently in a tabbed docked area, \a second will
       
  1085     be added as a new tab, not as a neighbor of \a first. This is because a
       
  1086     single tab can contain only one dock widget.
       
  1087 
       
  1088     \e Note: The Qt::LayoutDirection influences the order of the dock widgets
       
  1089     in the two parts of the divided area. When right-to-left layout direction
       
  1090     is enabled, the placing of the dock widgets will be reversed.
       
  1091 
       
  1092     \sa tabifyDockWidget(), addDockWidget(), removeDockWidget()
       
  1093 */
       
  1094 void QMainWindow::splitDockWidget(QDockWidget *after, QDockWidget *dockwidget,
       
  1095                                   Qt::Orientation orientation)
       
  1096 {
       
  1097     d_func()->layout->splitDockWidget(after, dockwidget, orientation);
       
  1098 }
       
  1099 
       
  1100 /*!
       
  1101     \fn void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
       
  1102 
       
  1103     Moves \a second dock widget on top of \a first dock widget, creating a tabbed
       
  1104     docked area in the main window.
       
  1105 
       
  1106     \sa tabifiedDockWidgets()
       
  1107 */
       
  1108 void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
       
  1109 {
       
  1110     d_func()->layout->tabifyDockWidget(first, second);
       
  1111 }
       
  1112 
       
  1113 
       
  1114 /*!
       
  1115     \fn QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
       
  1116 
       
  1117     Returns the dock widgets that are tabified together with \a dockwidget.
       
  1118 
       
  1119     \since 4.5
       
  1120     \sa tabifyDockWidget()
       
  1121 */
       
  1122 
       
  1123 QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
       
  1124 {
       
  1125     QList<QDockWidget*> ret;
       
  1126 #if defined(QT_NO_TABBAR)
       
  1127     Q_UNUSED(dockwidget);
       
  1128 #else
       
  1129     const QDockAreaLayoutInfo *info = d_func()->layout->layoutState.dockAreaLayout.info(dockwidget);
       
  1130     if (info && info->tabbed && info->tabBar) {
       
  1131         for(int i = 0; i < info->item_list.count(); ++i) {
       
  1132             const QDockAreaLayoutItem &item = info->item_list.at(i);
       
  1133             if (item.widgetItem) {
       
  1134                 if (QDockWidget *dock = qobject_cast<QDockWidget*>(item.widgetItem->widget())) {
       
  1135                     if (dock != dockwidget) {
       
  1136                         ret += dock;
       
  1137                     }
       
  1138                 }
       
  1139             }
       
  1140         }
       
  1141     }
       
  1142 #endif
       
  1143     return ret;
       
  1144 }
       
  1145 
       
  1146 
       
  1147 /*!
       
  1148     Removes the \a dockwidget from the main window layout and hides
       
  1149     it. Note that the \a dockwidget is \e not deleted.
       
  1150 */
       
  1151 void QMainWindow::removeDockWidget(QDockWidget *dockwidget)
       
  1152 {
       
  1153     if (dockwidget) {
       
  1154         d_func()->layout->removeWidget(dockwidget);
       
  1155         dockwidget->hide();
       
  1156     }
       
  1157 }
       
  1158 
       
  1159 /*!
       
  1160     Returns the Qt::DockWidgetArea for \a dockwidget. If \a dockwidget
       
  1161     has not been added to the main window, this function returns \c
       
  1162     Qt::NoDockWidgetArea.
       
  1163 
       
  1164     \sa addDockWidget() splitDockWidget() Qt::DockWidgetArea
       
  1165 */
       
  1166 Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
       
  1167 { return d_func()->layout->dockWidgetArea(dockwidget); }
       
  1168 
       
  1169 #endif // QT_NO_DOCKWIDGET
       
  1170 
       
  1171 /*!
       
  1172     Saves the current state of this mainwindow's toolbars and
       
  1173     dockwidgets. The \a version number is stored as part of the data.
       
  1174 
       
  1175     The \link QObject::objectName objectName\endlink property is used
       
  1176     to identify each QToolBar and QDockWidget.  You should make sure
       
  1177     that this property is unique for each QToolBar and QDockWidget you
       
  1178     add to the QMainWindow
       
  1179 
       
  1180     To restore the saved state, pass the return value and \a version
       
  1181     number to restoreState().
       
  1182 
       
  1183     To save the geometry when the window closes, you can
       
  1184     implement a close event like this:
       
  1185 
       
  1186     \snippet doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp 0
       
  1187 
       
  1188     \sa restoreState(), QWidget::saveGeometry(), QWidget::restoreGeometry()
       
  1189 */
       
  1190 QByteArray QMainWindow::saveState(int version) const
       
  1191 {
       
  1192     QByteArray data;
       
  1193     QDataStream stream(&data, QIODevice::WriteOnly);
       
  1194     stream << QMainWindowLayout::VersionMarker;
       
  1195     stream << version;
       
  1196     d_func()->layout->saveState(stream);
       
  1197     return data;
       
  1198 }
       
  1199 
       
  1200 /*!
       
  1201     Restores the \a state of this mainwindow's toolbars and
       
  1202     dockwidgets. The \a version number is compared with that stored
       
  1203     in \a state. If they do not match, the mainwindow's state is left
       
  1204     unchanged, and this function returns \c false; otherwise, the state
       
  1205     is restored, and this function returns \c true.
       
  1206 
       
  1207     To restore geometry saved using QSettings, you can use code like
       
  1208     this:
       
  1209 
       
  1210     \snippet doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp 1
       
  1211 
       
  1212     \sa saveState(), QWidget::saveGeometry(),
       
  1213     QWidget::restoreGeometry(), restoreDockWidget()
       
  1214 */
       
  1215 bool QMainWindow::restoreState(const QByteArray &state, int version)
       
  1216 {
       
  1217     if (state.isEmpty())
       
  1218         return false;
       
  1219     QByteArray sd = state;
       
  1220     QDataStream stream(&sd, QIODevice::ReadOnly);
       
  1221     int marker, v;
       
  1222     stream >> marker;
       
  1223     stream >> v;
       
  1224     if (stream.status() != QDataStream::Ok || marker != QMainWindowLayout::VersionMarker || v != version)
       
  1225         return false;
       
  1226     bool restored = d_func()->layout->restoreState(stream);
       
  1227     return restored;
       
  1228 }
       
  1229 
       
  1230 #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
       
  1231 QCursor QMainWindowPrivate::separatorCursor(const QList<int> &path) const
       
  1232 {
       
  1233     QDockAreaLayoutInfo *info = layout->layoutState.dockAreaLayout.info(path);
       
  1234     Q_ASSERT(info != 0);
       
  1235     if (path.size() == 1) { // is this the "top-level" separator which separates a dock area
       
  1236                             // from the central widget?
       
  1237         switch (path.first()) {
       
  1238             case QInternal::LeftDock:
       
  1239             case QInternal::RightDock:
       
  1240                 return Qt::SplitHCursor;
       
  1241             case QInternal::TopDock:
       
  1242             case QInternal::BottomDock:
       
  1243                 return Qt::SplitVCursor;
       
  1244             default:
       
  1245                 break;
       
  1246         }
       
  1247     }
       
  1248 
       
  1249     // no, it's a splitter inside a dock area, separating two dock widgets
       
  1250 
       
  1251     return info->o == Qt::Horizontal
       
  1252             ? Qt::SplitHCursor : Qt::SplitVCursor;
       
  1253 }
       
  1254 
       
  1255 void QMainWindowPrivate::adjustCursor(const QPoint &pos)
       
  1256 {
       
  1257     Q_Q(QMainWindow);
       
  1258 
       
  1259     hoverPos = pos;
       
  1260 
       
  1261     if (pos == QPoint(0, 0)) {
       
  1262         if (!hoverSeparator.isEmpty())
       
  1263             q->update(layout->layoutState.dockAreaLayout.separatorRect(hoverSeparator));
       
  1264         hoverSeparator.clear();
       
  1265 
       
  1266         if (cursorAdjusted) {
       
  1267             cursorAdjusted = false;
       
  1268             if (hasOldCursor)
       
  1269                 q->setCursor(oldCursor);
       
  1270             else
       
  1271                 q->unsetCursor();
       
  1272         }
       
  1273     } else {
       
  1274         QList<int> pathToSeparator
       
  1275             = layout->layoutState.dockAreaLayout.findSeparator(pos);
       
  1276 
       
  1277         if (pathToSeparator != hoverSeparator) {
       
  1278             if (!hoverSeparator.isEmpty())
       
  1279                 q->update(layout->layoutState.dockAreaLayout.separatorRect(hoverSeparator));
       
  1280 
       
  1281             hoverSeparator = pathToSeparator;
       
  1282 
       
  1283             if (hoverSeparator.isEmpty()) {
       
  1284                 if (cursorAdjusted) {
       
  1285                     cursorAdjusted = false;
       
  1286                     if (hasOldCursor)
       
  1287                         q->setCursor(oldCursor);
       
  1288                     else
       
  1289                         q->unsetCursor();
       
  1290                 }
       
  1291             } else {
       
  1292                 q->update(layout->layoutState.dockAreaLayout.separatorRect(hoverSeparator));
       
  1293                 if (!cursorAdjusted) {
       
  1294                     oldCursor = q->cursor();
       
  1295                     hasOldCursor = q->testAttribute(Qt::WA_SetCursor);
       
  1296                 }
       
  1297                 QCursor cursor = separatorCursor(hoverSeparator);
       
  1298                 cursorAdjusted = false; //to not reset the oldCursor in event(CursorChange)
       
  1299                 q->setCursor(cursor);
       
  1300                 cursorAdjusted = true;
       
  1301             }
       
  1302         }
       
  1303     }
       
  1304 }
       
  1305 #endif
       
  1306 
       
  1307 /*! \reimp */
       
  1308 bool QMainWindow::event(QEvent *event)
       
  1309 {
       
  1310     Q_D(QMainWindow);
       
  1311     switch (event->type()) {
       
  1312 
       
  1313 #ifndef QT_NO_DOCKWIDGET
       
  1314         case QEvent::Paint: {
       
  1315             QPainter p(this);
       
  1316             QRegion r = static_cast<QPaintEvent*>(event)->region();
       
  1317             d->layout->layoutState.dockAreaLayout.paintSeparators(&p, this, r, d->hoverPos);
       
  1318             break;
       
  1319         }
       
  1320 
       
  1321 #ifndef QT_NO_CURSOR
       
  1322         case QEvent::HoverMove:  {
       
  1323             d->adjustCursor(static_cast<QHoverEvent*>(event)->pos());
       
  1324             break;
       
  1325         }
       
  1326 
       
  1327         // We don't want QWidget to call update() on the entire QMainWindow
       
  1328         // on HoverEnter and HoverLeave, hence accept the event (return true).
       
  1329         case QEvent::HoverEnter:
       
  1330             return true;
       
  1331         case QEvent::HoverLeave:
       
  1332             d->adjustCursor(QPoint(0, 0));
       
  1333             return true;
       
  1334         case QEvent::ShortcutOverride: // when a menu pops up
       
  1335             d->adjustCursor(QPoint(0, 0));
       
  1336             break;
       
  1337 #endif // QT_NO_CURSOR
       
  1338 
       
  1339         case QEvent::MouseButtonPress: {
       
  1340             QMouseEvent *e = static_cast<QMouseEvent*>(event);
       
  1341             if (e->button() == Qt::LeftButton && d->layout->startSeparatorMove(e->pos())) {
       
  1342                 // The click was on a separator, eat this event
       
  1343                 e->accept();
       
  1344                 return true;
       
  1345             }
       
  1346             break;
       
  1347         }
       
  1348 
       
  1349         case QEvent::MouseMove: {
       
  1350             QMouseEvent *e = static_cast<QMouseEvent*>(event);
       
  1351 
       
  1352 #ifndef QT_NO_CURSOR
       
  1353             d->adjustCursor(e->pos());
       
  1354 #endif
       
  1355             if (e->buttons() & Qt::LeftButton) {
       
  1356                 if (d->layout->separatorMove(e->pos())) {
       
  1357                     // We're moving a separator, eat this event
       
  1358                     e->accept();
       
  1359                     return true;
       
  1360                 }
       
  1361             }
       
  1362 
       
  1363             break;
       
  1364         }
       
  1365 
       
  1366         case QEvent::MouseButtonRelease: {
       
  1367             QMouseEvent *e = static_cast<QMouseEvent*>(event);
       
  1368             if (d->layout->endSeparatorMove(e->pos())) {
       
  1369                 // We've released a separator, eat this event
       
  1370                 e->accept();
       
  1371                 return true;
       
  1372             }
       
  1373             break;
       
  1374         }
       
  1375 
       
  1376 #endif
       
  1377 
       
  1378 #ifndef QT_NO_TOOLBAR
       
  1379         case QEvent::ToolBarChange: {
       
  1380             d->layout->toggleToolBarsVisible();
       
  1381             return true;
       
  1382         }
       
  1383 #endif
       
  1384 
       
  1385 #ifndef QT_NO_STATUSTIP
       
  1386         case QEvent::StatusTip:
       
  1387 #ifndef QT_NO_STATUSBAR
       
  1388             if (QStatusBar *sb = d->layout->statusBar())
       
  1389                 sb->showMessage(static_cast<QStatusTipEvent*>(event)->tip());
       
  1390             else
       
  1391 #endif
       
  1392                 static_cast<QStatusTipEvent*>(event)->ignore();
       
  1393             return true;
       
  1394 #endif // QT_NO_STATUSTIP
       
  1395 
       
  1396         case QEvent::StyleChange:
       
  1397             if (!d->explicitIconSize)
       
  1398                 setIconSize(QSize());
       
  1399             break;
       
  1400 #ifdef Q_WS_MAC
       
  1401         case QEvent::Show:
       
  1402             if (unifiedTitleAndToolBarOnMac())
       
  1403                 d->layout->syncUnifiedToolbarVisibility();
       
  1404             d->layout->blockVisiblityCheck = false;
       
  1405             break;
       
  1406        case QEvent::WindowStateChange:
       
  1407             {
       
  1408                 if (isHidden()) {
       
  1409                     // We are coming out of a minimize, leave things as is.
       
  1410                     d->layout->blockVisiblityCheck = true;
       
  1411                 }
       
  1412 #  ifdef QT_MAC_USE_COCOA
       
  1413                 // We need to update the HIToolbar status when we go out of or into fullscreen.
       
  1414                 QWindowStateChangeEvent *wce = static_cast<QWindowStateChangeEvent *>(event);
       
  1415                 if ((windowState() & Qt::WindowFullScreen) || (wce->oldState() & Qt::WindowFullScreen)) {
       
  1416                     d->layout->updateHIToolBarStatus();
       
  1417                 }
       
  1418 #  endif // Cocoa
       
  1419             }
       
  1420             break;
       
  1421 #endif // Q_WS_MAC
       
  1422 #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
       
  1423        case QEvent::CursorChange:
       
  1424            if (d->cursorAdjusted) {
       
  1425                d->oldCursor = cursor();
       
  1426                d->hasOldCursor = testAttribute(Qt::WA_SetCursor);
       
  1427            }
       
  1428            break;
       
  1429 #endif
       
  1430         default:
       
  1431             break;
       
  1432     }
       
  1433 
       
  1434     return QWidget::event(event);
       
  1435 }
       
  1436 
       
  1437 #ifndef QT_NO_TOOLBAR
       
  1438 
       
  1439 /*!
       
  1440     \property QMainWindow::unifiedTitleAndToolBarOnMac
       
  1441     \brief whether the window uses the unified title and toolbar look on Mac OS X
       
  1442     \since 4.3
       
  1443 
       
  1444     This property is false by default and only has any effect on Mac OS X 10.4 or higher.
       
  1445 
       
  1446     If set to true, then the top toolbar area is replaced with a Carbon HIToolbar
       
  1447     or a Cocoa NSToolbar (depending on whether Qt was built with Carbon or Cocoa).
       
  1448     All toolbars in the top toolbar area and any toolbars added afterwards are
       
  1449     moved to that. This means a couple of things.
       
  1450 
       
  1451     \list
       
  1452     \i QToolBars in this toolbar area are not movable and you cannot drag other
       
  1453         toolbars to it
       
  1454     \i Toolbar breaks are not respected or preserved
       
  1455     \i Any custom widgets in the toolbar will not be shown if the toolbar
       
  1456         becomes too small (only actions will be shown)
       
  1457     \i Before Qt 4.5, if you called showFullScreen() on the main window, the QToolbar would
       
  1458         disappear since it is considered to be part of the title bar. Qt 4.5 and up will now work around this by pulling
       
  1459         the toolbars out and back into the regular toolbar and vice versa when you swap out.
       
  1460         However, a good practice would be that turning off the unified toolbar before you call
       
  1461         showFullScreen() and restoring it after you call showNormal().
       
  1462     \endlist
       
  1463 
       
  1464     Setting this back to false will remove these restrictions.
       
  1465 
       
  1466     The Qt::WA_MacBrushedMetal attribute takes precedence over this property.
       
  1467 */
       
  1468 void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
       
  1469 {
       
  1470 #ifdef Q_WS_MAC
       
  1471     Q_D(QMainWindow);
       
  1472     if (!isWindow() || d->useHIToolBar == set || QSysInfo::MacintoshVersion < QSysInfo::MV_10_3)
       
  1473         return;
       
  1474 
       
  1475     // ### Disable the unified toolbar when using anything but the native graphics system.
       
  1476     if (windowSurface())
       
  1477         return;
       
  1478 
       
  1479     d->useHIToolBar = set;
       
  1480     createWinId(); // We need the hiview for down below.
       
  1481 
       
  1482     d->layout->updateHIToolBarStatus();
       
  1483     // Enabling the unified toolbar clears the opaque size grip setting, update it.
       
  1484     d->macUpdateOpaqueSizeGrip();
       
  1485 #else
       
  1486     Q_UNUSED(set)
       
  1487 #endif
       
  1488 }
       
  1489 
       
  1490 bool QMainWindow::unifiedTitleAndToolBarOnMac() const
       
  1491 {
       
  1492 #ifdef Q_WS_MAC
       
  1493     return d_func()->useHIToolBar && !testAttribute(Qt::WA_MacBrushedMetal) && !(windowFlags() & Qt::FramelessWindowHint);
       
  1494 #endif
       
  1495     return false;
       
  1496 }
       
  1497 
       
  1498 #endif // QT_NO_TOOLBAR
       
  1499 
       
  1500 /*!
       
  1501     \internal
       
  1502 */
       
  1503 bool QMainWindow::isSeparator(const QPoint &pos) const
       
  1504 {
       
  1505 #ifndef QT_NO_DOCKWIDGET
       
  1506     Q_D(const QMainWindow);
       
  1507     return !d->layout->layoutState.dockAreaLayout.findSeparator(pos).isEmpty();
       
  1508 #else
       
  1509     Q_UNUSED(pos);
       
  1510     return false;
       
  1511 #endif
       
  1512 }
       
  1513 
       
  1514 #ifndef QT_NO_CONTEXTMENU
       
  1515 /*!
       
  1516     \reimp
       
  1517 */
       
  1518 void QMainWindow::contextMenuEvent(QContextMenuEvent *event)
       
  1519 {
       
  1520     event->ignore();
       
  1521     // only show the context menu for direct QDockWidget and QToolBar
       
  1522     // children and for the menu bar as well
       
  1523     QWidget *child = childAt(event->pos());
       
  1524     while (child && child != this) {
       
  1525 #ifndef QT_NO_MENUBAR
       
  1526         if (QMenuBar *mb = qobject_cast<QMenuBar *>(child)) {
       
  1527             if (mb->parentWidget() != this)
       
  1528                 return;
       
  1529             break;
       
  1530         }
       
  1531 #endif
       
  1532 #ifndef QT_NO_DOCKWIDGET
       
  1533         if (QDockWidget *dw = qobject_cast<QDockWidget *>(child)) {
       
  1534             if (dw->parentWidget() != this)
       
  1535                 return;
       
  1536             if (dw->widget()
       
  1537                 && dw->widget()->geometry().contains(child->mapFrom(this, event->pos()))) {
       
  1538                 // ignore the event if the mouse is over the QDockWidget contents
       
  1539                 return;
       
  1540             }
       
  1541             break;
       
  1542         }
       
  1543 #endif // QT_NO_DOCKWIDGET
       
  1544 #ifndef QT_NO_TOOLBAR
       
  1545         if (QToolBar *tb = qobject_cast<QToolBar *>(child)) {
       
  1546             if (tb->parentWidget() != this)
       
  1547                 return;
       
  1548             break;
       
  1549         }
       
  1550 #endif
       
  1551         child = child->parentWidget();
       
  1552     }
       
  1553     if (child == this)
       
  1554         return;
       
  1555 
       
  1556 #ifndef QT_NO_MENU
       
  1557     QMenu *popup = createPopupMenu();
       
  1558     if (popup && !popup->isEmpty()) {
       
  1559         popup->exec(event->globalPos());
       
  1560         event->accept();
       
  1561     }
       
  1562     delete popup;
       
  1563 #endif
       
  1564 }
       
  1565 #endif // QT_NO_CONTEXTMENU
       
  1566 
       
  1567 #ifndef QT_NO_MENU
       
  1568 /*!
       
  1569     Returns a popup menu containing checkable entries for the toolbars and
       
  1570     dock widgets present in the main window. If  there are no toolbars and
       
  1571     dock widgets present, this function returns a null pointer.
       
  1572 
       
  1573     By default, this function is called by the main window when the user
       
  1574     activates a context menu, typically by right-clicking on a toolbar or a dock
       
  1575     widget.
       
  1576 
       
  1577     If you want to create a custom popup menu, reimplement this function and
       
  1578     return a newly-created popup menu. Ownership of the popup menu is transferred
       
  1579     to the caller.
       
  1580 
       
  1581     \sa addDockWidget(), addToolBar(), menuBar()
       
  1582 */
       
  1583 QMenu *QMainWindow::createPopupMenu()
       
  1584 {
       
  1585     Q_D(QMainWindow);
       
  1586     QMenu *menu = 0;
       
  1587 #ifndef QT_NO_DOCKWIDGET
       
  1588     QList<QDockWidget *> dockwidgets = qFindChildren<QDockWidget *>(this);
       
  1589     if (dockwidgets.size()) {
       
  1590         menu = new QMenu(this);
       
  1591         for (int i = 0; i < dockwidgets.size(); ++i) {
       
  1592             QDockWidget *dockWidget = dockwidgets.at(i);
       
  1593             if (dockWidget->parentWidget() == this
       
  1594                 && !d->layout->layoutState.dockAreaLayout.indexOf(dockWidget).isEmpty()) {
       
  1595                 menu->addAction(dockwidgets.at(i)->toggleViewAction());
       
  1596             }
       
  1597         }
       
  1598         menu->addSeparator();
       
  1599     }
       
  1600 #endif // QT_NO_DOCKWIDGET
       
  1601 #ifndef QT_NO_TOOLBAR
       
  1602     QList<QToolBar *> toolbars = qFindChildren<QToolBar *>(this);
       
  1603     if (toolbars.size()) {
       
  1604         if (!menu)
       
  1605             menu = new QMenu(this);
       
  1606         for (int i = 0; i < toolbars.size(); ++i) {
       
  1607             QToolBar *toolBar = toolbars.at(i);
       
  1608             if (toolBar->parentWidget() == this
       
  1609                 && (!d->layout->layoutState.toolBarAreaLayout.indexOf(toolBar).isEmpty()
       
  1610                     || (unifiedTitleAndToolBarOnMac()
       
  1611                         && toolBarArea(toolBar) == Qt::TopToolBarArea))) {
       
  1612                 menu->addAction(toolbars.at(i)->toggleViewAction());
       
  1613             }
       
  1614         }
       
  1615     }
       
  1616 #endif
       
  1617     Q_UNUSED(d);
       
  1618     return menu;
       
  1619 }
       
  1620 #endif // QT_NO_MENU
       
  1621 
       
  1622 QT_END_NAMESPACE
       
  1623 
       
  1624 #endif // QT_NO_MAINWINDOW