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// Qt-Security score:significant reason:default
4
7#include "formwindow.h"
8
9#include <QtCore/qdebug.h>
10
11#include <QtWidgets/qlayout.h>
12#include <QtWidgets/qmenubar.h>
13#include <QtWidgets/qtoolbar.h>
14#include <QtWidgets/qstatusbar.h>
15#include <QtWidgets/qdockwidget.h>
16
18
19namespace qdesigner_internal {
20
21QMainWindowContainer::QMainWindowContainer(QMainWindow *widget, QObject *parent)
22 : QObject(parent),
23 m_mainWindow(widget)
24{
25}
26
28{
29 return m_widgets.size();
30}
31
33{
34 return m_widgets.value(index, nullptr);
35}
36
38{
39 // QTBUG-111603, handle plugins with unmanaged central widgets
40 auto *cw = m_mainWindow->centralWidget();
41 return cw != nullptr && m_widgets.contains(cw) ? 0 : -1;
42}
43
45{
46 Q_UNUSED(index);
47}
48
49
50namespace {
51 // Pair of <area,break_before>
52 using ToolBarData = std::pair<Qt::ToolBarArea, bool>;
53
54 ToolBarData toolBarData(QToolBar *me) {
55 const QMainWindow *mw = qobject_cast<const QMainWindow*>(me->parentWidget());
56 if (!mw || !mw->layout() || mw->layout()->indexOf(me) == -1) {
57 const QVariant desiredAreaV = me->property("_q_desiredArea");
58 const Qt::ToolBarArea desiredArea = desiredAreaV.canConvert<Qt::ToolBarArea>()
59 ? desiredAreaV.value<Qt::ToolBarArea>() : Qt::TopToolBarArea;
60 return {desiredArea, false};
61 }
62 return ToolBarData(mw->toolBarArea(me), mw->toolBarBreak(me));
63 }
64
65Qt::DockWidgetArea dockWidgetArea(QDockWidget *me)
66{
67 if (const QMainWindow *mw = qobject_cast<const QMainWindow*>(me->parentWidget())) {
68 // Make sure that me is actually managed by mw, otherwise
69 // QMainWindow::dockWidgetArea() will be VERY upset
70 QList<QLayout*> candidates;
71 if (mw->layout()) {
72 candidates.append(mw->layout());
73 candidates += mw->layout()->findChildren<QLayout*>();
74 }
75 for (QLayout *l : std::as_const(candidates)) {
76 if (l->indexOf(me) != -1)
77 return mw->dockWidgetArea(me);
78 }
79 }
80 return Qt::LeftDockWidgetArea;
81}
82}
83
84// In QMainWindowContainer::remove(), remember the dock area in a dynamic
85// property so that it can used in addWidget() if that is called by undo().
86static const char dockAreaPropertyName[] = "_q_dockArea";
87
89{
90 // remove all the occurrences of widget
91 m_widgets.removeAll(widget);
92
93 // the
94 if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
95 m_widgets.append(widget);
96 const ToolBarData data = toolBarData(toolBar);
97 m_mainWindow->addToolBar(data.first, toolBar);
98 if (data.second) m_mainWindow->insertToolBarBreak(toolBar);
99 toolBar->show();
100 }
101
102 else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(widget)) {
103 if (menuBar != m_mainWindow->menuBar())
104 m_mainWindow->setMenuBar(menuBar);
105
106 m_widgets.append(widget);
107 menuBar->show();
108 }
109
110 else if (QStatusBar *statusBar = qobject_cast<QStatusBar*>(widget)) {
111 if (statusBar != m_mainWindow->statusBar())
112 m_mainWindow->setStatusBar(statusBar);
113
114 m_widgets.append(widget);
115 statusBar->show();
116 }
117
118 else if (QDockWidget *dockWidget = qobject_cast<QDockWidget*>(widget)) {
119 m_widgets.append(widget);
120
121 Qt::DockWidgetArea area = Qt::LeftDockWidgetArea;
122 const auto areaProperty = widget->property(dockAreaPropertyName);
123 if (areaProperty.canConvert<Qt::DockWidgetArea>()) {
124 area = areaProperty.value<Qt::DockWidgetArea>();
125 widget->setProperty(dockAreaPropertyName, {});
126 } else {
127 area = dockWidgetArea(dockWidget);
128 }
129
130 m_mainWindow->addDockWidget(area, dockWidget);
131 dockWidget->show();
132
133 if (FormWindow *fw = FormWindow::findFormWindow(m_mainWindow)) {
134 fw->manageWidget(widget);
135 }
136 }
137
138 else if (widget) {
139 m_widgets.prepend(widget);
140
141 if (widget != m_mainWindow->centralWidget()) {
142 // note that qmainwindow will delete the current central widget if you
143 // call setCentralWidget(), we end up with dangeling pointers in m_widgets list
144 m_widgets.removeAll(m_mainWindow->centralWidget());
145
146 widget->setParent(m_mainWindow);
147 m_mainWindow->setCentralWidget(widget);
148 }
149 }
150}
151
153{
154 Q_UNUSED(index);
155
156 addWidget(widget);
157}
158
160{
161 QWidget *widget = m_widgets.at(index);
162 if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
163 m_mainWindow->removeToolBar(toolBar);
164 } else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(widget)) {
165 menuBar->hide();
166 menuBar->setParent(nullptr);
167 m_mainWindow->setMenuBar(nullptr);
168 } else if (QStatusBar *statusBar = qobject_cast<QStatusBar*>(widget)) {
169 statusBar->hide();
170 statusBar->setParent(nullptr);
171 m_mainWindow->setStatusBar(nullptr);
172 } else if (QDockWidget *dockWidget = qobject_cast<QDockWidget*>(widget)) {
173 const auto area = m_mainWindow->dockWidgetArea(dockWidget);
174 dockWidget->setProperty(dockAreaPropertyName, QVariant::fromValue(area));
175 m_mainWindow->removeDockWidget(dockWidget);
176 }
177 m_widgets.removeAt(index);
178}
179
180} // namespace qdesigner_internal
181
182QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:432
static FormWindow * findFormWindow(QWidget *w)
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[]