Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qmainwindow_container.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
6#include "formwindow.h"
7
8#include <QtCore/qdebug.h>
9
10#include <QtWidgets/qlayout.h>
11#include <QtWidgets/qmenubar.h>
12#include <QtWidgets/qtoolbar.h>
13#include <QtWidgets/qstatusbar.h>
14#include <QtWidgets/qdockwidget.h>
15
17
18namespace qdesigner_internal {
19
20QMainWindowContainer::QMainWindowContainer(QMainWindow *widget, QObject *parent)
21 : QObject(parent),
22 m_mainWindow(widget)
23{
24}
25
27{
28 return m_widgets.size();
29}
30
32{
33 return m_widgets.value(index, nullptr);
34}
35
37{
38 // QTBUG-111603, handle plugins with unmanaged central widgets
39 auto *cw = m_mainWindow->centralWidget();
40 return cw != nullptr && m_widgets.contains(cw) ? 0 : -1;
41}
42
44{
45 Q_UNUSED(index);
46}
47
48
49namespace {
50 // Pair of <area,break_before>
51 using ToolBarData = std::pair<Qt::ToolBarArea, bool>;
52
53 ToolBarData toolBarData(QToolBar *me) {
54 const QMainWindow *mw = qobject_cast<const QMainWindow*>(me->parentWidget());
55 if (!mw || !mw->layout() || mw->layout()->indexOf(me) == -1) {
56 const QVariant desiredAreaV = me->property("_q_desiredArea");
57 const Qt::ToolBarArea desiredArea = desiredAreaV.canConvert<Qt::ToolBarArea>()
58 ? desiredAreaV.value<Qt::ToolBarArea>() : Qt::TopToolBarArea;
59 return {desiredArea, false};
60 }
61 return ToolBarData(mw->toolBarArea(me), mw->toolBarBreak(me));
62 }
63
64Qt::DockWidgetArea dockWidgetArea(QDockWidget *me)
65{
66 if (const QMainWindow *mw = qobject_cast<const QMainWindow*>(me->parentWidget())) {
67 // Make sure that me is actually managed by mw, otherwise
68 // QMainWindow::dockWidgetArea() will be VERY upset
69 QList<QLayout*> candidates;
70 if (mw->layout()) {
71 candidates.append(mw->layout());
72 candidates += mw->layout()->findChildren<QLayout*>();
73 }
74 for (QLayout *l : std::as_const(candidates)) {
75 if (l->indexOf(me) != -1)
76 return mw->dockWidgetArea(me);
77 }
78 }
79 return Qt::LeftDockWidgetArea;
80}
81}
82
83// In QMainWindowContainer::remove(), remember the dock area in a dynamic
84// property so that it can used in addWidget() if that is called by undo().
85static const char dockAreaPropertyName[] = "_q_dockArea";
86
88{
89 // remove all the occurrences of widget
90 m_widgets.removeAll(widget);
91
92 // the
93 if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
94 m_widgets.append(widget);
95 const ToolBarData data = toolBarData(toolBar);
96 m_mainWindow->addToolBar(data.first, toolBar);
97 if (data.second) m_mainWindow->insertToolBarBreak(toolBar);
98 toolBar->show();
99 }
100
101 else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(widget)) {
102 if (menuBar != m_mainWindow->menuBar())
103 m_mainWindow->setMenuBar(menuBar);
104
105 m_widgets.append(widget);
106 menuBar->show();
107 }
108
109 else if (QStatusBar *statusBar = qobject_cast<QStatusBar*>(widget)) {
110 if (statusBar != m_mainWindow->statusBar())
111 m_mainWindow->setStatusBar(statusBar);
112
113 m_widgets.append(widget);
114 statusBar->show();
115 }
116
117 else if (QDockWidget *dockWidget = qobject_cast<QDockWidget*>(widget)) {
118 m_widgets.append(widget);
119
120 Qt::DockWidgetArea area = Qt::LeftDockWidgetArea;
121 const auto areaProperty = widget->property(dockAreaPropertyName);
122 if (areaProperty.canConvert<Qt::DockWidgetArea>()) {
123 area = areaProperty.value<Qt::DockWidgetArea>();
124 widget->setProperty(dockAreaPropertyName, {});
125 } else {
126 area = dockWidgetArea(dockWidget);
127 }
128
129 m_mainWindow->addDockWidget(area, dockWidget);
130 dockWidget->show();
131
132 if (FormWindow *fw = FormWindow::findFormWindow(m_mainWindow)) {
133 fw->manageWidget(widget);
134 }
135 }
136
137 else if (widget) {
138 m_widgets.prepend(widget);
139
140 if (widget != m_mainWindow->centralWidget()) {
141 // note that qmainwindow will delete the current central widget if you
142 // call setCentralWidget(), we end up with dangeling pointers in m_widgets list
143 m_widgets.removeAll(m_mainWindow->centralWidget());
144
145 widget->setParent(m_mainWindow);
146 m_mainWindow->setCentralWidget(widget);
147 }
148 }
149}
150
152{
153 Q_UNUSED(index);
154
155 addWidget(widget);
156}
157
159{
160 QWidget *widget = m_widgets.at(index);
161 if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
162 m_mainWindow->removeToolBar(toolBar);
163 } else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(widget)) {
164 menuBar->hide();
165 menuBar->setParent(nullptr);
166 m_mainWindow->setMenuBar(nullptr);
167 } else if (QStatusBar *statusBar = qobject_cast<QStatusBar*>(widget)) {
168 statusBar->hide();
169 statusBar->setParent(nullptr);
170 m_mainWindow->setStatusBar(nullptr);
171 } else if (QDockWidget *dockWidget = qobject_cast<QDockWidget*>(widget)) {
172 const auto area = m_mainWindow->dockWidgetArea(dockWidget);
173 dockWidget->setProperty(dockAreaPropertyName, QVariant::fromValue(area));
174 m_mainWindow->removeDockWidget(dockWidget);
175 }
176 m_widgets.removeAt(index);
177}
178
179} // namespace qdesigner_internal
180
181QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:421
void manageWidget(QWidget *w) override
Instructs the form window to manage the specified widget.
QWidget * widget(int index) const override
void insertWidget(int index, QWidget *widget) override
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.
static const char dockAreaPropertyName[]