1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QMDIAREA_P_H
5#define QMDIAREA_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtWidgets/private/qtwidgetsglobal_p.h>
19#include "qmdiarea.h"
20#include "qmdisubwindow.h"
21
22QT_REQUIRE_CONFIG(mdiarea);
23
24#include <QList>
25#include <QList>
26#include <QRect>
27#include <QPoint>
28#include <QtWidgets/qapplication.h>
29#include <private/qmdisubwindow_p.h>
30#include <private/qabstractscrollarea_p.h>
31
32QT_BEGIN_NAMESPACE
33
34namespace QMdi {
35class Rearranger
36{
37public:
38 enum Type {
39 RegularTiler,
40 SimpleCascader,
41 IconTiler
42 };
43
44 // Rearranges widgets relative to domain.
45 virtual void rearrange(QList<QWidget *> &widgets, const QRect &domain) const = 0;
46 virtual Type type() const = 0;
47 virtual ~Rearranger() {}
48};
49
50class RegularTiler : public Rearranger
51{
52 // Rearranges widgets according to a regular tiling pattern
53 // covering the entire domain.
54 // Both positions and sizes may change.
55 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override;
56 Type type() const override { return Rearranger::RegularTiler; }
57};
58
59class SimpleCascader : public Rearranger
60{
61 // Rearranges widgets according to a simple, regular cascading pattern.
62 // Widgets are resized to minimumSize.
63 // Both positions and sizes may change.
64 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override;
65 Type type() const override { return Rearranger::SimpleCascader; }
66};
67
68class IconTiler : public Rearranger
69{
70 // Rearranges icons (assumed to be the same size) according to a regular
71 // tiling pattern filling up the domain from the bottom.
72 // Only positions may change.
73 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override;
74 Type type() const override { return Rearranger::IconTiler; }
75};
76
77class Placer
78{
79public:
80 // Places the rectangle defined by 'size' relative to 'rects' and 'domain'.
81 // Returns the position of the resulting rectangle.
82 virtual QPoint place(const QSize &size, const QList<QRect> &rects,
83 const QRect &domain) const = 0;
84 virtual ~Placer() {}
85};
86
87class MinOverlapPlacer : public Placer
88{
89 QPoint place(const QSize &size, const QList<QRect> &rects, const QRect &domain) const override;
90 static int accumulatedOverlap(const QRect &source, const QList<QRect> &rects);
91 static QRect findMinOverlapRect(const QList<QRect> &source, const QList<QRect> &rects);
92 static QList<QRect> getCandidatePlacements(const QSize &size, const QList<QRect> &rects,
93 const QRect &domain);
94 static QPoint findBestPlacement(const QRect &domain, const QList<QRect> &rects,
95 QList<QRect> &source);
96 static QList<QRect> findNonInsiders(const QRect &domain, QList<QRect> &source);
97 static QList<QRect> findMaxOverlappers(const QRect &domain, const QList<QRect> &source);
98};
99} // namespace QMdi
100
101class QMdiAreaTabBar;
102class QMdiAreaPrivate : public QAbstractScrollAreaPrivate
103{
104 Q_DECLARE_PUBLIC(QMdiArea)
105public:
106 QMdiAreaPrivate();
107
108 // Variables.
109 QMdi::Rearranger *cascader;
110 QMdi::Rearranger *regularTiler;
111 QMdi::Rearranger *iconTiler;
112 QMdi::Placer *placer;
113#if QT_CONFIG(rubberband)
114 QRubberBand *rubberBand;
115#endif
116 QMdiAreaTabBar *tabBar;
117 QList<QMdi::Rearranger *> pendingRearrangements;
118 QList<QPointer<QMdiSubWindow>> pendingPlacements;
119 QList<QPointer<QMdiSubWindow>> childWindows;
120 QList<int> indicesToActivatedChildren;
121 QPointer<QMdiSubWindow> active;
122 QPointer<QMdiSubWindow> aboutToBecomeActive;
123 QBrush background;
124 QMdiArea::WindowOrder activationOrder;
125 QMdiArea::AreaOptions options;
126 QMdiArea::ViewMode viewMode;
127#if QT_CONFIG(tabbar)
128 bool documentMode;
129 bool tabsClosable;
130 bool tabsMovable;
131#endif
132#if QT_CONFIG(tabwidget)
133 QTabWidget::TabShape tabShape;
134 QTabWidget::TabPosition tabPosition;
135#endif
136 bool ignoreGeometryChange;
137 bool ignoreWindowStateChange;
138 bool isActivated;
139 bool isSubWindowsTiled;
140 bool showActiveWindowMaximized;
141 bool tileCalledFromResizeEvent;
142 bool updatesDisabledByUs;
143 bool inViewModeChange;
144 int indexToNextWindow;
145 int indexToPreviousWindow;
146 int indexToHighlighted;
147 int indexToLastActiveTab;
148 int resizeTimerId;
149 int tabToPreviousTimerId;
150
151 // Slots.
152 void _q_deactivateAllWindows(QMdiSubWindow *aboutToActivate = nullptr);
153 void _q_processWindowStateChanged(Qt::WindowStates oldState, Qt::WindowStates newState);
154 void _q_currentTabChanged(int index);
155 void _q_closeTab(int index);
156 void _q_moveTab(int from, int to);
157
158 // Functions.
159 void appendChild(QMdiSubWindow *child);
160 void place(QMdi::Placer *placer, QMdiSubWindow *child);
161 void rearrange(QMdi::Rearranger *rearranger);
162 void arrangeMinimizedSubWindows();
163 void activateWindow(QMdiSubWindow *child);
164 void activateCurrentWindow();
165 void activateHighlightedWindow();
166 void emitWindowActivated(QMdiSubWindow *child);
167 void resetActiveWindow(QMdiSubWindow *child = nullptr);
168 void updateActiveWindow(int removedIndex, bool activeRemoved);
169 void updateScrollBars();
170 void internalRaise(QMdiSubWindow *child) const;
171 bool scrollBarsEnabled() const;
172 bool lastWindowAboutToBeDestroyed() const;
173 void setChildActivationEnabled(bool enable = true, bool onlyNextActivationEvent = false) const;
174 QRect resizeToMinimumTileSize(const QSize &minSubWindowSize, int subWindowCount);
175 void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) override; // reimp
176 QMdiSubWindow *nextVisibleSubWindow(int increaseFactor, QMdiArea::WindowOrder,
177 int removed = -1, int fromIndex = -1) const;
178 void highlightNextSubWindow(int increaseFactor);
179 QList<QMdiSubWindow *> subWindowList(QMdiArea::WindowOrder, bool reversed = false) const;
180 void disconnectSubWindow(QObject *subWindow);
181 void setViewMode(QMdiArea::ViewMode mode);
182#if QT_CONFIG(tabbar)
183 void updateTabBarGeometry();
184 void refreshTabBar();
185#endif
186
187 inline void startResizeTimer()
188 {
189 Q_Q(QMdiArea);
190 if (resizeTimerId > 0)
191 q->killTimer(id: resizeTimerId);
192 resizeTimerId = q->startTimer(interval: 200);
193 }
194
195 inline void startTabToPreviousTimer()
196 {
197 Q_Q(QMdiArea);
198 if (tabToPreviousTimerId > 0)
199 q->killTimer(id: tabToPreviousTimerId);
200 tabToPreviousTimerId = q->startTimer(interval: QApplication::keyboardInputInterval());
201 }
202
203 inline bool windowStaysOnTop(QMdiSubWindow *subWindow) const
204 {
205 if (!subWindow)
206 return false;
207 return subWindow->windowFlags() & Qt::WindowStaysOnTopHint;
208 }
209
210 inline bool isExplicitlyDeactivated(QMdiSubWindow *subWindow) const
211 {
212 if (!subWindow)
213 return true;
214 return subWindow->d_func()->isExplicitlyDeactivated;
215 }
216
217 inline void setActive(QMdiSubWindow *subWindow, bool active = true, bool changeFocus = true) const
218 {
219 if (subWindow)
220 subWindow->d_func()->setActive(activate: active, changeFocus);
221 }
222
223#if QT_CONFIG(rubberband)
224 void showRubberBandFor(QMdiSubWindow *subWindow);
225
226 inline void hideRubberBand()
227 {
228 if (rubberBand && rubberBand->isVisible())
229 rubberBand->hide();
230 indexToHighlighted = -1;
231 }
232#endif // QT_CONFIG(rubberband)
233};
234
235QT_END_NAMESPACE
236
237#endif // QMDIAREA_P_H
238

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