1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qmainwindow.h"
5#include "qmainwindowlayout_p.h"
6
7#if QT_CONFIG(dockwidget)
8#include "qdockwidget.h"
9#endif
10#if QT_CONFIG(toolbar)
11#include "qtoolbar.h"
12#endif
13
14#include <qapplication.h>
15#include <qmenu.h>
16#if QT_CONFIG(menubar)
17#include <qmenubar.h>
18#endif
19#if QT_CONFIG(statusbar)
20#include <qstatusbar.h>
21#endif
22#include <qevent.h>
23#include <qstyle.h>
24#include <qdebug.h>
25#include <qpainter.h>
26#include <qmimedata.h>
27
28#include <private/qwidget_p.h>
29#if QT_CONFIG(toolbar)
30#include "qtoolbar_p.h"
31#endif
32#include "qwidgetanimator_p.h"
33#include <QtGui/qpa/qplatformwindow.h>
34#include <QtGui/qpa/qplatformwindow_p.h>
35
36QT_BEGIN_NAMESPACE
37
38using namespace Qt::StringLiterals;
39
40class QMainWindowPrivate : public QWidgetPrivate
41{
42 Q_DECLARE_PUBLIC(QMainWindow)
43public:
44 inline QMainWindowPrivate()
45 : layout(nullptr), explicitIconSize(false), toolButtonStyle(Qt::ToolButtonIconOnly)
46#ifdef Q_OS_MACOS
47 , useUnifiedToolBar(false)
48#endif
49 { }
50 QPointer<QMainWindowLayout> layout;
51 QSize iconSize;
52 bool explicitIconSize;
53 Qt::ToolButtonStyle toolButtonStyle;
54#ifdef Q_OS_MACOS
55 bool useUnifiedToolBar;
56#endif
57 void init();
58
59 static inline QMainWindowLayout *mainWindowLayout(const QMainWindow *mainWindow)
60 {
61 return mainWindow ? mainWindow->d_func()->layout.data() : static_cast<QMainWindowLayout *>(nullptr);
62 }
63};
64
65QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *mainWindow)
66{
67 return QMainWindowPrivate::mainWindowLayout(mainWindow);
68}
69
70void QMainWindowPrivate::init()
71{
72 Q_Q(QMainWindow);
73
74 layout = new QMainWindowLayout(q, nullptr);
75
76 const int metric = q->style()->pixelMetric(metric: QStyle::PM_ToolBarIconSize, option: nullptr, widget: q);
77 iconSize = QSize(metric, metric);
78 q->setAttribute(Qt::WA_Hover);
79 q->setAcceptDrops(true);
80}
81
82/*
83 The Main Window:
84
85 +----------------------------------------------------------+
86 | Menu Bar |
87 +----------------------------------------------------------+
88 | Tool Bar Area |
89 | +--------------------------------------------------+ |
90 | | Dock Window Area | |
91 | | +------------------------------------------+ | |
92 | | | | | |
93 | | | Central Widget | | |
94 | | | | | |
95 | | | | | |
96 | | | | | |
97 | | | | | |
98 | | | | | |
99 | | | | | |
100 | | | | | |
101 | | | | | |
102 | | | | | |
103 | | | | | |
104 | | +------------------------------------------+ | |
105 | | | |
106 | +--------------------------------------------------+ |
107 | |
108 +----------------------------------------------------------+
109 | Status Bar |
110 +----------------------------------------------------------+
111
112*/
113
114/*!
115 \class QMainWindow
116 \brief The QMainWindow class provides a main application
117 window.
118 \ingroup mainwindow-classes
119 \inmodule QtWidgets
120
121 \section1 Qt Main Window Framework
122
123 A main window provides a framework for building an
124 application's user interface. Qt has QMainWindow and its \l{Main
125 Window and Related Classes}{related classes} for main window
126 management. QMainWindow has its own layout to which you can add
127 \l{QToolBar}s, \l{QDockWidget}s, a
128 QMenuBar, and a QStatusBar. The layout has a center area that can
129 be occupied by any kind of widget. You can see an image of the
130 layout below.
131
132 \image mainwindowlayout.png
133
134 \section1 Creating Main Window Components
135
136 A central widget will typically be a standard Qt widget such
137 as a QTextEdit or a QGraphicsView. Custom widgets can also be
138 used for advanced applications. You set the central widget with \c
139 setCentralWidget().
140
141 Main windows have either a single (SDI) or multiple (MDI)
142 document interface. You create MDI applications in Qt by using a
143 QMdiArea as the central widget.
144
145 We will now examine each of the other widgets that can be
146 added to a main window. We give examples on how to create and add
147 them.
148
149 \section2 Creating Menus
150
151 Qt implements menus in QMenu and QMainWindow keeps them in a
152 QMenuBar. \l{QAction}{QAction}s are added to the menus, which
153 display them as menu items.
154
155 You can add new menus to the main window's menu bar by calling
156 \c menuBar(), which returns the QMenuBar for the window, and then
157 add a menu with QMenuBar::addMenu().
158
159 QMainWindow comes with a default menu bar, but you can also
160 set one yourself with \c setMenuBar(). If you wish to implement a
161 custom menu bar (i.e., not use the QMenuBar widget), you can set it
162 with \c setMenuWidget().
163
164 An example of how to create menus follows:
165
166 \snippet code/src_widgets_widgets_qmainwindow.cpp 0
167
168 The \c createPopupMenu() function creates popup menus when the
169 main window receives context menu events. The default
170 implementation generates a menu with the checkable actions from
171 the dock widgets and toolbars. You can reimplement \c
172 createPopupMenu() for a custom menu.
173
174 \section2 Creating Toolbars
175
176 Toolbars are implemented in the QToolBar class. You add a
177 toolbar to a main window with \c addToolBar().
178
179 You control the initial position of toolbars by assigning them
180 to a specific Qt::ToolBarArea. You can split an area by inserting
181 a toolbar break - think of this as a line break in text editing -
182 with \c addToolBarBreak() or \c insertToolBarBreak(). You can also
183 restrict placement by the user with QToolBar::setAllowedAreas()
184 and QToolBar::setMovable().
185
186 The size of toolbar icons can be retrieved with \c iconSize().
187 The sizes are platform dependent; you can set a fixed size with \c
188 setIconSize(). You can alter the appearance of all tool buttons in
189 the toolbars with \c setToolButtonStyle().
190
191 An example of toolbar creation follows:
192
193 \snippet code/src_widgets_widgets_qmainwindow.cpp 1
194
195 \section2 Creating Dock Widgets
196
197 Dock widgets are implemented in the QDockWidget class. A dock
198 widget is a window that can be docked into the main window. You
199 add dock widgets to a main window with \c addDockWidget().
200
201 There are four dock widget areas as given by the
202 Qt::DockWidgetArea enum: left, right, top, and bottom. You can
203 specify which dock widget area that should occupy the corners
204 where the areas overlap with \c setCorner(). By default
205 each area can only contain one row (vertical or horizontal) of
206 dock widgets, but if you enable nesting with \c
207 setDockNestingEnabled(), dock widgets can be added in either
208 direction.
209
210 Two dock widgets may also be stacked on top of each other. A
211 QTabBar is then used to select which of the widgets should be
212 displayed.
213
214 We give an example of how to create and add dock widgets to a
215 main window:
216
217 \snippet mainwindowsnippet.cpp 0
218
219 \section2 The Status Bar
220
221 You can set a status bar with \c setStatusBar(), but one is
222 created the first time \c statusBar() (which returns the main
223 window's status bar) is called. See QStatusBar for information on
224 how to use it.
225
226 \section1 Storing State
227
228 QMainWindow can store the state of its layout with \c
229 saveState(); it can later be retrieved with \c restoreState(). It
230 is the position and size (relative to the size of the main window)
231 of the toolbars and dock widgets that are stored.
232
233 \sa QMenuBar, QToolBar, QStatusBar, QDockWidget, {Menus Example}
234*/
235
236/*!
237 \fn void QMainWindow::iconSizeChanged(const QSize &iconSize)
238
239 This signal is emitted when the size of the icons used in the
240 window is changed. The new icon size is passed in \a iconSize.
241
242 You can connect this signal to other components to help maintain
243 a consistent appearance for your application.
244
245 \sa setIconSize()
246*/
247
248/*!
249 \fn void QMainWindow::toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle)
250
251 This signal is emitted when the style used for tool buttons in the
252 window is changed. The new style is passed in \a toolButtonStyle.
253
254 You can connect this signal to other components to help maintain
255 a consistent appearance for your application.
256
257 \sa setToolButtonStyle()
258*/
259
260#if QT_CONFIG(dockwidget)
261/*!
262 \fn void QMainWindow::tabifiedDockWidgetActivated(QDockWidget *dockWidget)
263
264 This signal is emitted when the tabified dock widget is activated by
265 selecting the tab. The activated dock widget is passed in \a dockWidget.
266
267 \since 5.8
268 \sa tabifyDockWidget(), tabifiedDockWidgets()
269*/
270#endif
271
272/*!
273 Constructs a QMainWindow with the given \a parent and the specified
274 widget \a flags.
275
276 QMainWindow sets the Qt::Window flag itself, and will hence
277 always be created as a top-level widget.
278 */
279QMainWindow::QMainWindow(QWidget *parent, Qt::WindowFlags flags)
280 : QWidget(*(new QMainWindowPrivate()), parent, flags | Qt::Window)
281{
282 d_func()->init();
283}
284
285
286/*!
287 Destroys the main window.
288 */
289QMainWindow::~QMainWindow()
290{ }
291
292/*! \property QMainWindow::iconSize
293 \brief size of toolbar icons in this mainwindow.
294
295 The default is the default tool bar icon size of the GUI style.
296 Note that the icons used must be at least of this size as the
297 icons are only scaled down.
298*/
299
300/*!
301 \property QMainWindow::dockOptions
302 \brief the docking behavior of QMainWindow
303 \since 4.3
304
305 The default value is AnimatedDocks | AllowTabbedDocks.
306*/
307
308/*!
309 \enum QMainWindow::DockOption
310 \since 4.3
311
312 This enum contains flags that specify the docking behavior of QMainWindow.
313
314 \value AnimatedDocks Identical to the \l animated property.
315
316 \value AllowNestedDocks Identical to the \l dockNestingEnabled property.
317
318 \value AllowTabbedDocks The user can drop one dock widget "on top" of
319 another. The two widgets are stacked and a tab
320 bar appears for selecting which one is visible.
321
322 \value ForceTabbedDocks Each dock area contains a single stack of tabbed
323 dock widgets. In other words, dock widgets cannot
324 be placed next to each other in a dock area. If
325 this option is set, AllowNestedDocks has no effect.
326
327 \value VerticalTabs The two vertical dock areas on the sides of the
328 main window show their tabs vertically. If this
329 option is not set, all dock areas show their tabs
330 at the bottom. Implies AllowTabbedDocks. See also
331 \l setTabPosition().
332
333 \value GroupedDragging When dragging the titlebar of a dock, all the tabs
334 that are tabbed with it are going to be dragged.
335 Implies AllowTabbedDocks. Does not work well if
336 some QDockWidgets have restrictions in which area
337 they are allowed. (This enum value was added in Qt
338 5.6.)
339
340 These options only control how dock widgets may be dropped in a QMainWindow.
341 They do not re-arrange the dock widgets to conform with the specified
342 options. For this reason they should be set before any dock widgets
343 are added to the main window. Exceptions to this are the AnimatedDocks and
344 VerticalTabs options, which may be set at any time.
345*/
346
347void QMainWindow::setDockOptions(DockOptions opt)
348{
349 Q_D(QMainWindow);
350 d->layout->setDockOptions(opt);
351}
352
353QMainWindow::DockOptions QMainWindow::dockOptions() const
354{
355 Q_D(const QMainWindow);
356 return d->layout->dockOptions;
357}
358
359QSize QMainWindow::iconSize() const
360{ return d_func()->iconSize; }
361
362void QMainWindow::setIconSize(const QSize &iconSize)
363{
364 Q_D(QMainWindow);
365 QSize sz = iconSize;
366 if (!sz.isValid()) {
367 const int metric = style()->pixelMetric(metric: QStyle::PM_ToolBarIconSize, option: nullptr, widget: this);
368 sz = QSize(metric, metric);
369 }
370 if (d->iconSize != sz) {
371 d->iconSize = sz;
372 emit iconSizeChanged(iconSize: d->iconSize);
373 }
374 d->explicitIconSize = iconSize.isValid();
375}
376
377/*! \property QMainWindow::toolButtonStyle
378 \brief style of toolbar buttons in this mainwindow.
379
380 To have the style of toolbuttons follow the system settings, set this property to Qt::ToolButtonFollowStyle.
381 On Unix, the user settings from the desktop environment will be used.
382 On other platforms, Qt::ToolButtonFollowStyle means icon only.
383
384 The default is Qt::ToolButtonIconOnly.
385*/
386
387Qt::ToolButtonStyle QMainWindow::toolButtonStyle() const
388{ return d_func()->toolButtonStyle; }
389
390void QMainWindow::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
391{
392 Q_D(QMainWindow);
393 if (d->toolButtonStyle == toolButtonStyle)
394 return;
395 d->toolButtonStyle = toolButtonStyle;
396 emit toolButtonStyleChanged(toolButtonStyle: d->toolButtonStyle);
397}
398
399#if QT_CONFIG(menubar)
400/*!
401 Returns the menu bar for the main window. This function creates
402 and returns an empty menu bar if the menu bar does not exist.
403
404 If you want all windows in a Mac application to share one menu
405 bar, don't use this function to create it, because the menu bar
406 created here will have this QMainWindow as its parent. Instead,
407 you must create a menu bar that does not have a parent, which you
408 can then share among all the Mac windows. Create a parent-less
409 menu bar this way:
410
411 \snippet code/src_gui_widgets_qmenubar.cpp 1
412
413 \sa setMenuBar()
414*/
415QMenuBar *QMainWindow::menuBar() const
416{
417 QMenuBar *menuBar = qobject_cast<QMenuBar *>(object: layout()->menuBar());
418 if (!menuBar) {
419 QMainWindow *self = const_cast<QMainWindow *>(this);
420 menuBar = new QMenuBar(self);
421 self->setMenuBar(menuBar);
422 }
423 return menuBar;
424}
425
426/*!
427 Sets the menu bar for the main window to \a menuBar.
428
429 Note: QMainWindow takes ownership of the \a menuBar pointer and
430 deletes it at the appropriate time.
431
432 \sa menuBar()
433*/
434void QMainWindow::setMenuBar(QMenuBar *menuBar)
435{
436 QLayout *topLayout = layout();
437
438 if (QWidget *existingMenuBar = topLayout->menuBar(); existingMenuBar && existingMenuBar != menuBar) {
439 // Reparent corner widgets before we delete the old menu bar.
440 QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(object: existingMenuBar);
441 if (oldMenuBar && menuBar) {
442 // TopLeftCorner widget.
443 QWidget *cornerWidget = oldMenuBar->cornerWidget(corner: Qt::TopLeftCorner);
444 if (cornerWidget)
445 menuBar->setCornerWidget(w: cornerWidget, corner: Qt::TopLeftCorner);
446 // TopRightCorner widget.
447 cornerWidget = oldMenuBar->cornerWidget(corner: Qt::TopRightCorner);
448 if (cornerWidget)
449 menuBar->setCornerWidget(w: cornerWidget, corner: Qt::TopRightCorner);
450 }
451
452 existingMenuBar->hide();
453 existingMenuBar->setParent(nullptr);
454 existingMenuBar->deleteLater();
455 }
456 topLayout->setMenuBar(menuBar);
457}
458
459/*!
460 \since 4.2
461
462 Returns the menu bar for the main window. This function returns
463 null if a menu bar hasn't been constructed yet.
464*/
465QWidget *QMainWindow::menuWidget() const
466{
467 QWidget *menuBar = d_func()->layout->menuBar();
468 return menuBar;
469}
470
471/*!
472 \since 4.2
473
474 Sets the menu bar for the main window to \a menuBar.
475
476 QMainWindow takes ownership of the \a menuBar pointer and
477 deletes it at the appropriate time.
478*/
479void QMainWindow::setMenuWidget(QWidget *menuBar)
480{
481 Q_D(QMainWindow);
482 if (d->layout->menuBar() && d->layout->menuBar() != menuBar) {
483 d->layout->menuBar()->hide();
484 d->layout->menuBar()->deleteLater();
485 }
486 d->layout->setMenuBar(menuBar);
487}
488#endif // QT_CONFIG(menubar)
489
490#if QT_CONFIG(statusbar)
491/*!
492 Returns the status bar for the main window. This function creates
493 and returns an empty status bar if the status bar does not exist.
494
495 \sa setStatusBar()
496*/
497QStatusBar *QMainWindow::statusBar() const
498{
499 QStatusBar *statusbar = d_func()->layout->statusBar();
500 if (!statusbar) {
501 QMainWindow *self = const_cast<QMainWindow *>(this);
502 statusbar = new QStatusBar(self);
503 statusbar->setSizePolicy(hor: QSizePolicy::Ignored, ver: QSizePolicy::Fixed);
504 self->setStatusBar(statusbar);
505 }
506 return statusbar;
507}
508
509/*!
510 Sets the status bar for the main window to \a statusbar.
511
512 Setting the status bar to \nullptr will remove it from the main window.
513 Note that QMainWindow takes ownership of the \a statusbar pointer
514 and deletes it at the appropriate time.
515
516 \sa statusBar()
517*/
518void QMainWindow::setStatusBar(QStatusBar *statusbar)
519{
520 Q_D(QMainWindow);
521 if (d->layout->statusBar() && d->layout->statusBar() != statusbar) {
522 d->layout->statusBar()->hide();
523 d->layout->statusBar()->deleteLater();
524 }
525 d->layout->setStatusBar(statusbar);
526}
527#endif // QT_CONFIG(statusbar)
528
529/*!
530 Returns the central widget for the main window. This function
531 returns \nullptr if the central widget has not been set.
532
533 \sa setCentralWidget()
534*/
535QWidget *QMainWindow::centralWidget() const
536{ return d_func()->layout->centralWidget(); }
537
538/*!
539 Sets the given \a widget to be the main window's central widget.
540
541 Note: QMainWindow takes ownership of the \a widget pointer and
542 deletes it at the appropriate time.
543
544 \sa centralWidget()
545*/
546void QMainWindow::setCentralWidget(QWidget *widget)
547{
548 Q_D(QMainWindow);
549 if (d->layout->centralWidget() && d->layout->centralWidget() != widget) {
550 d->layout->centralWidget()->hide();
551 d->layout->centralWidget()->deleteLater();
552 }
553 d->layout->setCentralWidget(widget);
554}
555
556/*!
557 Removes the central widget from this main window.
558
559 The ownership of the removed widget is passed to the caller.
560
561 \since 5.2
562*/
563QWidget *QMainWindow::takeCentralWidget()
564{
565 Q_D(QMainWindow);
566 QWidget *oldcentralwidget = d->layout->centralWidget();
567 if (oldcentralwidget) {
568 oldcentralwidget->setParent(nullptr);
569 d->layout->setCentralWidget(nullptr);
570 }
571 return oldcentralwidget;
572}
573
574#if QT_CONFIG(dockwidget)
575/*!
576 Sets the given dock widget \a area to occupy the specified \a
577 corner.
578
579 \sa corner()
580*/
581void QMainWindow::setCorner(Qt::Corner corner, Qt::DockWidgetArea area)
582{
583 bool valid = false;
584 switch (corner) {
585 case Qt::TopLeftCorner:
586 valid = (area == Qt::TopDockWidgetArea || area == Qt::LeftDockWidgetArea);
587 break;
588 case Qt::TopRightCorner:
589 valid = (area == Qt::TopDockWidgetArea || area == Qt::RightDockWidgetArea);
590 break;
591 case Qt::BottomLeftCorner:
592 valid = (area == Qt::BottomDockWidgetArea || area == Qt::LeftDockWidgetArea);
593 break;
594 case Qt::BottomRightCorner:
595 valid = (area == Qt::BottomDockWidgetArea || area == Qt::RightDockWidgetArea);
596 break;
597 }
598 if (Q_UNLIKELY(!valid))
599 qWarning(msg: "QMainWindow::setCorner(): 'area' is not valid for 'corner'");
600 else
601 d_func()->layout->setCorner(corner, area);
602}
603
604/*!
605 Returns the dock widget area that occupies the specified \a
606 corner.
607
608 \sa setCorner()
609*/
610Qt::DockWidgetArea QMainWindow::corner(Qt::Corner corner) const
611{ return d_func()->layout->corner(corner); }
612#endif
613
614#if QT_CONFIG(toolbar)
615
616static bool checkToolBarArea(Qt::ToolBarArea area, const char *where)
617{
618 switch (area) {
619 case Qt::LeftToolBarArea:
620 case Qt::RightToolBarArea:
621 case Qt::TopToolBarArea:
622 case Qt::BottomToolBarArea:
623 return true;
624 default:
625 break;
626 }
627 qWarning(msg: "%s: invalid 'area' argument", where);
628 return false;
629}
630
631/*!
632 Adds a toolbar break to the given \a area after all the other
633 objects that are present.
634*/
635void QMainWindow::addToolBarBreak(Qt::ToolBarArea area)
636{
637 if (!checkToolBarArea(area, where: "QMainWindow::addToolBarBreak"))
638 return;
639 d_func()->layout->addToolBarBreak(area);
640}
641
642/*!
643 Inserts a toolbar break before the toolbar specified by \a before.
644*/
645void QMainWindow::insertToolBarBreak(QToolBar *before)
646{ d_func()->layout->insertToolBarBreak(before); }
647
648/*!
649 Removes a toolbar break previously inserted before the toolbar specified by \a before.
650*/
651
652void QMainWindow::removeToolBarBreak(QToolBar *before)
653{
654 Q_D(QMainWindow);
655 d->layout->removeToolBarBreak(before);
656}
657
658/*!
659 Adds the \a toolbar into the specified \a area in this main
660 window. The \a toolbar is placed at the end of the current tool
661 bar block (i.e. line). If the main window already manages \a toolbar
662 then it will only move the toolbar to \a area.
663
664 \sa insertToolBar(), addToolBarBreak(), insertToolBarBreak()
665*/
666void QMainWindow::addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)
667{
668 if (!checkToolBarArea(area, where: "QMainWindow::addToolBar"))
669 return;
670
671 Q_D(QMainWindow);
672
673 disconnect(sender: this, SIGNAL(iconSizeChanged(QSize)),
674 receiver: toolbar, SLOT(_q_updateIconSize(QSize)));
675 disconnect(sender: this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
676 receiver: toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
677
678 if (toolbar->d_func()->state && toolbar->d_func()->state->dragging) {
679 //removing a toolbar which is dragging will cause crash
680#if QT_CONFIG(dockwidget)
681 bool animated = isAnimated();
682 setAnimated(false);
683#endif
684 toolbar->d_func()->endDrag();
685#if QT_CONFIG(dockwidget)
686 setAnimated(animated);
687#endif
688 }
689
690 d->layout->removeToolBar(toolbar);
691
692 toolbar->d_func()->_q_updateIconSize(sz: d->iconSize);
693 toolbar->d_func()->_q_updateToolButtonStyle(style: d->toolButtonStyle);
694 connect(sender: this, SIGNAL(iconSizeChanged(QSize)),
695 receiver: toolbar, SLOT(_q_updateIconSize(QSize)));
696 connect(sender: this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
697 receiver: toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
698
699 d->layout->addToolBar(area, toolbar);
700}
701
702/*! \overload
703 Equivalent of calling addToolBar(Qt::TopToolBarArea, \a toolbar)
704*/
705void QMainWindow::addToolBar(QToolBar *toolbar)
706{ addToolBar(area: Qt::TopToolBarArea, toolbar); }
707
708/*!
709 \overload
710
711 Creates a QToolBar object, setting its window title to \a title,
712 and inserts it into the top toolbar area.
713
714 \sa setWindowTitle()
715*/
716QToolBar *QMainWindow::addToolBar(const QString &title)
717{
718 QToolBar *toolBar = new QToolBar(this);
719 toolBar->setWindowTitle(title);
720 addToolBar(toolbar: toolBar);
721 return toolBar;
722}
723
724/*!
725 Inserts the \a toolbar into the area occupied by the \a before toolbar
726 so that it appears before it. For example, in normal left-to-right
727 layout operation, this means that \a toolbar will appear to the left
728 of the toolbar specified by \a before in a horizontal toolbar area.
729
730 \sa insertToolBarBreak(), addToolBar(), addToolBarBreak()
731*/
732void QMainWindow::insertToolBar(QToolBar *before, QToolBar *toolbar)
733{
734 Q_D(QMainWindow);
735
736 d->layout->removeToolBar(toolbar);
737
738 toolbar->d_func()->_q_updateIconSize(sz: d->iconSize);
739 toolbar->d_func()->_q_updateToolButtonStyle(style: d->toolButtonStyle);
740 connect(sender: this, SIGNAL(iconSizeChanged(QSize)),
741 receiver: toolbar, SLOT(_q_updateIconSize(QSize)));
742 connect(sender: this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
743 receiver: toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
744
745 d->layout->insertToolBar(before, toolbar);
746}
747
748/*!
749 Removes the \a toolbar from the main window layout and hides
750 it. Note that the \a toolbar is \e not deleted.
751*/
752void QMainWindow::removeToolBar(QToolBar *toolbar)
753{
754 if (toolbar) {
755 d_func()->layout->removeToolBar(toolbar);
756 toolbar->hide();
757 }
758}
759
760/*!
761 Returns the Qt::ToolBarArea for \a toolbar. If \a toolbar has not
762 been added to the main window, this function returns \c
763 Qt::NoToolBarArea.
764
765 \sa addToolBar(), addToolBarBreak(), Qt::ToolBarArea
766*/
767Qt::ToolBarArea QMainWindow::toolBarArea(const QToolBar *toolbar) const
768{ return d_func()->layout->toolBarArea(toolbar); }
769
770/*!
771
772 Returns whether there is a toolbar
773 break before the \a toolbar.
774
775 \sa addToolBarBreak(), insertToolBarBreak()
776*/
777bool QMainWindow::toolBarBreak(QToolBar *toolbar) const
778{
779 return d_func()->layout->toolBarBreak(toolBar: toolbar);
780}
781
782#endif // QT_CONFIG(toolbar)
783
784#if QT_CONFIG(dockwidget)
785
786/*! \property QMainWindow::animated
787 \brief whether manipulating dock widgets and tool bars is animated
788 \since 4.2
789
790 When a dock widget or tool bar is dragged over the
791 main window, the main window adjusts its contents
792 to indicate where the dock widget or tool bar will
793 be docked if it is dropped. Setting this property
794 causes QMainWindow to move its contents in a smooth
795 animation. Clearing this property causes the contents
796 to snap into their new positions.
797
798 By default, this property is set. It may be cleared if
799 the main window contains widgets which are slow at resizing
800 or repainting themselves.
801
802 Setting this property is identical to setting the AnimatedDocks
803 option using setDockOptions().
804*/
805
806bool QMainWindow::isAnimated() const
807{
808 Q_D(const QMainWindow);
809 return d->layout->dockOptions & AnimatedDocks;
810}
811
812void QMainWindow::setAnimated(bool enabled)
813{
814 Q_D(QMainWindow);
815
816 DockOptions opts = d->layout->dockOptions;
817 opts.setFlag(flag: AnimatedDocks, on: enabled);
818
819 d->layout->setDockOptions(opts);
820}
821
822/*! \property QMainWindow::dockNestingEnabled
823 \brief whether docks can be nested
824 \since 4.2
825
826 If this property is \c false, dock areas can only contain a single row
827 (horizontal or vertical) of dock widgets. If this property is \c true,
828 the area occupied by a dock widget can be split in either direction to contain
829 more dock widgets.
830
831 Dock nesting is only necessary in applications that contain a lot of
832 dock widgets. It gives the user greater freedom in organizing their
833 main window. However, dock nesting leads to more complex
834 (and less intuitive) behavior when a dock widget is dragged over the
835 main window, since there are more ways in which a dropped dock widget
836 may be placed in the dock area.
837
838 Setting this property is identical to setting the AllowNestedDocks option
839 using setDockOptions().
840*/
841
842bool QMainWindow::isDockNestingEnabled() const
843{
844 Q_D(const QMainWindow);
845 return d->layout->dockOptions & AllowNestedDocks;
846}
847
848void QMainWindow::setDockNestingEnabled(bool enabled)
849{
850 Q_D(QMainWindow);
851
852 DockOptions opts = d->layout->dockOptions;
853 opts.setFlag(flag: AllowNestedDocks, on: enabled);
854
855 d->layout->setDockOptions(opts);
856}
857
858#if 0
859// If added back in, add the '!' to the qdoc comment marker as well.
860/*
861 \property QMainWindow::verticalTabsEnabled
862 \brief whether left and right dock areas use vertical tabs
863 \since 4.2
864
865 If this property is set to false, dock areas containing tabbed dock widgets
866 display horizontal tabs, similar to Visual Studio.
867
868 If this property is set to true, then the right and left dock areas display vertical
869 tabs, similar to KDevelop.
870
871 This property should be set before any dock widgets are added to the main window.
872*/
873
874bool QMainWindow::verticalTabsEnabled() const
875{
876 return d_func()->layout->verticalTabsEnabled();
877}
878
879void QMainWindow::setVerticalTabsEnabled(bool enabled)
880{
881 d_func()->layout->setVerticalTabsEnabled(enabled);
882}
883#endif
884
885static bool checkDockWidgetArea(Qt::DockWidgetArea area, const char *where)
886{
887 switch (area) {
888 case Qt::LeftDockWidgetArea:
889 case Qt::RightDockWidgetArea:
890 case Qt::TopDockWidgetArea:
891 case Qt::BottomDockWidgetArea:
892 return true;
893 default:
894 break;
895 }
896 qWarning(msg: "%s: invalid 'area' argument", where);
897 return false;
898}
899
900#if QT_CONFIG(tabbar)
901/*!
902 \property QMainWindow::documentMode
903 \brief whether the tab bar for tabbed dockwidgets is set to document mode.
904 \since 4.5
905
906 The default is false.
907
908 \sa QTabBar::documentMode
909*/
910bool QMainWindow::documentMode() const
911{
912 return d_func()->layout->documentMode();
913}
914
915void QMainWindow::setDocumentMode(bool enabled)
916{
917 d_func()->layout->setDocumentMode(enabled);
918}
919#endif // QT_CONFIG(tabbar)
920
921#if QT_CONFIG(tabwidget)
922/*!
923 \property QMainWindow::tabShape
924 \brief the tab shape used for tabbed dock widgets.
925 \since 4.5
926
927 The default is \l QTabWidget::Rounded.
928
929 \sa setTabPosition()
930*/
931QTabWidget::TabShape QMainWindow::tabShape() const
932{
933 return d_func()->layout->tabShape();
934}
935
936void QMainWindow::setTabShape(QTabWidget::TabShape tabShape)
937{
938 d_func()->layout->setTabShape(tabShape);
939}
940
941/*!
942 \since 4.5
943
944 Returns the tab position for \a area.
945
946 \note The \l VerticalTabs dock option overrides the tab positions returned
947 by this function.
948
949 \sa setTabPosition(), tabShape()
950*/
951QTabWidget::TabPosition QMainWindow::tabPosition(Qt::DockWidgetArea area) const
952{
953 if (!checkDockWidgetArea(area, where: "QMainWindow::tabPosition"))
954 return QTabWidget::South;
955 return d_func()->layout->tabPosition(area);
956}
957
958/*!
959 \since 4.5
960
961 Sets the tab position for the given dock widget \a areas to the specified
962 \a tabPosition. By default, all dock areas show their tabs at the bottom.
963
964 \note The \l VerticalTabs dock option overrides the tab positions set by
965 this method.
966
967 \sa tabPosition(), setTabShape()
968*/
969void QMainWindow::setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition)
970{
971 d_func()->layout->setTabPosition(areas, tabPosition);
972}
973#endif // QT_CONFIG(tabwidget)
974
975/*!
976 Adds the given \a dockwidget to the specified \a area.
977*/
978void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget)
979{
980 if (!checkDockWidgetArea(area, where: "QMainWindow::addDockWidget"))
981 return;
982
983 Qt::Orientation orientation = Qt::Vertical;
984 switch (area) {
985 case Qt::TopDockWidgetArea:
986 case Qt::BottomDockWidgetArea:
987 orientation = Qt::Horizontal;
988 break;
989 default:
990 break;
991 }
992 const Qt::DockWidgetArea oldArea = dockWidgetArea(dockwidget);
993 d_func()->layout->removeWidget(w: dockwidget); // in case it was already in here
994 addDockWidget(area, dockwidget, orientation);
995 if (oldArea != area)
996 emit dockwidget->dockLocationChanged(area);
997}
998
999/*!
1000 Restores the state of \a dockwidget if it is created after the call
1001 to restoreState(). Returns \c true if the state was restored; otherwise
1002 returns \c false.
1003
1004 \sa restoreState(), saveState()
1005*/
1006
1007bool QMainWindow::restoreDockWidget(QDockWidget *dockwidget)
1008{
1009 return d_func()->layout->restoreDockWidget(dockwidget);
1010}
1011
1012/*!
1013 Adds \a dockwidget into the given \a area in the direction
1014 specified by the \a orientation.
1015*/
1016void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget,
1017 Qt::Orientation orientation)
1018{
1019 if (!checkDockWidgetArea(area, where: "QMainWindow::addDockWidget"))
1020 return;
1021
1022 // add a window to an area, placing done relative to the previous
1023 d_func()->layout->addDockWidget(area, dockwidget, orientation);
1024}
1025
1026/*!
1027 \fn void QMainWindow::splitDockWidget(QDockWidget *first, QDockWidget *second, Qt::Orientation orientation)
1028
1029 Splits the space covered by the \a first dock widget into two parts,
1030 moves the \a first dock widget into the first part, and moves the
1031 \a second dock widget into the second part.
1032
1033 The \a orientation specifies how the space is divided: A Qt::Horizontal
1034 split places the second dock widget to the right of the first; a
1035 Qt::Vertical split places the second dock widget below the first.
1036
1037 \e Note: if \a first is currently in a tabbed docked area, \a second will
1038 be added as a new tab, not as a neighbor of \a first. This is because a
1039 single tab can contain only one dock widget.
1040
1041 \e Note: The Qt::LayoutDirection influences the order of the dock widgets
1042 in the two parts of the divided area. When right-to-left layout direction
1043 is enabled, the placing of the dock widgets will be reversed.
1044
1045 \sa tabifyDockWidget(), addDockWidget(), removeDockWidget()
1046*/
1047void QMainWindow::splitDockWidget(QDockWidget *after, QDockWidget *dockwidget,
1048 Qt::Orientation orientation)
1049{
1050 d_func()->layout->splitDockWidget(after, dockwidget, orientation);
1051}
1052
1053#if QT_CONFIG(tabbar)
1054/*!
1055 \fn void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
1056
1057 Moves \a second dock widget on top of \a first dock widget, creating a tabbed
1058 docked area in the main window.
1059
1060 \sa tabifiedDockWidgets()
1061*/
1062void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
1063{
1064 d_func()->layout->tabifyDockWidget(first, second);
1065}
1066
1067
1068/*!
1069 \fn QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
1070
1071 Returns the dock widgets that are tabified together with \a dockwidget.
1072
1073 \since 4.5
1074 \sa tabifyDockWidget()
1075*/
1076
1077QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
1078{
1079 Q_D(const QMainWindow);
1080 return d->layout ? d->layout->tabifiedDockWidgets(dockWidget: dockwidget) : QList<QDockWidget *>();
1081}
1082#endif // QT_CONFIG(tabbar)
1083
1084
1085/*!
1086 Removes the \a dockwidget from the main window layout and hides
1087 it. Note that the \a dockwidget is \e not deleted.
1088*/
1089void QMainWindow::removeDockWidget(QDockWidget *dockwidget)
1090{
1091 if (dockwidget) {
1092 d_func()->layout->removeWidget(w: dockwidget);
1093 dockwidget->hide();
1094 }
1095}
1096
1097/*!
1098 Returns the Qt::DockWidgetArea for \a dockwidget. If \a dockwidget
1099 has not been added to the main window, this function returns \c
1100 Qt::NoDockWidgetArea.
1101
1102 \sa addDockWidget(), splitDockWidget(), Qt::DockWidgetArea
1103*/
1104Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
1105{ return d_func()->layout->dockWidgetArea(widget: dockwidget); }
1106
1107
1108/*!
1109 \since 5.6
1110 Resizes the dock widgets in the list \a docks to the corresponding size in
1111 pixels from the list \a sizes. If \a orientation is Qt::Horizontal, adjusts
1112 the width, otherwise adjusts the height of the dock widgets.
1113 The sizes will be adjusted such that the maximum and the minimum sizes are
1114 respected and the QMainWindow itself will not be resized.
1115 Any additional/missing space is distributed amongst the widgets according
1116 to the relative weight of the sizes.
1117
1118 Example:
1119 \snippet code/src_widgets_widgets_qmainwindow.cpp 2
1120
1121 If the blue and the yellow widget are nested on the same level they will be
1122 resized such that the yellowWidget is twice as big as the blueWidget
1123
1124 If some widgets are grouped in tabs, only one widget per group should be
1125 specified. Widgets not in the list might be changed to respect the constraints.
1126*/
1127void QMainWindow::resizeDocks(const QList<QDockWidget *> &docks,
1128 const QList<int> &sizes, Qt::Orientation orientation)
1129{
1130 d_func()->layout->layoutState.dockAreaLayout.resizeDocks(docks, sizes, o: orientation);
1131 d_func()->layout->invalidate();
1132}
1133
1134
1135#endif // QT_CONFIG(dockwidget)
1136
1137/*!
1138 Saves the current state of this mainwindow's toolbars and
1139 dockwidgets. This includes the corner settings which can
1140 be set with setCorner(). The \a version number is stored
1141 as part of the data.
1142
1143 The \l{QObject::objectName}{objectName} property is used
1144 to identify each QToolBar and QDockWidget. You should make sure
1145 that this property is unique for each QToolBar and QDockWidget you
1146 add to the QMainWindow
1147
1148 To restore the saved state, pass the return value and \a version
1149 number to restoreState().
1150
1151 To save the geometry when the window closes, you can
1152 implement a close event like this:
1153
1154 \snippet code/src_gui_widgets_qmainwindow.cpp 0
1155
1156 \sa restoreState(), QWidget::saveGeometry(), QWidget::restoreGeometry()
1157*/
1158QByteArray QMainWindow::saveState(int version) const
1159{
1160 QByteArray data;
1161 QDataStream stream(&data, QIODevice::WriteOnly);
1162 stream.setVersion(QDataStream::Qt_5_0);
1163 stream << QMainWindowLayout::VersionMarker;
1164 stream << version;
1165 d_func()->layout->saveState(stream);
1166 return data;
1167}
1168
1169/*!
1170 Restores the \a state of this mainwindow's toolbars and
1171 dockwidgets. Also restores the corner settings too. The
1172 \a version number is compared with that stored in \a state.
1173 If they do not match, the mainwindow's state is left
1174 unchanged, and this function returns \c false; otherwise, the state
1175 is restored, and this function returns \c true.
1176
1177 To restore geometry saved using QSettings, you can use code like
1178 this:
1179
1180 \snippet code/src_gui_widgets_qmainwindow.cpp 1
1181
1182 \sa saveState(), QWidget::saveGeometry(),
1183 QWidget::restoreGeometry(), restoreDockWidget()
1184*/
1185bool QMainWindow::restoreState(const QByteArray &state, int version)
1186{
1187 if (state.isEmpty())
1188 return false;
1189 QByteArray sd = state;
1190 QDataStream stream(&sd, QIODevice::ReadOnly);
1191 stream.setVersion(QDataStream::Qt_5_0);
1192 int marker, v;
1193 stream >> marker;
1194 stream >> v;
1195 if (stream.status() != QDataStream::Ok || marker != QMainWindowLayout::VersionMarker || v != version)
1196 return false;
1197 bool restored = d_func()->layout->restoreState(stream);
1198 return restored;
1199}
1200
1201/*! \reimp */
1202bool QMainWindow::event(QEvent *event)
1203{
1204 Q_D(QMainWindow);
1205
1206#if QT_CONFIG(dockwidget)
1207 if (d->layout && d->layout->windowEvent(e: event))
1208 return true;
1209#endif
1210
1211 switch (event->type()) {
1212
1213#if QT_CONFIG(toolbar)
1214 case QEvent::ToolBarChange: {
1215 Q_ASSERT(d->layout);
1216 d->layout->toggleToolBarsVisible();
1217 return true;
1218 }
1219#endif
1220
1221#if QT_CONFIG(statustip)
1222 case QEvent::StatusTip:
1223#if QT_CONFIG(statusbar)
1224 Q_ASSERT(d->layout);
1225 if (QStatusBar *sb = d->layout->statusBar())
1226 sb->showMessage(text: static_cast<QStatusTipEvent*>(event)->tip());
1227 else
1228#endif
1229 static_cast<QStatusTipEvent*>(event)->ignore();
1230 return true;
1231#endif // QT_CONFIG(statustip)
1232
1233 case QEvent::StyleChange:
1234#if QT_CONFIG(dockwidget)
1235 Q_ASSERT(d->layout);
1236 d->layout->layoutState.dockAreaLayout.styleChangedEvent();
1237#endif
1238 if (!d->explicitIconSize)
1239 setIconSize(QSize());
1240 break;
1241#if QT_CONFIG(draganddrop)
1242 case QEvent::DragEnter:
1243 case QEvent::Drop:
1244 if (!d->layout->draggingWidget)
1245 break;
1246 event->accept();
1247 return true;
1248 case QEvent::DragMove: {
1249 if (!d->layout->draggingWidget)
1250 break;
1251 auto dragMoveEvent = static_cast<QDragMoveEvent *>(event);
1252 d->layout->hover(hoverTarget: d->layout->draggingWidget,
1253 mousePos: mapToGlobal(dragMoveEvent->position()).toPoint());
1254 event->accept();
1255 return true;
1256 }
1257 case QEvent::DragLeave:
1258 if (!d->layout->draggingWidget)
1259 break;
1260 d->layout->hover(hoverTarget: d->layout->draggingWidget, mousePos: pos() - QPoint(-1, -1));
1261 return true;
1262#endif
1263 default:
1264 break;
1265 }
1266
1267 return QWidget::event(event);
1268}
1269
1270#if QT_CONFIG(toolbar)
1271
1272/*!
1273 \property QMainWindow::unifiedTitleAndToolBarOnMac
1274 \brief whether the window uses the unified title and toolbar look on \macos
1275
1276 Note that the Qt 5 implementation has several limitations compared to Qt 4:
1277 \list
1278 \li Use in windows with OpenGL content is not supported. This includes QOpenGLWidget.
1279 \li Using dockable or movable toolbars may result in painting errors and is not recommended
1280 \endlist
1281
1282 \since 5.2
1283*/
1284void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool enabled)
1285{
1286#ifdef Q_OS_MACOS
1287 if (!isWindow())
1288 return;
1289
1290 Q_D(QMainWindow);
1291 d->useUnifiedToolBar = enabled;
1292
1293 // The unified toolbar is drawn by the macOS style with a transparent background.
1294 // To ensure a suitable surface format is used we need to first create backing
1295 // QWindow so we have something to update the surface format on, and then let
1296 // QWidget know about the translucency, which it will propagate to the surface.
1297 setAttribute(Qt::WA_NativeWindow);
1298 setAttribute(Qt::WA_TranslucentBackground, enabled);
1299
1300 d->create(); // Create first, before querying the platform window
1301 using namespace QNativeInterface::Private;
1302 if (auto *platformWindow = dynamic_cast<QCocoaWindow*>(window()->windowHandle()->handle()))
1303 platformWindow->setContentBorderEnabled(enabled);
1304
1305 update();
1306#else
1307 Q_UNUSED(enabled);
1308#endif
1309}
1310
1311bool QMainWindow::unifiedTitleAndToolBarOnMac() const
1312{
1313#ifdef Q_OS_MACOS
1314 return d_func()->useUnifiedToolBar;
1315#endif
1316 return false;
1317}
1318
1319#endif // QT_CONFIG(toolbar)
1320
1321/*!
1322 \internal
1323*/
1324bool QMainWindow::isSeparator(const QPoint &pos) const
1325{
1326#if QT_CONFIG(dockwidget)
1327 Q_D(const QMainWindow);
1328 return !d->layout->layoutState.dockAreaLayout.findSeparator(pos).isEmpty();
1329#else
1330 Q_UNUSED(pos);
1331 return false;
1332#endif
1333}
1334
1335#ifndef QT_NO_CONTEXTMENU
1336/*!
1337 \reimp
1338*/
1339void QMainWindow::contextMenuEvent(QContextMenuEvent *event)
1340{
1341 event->ignore();
1342 // only show the context menu for direct QDockWidget and QToolBar
1343 // children and for the menu bar as well
1344 QWidget *child = childAt(p: event->pos());
1345 while (child && child != this) {
1346#if QT_CONFIG(menubar)
1347 if (QMenuBar *mb = qobject_cast<QMenuBar *>(object: child)) {
1348 if (mb->parentWidget() != this)
1349 return;
1350 break;
1351 }
1352#endif
1353#if QT_CONFIG(dockwidget)
1354 if (QDockWidget *dw = qobject_cast<QDockWidget *>(object: child)) {
1355 if (dw->parentWidget() != this)
1356 return;
1357 if (dw->widget()
1358 && dw->widget()->geometry().contains(p: child->mapFrom(this, event->pos()))) {
1359 // ignore the event if the mouse is over the QDockWidget contents
1360 return;
1361 }
1362 break;
1363 }
1364#endif // QT_CONFIG(dockwidget)
1365#if QT_CONFIG(toolbar)
1366 if (QToolBar *tb = qobject_cast<QToolBar *>(object: child)) {
1367 if (tb->parentWidget() != this)
1368 return;
1369 break;
1370 }
1371#endif
1372 child = child->parentWidget();
1373 }
1374 if (child == this)
1375 return;
1376
1377#if QT_CONFIG(menu)
1378 QMenu *popup = createPopupMenu();
1379 if (popup) {
1380 if (!popup->isEmpty()) {
1381 popup->setAttribute(Qt::WA_DeleteOnClose);
1382 popup->popup(pos: event->globalPos());
1383 event->accept();
1384 } else {
1385 delete popup;
1386 }
1387 }
1388#endif
1389}
1390#endif // QT_NO_CONTEXTMENU
1391
1392#if QT_CONFIG(menu)
1393/*!
1394 Returns a popup menu containing checkable entries for the toolbars and
1395 dock widgets present in the main window. If there are no toolbars and
1396 dock widgets present, this function returns \nullptr.
1397
1398 By default, this function is called by the main window when the user
1399 activates a context menu, typically by right-clicking on a toolbar or a dock
1400 widget.
1401
1402 If you want to create a custom popup menu, reimplement this function and
1403 return a newly-created popup menu. Ownership of the popup menu is transferred
1404 to the caller.
1405
1406 \sa addDockWidget(), addToolBar(), menuBar()
1407*/
1408QMenu *QMainWindow::createPopupMenu()
1409{
1410 Q_D(QMainWindow);
1411 QMenu *menu = nullptr;
1412#if QT_CONFIG(dockwidget)
1413 QList<QDockWidget *> dockwidgets = findChildren<QDockWidget *>();
1414 if (dockwidgets.size()) {
1415 menu = new QMenu(this);
1416 for (int i = 0; i < dockwidgets.size(); ++i) {
1417 QDockWidget *dockWidget = dockwidgets.at(i);
1418 // filter to find out if we own this QDockWidget
1419 if (dockWidget->parentWidget() == this) {
1420 if (d->layout->layoutState.dockAreaLayout.indexOf(dockWidget).isEmpty())
1421 continue;
1422 } else if (QDockWidgetGroupWindow *dwgw =
1423 qobject_cast<QDockWidgetGroupWindow *>(object: dockWidget->parentWidget())) {
1424 if (dwgw->parentWidget() != this)
1425 continue;
1426 if (dwgw->layoutInfo()->indexOf(widget: dockWidget).isEmpty())
1427 continue;
1428 } else {
1429 continue;
1430 }
1431 menu->addAction(action: dockwidgets.at(i)->toggleViewAction());
1432 }
1433 menu->addSeparator();
1434 }
1435#endif // QT_CONFIG(dockwidget)
1436#if QT_CONFIG(toolbar)
1437 QList<QToolBar *> toolbars = findChildren<QToolBar *>();
1438 if (toolbars.size()) {
1439 if (!menu)
1440 menu = new QMenu(this);
1441 for (int i = 0; i < toolbars.size(); ++i) {
1442 QToolBar *toolBar = toolbars.at(i);
1443 if (toolBar->parentWidget() == this
1444 && (!d->layout->layoutState.toolBarAreaLayout.indexOf(toolBar).isEmpty())) {
1445 menu->addAction(action: toolbars.at(i)->toggleViewAction());
1446 }
1447 }
1448 }
1449#endif
1450 Q_UNUSED(d);
1451 return menu;
1452}
1453#endif // QT_CONFIG(menu)
1454
1455QT_END_NAMESPACE
1456
1457#include "moc_qmainwindow.cpp"
1458

source code of qtbase/src/widgets/widgets/qmainwindow.cpp