1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtWidgets module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QMDISUBWINDOW_P_H
41#define QMDISUBWINDOW_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <QtWidgets/private/qtwidgetsglobal_p.h>
55#include "qmdisubwindow.h"
56
57#include <QStyle>
58#include <QStyleOptionTitleBar>
59#if QT_CONFIG(menubar)
60#include <QMenuBar>
61#endif
62#if QT_CONFIG(sizegrip)
63#include <QSizeGrip>
64#endif
65#include <QPointer>
66#include <QDebug>
67#include <private/qwidget_p.h>
68
69QT_REQUIRE_CONFIG(mdiarea);
70
71QT_BEGIN_NAMESPACE
72
73class QVBoxLayout;
74class QMouseEvent;
75
76namespace QMdi {
77template<typename T>
78class ControlElement : public T
79{
80public:
81 ControlElement(QMdiSubWindow *child) : T(child, nullptr)
82 {
83 Q_ASSERT(child);
84 mdiChild = child;
85 }
86
87 void *qt_metacast(const char *classname) override
88 {
89 if (classname && strcmp(s1: classname, s2: "ControlElement") == 0)
90 return this;
91 return nullptr;
92 }
93
94 QPointer<QMdiSubWindow> mdiChild;
95};
96
97class ControlContainer : public QObject
98{
99public:
100 ControlContainer(QMdiSubWindow *mdiChild);
101 ~ControlContainer();
102
103#if QT_CONFIG(menubar)
104 void showButtonsInMenuBar(QMenuBar *menuBar);
105 void removeButtonsFromMenuBar(QMenuBar *menuBar = nullptr);
106 QMenuBar *menuBar() const { return m_menuBar; }
107#endif
108 void updateWindowIcon(const QIcon &windowIcon);
109 QWidget *controllerWidget() const { return m_controllerWidget; }
110 QWidget *systemMenuLabel() const { return m_menuLabel; }
111
112private:
113 QPointer<QWidget> previousLeft;
114 QPointer<QWidget> previousRight;
115#if QT_CONFIG(menubar)
116 QPointer<QMenuBar> m_menuBar;
117#endif
118 QPointer<QWidget> m_controllerWidget;
119 QPointer<QWidget> m_menuLabel;
120 QPointer<QMdiSubWindow> mdiChild;
121};
122} // namespace QMdi
123
124class QMdiSubWindowPrivate : public QWidgetPrivate
125{
126 Q_DECLARE_PUBLIC(QMdiSubWindow)
127public:
128 // Enums and typedefs.
129 enum Operation {
130 None,
131 Move,
132 TopResize,
133 BottomResize,
134 LeftResize,
135 RightResize,
136 TopLeftResize,
137 TopRightResize,
138 BottomLeftResize,
139 BottomRightResize
140 };
141
142 enum ChangeFlag {
143 HMove = 0x01,
144 VMove = 0x02,
145 HResize = 0x04,
146 VResize = 0x08,
147 HResizeReverse = 0x10,
148 VResizeReverse = 0x20
149 };
150
151 enum WindowStateAction {
152 RestoreAction,
153 MoveAction,
154 ResizeAction,
155 MinimizeAction,
156 MaximizeAction,
157 StayOnTopAction,
158 CloseAction,
159 /* Add new states _above_ this line! */
160 NumWindowStateActions
161 };
162
163 struct OperationInfo {
164 uint changeFlags;
165 Qt::CursorShape cursorShape;
166 QRegion region;
167 bool hover;
168 OperationInfo(uint changeFlags, Qt::CursorShape cursorShape, bool hover = true)
169 : changeFlags(changeFlags),
170 cursorShape(cursorShape),
171 hover(hover)
172 {}
173 };
174
175 typedef QMap<Operation, OperationInfo> OperationInfoMap;
176
177 QMdiSubWindowPrivate();
178
179 // Variables.
180 QPointer<QWidget> baseWidget;
181 QPointer<QWidget> restoreFocusWidget;
182 QPointer<QMdi::ControlContainer> controlContainer;
183#if QT_CONFIG(sizegrip)
184 QPointer<QSizeGrip> sizeGrip;
185#endif
186#if QT_CONFIG(rubberband)
187 QRubberBand *rubberBand;
188#endif
189 QPoint mousePressPosition;
190 QRect oldGeometry;
191 QSize internalMinimumSize;
192 QSize userMinimumSize;
193 QSize restoreSize;
194 bool resizeEnabled;
195 bool moveEnabled;
196 bool isInInteractiveMode;
197#if QT_CONFIG(rubberband)
198 bool isInRubberBandMode;
199#endif
200 bool isShadeMode;
201 bool ignoreWindowTitleChange;
202 bool ignoreNextActivationEvent;
203 bool activationEnabled;
204 bool isShadeRequestFromMinimizeMode;
205 bool isMaximizeMode;
206 bool isWidgetHiddenByUs;
207 bool isActive;
208 bool isExplicitlyDeactivated;
209 int keyboardSingleStep;
210 int keyboardPageStep;
211 int resizeTimerId;
212 Operation currentOperation;
213 QStyle::SubControl hoveredSubControl;
214 QStyle::SubControl activeSubControl;
215 Qt::FocusReason focusInReason;
216 OperationInfoMap operationMap;
217 QPointer<QMenu> systemMenu;
218#ifndef QT_NO_ACTION
219 QPointer<QAction> actions[NumWindowStateActions];
220#endif
221 QMdiSubWindow::SubWindowOptions options;
222 QString lastChildWindowTitle;
223 QPalette titleBarPalette;
224 QString windowTitle;
225 QFont font;
226 QIcon menuIcon;
227 QStyleOptionTitleBar cachedStyleOptions;
228 QString originalTitle;
229
230 // Slots.
231 void _q_updateStaysOnTopHint();
232 void _q_enterInteractiveMode();
233 void _q_processFocusChanged(QWidget *old, QWidget *now);
234
235 // Functions.
236 void leaveInteractiveMode();
237 void removeBaseWidget();
238 void initOperationMap();
239#if QT_CONFIG(menu)
240 void createSystemMenu();
241#endif
242 void updateCursor();
243 void updateDirtyRegions();
244 void updateGeometryConstraints();
245 void updateMask();
246 void setNewGeometry(const QPoint &pos);
247 void setMinimizeMode();
248 void setNormalMode();
249 void setMaximizeMode();
250 void setActive(bool activate, bool changeFocus = true);
251 void processClickedSubControl();
252 QRegion getRegion(Operation operation) const;
253 Operation getOperation(const QPoint &pos) const;
254 QStyleOptionTitleBar titleBarOptions() const;
255 void ensureWindowState(Qt::WindowState state);
256 int titleBarHeight(const QStyleOptionTitleBar &options) const;
257 void sizeParameters(int *margin, int *minWidth) const;
258 bool drawTitleBarWhenMaximized() const;
259#if QT_CONFIG(menubar)
260 QMenuBar *menuBar() const;
261 void showButtonsInMenuBar(QMenuBar *menuBar);
262 void removeButtonsFromMenuBar();
263#endif
264 void updateWindowTitle(bool requestFromChild);
265#if QT_CONFIG(rubberband)
266 void enterRubberBandMode();
267 void leaveRubberBandMode();
268#endif
269 QPalette desktopPalette() const;
270 void updateActions();
271 void setFocusWidget();
272 bool restoreFocus();
273 void storeFocusWidget();
274 void setWindowFlags(Qt::WindowFlags windowFlags) override;
275 void setVisible(WindowStateAction, bool visible = true);
276#ifndef QT_NO_ACTION
277 void setEnabled(WindowStateAction, bool enable = true);
278#if QT_CONFIG(menu)
279 void addToSystemMenu(WindowStateAction, const QString &text, const char *slot);
280#endif
281#endif // QT_NO_ACTION
282 QSize iconSize() const;
283#if QT_CONFIG(sizegrip)
284 void setSizeGrip(QSizeGrip *sizeGrip);
285 void setSizeGripVisible(bool visible = true) const;
286#endif
287 void updateInternalWindowTitle();
288 QString originalWindowTitle();
289 QString originalWindowTitleHelper() const;
290 void setNewWindowTitle();
291
292 inline int titleBarHeight() const
293 {
294 Q_Q(const QMdiSubWindow);
295 if (!parent || q->windowFlags() & Qt::FramelessWindowHint
296 || (q->isMaximized() && !drawTitleBarWhenMaximized())) {
297 return 0;
298 }
299 QStyleOptionTitleBar options = titleBarOptions();
300 int height = options.rect.height();
301 if (hasBorder(options))
302 height += q->isMinimized() ? 8 : 4;
303 return height;
304 }
305
306 inline QStyle::SubControl getSubControl(const QPoint &pos) const
307 {
308 Q_Q(const QMdiSubWindow);
309 QStyleOptionTitleBar titleBarOptions = this->titleBarOptions();
310 return q->style()->hitTestComplexControl(cc: QStyle::CC_TitleBar, opt: &titleBarOptions, pt: pos, widget: q);
311 }
312
313 inline void setNewGeometry(QRect *geometry)
314 {
315 Q_Q(QMdiSubWindow);
316 Q_ASSERT(parent);
317 geometry->setSize(geometry->size().expandedTo(otherSize: internalMinimumSize));
318#if QT_CONFIG(rubberband)
319 if (isInRubberBandMode)
320 rubberBand->setGeometry(*geometry);
321 else
322#endif
323 q->setGeometry(*geometry);
324 }
325
326 inline bool hasBorder(const QStyleOptionTitleBar &options) const
327 {
328 Q_Q(const QMdiSubWindow);
329 return !q->style()->styleHint(stylehint: QStyle::SH_TitleBar_NoBorder, opt: &options, widget: q);
330 }
331
332 inline bool autoRaise() const
333 {
334 Q_Q(const QMdiSubWindow);
335 return q->style()->styleHint(stylehint: QStyle::SH_TitleBar_AutoRaise, opt: nullptr, widget: q);
336 }
337
338 inline bool isResizeOperation() const
339 {
340 return currentOperation != None && currentOperation != Move;
341 }
342
343 inline bool isMoveOperation() const
344 {
345 return currentOperation == Move;
346 }
347};
348
349QT_END_NAMESPACE
350
351#endif // QMDISUBWINDOW_P_H
352

source code of qtbase/src/widgets/widgets/qmdisubwindow_p.h