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