source: trunk/src/gui/widgets/qmainwindow.cpp@ 112

Last change on this file since 112 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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