8#if QT_CONFIG(dockwidget)
9#include "qdockwidget.h"
15#include <qapplication.h>
20#if QT_CONFIG(statusbar)
21#include <qstatusbar.h>
29#include <private/qwidget_p.h>
31#include "qtoolbar_p.h"
34#include <QtGui/qpa/qplatformwindow.h>
35#include <QtGui/qpa/qplatformwindow_p.h>
39using namespace Qt::StringLiterals;
43 Q_DECLARE_PUBLIC(QMainWindow)
62 return mainWindow ? mainWindow->d_func()->layout.data() :
static_cast<QMainWindowLayout *>(
nullptr);
68 return QMainWindowPrivate::mainWindowLayout(mainWindow);
75 layout =
new QMainWindowLayout(q,
nullptr);
77 const int metric = q->style()->pixelMetric(QStyle::PM_ToolBarIconSize,
nullptr, q);
78 iconSize = QSize(metric, metric);
79 q->setAttribute(Qt::WA_Hover);
80 q->setAcceptDrops(
true);
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
256
257
258
259
260
261
262
263
264
265
268
269
270
271
272
273
274
275
276
277
279#if QT_CONFIG(dockwidget)
281
282
283
284
285
286
287
288
292
293
294
295
296
297
298QMainWindow::QMainWindow(QWidget *parent, Qt::WindowFlags flags)
299 : QWidget(*(
new QMainWindowPrivate()), parent, flags | Qt::Window)
306
307
308QMainWindow::~QMainWindow()
312
313
314
315
316
317
320
321
322
323
324
325
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
366void QMainWindow::setDockOptions(DockOptions opt)
369 d->layout->setDockOptions(opt);
372QMainWindow::DockOptions QMainWindow::dockOptions()
const
374 Q_D(
const QMainWindow);
375 return d->layout->dockOptions;
378QSize QMainWindow::iconSize()
const
379{
return d_func()->iconSize; }
381void QMainWindow::setIconSize(
const QSize &iconSize)
386 const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize,
nullptr,
this);
387 sz = QSize(metric, metric);
389 if (d->iconSize != sz) {
391 emit iconSizeChanged(d->iconSize);
393 d->explicitIconSize = iconSize.isValid();
397
398
399
400
401
402
403
404
406Qt::ToolButtonStyle QMainWindow::toolButtonStyle()
const
407{
return d_func()->toolButtonStyle; }
409void QMainWindow::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
412 if (d->toolButtonStyle == toolButtonStyle)
414 d->toolButtonStyle = toolButtonStyle;
415 emit toolButtonStyleChanged(d->toolButtonStyle);
418#if QT_CONFIG(menubar)
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434QMenuBar *QMainWindow::menuBar()
const
436 QMenuBar *menuBar = qobject_cast<QMenuBar *>(layout()->menuBar());
438 QMainWindow *self =
const_cast<QMainWindow *>(
this);
439 menuBar =
new QMenuBar(self);
440 self->setMenuBar(menuBar);
446
447
448
449
450
451
452
453void QMainWindow::setMenuBar(QMenuBar *menuBar)
455 QLayout *topLayout = layout();
457 if (QWidget *existingMenuBar = topLayout->menuBar(); existingMenuBar && existingMenuBar != menuBar) {
459 QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(existingMenuBar);
460 if (oldMenuBar && menuBar) {
462 QWidget *cornerWidget = oldMenuBar->cornerWidget(Qt::TopLeftCorner);
464 menuBar->setCornerWidget(cornerWidget, Qt::TopLeftCorner);
466 cornerWidget = oldMenuBar->cornerWidget(Qt::TopRightCorner);
468 menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner);
471 existingMenuBar->hide();
472 existingMenuBar->setParent(
nullptr);
473 existingMenuBar->deleteLater();
475 topLayout->setMenuBar(menuBar);
479
480
481
482
483
484QWidget *QMainWindow::menuWidget()
const
486 QWidget *menuBar = d_func()->layout->menuBar();
491
492
493
494
495
496
497
498void QMainWindow::setMenuWidget(QWidget *menuBar)
501 if (d->layout->menuBar() && d->layout->menuBar() != menuBar) {
502 d->layout->menuBar()->hide();
503 d->layout->menuBar()->deleteLater();
505 d->layout->setMenuBar(menuBar);
509#if QT_CONFIG(statusbar)
511
512
513
514
515
516QStatusBar *QMainWindow::statusBar()
const
518 QStatusBar *statusbar = d_func()->layout->statusBar();
520 QMainWindow *self =
const_cast<QMainWindow *>(
this);
521 statusbar =
new QStatusBar(self);
522 statusbar->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
523 self->setStatusBar(statusbar);
529
530
531
532
533
534
535
536
537void QMainWindow::setStatusBar(QStatusBar *statusbar)
540 if (d->layout->statusBar() && d->layout->statusBar() != statusbar) {
541 d->layout->statusBar()->hide();
542 d->layout->statusBar()->deleteLater();
544 d->layout->setStatusBar(statusbar);
549
550
551
552
553
554QWidget *QMainWindow::centralWidget()
const
555{
return d_func()->layout->centralWidget(); }
558
559
560
561
562
563
564
565void QMainWindow::setCentralWidget(QWidget *widget)
568 if (d->layout->centralWidget() && d->layout->centralWidget() != widget) {
569 d->layout->centralWidget()->hide();
570 d->layout->centralWidget()->deleteLater();
572 d->layout->setCentralWidget(widget);
576
577
578
579
580
581
582QWidget *QMainWindow::takeCentralWidget()
585 QWidget *oldcentralwidget = d->layout->centralWidget();
586 if (oldcentralwidget) {
587 oldcentralwidget->setParent(
nullptr);
588 d->layout->setCentralWidget(
nullptr);
590 return oldcentralwidget;
593#if QT_CONFIG(dockwidget)
595
596
597
598
599
600void QMainWindow::setCorner(Qt::Corner corner, Qt::DockWidgetArea area)
604 case Qt::TopLeftCorner:
605 valid = (area == Qt::TopDockWidgetArea || area == Qt::LeftDockWidgetArea);
607 case Qt::TopRightCorner:
608 valid = (area == Qt::TopDockWidgetArea || area == Qt::RightDockWidgetArea);
610 case Qt::BottomLeftCorner:
611 valid = (area == Qt::BottomDockWidgetArea || area == Qt::LeftDockWidgetArea);
613 case Qt::BottomRightCorner:
614 valid = (area == Qt::BottomDockWidgetArea || area == Qt::RightDockWidgetArea);
617 if (Q_UNLIKELY(!valid))
618 qWarning(
"QMainWindow::setCorner(): 'area' is not valid for 'corner'");
620 d_func()->layout->setCorner(corner, area);
624
625
626
627
628
629Qt::DockWidgetArea QMainWindow::corner(Qt::Corner corner)
const
630{
return d_func()->layout->corner(corner); }
633#if QT_CONFIG(toolbar)
635static bool checkToolBarArea(Qt::ToolBarArea area,
const char *where)
638 case Qt::LeftToolBarArea:
639 case Qt::RightToolBarArea:
640 case Qt::TopToolBarArea:
641 case Qt::BottomToolBarArea:
646 qWarning(
"%s: invalid 'area' argument", where);
651
652
653
654void QMainWindow::addToolBarBreak(Qt::ToolBarArea area)
656 if (!checkToolBarArea(area,
"QMainWindow::addToolBarBreak"))
658 d_func()->layout->addToolBarBreak(area);
662
663
664void QMainWindow::insertToolBarBreak(QToolBar *before)
665{ d_func()->layout->insertToolBarBreak(before); }
668
669
671void QMainWindow::removeToolBarBreak(QToolBar *before)
674 d->layout->removeToolBarBreak(before);
678
679
680
681
682
683
684
685void QMainWindow::addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)
687 if (!checkToolBarArea(area,
"QMainWindow::addToolBar"))
692 disconnect(
this, SIGNAL(iconSizeChanged(QSize)),
693 toolbar, SLOT(_q_updateIconSize(QSize)));
694 disconnect(
this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
695 toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
697 if (toolbar->d_func()->state && toolbar->d_func()->state->dragging) {
699#if QT_CONFIG(dockwidget)
700 bool animated = isAnimated();
703 toolbar->d_func()->endDrag();
704#if QT_CONFIG(dockwidget)
705 setAnimated(animated);
709 d->layout->removeToolBar(toolbar);
711 toolbar->d_func()->_q_updateIconSize(d->iconSize);
712 toolbar->d_func()->_q_updateToolButtonStyle(d->toolButtonStyle);
713 connect(
this, SIGNAL(iconSizeChanged(QSize)),
714 toolbar, SLOT(_q_updateIconSize(QSize)));
715 connect(
this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
716 toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
718 d->layout->addToolBar(area, toolbar);
722
723
724void QMainWindow::addToolBar(QToolBar *toolbar)
725{ addToolBar(Qt::TopToolBarArea, toolbar); }
728
729
730
731
732
733
734
735QToolBar *QMainWindow::addToolBar(
const QString &title)
737 QToolBar *toolBar =
new QToolBar(
this);
738 toolBar->setWindowTitle(title);
744
745
746
747
748
749
750
751void QMainWindow::insertToolBar(QToolBar *before, QToolBar *toolbar)
755 d->layout->removeToolBar(toolbar);
757 toolbar->d_func()->_q_updateIconSize(d->iconSize);
758 toolbar->d_func()->_q_updateToolButtonStyle(d->toolButtonStyle);
759 connect(
this, SIGNAL(iconSizeChanged(QSize)),
760 toolbar, SLOT(_q_updateIconSize(QSize)));
761 connect(
this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
762 toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
764 d->layout->insertToolBar(before, toolbar);
768
769
770
771void QMainWindow::removeToolBar(QToolBar *toolbar)
774 d_func()->layout->removeToolBar(toolbar);
780
781
782
783
784
785
786Qt::ToolBarArea QMainWindow::toolBarArea(
const QToolBar *toolbar)
const
787{
return d_func()->layout->toolBarArea(toolbar); }
790
791
792
793
794
795
796bool QMainWindow::toolBarBreak(QToolBar *toolbar)
const
798 return d_func()->layout->toolBarBreak(toolbar);
803#if QT_CONFIG(dockwidget)
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
825bool QMainWindow::isAnimated()
const
827 Q_D(
const QMainWindow);
828 return d->layout->dockOptions & AnimatedDocks;
831void QMainWindow::setAnimated(
bool enabled)
835 DockOptions opts = d->layout->dockOptions;
836 opts.setFlag(AnimatedDocks, enabled);
838 d->layout->setDockOptions(opts);
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
861bool QMainWindow::isDockNestingEnabled()
const
863 Q_D(
const QMainWindow);
864 return d->layout->dockOptions & AllowNestedDocks;
867void QMainWindow::setDockNestingEnabled(
bool enabled)
871 DockOptions opts = d->layout->dockOptions;
872 opts.setFlag(AllowNestedDocks, enabled);
874 d->layout->setDockOptions(opts);
880
881
882
883
884
885
886
887
888
889
890
891
893bool QMainWindow::verticalTabsEnabled()
const
895 return d_func()->layout->verticalTabsEnabled();
898void QMainWindow::setVerticalTabsEnabled(
bool enabled)
900 d_func()->layout->setVerticalTabsEnabled(enabled);
904static bool checkDockWidgetArea(Qt::DockWidgetArea area,
const char *where)
907 case Qt::LeftDockWidgetArea:
908 case Qt::RightDockWidgetArea:
909 case Qt::TopDockWidgetArea:
910 case Qt::BottomDockWidgetArea:
915 qWarning(
"%s: invalid 'area' argument", where);
921
922
923
924
925
926
927
928
929bool QMainWindow::documentMode()
const
931 return d_func()->layout->documentMode();
934void QMainWindow::setDocumentMode(
bool enabled)
936 d_func()->layout->setDocumentMode(enabled);
940#if QT_CONFIG(tabwidget)
942
943
944
945
946
947
948
949
950QTabWidget::TabShape QMainWindow::tabShape()
const
952 return d_func()->layout->tabShape();
955void QMainWindow::setTabShape(QTabWidget::TabShape tabShape)
957 d_func()->layout->setTabShape(tabShape);
961
962
963
964
965
966
967
968
969
970QTabWidget::TabPosition QMainWindow::tabPosition(Qt::DockWidgetArea area)
const
972 if (!checkDockWidgetArea(area,
"QMainWindow::tabPosition"))
973 return QTabWidget::South;
974 return d_func()->layout->tabPosition(area);
978
979
980
981
982
983
984
985
986
987
988void QMainWindow::setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition)
990 d_func()->layout->setTabPosition(areas, tabPosition);
995
996
997void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget)
999 if (!checkDockWidgetArea(area,
"QMainWindow::addDockWidget"))
1002 Qt::Orientation orientation = Qt::Vertical;
1004 case Qt::TopDockWidgetArea:
1005 case Qt::BottomDockWidgetArea:
1006 orientation = Qt::Horizontal;
1011 const Qt::DockWidgetArea oldArea = dockWidgetArea(dockwidget);
1012 d_func()->layout->removeWidget(dockwidget);
1013 addDockWidget(area, dockwidget, orientation);
1014 if (oldArea != area)
1015 emit dockwidget->dockLocationChanged(area);
1019
1020
1021
1022
1023
1024
1026bool QMainWindow::restoreDockWidget(QDockWidget *dockwidget)
1028 return d_func()->layout->restoreDockWidget(dockwidget);
1032
1033
1034
1035void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget,
1036 Qt::Orientation orientation)
1038 if (!checkDockWidgetArea(area,
"QMainWindow::addDockWidget"))
1042 d_func()->layout->addDockWidget(area, dockwidget, orientation);
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066void QMainWindow::splitDockWidget(QDockWidget *after, QDockWidget *dockwidget,
1067 Qt::Orientation orientation)
1069 d_func()->layout->splitDockWidget(after, dockwidget, orientation);
1072#if QT_CONFIG(tabbar)
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
1086 d_func()->layout->tabifyDockWidget(first, second);
1091
1092
1093
1094
1095
1096
1097
1099QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget)
const
1101 Q_D(
const QMainWindow);
1102 return d->layout ? d->layout->tabifiedDockWidgets(dockwidget) : QList<QDockWidget *>();
1108
1109
1110
1111void QMainWindow::removeDockWidget(QDockWidget *dockwidget)
1114 d_func()->layout->removeWidget(dockwidget);
1120
1121
1122
1123
1124
1125
1126Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget)
const
1127{
return d_func()->layout->dockWidgetArea(dockwidget); }
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149void QMainWindow::resizeDocks(
const QList<QDockWidget *> &docks,
1150 const QList<
int> &sizes, Qt::Orientation orientation)
1152 d_func()->layout->layoutState.dockAreaLayout.resizeDocks(docks, sizes, orientation);
1153 d_func()->layout->invalidate();
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180QByteArray QMainWindow::saveState(
int version)
const
1183 QDataStream stream(&data, QIODevice::WriteOnly);
1184 stream.setVersion(QDataStream::Qt_5_0);
1185 stream << QMainWindowLayout::VersionMarker;
1187 d_func()->layout->saveState(stream);
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207bool QMainWindow::restoreState(
const QByteArray &state,
int version)
1209 if (state.isEmpty())
1211 QByteArray sd = state;
1212 QDataStream stream(&sd, QIODevice::ReadOnly);
1213 stream.setVersion(QDataStream::Qt_5_0);
1217 if (stream.status() != QDataStream::Ok || marker != QMainWindowLayout::VersionMarker || v != version)
1219 bool restored = d_func()->layout->restoreState(stream);
1224bool QMainWindow::event(QEvent *event)
1228#if QT_CONFIG(dockwidget)
1229 if (d->layout && d->layout->windowEvent(event))
1233 switch (event->type()) {
1235#if QT_CONFIG(toolbar)
1236 case QEvent::ToolBarChange: {
1237 Q_ASSERT(d->layout);
1238 d->layout->toggleToolBarsVisible();
1243#if QT_CONFIG(statustip)
1244 case QEvent::StatusTip:
1245#if QT_CONFIG(statusbar)
1246 Q_ASSERT(d->layout);
1247 if (QStatusBar *sb = d->layout->statusBar())
1248 sb->showMessage(
static_cast<QStatusTipEvent*>(event)->tip());
1251 static_cast<QStatusTipEvent*>(event)->ignore();
1255 case QEvent::StyleChange:
1256#if QT_CONFIG(dockwidget)
1257 Q_ASSERT(d->layout);
1258 d->layout->layoutState.dockAreaLayout.styleChangedEvent();
1260 if (!d->explicitIconSize)
1261 setIconSize(QSize());
1263#if QT_CONFIG(draganddrop)
1264 case QEvent::DragEnter:
1266 if (!d->layout->draggingWidget)
1270 case QEvent::DragMove: {
1271 if (!d->layout->draggingWidget)
1273 auto dragMoveEvent =
static_cast<QDragMoveEvent *>(event);
1274 d->layout->hover(d->layout->draggingWidget,
1275 mapToGlobal(dragMoveEvent->position()).toPoint());
1279 case QEvent::DragLeave:
1280 if (!d->layout->draggingWidget)
1282 d->layout->hover(d->layout->draggingWidget, pos() - QPoint(1, 1));
1289 return QWidget::event(event);
1292#if QT_CONFIG(toolbar)
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306void QMainWindow::setUnifiedTitleAndToolBarOnMac(
bool enabled)
1313 d->useUnifiedToolBar = enabled;
1319 setAttribute(Qt::WA_NativeWindow);
1320 setAttribute(Qt::WA_TranslucentBackground, enabled);
1324 auto *windowHandle = window()->windowHandle();
1325 windowHandle->setFlag(Qt::NoTitleBarBackgroundHint, enabled);
1327 if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSTahoe)
1328 windowHandle->setFlag(Qt::ExpandedClientAreaHint, enabled);
1329 overrideWindowFlags(windowHandle->flags());
1331 d->layout->updateUnifiedToolBarArea();
1339bool QMainWindow::unifiedTitleAndToolBarOnMac()
const
1342 return d_func()->useUnifiedToolBar;
1350
1351
1352bool QMainWindow::isSeparator(
const QPoint &pos)
const
1354#if QT_CONFIG(dockwidget)
1355 Q_D(
const QMainWindow);
1356 return !d->layout->layoutState.dockAreaLayout.findSeparator(pos).isEmpty();
1363#ifndef QT_NO_CONTEXTMENU
1365
1366
1367void QMainWindow::contextMenuEvent(QContextMenuEvent *event)
1372 QWidget *child = childAt(event->pos());
1373 while (child && child !=
this) {
1374#if QT_CONFIG(menubar)
1375 if (QMenuBar *mb = qobject_cast<QMenuBar *>(child)) {
1376 if (mb->parentWidget() !=
this)
1381#if QT_CONFIG(dockwidget)
1382 if (QDockWidget *dw = qobject_cast<QDockWidget *>(child)) {
1383 if (dw->parentWidget() !=
this)
1386 && dw->widget()->geometry().contains(child->mapFrom(
this, event->pos()))) {
1393#if QT_CONFIG(toolbar)
1394 if (QToolBar *tb = qobject_cast<QToolBar *>(child)) {
1395 if (tb->parentWidget() !=
this)
1400 child = child->parentWidget();
1406 QMenu *popup = createPopupMenu();
1408 if (!popup->isEmpty()) {
1409 popup->setAttribute(Qt::WA_DeleteOnClose);
1410 popup->popup(event->globalPos());
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436QMenu *QMainWindow::createPopupMenu()
1439 QMenu *menu =
nullptr;
1440#if QT_CONFIG(dockwidget)
1441 QList<QDockWidget *> dockwidgets = findChildren<QDockWidget *>();
1442 if (dockwidgets.size()) {
1443 menu =
new QMenu(
this);
1444 for (
int i = 0; i < dockwidgets.size(); ++i) {
1445 QDockWidget *dockWidget = dockwidgets.at(i);
1447 if (dockWidget->parentWidget() ==
this) {
1448 if (d->layout->layoutState.dockAreaLayout.indexOf(dockWidget).isEmpty())
1450 }
else if (QDockWidgetGroupWindow *dwgw =
1451 qobject_cast<QDockWidgetGroupWindow *>(dockWidget->parentWidget())) {
1452 if (dwgw->parentWidget() !=
this)
1454 if (dwgw->layoutInfo()->indexOf(dockWidget).isEmpty())
1459 menu->addAction(dockwidgets.at(i)->toggleViewAction());
1461 menu->addSeparator();
1464#if QT_CONFIG(toolbar)
1465 QList<QToolBar *> toolbars = findChildren<QToolBar *>();
1466 if (toolbars.size()) {
1468 menu =
new QMenu(
this);
1469 for (
int i = 0; i < toolbars.size(); ++i) {
1470 QToolBar *toolBar = toolbars.at(i);
1471 if (toolBar->parentWidget() ==
this
1472 && (!d->layout->layoutState.toolBarAreaLayout.indexOf(toolBar).isEmpty())) {
1473 menu->addAction(toolbars.at(i)->toggleViewAction());
1485#include "moc_qmainwindow.cpp"
Qt::ToolButtonStyle toolButtonStyle
static QMainWindowLayout * mainWindowLayout(const QMainWindow *mainWindow)
Combined button and popup list for selecting options.
QMainWindowLayout * qt_mainwindow_layout(const QMainWindow *mainWindow)