|
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 |