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 QMDIAREA_P_H
41#define QMDIAREA_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 "qmdiarea.h"
56#include "qmdisubwindow.h"
57
58QT_REQUIRE_CONFIG(mdiarea);
59
60#include <QList>
61#include <QVector>
62#include <QRect>
63#include <QPoint>
64#include <QtWidgets/qapplication.h>
65#include <private/qmdisubwindow_p.h>
66#include <private/qabstractscrollarea_p.h>
67
68QT_BEGIN_NAMESPACE
69
70namespace QMdi {
71class Rearranger
72{
73public:
74 enum Type {
75 RegularTiler,
76 SimpleCascader,
77 IconTiler
78 };
79
80 // Rearranges widgets relative to domain.
81 virtual void rearrange(QList<QWidget *> &widgets, const QRect &domain) const = 0;
82 virtual Type type() const = 0;
83 virtual ~Rearranger() {}
84};
85
86class RegularTiler : public Rearranger
87{
88 // Rearranges widgets according to a regular tiling pattern
89 // covering the entire domain.
90 // Both positions and sizes may change.
91 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override;
92 Type type() const override { return Rearranger::RegularTiler; }
93};
94
95class SimpleCascader : public Rearranger
96{
97 // Rearranges widgets according to a simple, regular cascading pattern.
98 // Widgets are resized to minimumSize.
99 // Both positions and sizes may change.
100 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override;
101 Type type() const override { return Rearranger::SimpleCascader; }
102};
103
104class IconTiler : public Rearranger
105{
106 // Rearranges icons (assumed to be the same size) according to a regular
107 // tiling pattern filling up the domain from the bottom.
108 // Only positions may change.
109 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override;
110 Type type() const override { return Rearranger::IconTiler; }
111};
112
113class Placer
114{
115public:
116 // Places the rectangle defined by 'size' relative to 'rects' and 'domain'.
117 // Returns the position of the resulting rectangle.
118 virtual QPoint place(
119 const QSize &size, const QVector<QRect> &rects, const QRect &domain) const = 0;
120 virtual ~Placer() {}
121};
122
123class MinOverlapPlacer : public Placer
124{
125 QPoint place(const QSize &size, const QVector<QRect> &rects, const QRect &domain) const override;
126 static int accumulatedOverlap(const QRect &source, const QVector<QRect> &rects);
127 static QRect findMinOverlapRect(const QVector<QRect> &source, const QVector<QRect> &rects);
128 static QVector<QRect> getCandidatePlacements(const QSize &size, const QVector<QRect> &rects, const QRect &domain);
129 static QPoint findBestPlacement(const QRect &domain, const QVector<QRect> &rects, QVector<QRect> &source);
130 static QVector<QRect> findNonInsiders(const QRect &domain, QVector<QRect> &source);
131 static QVector<QRect> findMaxOverlappers(const QRect &domain, const QVector<QRect> &source);
132};
133} // namespace QMdi
134
135class QMdiAreaTabBar;
136class QMdiAreaPrivate : public QAbstractScrollAreaPrivate
137{
138 Q_DECLARE_PUBLIC(QMdiArea)
139public:
140 QMdiAreaPrivate();
141
142 // Variables.
143 QMdi::Rearranger *cascader;
144 QMdi::Rearranger *regularTiler;
145 QMdi::Rearranger *iconTiler;
146 QMdi::Placer *placer;
147#if QT_CONFIG(rubberband)
148 QRubberBand *rubberBand;
149#endif
150 QMdiAreaTabBar *tabBar;
151 QList<QMdi::Rearranger *> pendingRearrangements;
152 QVector< QPointer<QMdiSubWindow> > pendingPlacements;
153 QVector< QPointer<QMdiSubWindow> > childWindows;
154 QVector<int> indicesToActivatedChildren;
155 QPointer<QMdiSubWindow> active;
156 QPointer<QMdiSubWindow> aboutToBecomeActive;
157 QBrush background;
158 QMdiArea::WindowOrder activationOrder;
159 QMdiArea::AreaOptions options;
160 QMdiArea::ViewMode viewMode;
161#if QT_CONFIG(tabbar)
162 bool documentMode;
163 bool tabsClosable;
164 bool tabsMovable;
165#endif
166#if QT_CONFIG(tabwidget)
167 QTabWidget::TabShape tabShape;
168 QTabWidget::TabPosition tabPosition;
169#endif
170 bool ignoreGeometryChange;
171 bool ignoreWindowStateChange;
172 bool isActivated;
173 bool isSubWindowsTiled;
174 bool showActiveWindowMaximized;
175 bool tileCalledFromResizeEvent;
176 bool updatesDisabledByUs;
177 bool inViewModeChange;
178 int indexToNextWindow;
179 int indexToPreviousWindow;
180 int indexToHighlighted;
181 int indexToLastActiveTab;
182 int resizeTimerId;
183 int tabToPreviousTimerId;
184
185 // Slots.
186 void _q_deactivateAllWindows(QMdiSubWindow *aboutToActivate = nullptr);
187 void _q_processWindowStateChanged(Qt::WindowStates oldState, Qt::WindowStates newState);
188 void _q_currentTabChanged(int index);
189 void _q_closeTab(int index);
190 void _q_moveTab(int from, int to);
191
192 // Functions.
193 void appendChild(QMdiSubWindow *child);
194 void place(QMdi::Placer *placer, QMdiSubWindow *child);
195 void rearrange(QMdi::Rearranger *rearranger);
196 void arrangeMinimizedSubWindows();
197 void activateWindow(QMdiSubWindow *child);
198 void activateCurrentWindow();
199 void activateHighlightedWindow();
200 void emitWindowActivated(QMdiSubWindow *child);
201 void resetActiveWindow(QMdiSubWindow *child = nullptr);
202 void updateActiveWindow(int removedIndex, bool activeRemoved);
203 void updateScrollBars();
204 void internalRaise(QMdiSubWindow *child) const;
205 bool scrollBarsEnabled() const;
206 bool lastWindowAboutToBeDestroyed() const;
207 void setChildActivationEnabled(bool enable = true, bool onlyNextActivationEvent = false) const;
208 QRect resizeToMinimumTileSize(const QSize &minSubWindowSize, int subWindowCount);
209 void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) override; // reimp
210 QMdiSubWindow *nextVisibleSubWindow(int increaseFactor, QMdiArea::WindowOrder,
211 int removed = -1, int fromIndex = -1) const;
212 void highlightNextSubWindow(int increaseFactor);
213 QList<QMdiSubWindow *> subWindowList(QMdiArea::WindowOrder, bool reversed = false) const;
214 void disconnectSubWindow(QObject *subWindow);
215 void setViewMode(QMdiArea::ViewMode mode);
216#if QT_CONFIG(tabbar)
217 void updateTabBarGeometry();
218 void refreshTabBar();
219#endif
220
221 inline void startResizeTimer()
222 {
223 Q_Q(QMdiArea);
224 if (resizeTimerId > 0)
225 q->killTimer(id: resizeTimerId);
226 resizeTimerId = q->startTimer(interval: 200);
227 }
228
229 inline void startTabToPreviousTimer()
230 {
231 Q_Q(QMdiArea);
232 if (tabToPreviousTimerId > 0)
233 q->killTimer(id: tabToPreviousTimerId);
234 tabToPreviousTimerId = q->startTimer(interval: QApplication::keyboardInputInterval());
235 }
236
237 inline bool windowStaysOnTop(QMdiSubWindow *subWindow) const
238 {
239 if (!subWindow)
240 return false;
241 return subWindow->windowFlags() & Qt::WindowStaysOnTopHint;
242 }
243
244 inline bool isExplicitlyDeactivated(QMdiSubWindow *subWindow) const
245 {
246 if (!subWindow)
247 return true;
248 return subWindow->d_func()->isExplicitlyDeactivated;
249 }
250
251 inline void setActive(QMdiSubWindow *subWindow, bool active = true, bool changeFocus = true) const
252 {
253 if (subWindow)
254 subWindow->d_func()->setActive(activate: active, changeFocus);
255 }
256
257#if QT_CONFIG(rubberband)
258 void showRubberBandFor(QMdiSubWindow *subWindow);
259
260 inline void hideRubberBand()
261 {
262 if (rubberBand && rubberBand->isVisible())
263 rubberBand->hide();
264 indexToHighlighted = -1;
265 }
266#endif // QT_CONFIG(rubberband)
267};
268
269QT_END_NAMESPACE
270
271#endif // QMDIAREA_P_H
272

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