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
qmdiarea_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
5
6#include <QtDesigner/qextensionmanager.h>
7#include <QtDesigner/abstractformeditor.h>
8
9#include <QtWidgets/qmdiarea.h>
10#include <QtWidgets/qmdisubwindow.h>
11#include <QtWidgets/qapplication.h>
12#include <QtCore/qdebug.h>
13#include <QtCore/qhash.h>
14
16
17using namespace Qt::StringLiterals;
18
19namespace qdesigner_internal {
20
21QMdiAreaContainer::QMdiAreaContainer(QMdiArea *widget, QObject *parent)
22 : QObject(parent),
23 m_mdiArea(widget)
24{
25}
26
28{
29 return m_mdiArea->subWindowList(QMdiArea::CreationOrder).size();
30}
31
33{
34 if (index < 0)
35 return nullptr;
36 return m_mdiArea->subWindowList(QMdiArea::CreationOrder).at(index)->widget();
37}
38
40{
41 if (QMdiSubWindow *sub = m_mdiArea->activeSubWindow())
42 return m_mdiArea->subWindowList(QMdiArea::CreationOrder).indexOf(sub);
43 return -1;
44}
45
47{
48 if (index < 0) {
49 qDebug() << "** WARNING Attempt to QMdiAreaContainer::setCurrentIndex(-1)";
50 return;
51 }
52 QMdiSubWindow *frame = m_mdiArea->subWindowList(QMdiArea::CreationOrder).at(index);
53 m_mdiArea->setActiveSubWindow(frame);
54}
55
56void QMdiAreaContainer::addWidget(QWidget *widget)
57{
58 QMdiSubWindow *frame = m_mdiArea->addSubWindow(widget, Qt::Window);
59 frame->show();
60 m_mdiArea->cascadeSubWindows();
61 positionNewMdiChild(m_mdiArea, frame);
62}
63
64// Semi-smart positioning of new windows: Make child fill the whole MDI window below
65// cascaded other windows
66void QMdiAreaContainer::positionNewMdiChild(const QWidget *area, QWidget *mdiChild)
67{
68 enum { MinSize = 20 };
69 const QPoint pos = mdiChild->pos();
70 const QSize areaSize = area->size();
71 switch (QApplication::layoutDirection()) {
72 case Qt::LayoutDirectionAuto:
73 case Qt::LeftToRight: {
74 const QSize fullSize = QSize(areaSize.width() - pos.x(), areaSize.height() - pos.y());
75 if (fullSize.width() > MinSize && fullSize.height() > MinSize)
76 mdiChild->resize(fullSize);
77 }
78 break;
79 case Qt::RightToLeft: {
80 const QSize fullSize = QSize(pos.x() + mdiChild->width(), areaSize.height() - pos.y());
81 if (fullSize.width() > MinSize && fullSize.height() > MinSize) {
82 mdiChild->move(0, pos.y());
83 mdiChild->resize(fullSize);
84 }
85 }
86 break;
87 }
88}
89
90void QMdiAreaContainer::insertWidget(int, QWidget *widget)
91{
92 addWidget(widget);
93}
94
95void QMdiAreaContainer::remove(int index)
96{
97 auto subWins = m_mdiArea->subWindowList(QMdiArea::CreationOrder);
98 if (index >= 0 && index < subWins.size()) {
99 QMdiSubWindow *f = subWins.at(index);
100 m_mdiArea->removeSubWindow(f->widget());
101 delete f;
102 }
103}
104
105// ---------- MdiAreaPropertySheet, creates fake properties:
106// 1) window name (object name of child)
107// 2) title (windowTitle of child).
108
109static constexpr auto subWindowTitleC = "activeSubWindowTitle"_L1;
110static constexpr auto subWindowNameC = "activeSubWindowName"_L1;
111
112QMdiAreaPropertySheet::QMdiAreaPropertySheet(QWidget *mdiArea, QObject *parent) :
113 QDesignerPropertySheet(mdiArea, parent),
114 m_windowTitleProperty(u"windowTitle"_s)
115{
116 createFakeProperty(subWindowNameC, QString());
117 createFakeProperty(subWindowTitleC, QString());
118}
119
120QMdiAreaPropertySheet::MdiAreaProperty QMdiAreaPropertySheet::mdiAreaProperty(const QString &name)
121{
122 static const QHash<QString, MdiAreaProperty> mdiAreaPropertyHash = {
123 {subWindowNameC, MdiAreaSubWindowName},
124 {subWindowTitleC, MdiAreaSubWindowTitle}
125 };
126 return mdiAreaPropertyHash.value(name, MdiAreaNone);
127}
128
129void QMdiAreaPropertySheet::setProperty(int index, const QVariant &value)
130{
131 switch (mdiAreaProperty(propertyName(index))) {
132 case MdiAreaSubWindowName:
133 if (QWidget *w = currentWindow())
134 w->setObjectName(value.toString());
135 break;
136 case MdiAreaSubWindowTitle: // Forward to window title of subwindow
137 if (QDesignerPropertySheetExtension *cws = currentWindowSheet()) {
138 const int index = cws->indexOf(m_windowTitleProperty);
139 cws->setProperty(index, value);
140 cws->setChanged(index, true);
141 }
142 break;
143 default:
144 QDesignerPropertySheet::setProperty(index, value);
145 break;
146 }
147}
148
150{
151 bool rc = true;
152 switch (mdiAreaProperty(propertyName(index))) {
153 case MdiAreaSubWindowName:
154 setProperty(index, QVariant(QString()));
155 setChanged(index, false);
156 break;
157 case MdiAreaSubWindowTitle: // Forward to window title of subwindow
158 if (QDesignerPropertySheetExtension *cws = currentWindowSheet()) {
159 const int index = cws->indexOf(m_windowTitleProperty);
160 rc = cws->reset(index);
161 }
162 break;
163 default:
164 rc = QDesignerPropertySheet::reset(index);
165 break;
166 }
167 return rc;
168}
169
171{
172 switch (mdiAreaProperty(propertyName(index))) {
173 case MdiAreaSubWindowName:
174 if (QWidget *w = currentWindow())
175 return w->objectName();
176 return QVariant(QString());
177 case MdiAreaSubWindowTitle:
178 if (QWidget *w = currentWindow())
179 return w->windowTitle();
180 return QVariant(QString());
181 case MdiAreaNone:
182 break;
183 }
184 return QDesignerPropertySheet::property(index);
185}
186
187bool QMdiAreaPropertySheet::isEnabled(int index) const
188{
189 switch (mdiAreaProperty(propertyName(index))) {
190 case MdiAreaSubWindowName:
191 case MdiAreaSubWindowTitle:
192 return currentWindow() != nullptr;
193 case MdiAreaNone:
194 break;
195 }
196 return QDesignerPropertySheet::isEnabled(index);
197}
198
199bool QMdiAreaPropertySheet::isChanged(int index) const
200{
201 bool rc = false;
202 switch (mdiAreaProperty(propertyName(index))) {
203 case MdiAreaSubWindowName:
204 rc = currentWindow() != nullptr;
205 break;
206 case MdiAreaSubWindowTitle:
207 if (QDesignerPropertySheetExtension *cws = currentWindowSheet()) {
208 const int index = cws->indexOf(m_windowTitleProperty);
209 rc = cws->isChanged(index);
210 }
211 break;
212 default:
213 rc = QDesignerPropertySheet::isChanged(index);
214 break;
215 }
216 return rc;
217}
218
219QWidget *QMdiAreaPropertySheet::currentWindow() const
220{
221 if (const QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), object())) {
222 const int ci = c->currentIndex();
223 if (ci < 0)
224 return nullptr;
225 return c->widget(ci);
226 }
227 return nullptr;
228}
229
230QDesignerPropertySheetExtension *QMdiAreaPropertySheet::currentWindowSheet() const
231{
232 QWidget *cw = currentWindow();
233 if (cw == nullptr)
234 return nullptr;
235 return qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), cw);
236}
237
238bool QMdiAreaPropertySheet::checkProperty(const QString &propertyName)
239{
240 return mdiAreaProperty(propertyName) == MdiAreaNone;
241}
242}
243QT_END_NAMESPACE
QWidget * widget(int index) const override
void setProperty(int index, const QVariant &value) override
static bool checkProperty(const QString &propertyName)
QVariant property(int index) const override
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.
static constexpr auto subWindowTitleC
static constexpr auto subWindowNameC