Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/widgets/widgets/qmdiarea.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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 | /*! | - | ||||||||||||
41 | \class QMdiArea | - | ||||||||||||
42 | \brief The QMdiArea widget provides an area in which MDI windows are displayed. | - | ||||||||||||
43 | \since 4.3 | - | ||||||||||||
44 | \ingroup mainwindow-classes | - | ||||||||||||
45 | \inmodule QtWidgets | - | ||||||||||||
46 | - | |||||||||||||
47 | QMdiArea functions, essentially, like a window manager for MDI | - | ||||||||||||
48 | windows. For instance, it draws the windows it manages on itself | - | ||||||||||||
49 | and arranges them in a cascading or tile pattern. QMdiArea is | - | ||||||||||||
50 | commonly used as the center widget in a QMainWindow to create MDI | - | ||||||||||||
51 | applications, but can also be placed in any layout. The following | - | ||||||||||||
52 | code adds an area to a main window: | - | ||||||||||||
53 | - | |||||||||||||
54 | \snippet mdiareasnippets.cpp 0 | - | ||||||||||||
55 | - | |||||||||||||
56 | Unlike the window managers for top-level windows, all window flags | - | ||||||||||||
57 | (Qt::WindowFlags) are supported by QMdiArea as long as the flags | - | ||||||||||||
58 | are supported by the current widget style. If a specific flag is | - | ||||||||||||
59 | not supported by the style (e.g., the | - | ||||||||||||
60 | \l{Qt::}{WindowShadeButtonHint}), you can still shade the window | - | ||||||||||||
61 | with showShaded(). | - | ||||||||||||
62 | - | |||||||||||||
63 | Subwindows in QMdiArea are instances of QMdiSubWindow. They | - | ||||||||||||
64 | are added to an MDI area with addSubWindow(). It is common to pass | - | ||||||||||||
65 | a QWidget, which is set as the internal widget, to this function, | - | ||||||||||||
66 | but it is also possible to pass a QMdiSubWindow directly.The class | - | ||||||||||||
67 | inherits QWidget, and you can use the same API as with a normal | - | ||||||||||||
68 | top-level window when programming. QMdiSubWindow also has behavior | - | ||||||||||||
69 | that is specific to MDI windows. See the QMdiSubWindow class | - | ||||||||||||
70 | description for more details. | - | ||||||||||||
71 | - | |||||||||||||
72 | A subwindow becomes active when it gets the keyboard focus, or | - | ||||||||||||
73 | when setFocus() is called. The user activates a window by moving | - | ||||||||||||
74 | focus in the usual ways. The MDI area emits the | - | ||||||||||||
75 | subWindowActivated() signal when the active window changes, and | - | ||||||||||||
76 | the activeSubWindow() function returns the active subwindow. | - | ||||||||||||
77 | - | |||||||||||||
78 | The convenience function subWindowList() returns a list of all | - | ||||||||||||
79 | subwindows. This information could be used in a popup menu | - | ||||||||||||
80 | containing a list of windows, for example. | - | ||||||||||||
81 | - | |||||||||||||
82 | The subwindows are sorted by the current | - | ||||||||||||
83 | \l{QMdiArea::}{WindowOrder}. This is used for the subWindowList() | - | ||||||||||||
84 | and for activateNextSubWindow() and activatePreviousSubWindow(). | - | ||||||||||||
85 | Also, it is used when cascading or tiling the windows with | - | ||||||||||||
86 | cascadeSubWindows() and tileSubWindows(). | - | ||||||||||||
87 | - | |||||||||||||
88 | QMdiArea provides two built-in layout strategies for | - | ||||||||||||
89 | subwindows: cascadeSubWindows() and tileSubWindows(). Both are | - | ||||||||||||
90 | slots and are easily connected to menu entries. | - | ||||||||||||
91 | - | |||||||||||||
92 | \table | - | ||||||||||||
93 | \row \li \inlineimage mdi-cascade.png | - | ||||||||||||
94 | \li \inlineimage mdi-tile.png | - | ||||||||||||
95 | \endtable | - | ||||||||||||
96 | - | |||||||||||||
97 | \note The default scroll bar property for QMdiArea is Qt::ScrollBarAlwaysOff. | - | ||||||||||||
98 | - | |||||||||||||
99 | \sa QMdiSubWindow | - | ||||||||||||
100 | */ | - | ||||||||||||
101 | - | |||||||||||||
102 | /*! | - | ||||||||||||
103 | \fn QMdiArea::subWindowActivated(QMdiSubWindow *window) | - | ||||||||||||
104 | - | |||||||||||||
105 | QMdiArea emits this signal after \a window has been activated. When \a | - | ||||||||||||
106 | window is 0, QMdiArea has just deactivated its last active window, and | - | ||||||||||||
107 | there are no active windows on the workspace. | - | ||||||||||||
108 | - | |||||||||||||
109 | \sa QMdiArea::activeSubWindow() | - | ||||||||||||
110 | */ | - | ||||||||||||
111 | - | |||||||||||||
112 | /*! | - | ||||||||||||
113 | \enum QMdiArea::AreaOption | - | ||||||||||||
114 | - | |||||||||||||
115 | This enum describes options that customize the behavior of the | - | ||||||||||||
116 | QMdiArea. | - | ||||||||||||
117 | - | |||||||||||||
118 | \value DontMaximizeSubWindowOnActivation When the active subwindow | - | ||||||||||||
119 | is maximized, the default behavior is to maximize the next | - | ||||||||||||
120 | subwindow that is activated. Set this option if you do not want | - | ||||||||||||
121 | this behavior. | - | ||||||||||||
122 | */ | - | ||||||||||||
123 | - | |||||||||||||
124 | /*! | - | ||||||||||||
125 | \enum QMdiArea::WindowOrder | - | ||||||||||||
126 | - | |||||||||||||
127 | Specifies the criteria to use for ordering the list of child windows | - | ||||||||||||
128 | returned by subWindowList(). The functions cascadeSubWindows() and | - | ||||||||||||
129 | tileSubWindows() follow this order when arranging the windows. | - | ||||||||||||
130 | - | |||||||||||||
131 | \value CreationOrder The windows are returned in the order of | - | ||||||||||||
132 | their creation. | - | ||||||||||||
133 | - | |||||||||||||
134 | \value StackingOrder The windows are returned in the order in | - | ||||||||||||
135 | which they are stacked, with the top-most window being last in | - | ||||||||||||
136 | the list. | - | ||||||||||||
137 | - | |||||||||||||
138 | \value ActivationHistoryOrder The windows are returned in the order in | - | ||||||||||||
139 | which they were activated. | - | ||||||||||||
140 | - | |||||||||||||
141 | \sa subWindowList() | - | ||||||||||||
142 | */ | - | ||||||||||||
143 | - | |||||||||||||
144 | /*! | - | ||||||||||||
145 | \enum QMdiArea::ViewMode | - | ||||||||||||
146 | \since 4.4 | - | ||||||||||||
147 | - | |||||||||||||
148 | This enum describes the view mode of the area; i.e. how sub-windows | - | ||||||||||||
149 | will be displayed. | - | ||||||||||||
150 | - | |||||||||||||
151 | \value SubWindowView Display sub-windows with window frames (default). | - | ||||||||||||
152 | \value TabbedView Display sub-windows with tabs in a tab bar. | - | ||||||||||||
153 | - | |||||||||||||
154 | \sa setViewMode() | - | ||||||||||||
155 | */ | - | ||||||||||||
156 | - | |||||||||||||
157 | #include "qmdiarea_p.h" | - | ||||||||||||
158 | - | |||||||||||||
159 | #ifndef QT_NO_MDIAREA | - | ||||||||||||
160 | - | |||||||||||||
161 | #include <QApplication> | - | ||||||||||||
162 | #include <QStyle> | - | ||||||||||||
163 | #if defined(Q_DEAD_CODE_FROM_QT4_MAC) && !defined(QT_NO_STYLE_MAC) | - | ||||||||||||
164 | #include <private/qmacstyle_mac_p.h> | - | ||||||||||||
165 | #endif | - | ||||||||||||
166 | #include <QChildEvent> | - | ||||||||||||
167 | #include <QResizeEvent> | - | ||||||||||||
168 | #include <QScrollBar> | - | ||||||||||||
169 | #include <QtAlgorithms> | - | ||||||||||||
#include <QMutableVectorIterator> | ||||||||||||||
170 | #include <QPainter> | - | ||||||||||||
171 | #include <QFontMetrics> | - | ||||||||||||
172 | #include <QStyleOption> | - | ||||||||||||
173 | #include <QDesktopWidget> | - | ||||||||||||
174 | #include <QDebug> | - | ||||||||||||
175 | #include <qmath.h> | - | ||||||||||||
176 | #include <private/qlayoutengine_p.h> | - | ||||||||||||
177 | - | |||||||||||||
178 | #include <algorithm> | - | ||||||||||||
179 | - | |||||||||||||
180 | QT_BEGIN_NAMESPACE | - | ||||||||||||
181 | - | |||||||||||||
182 | using namespace QMdi; | - | ||||||||||||
183 | - | |||||||||||||
184 | // Asserts in debug mode, gives warning otherwise. | - | ||||||||||||
185 | static bool sanityCheck(const QMdiSubWindow * const child, const char *where) | - | ||||||||||||
186 | { | - | ||||||||||||
187 | if (Q_UNLIKELY(!child))) {
| 0 | ||||||||||||
188 | const char error[] = "null pointer"; | - | ||||||||||||
189 | Q_ASSERT_X(false, where, error); | - | ||||||||||||
190 | qWarning("%s:%s", where, error); | - | ||||||||||||
191 | return false; never executed: return false; | 0 | ||||||||||||
192 | } | - | ||||||||||||
193 | return true; never executed: return true; | 0 | ||||||||||||
194 | } | - | ||||||||||||
195 | - | |||||||||||||
196 | static bool sanityCheck(const QList<QWidget *> &widgets, const int index, const char *where) | - | ||||||||||||
197 | { | - | ||||||||||||
198 | if (Q_UNLIKELY(index < 0 || index >= widgets.size())())) {
| 0 | ||||||||||||
199 | const char error[] = "index out of range"; | - | ||||||||||||
200 | Q_ASSERT_X(false, where, error); | - | ||||||||||||
201 | qWarning("%s:%s", where, error); | - | ||||||||||||
202 | return false; never executed: return false; | 0 | ||||||||||||
203 | } | - | ||||||||||||
204 | if (Q_UNLIKELY(!widgets.at(index))))) {
| 0 | ||||||||||||
205 | const char error[] = "null pointer"; | - | ||||||||||||
206 | Q_ASSERT_X(false, where, error); | - | ||||||||||||
207 | qWarning("%s:%s", where, error); | - | ||||||||||||
208 | return false; never executed: return false; | 0 | ||||||||||||
209 | } | - | ||||||||||||
210 | return true; never executed: return true; | 0 | ||||||||||||
211 | } | - | ||||||||||||
212 | - | |||||||||||||
213 | static void setIndex(int *index, int candidate, int min, int max, bool isIncreasing) | - | ||||||||||||
214 | { | - | ||||||||||||
215 | if (!index) | - | ||||||||||||
216 | return; | - | ||||||||||||
217 | - | |||||||||||||
218 | if (isIncreasing) { | - | ||||||||||||
219 | if (candidate > max) | - | ||||||||||||
220 | *index = min; | - | ||||||||||||
221 | else | - | ||||||||||||
222 | *index = qMax(candidate, min); | - | ||||||||||||
223 | } else { | - | ||||||||||||
224 | if (candidate < min) | - | ||||||||||||
225 | *index = max; | - | ||||||||||||
226 | else | - | ||||||||||||
227 | *index = qMin(candidate, max); | - | ||||||||||||
228 | } | - | ||||||||||||
229 | Q_ASSERT(*index >= min && *index <= max); | - | ||||||||||||
230 | } | - | ||||||||||||
231 | - | |||||||||||||
232 | static inline bool useScrollBar(const QRect &childrenRect, const QSize &maxViewportSize, | - | ||||||||||||
233 | Qt::Orientation orientation) | - | ||||||||||||
234 | { | - | ||||||||||||
235 | if (orientation == Qt::Horizontal) | - | ||||||||||||
236 | return childrenRect.width() > maxViewportSize.width() | - | ||||||||||||
237 | || childrenRect.left() < 0 | - | ||||||||||||
238 | || childrenRect.right() >= maxViewportSize.width(); | - | ||||||||||||
239 | else | - | ||||||||||||
240 | return childrenRect.height() > maxViewportSize.height() | - | ||||||||||||
241 | || childrenRect.top() < 0 | - | ||||||||||||
242 | || childrenRect.bottom() >= maxViewportSize.height(); | - | ||||||||||||
243 | } | - | ||||||||||||
244 | - | |||||||||||||
245 | // Returns the closest mdi area containing the widget (if any). | - | ||||||||||||
246 | static inline QMdiArea *mdiAreaParent(QWidget *widget) | - | ||||||||||||
247 | { | - | ||||||||||||
248 | if (!widget) | - | ||||||||||||
249 | return 0; | - | ||||||||||||
250 | - | |||||||||||||
251 | QWidget *parent = widget->parentWidget(); | - | ||||||||||||
252 | while (parent) { | - | ||||||||||||
253 | if (QMdiArea *area = qobject_cast<QMdiArea *>(parent)) | - | ||||||||||||
254 | return area; | - | ||||||||||||
255 | parent = parent->parentWidget(); | - | ||||||||||||
256 | } | - | ||||||||||||
257 | return 0; | - | ||||||||||||
258 | } | - | ||||||||||||
259 | - | |||||||||||||
260 | #ifndef QT_NO_TABWIDGET | - | ||||||||||||
261 | static inline QTabBar::Shape tabBarShapeFrom(QTabWidget::TabShape shape, QTabWidget::TabPosition position) | - | ||||||||||||
262 | { | - | ||||||||||||
263 | const bool rounded = (shape == QTabWidget::Rounded); | - | ||||||||||||
264 | if (position == QTabWidget::North) | - | ||||||||||||
265 | return rounded ? QTabBar::RoundedNorth : QTabBar::TriangularNorth; | - | ||||||||||||
266 | if (position == QTabWidget::South) | - | ||||||||||||
267 | return rounded ? QTabBar::RoundedSouth : QTabBar::TriangularSouth; | - | ||||||||||||
268 | if (position == QTabWidget::East) | - | ||||||||||||
269 | return rounded ? QTabBar::RoundedEast : QTabBar::TriangularEast; | - | ||||||||||||
270 | if (position == QTabWidget::West) | - | ||||||||||||
271 | return rounded ? QTabBar::RoundedWest : QTabBar::TriangularWest; | - | ||||||||||||
272 | return QTabBar::RoundedNorth; | - | ||||||||||||
273 | } | - | ||||||||||||
274 | #endif // QT_NO_TABWIDGET | - | ||||||||||||
275 | - | |||||||||||||
276 | static inline QString tabTextFor(QMdiSubWindow *subWindow) | - | ||||||||||||
277 | { | - | ||||||||||||
278 | if (!subWindow) | - | ||||||||||||
279 | return QString(); | - | ||||||||||||
280 | - | |||||||||||||
281 | QString title = subWindow->windowTitle(); | - | ||||||||||||
282 | if (subWindow->isWindowModified()) { | - | ||||||||||||
283 | title.replace(QLatin1String("[*]"), QLatin1String("*")); | - | ||||||||||||
284 | } else { | - | ||||||||||||
285 | extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); | - | ||||||||||||
286 | title = qt_setWindowTitle_helperHelper(title, subWindow); | - | ||||||||||||
287 | } | - | ||||||||||||
288 | - | |||||||||||||
289 | return title.isEmpty() ? QMdiArea::tr("(Untitled)") : title; | - | ||||||||||||
290 | } | - | ||||||||||||
291 | - | |||||||||||||
292 | /*! | - | ||||||||||||
293 | \internal | - | ||||||||||||
294 | */ | - | ||||||||||||
295 | void RegularTiler::rearrange(QList<QWidget *> &widgets, const QRect &domain) const | - | ||||||||||||
296 | { | - | ||||||||||||
297 | if (widgets.isEmpty()) | - | ||||||||||||
298 | return; | - | ||||||||||||
299 | - | |||||||||||||
300 | const int n = widgets.size(); | - | ||||||||||||
301 | const int ncols = qMax(qCeil(qSqrt(qreal(n))), 1); | - | ||||||||||||
302 | const int nrows = qMax((n % ncols) ? (n / ncols + 1) : (n / ncols), 1); | - | ||||||||||||
303 | const int nspecial = (n % ncols) ? (ncols - n % ncols) : 0; | - | ||||||||||||
304 | const int dx = domain.width() / ncols; | - | ||||||||||||
305 | const int dy = domain.height() / nrows; | - | ||||||||||||
306 | - | |||||||||||||
307 | int i = 0; | - | ||||||||||||
308 | for (int row = 0; row < nrows; ++row) { | - | ||||||||||||
309 | const int y1 = int(row * (dy + 1)); | - | ||||||||||||
310 | for (int col = 0; col < ncols; ++col) { | - | ||||||||||||
311 | if (row == 1 && col < nspecial) | - | ||||||||||||
312 | continue; | - | ||||||||||||
313 | const int x1 = int(col * (dx + 1)); | - | ||||||||||||
314 | int x2 = int(x1 + dx); | - | ||||||||||||
315 | int y2 = int(y1 + dy); | - | ||||||||||||
316 | if (row == 0 && col < nspecial) { | - | ||||||||||||
317 | y2 *= 2; | - | ||||||||||||
318 | if (nrows != 2) | - | ||||||||||||
319 | y2 += 1; | - | ||||||||||||
320 | else | - | ||||||||||||
321 | y2 = domain.bottom(); | - | ||||||||||||
322 | } | - | ||||||||||||
323 | if (col == ncols - 1 && x2 != domain.right()) | - | ||||||||||||
324 | x2 = domain.right(); | - | ||||||||||||
325 | if (row == nrows - 1 && y2 != domain.bottom()) | - | ||||||||||||
326 | y2 = domain.bottom(); | - | ||||||||||||
327 | if (!sanityCheck(widgets, i, "RegularTiler")) | - | ||||||||||||
328 | continue; | - | ||||||||||||
329 | QWidget *widget = widgets.at(i++); | - | ||||||||||||
330 | QRect newGeometry = QRect(QPoint(x1, y1), QPoint(x2, y2)); | - | ||||||||||||
331 | widget->setGeometry(QStyle::visualRect(widget->layoutDirection(), domain, newGeometry)); | - | ||||||||||||
332 | } | - | ||||||||||||
333 | } | - | ||||||||||||
334 | } | - | ||||||||||||
335 | - | |||||||||||||
336 | /*! | - | ||||||||||||
337 | \internal | - | ||||||||||||
338 | */ | - | ||||||||||||
339 | void SimpleCascader::rearrange(QList<QWidget *> &widgets, const QRect &domain) const | - | ||||||||||||
340 | { | - | ||||||||||||
341 | if (widgets.isEmpty()) | - | ||||||||||||
342 | return; | - | ||||||||||||
343 | - | |||||||||||||
344 | // Tunables: | - | ||||||||||||
345 | const int topOffset = 0; | - | ||||||||||||
346 | const int bottomOffset = 50; | - | ||||||||||||
347 | const int leftOffset = 0; | - | ||||||||||||
348 | const int rightOffset = 100; | - | ||||||||||||
349 | const int dx = 10; | - | ||||||||||||
350 | - | |||||||||||||
351 | QStyleOptionTitleBar options; | - | ||||||||||||
352 | options.initFrom(widgets.at(0)); | - | ||||||||||||
353 | int titleBarHeight = widgets.at(0)->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options, widgets.at(0)); | - | ||||||||||||
354 | const QFontMetrics fontMetrics = QFontMetrics(QApplication::font("QMdiSubWindowTitleBar")); | - | ||||||||||||
355 | const int dy = qMax(titleBarHeight - (titleBarHeight - fontMetrics.height()) / 2, 1) | - | ||||||||||||
356 | + widgets.at(0)->style()->pixelMetric(QStyle::PM_FocusFrameVMargin, 0, widgets.at(0)); | - | ||||||||||||
357 | - | |||||||||||||
358 | const int n = widgets.size(); | - | ||||||||||||
359 | const int nrows = qMax((domain.height() - (topOffset + bottomOffset)) / dy, 1); | - | ||||||||||||
360 | const int ncols = qMax(n / nrows + ((n % nrows) ? 1 : 0), 1); | - | ||||||||||||
361 | const int dcol = (domain.width() - (leftOffset + rightOffset)) / ncols; | - | ||||||||||||
362 | - | |||||||||||||
363 | int i = 0; | - | ||||||||||||
364 | for (int row = 0; row < nrows; ++row) { | - | ||||||||||||
365 | for (int col = 0; col < ncols; ++col) { | - | ||||||||||||
366 | const int x = leftOffset + row * dx + col * dcol; | - | ||||||||||||
367 | const int y = topOffset + row * dy; | - | ||||||||||||
368 | if (!sanityCheck(widgets, i, "SimpleCascader")) | - | ||||||||||||
369 | continue; | - | ||||||||||||
370 | QWidget *widget = widgets.at(i++); | - | ||||||||||||
371 | QRect newGeometry = QRect(QPoint(x, y), widget->sizeHint()); | - | ||||||||||||
372 | widget->setGeometry(QStyle::visualRect(widget->layoutDirection(), domain, newGeometry)); | - | ||||||||||||
373 | if (i == n) | - | ||||||||||||
374 | return; | - | ||||||||||||
375 | } | - | ||||||||||||
376 | } | - | ||||||||||||
377 | } | - | ||||||||||||
378 | - | |||||||||||||
379 | /*! | - | ||||||||||||
380 | \internal | - | ||||||||||||
381 | */ | - | ||||||||||||
382 | void IconTiler::rearrange(QList<QWidget *> &widgets, const QRect &domain) const | - | ||||||||||||
383 | { | - | ||||||||||||
384 | if (widgets.isEmpty() || !sanityCheck(widgets, 0, "IconTiler"))
| 0 | ||||||||||||
385 | return; never executed: return; | 0 | ||||||||||||
386 | - | |||||||||||||
387 | const int n = widgets.size(); | - | ||||||||||||
388 | const int width = qMax(widgets.at(0)->width();(), 1); | - | ||||||||||||
389 | const int height = widgets.at(0)->height(); | - | ||||||||||||
390 | const int ncols = qMax(domain.width() / width, 1); | - | ||||||||||||
391 | const int nrows = n / ncols + ((n % ncols) ? 1 : 0);
| 0 | ||||||||||||
392 | - | |||||||||||||
393 | int i = 0; | - | ||||||||||||
394 | for (int row = 0; row < nrows; ++row) {
| 0 | ||||||||||||
395 | for (int col = 0; col < ncols; ++col) {
| 0 | ||||||||||||
396 | const int x = col * width; | - | ||||||||||||
397 | const int y = domain.height() - height - row * height; | - | ||||||||||||
398 | if (!sanityCheck(widgets, i, "IconTiler"))
| 0 | ||||||||||||
399 | continue; never executed: continue; | 0 | ||||||||||||
400 | QWidget *widget = widgets.at(i++); | - | ||||||||||||
401 | QPoint newPos(x, y); | - | ||||||||||||
402 | QRect newGeometry = QRect(newPos.x(), newPos.y(), widget->width(), widget->height()); | - | ||||||||||||
403 | widget->setGeometry(QStyle::visualRect(widget->layoutDirection(), domain, newGeometry)); | - | ||||||||||||
404 | if (i == n)
| 0 | ||||||||||||
405 | return; never executed: return; | 0 | ||||||||||||
406 | } never executed: end of block | 0 | ||||||||||||
407 | } never executed: end of block | 0 | ||||||||||||
408 | } never executed: end of block | 0 | ||||||||||||
409 | - | |||||||||||||
410 | /*! | - | ||||||||||||
411 | \internal | - | ||||||||||||
412 | Calculates the accumulated overlap (intersection area) between 'source' and 'rects'. | - | ||||||||||||
413 | */ | - | ||||||||||||
414 | int MinOverlapPlacer::accumulatedOverlap(const QRect &source, const QVector<QRect> &rects) | - | ||||||||||||
415 | { | - | ||||||||||||
416 | int accOverlap = 0; | - | ||||||||||||
417 | foreachfor (const QRect &rect ,: rects) { | - | ||||||||||||
418 | QRect intersection = source.intersected(rect); | - | ||||||||||||
419 | accOverlap += intersection.width() * intersection.height(); | - | ||||||||||||
420 | } never executed: end of block | 0 | ||||||||||||
421 | return accOverlap; never executed: return accOverlap; | 0 | ||||||||||||
422 | } | - | ||||||||||||
423 | - | |||||||||||||
424 | - | |||||||||||||
425 | /*! | - | ||||||||||||
426 | \internal | - | ||||||||||||
427 | Finds among 'source' the rectangle with the minimum accumulated overlap with the | - | ||||||||||||
428 | rectangles in 'rects'. | - | ||||||||||||
429 | */ | - | ||||||||||||
430 | QRect MinOverlapPlacer::findMinOverlapRect(const QVector<QRect> &source, const QVector<QRect> &rects) | - | ||||||||||||
431 | { | - | ||||||||||||
432 | int minAccOverlap = -1; | - | ||||||||||||
433 | QRect minAccOverlapRect; | - | ||||||||||||
434 | foreachfor (const QRect &srcRect ,: source) { | - | ||||||||||||
435 | const int accOverlap = accumulatedOverlap(srcRect, rects); | - | ||||||||||||
436 | if (accOverlap < minAccOverlap || minAccOverlap == -1) {
| 0 | ||||||||||||
437 | minAccOverlap = accOverlap; | - | ||||||||||||
438 | minAccOverlapRect = srcRect; | - | ||||||||||||
439 | } never executed: end of block | 0 | ||||||||||||
440 | } never executed: end of block | 0 | ||||||||||||
441 | return minAccOverlapRect; never executed: return minAccOverlapRect; | 0 | ||||||||||||
442 | } | - | ||||||||||||
443 | - | |||||||||||||
444 | /*! | - | ||||||||||||
445 | \internal | - | ||||||||||||
446 | Gets candidates for the final placement. | - | ||||||||||||
447 | */ | - | ||||||||||||
448 | QVector<QRect> MinOverlapPlacer::getCandidatePlacements(const QSize &size, const QVector<QRect> &rects, | - | ||||||||||||
449 | const QRect &domain) | - | ||||||||||||
450 | { | - | ||||||||||||
451 | QVector<QRect> result; | - | ||||||||||||
452 | - | |||||||||||||
453 | QVector<int> xlist; | - | ||||||||||||
454 | xlist.reserve(2 + rects.size()); | - | ||||||||||||
455 | xlist << domain.left() << domain.right() - size.width() + 1; | - | ||||||||||||
456 | - | |||||||||||||
457 | QVector<int> ylist; | - | ||||||||||||
458 | ylist.reserve(2 + rects.size()); | - | ||||||||||||
459 | ylist << domain.top(); | - | ||||||||||||
460 | if (domain.bottom() - size.height() + 1 >= 0)
| 0 | ||||||||||||
461 | ylist << domain.bottom() - size.height() + 1; never executed: ylist << domain.bottom() - size.height() + 1; | 0 | ||||||||||||
462 | - | |||||||||||||
463 | foreachfor (const QRect &rect ,: rects) { | - | ||||||||||||
464 | xlist << rect.right() + 1; | - | ||||||||||||
465 | ylist << rect.bottom() + 1; | - | ||||||||||||
466 | } never executed: end of block | 0 | ||||||||||||
467 | - | |||||||||||||
468 | std::sort(xlist.begin(), xlist.end()); | - | ||||||||||||
469 | xlist.erase(std::unique(xlist.begin(), xlist.end()), xlist.end()); | - | ||||||||||||
470 | - | |||||||||||||
471 | std::sort(ylist.begin(), ylist.end()); | - | ||||||||||||
472 | ylist.erase(std::unique(ylist.begin(), ylist.end()), ylist.end()); | - | ||||||||||||
473 | - | |||||||||||||
474 | result.reserve(ylist.size() * xlist.size()); | - | ||||||||||||
475 | foreach (int y, ylist) | - | ||||||||||||
476 | foreach (int x, xlist) | - | ||||||||||||
477 | result << QRect(QPoint(x, y), size); never executed: result << QRect(QPoint(x, y), size); | 0 | ||||||||||||
478 | return result; never executed: return result; | 0 | ||||||||||||
479 | } | - | ||||||||||||
480 | - | |||||||||||||
481 | /*! | - | ||||||||||||
482 | \internal | - | ||||||||||||
483 | Finds all rectangles in 'source' not completely inside 'domain'. The result is stored | - | ||||||||||||
484 | in 'result' and also removed from 'source'. | - | ||||||||||||
485 | */ | - | ||||||||||||
486 | QVector<QRect> MinOverlapPlacer::findNonInsiders(const QRect &domain, QVector<QRect> &source) | - | ||||||||||||
487 | { | - | ||||||||||||
488 | const auto containedInDomain = | - | ||||||||||||
489 | [domain](const QRect &srcRect never executed: ) { return domain.contains(srcRect); };return domain.contains(srcRect); never executed: return domain.contains(srcRect); | 0 | ||||||||||||
490 | - | |||||||||||||
491 | const auto firstOut = std::stable_partition(source.begin(), source.end(), containedInDomain); | - | ||||||||||||
492 | - | |||||||||||||
493 | QVector<QRect> result; | - | ||||||||||||
494 | result.reserve(source.size()); | - | ||||||||||||
QMutableVectorIterator<QRect> it(sourceend() - firstOut); | ||||||||||||||
495 | whilestd::copy(it.hasNext()) { | - | ||||||||||||
const QRect srcRect = it.next(); | ||||||||||||||
if (!domainfirstOut, source.containsend(), std::back_inserter(srcRect)) {result<< srcRect; | ||||||||||||||
it)); | ||||||||||||||
496 | - | |||||||||||||
497 | source.remove(); | - | ||||||||||||
} | ||||||||||||||
}erase(firstOut, source.end()); | ||||||||||||||
498 | - | |||||||||||||
499 | return result; never executed: return result; | 0 | ||||||||||||
500 | } | - | ||||||||||||
501 | - | |||||||||||||
502 | /*! | - | ||||||||||||
503 | \internal | - | ||||||||||||
504 | Finds all rectangles in 'source' that overlaps 'domain' by the maximum overlap area | - | ||||||||||||
505 | between 'domain' and any rectangle in 'source'. The result is stored in 'result'. | - | ||||||||||||
506 | */ | - | ||||||||||||
507 | QVector<QRect> MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const QVector<QRect> &source) | - | ||||||||||||
508 | { | - | ||||||||||||
509 | QVector<QRect> result; | - | ||||||||||||
510 | result.reserve(source.size()); | - | ||||||||||||
511 | - | |||||||||||||
512 | int maxOverlap = -1; | - | ||||||||||||
513 | foreachfor (const QRect &srcRect ,: source) { | - | ||||||||||||
514 | QRect intersection = domain.intersected(srcRect); | - | ||||||||||||
515 | const int overlap = intersection.width() * intersection.height(); | - | ||||||||||||
516 | if (overlap >= maxOverlap || maxOverlap == -1) {
| 0 | ||||||||||||
517 | if (overlap > maxOverlap) {
| 0 | ||||||||||||
518 | maxOverlap = overlap; | - | ||||||||||||
519 | result.clear(); | - | ||||||||||||
520 | } never executed: end of block | 0 | ||||||||||||
521 | result << srcRect; | - | ||||||||||||
522 | } never executed: end of block | 0 | ||||||||||||
523 | } never executed: end of block | 0 | ||||||||||||
524 | - | |||||||||||||
525 | return result; never executed: return result; | 0 | ||||||||||||
526 | } | - | ||||||||||||
527 | - | |||||||||||||
528 | /*! | - | ||||||||||||
529 | \internal | - | ||||||||||||
530 | Finds among the rectangles in 'source' the best placement. Here, 'best' means the | - | ||||||||||||
531 | placement that overlaps the rectangles in 'rects' as little as possible while at the | - | ||||||||||||
532 | same time being as much as possible inside 'domain'. | - | ||||||||||||
533 | */ | - | ||||||||||||
534 | QPoint MinOverlapPlacer::findBestPlacement(const QRect &domain, const QVector<QRect> &rects, | - | ||||||||||||
535 | QVector<QRect> &source) | - | ||||||||||||
536 | { | - | ||||||||||||
537 | const QVector<QRect> nonInsiders = findNonInsiders(domain, source); | - | ||||||||||||
538 | - | |||||||||||||
539 | if (!source.empty()) | - | ||||||||||||
540 | return findMinOverlapRect(source, rects).topLeft(); | - | ||||||||||||
541 | - | |||||||||||||
542 | QVector<QRect> maxOverlappers = findMaxOverlappers(domain, nonInsiders); | - | ||||||||||||
543 | return findMinOverlapRect(maxOverlappers, rects).topLeft(); | - | ||||||||||||
544 | } | - | ||||||||||||
545 | - | |||||||||||||
546 | - | |||||||||||||
547 | /*! | - | ||||||||||||
548 | \internal | - | ||||||||||||
549 | Places the rectangle defined by 'size' relative to 'rects' and 'domain' so that it | - | ||||||||||||
550 | overlaps 'rects' as little as possible and 'domain' as much as possible. | - | ||||||||||||
551 | Returns the position of the resulting rectangle. | - | ||||||||||||
552 | */ | - | ||||||||||||
553 | QPoint MinOverlapPlacer::place(const QSize &size, const QVector<QRect> &rects, | - | ||||||||||||
554 | const QRect &domain) const | - | ||||||||||||
555 | { | - | ||||||||||||
556 | if (size.isEmpty() || !domain.isValid())
| 0 | ||||||||||||
557 | return QPoint(); never executed: return QPoint(); | 0 | ||||||||||||
558 | foreachfor (const QRect &rect ,: rects) { | - | ||||||||||||
559 | if (!rect.isValid())
| 0 | ||||||||||||
560 | return QPoint(); never executed: return QPoint(); | 0 | ||||||||||||
561 | } never executed: end of block | 0 | ||||||||||||
562 | - | |||||||||||||
563 | QVector<QRect> candidates = getCandidatePlacements(size, rects, domain); | - | ||||||||||||
564 | return findBestPlacement(domain, rects, candidates); never executed: return findBestPlacement(domain, rects, candidates); | 0 | ||||||||||||
565 | } | - | ||||||||||||
566 | - | |||||||||||||
567 | #ifndef QT_NO_TABBAR | - | ||||||||||||
568 | class QMdiAreaTabBar : public QTabBar | - | ||||||||||||
569 | { | - | ||||||||||||
570 | public: | - | ||||||||||||
571 | QMdiAreaTabBar(QWidget *parent) : QTabBar(parent) {} | - | ||||||||||||
572 | - | |||||||||||||
573 | protected: | - | ||||||||||||
574 | void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; | - | ||||||||||||
575 | #ifndef QT_NO_CONTEXTMENU | - | ||||||||||||
576 | void contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE; | - | ||||||||||||
577 | #endif | - | ||||||||||||
578 | - | |||||||||||||
579 | private: | - | ||||||||||||
580 | QMdiSubWindow *subWindowFromIndex(int index) const; | - | ||||||||||||
581 | }; | - | ||||||||||||
582 | - | |||||||||||||
583 | /*! | - | ||||||||||||
584 | \internal | - | ||||||||||||
585 | */ | - | ||||||||||||
586 | void QMdiAreaTabBar::mousePressEvent(QMouseEvent *event) | - | ||||||||||||
587 | { | - | ||||||||||||
588 | if (event->button() != Qt::MidButton) { | - | ||||||||||||
589 | QTabBar::mousePressEvent(event); | - | ||||||||||||
590 | return; | - | ||||||||||||
591 | } | - | ||||||||||||
592 | - | |||||||||||||
593 | QMdiSubWindow *subWindow = subWindowFromIndex(tabAt(event->pos())); | - | ||||||||||||
594 | if (!subWindow) { | - | ||||||||||||
595 | event->ignore(); | - | ||||||||||||
596 | return; | - | ||||||||||||
597 | } | - | ||||||||||||
598 | - | |||||||||||||
599 | subWindow->close(); | - | ||||||||||||
600 | } | - | ||||||||||||
601 | - | |||||||||||||
602 | #ifndef QT_NO_CONTEXTMENU | - | ||||||||||||
603 | /*! | - | ||||||||||||
604 | \internal | - | ||||||||||||
605 | */ | - | ||||||||||||
606 | void QMdiAreaTabBar::contextMenuEvent(QContextMenuEvent *event) | - | ||||||||||||
607 | { | - | ||||||||||||
608 | QPointer<QMdiSubWindow> subWindow = subWindowFromIndex(tabAt(event->pos())); | - | ||||||||||||
609 | if (!subWindow || subWindow->isHidden()) { | - | ||||||||||||
610 | event->ignore(); | - | ||||||||||||
611 | return; | - | ||||||||||||
612 | } | - | ||||||||||||
613 | - | |||||||||||||
614 | #ifndef QT_NO_MENU | - | ||||||||||||
615 | QMdiSubWindowPrivate *subWindowPrivate = subWindow->d_func(); | - | ||||||||||||
616 | if (!subWindowPrivate->systemMenu) { | - | ||||||||||||
617 | event->ignore(); | - | ||||||||||||
618 | return; | - | ||||||||||||
619 | } | - | ||||||||||||
620 | - | |||||||||||||
621 | QMdiSubWindow *currentSubWindow = subWindowFromIndex(currentIndex()); | - | ||||||||||||
622 | Q_ASSERT(currentSubWindow); | - | ||||||||||||
623 | - | |||||||||||||
624 | // We don't want these actions to show up in the system menu when the | - | ||||||||||||
625 | // current sub-window is maximized, i.e. covers the entire viewport. | - | ||||||||||||
626 | if (currentSubWindow->isMaximized()) { | - | ||||||||||||
627 | subWindowPrivate->setVisible(QMdiSubWindowPrivate::MoveAction, false); | - | ||||||||||||
628 | subWindowPrivate->setVisible(QMdiSubWindowPrivate::ResizeAction, false); | - | ||||||||||||
629 | subWindowPrivate->setVisible(QMdiSubWindowPrivate::MinimizeAction, false); | - | ||||||||||||
630 | subWindowPrivate->setVisible(QMdiSubWindowPrivate::MaximizeAction, false); | - | ||||||||||||
631 | subWindowPrivate->setVisible(QMdiSubWindowPrivate::RestoreAction, false); | - | ||||||||||||
632 | subWindowPrivate->setVisible(QMdiSubWindowPrivate::StayOnTopAction, false); | - | ||||||||||||
633 | } | - | ||||||||||||
634 | - | |||||||||||||
635 | // Show system menu. | - | ||||||||||||
636 | subWindowPrivate->systemMenu->exec(event->globalPos()); | - | ||||||||||||
637 | if (!subWindow) | - | ||||||||||||
638 | return; | - | ||||||||||||
639 | - | |||||||||||||
640 | // Restore action visibility. | - | ||||||||||||
641 | subWindowPrivate->updateActions(); | - | ||||||||||||
642 | #endif // QT_NO_MENU | - | ||||||||||||
643 | } | - | ||||||||||||
644 | #endif // QT_NO_CONTEXTMENU | - | ||||||||||||
645 | - | |||||||||||||
646 | /*! | - | ||||||||||||
647 | \internal | - | ||||||||||||
648 | */ | - | ||||||||||||
649 | QMdiSubWindow *QMdiAreaTabBar::subWindowFromIndex(int index) const | - | ||||||||||||
650 | { | - | ||||||||||||
651 | if (index < 0 || index >= count()) | - | ||||||||||||
652 | return 0; | - | ||||||||||||
653 | - | |||||||||||||
654 | QMdiArea *mdiArea = qobject_cast<QMdiArea *>(parentWidget()); | - | ||||||||||||
655 | Q_ASSERT(mdiArea); | - | ||||||||||||
656 | - | |||||||||||||
657 | const QList<QMdiSubWindow *> subWindows = mdiArea->subWindowList(); | - | ||||||||||||
658 | Q_ASSERT(index < subWindows.size()); | - | ||||||||||||
659 | - | |||||||||||||
660 | QMdiSubWindow *subWindow = mdiArea->subWindowList().at(index); | - | ||||||||||||
661 | Q_ASSERT(subWindow); | - | ||||||||||||
662 | - | |||||||||||||
663 | return subWindow; | - | ||||||||||||
664 | } | - | ||||||||||||
665 | #endif // QT_NO_TABBAR | - | ||||||||||||
666 | - | |||||||||||||
667 | /*! | - | ||||||||||||
668 | \internal | - | ||||||||||||
669 | */ | - | ||||||||||||
670 | QMdiAreaPrivate::QMdiAreaPrivate() | - | ||||||||||||
671 | : cascader(0), | - | ||||||||||||
672 | regularTiler(0), | - | ||||||||||||
673 | iconTiler(0), | - | ||||||||||||
674 | placer(0), | - | ||||||||||||
675 | #ifndef QT_NO_RUBBERBAND | - | ||||||||||||
676 | rubberBand(0), | - | ||||||||||||
677 | #endif | - | ||||||||||||
678 | #ifndef QT_NO_TABBAR | - | ||||||||||||
679 | tabBar(0), | - | ||||||||||||
680 | #endif | - | ||||||||||||
681 | activationOrder(QMdiArea::CreationOrder), | - | ||||||||||||
682 | viewMode(QMdiArea::SubWindowView), | - | ||||||||||||
683 | #ifndef QT_NO_TABBAR | - | ||||||||||||
684 | documentMode(false), | - | ||||||||||||
685 | tabsClosable(false), | - | ||||||||||||
686 | tabsMovable(false), | - | ||||||||||||
687 | #endif | - | ||||||||||||
688 | #ifndef QT_NO_TABWIDGET | - | ||||||||||||
689 | tabShape(QTabWidget::Rounded), | - | ||||||||||||
690 | tabPosition(QTabWidget::North), | - | ||||||||||||
691 | #endif | - | ||||||||||||
692 | ignoreGeometryChange(false), | - | ||||||||||||
693 | ignoreWindowStateChange(false), | - | ||||||||||||
694 | isActivated(false), | - | ||||||||||||
695 | isSubWindowsTiled(false), | - | ||||||||||||
696 | showActiveWindowMaximized(false), | - | ||||||||||||
697 | tileCalledFromResizeEvent(false), | - | ||||||||||||
698 | updatesDisabledByUs(false), | - | ||||||||||||
699 | inViewModeChange(false), | - | ||||||||||||
700 | indexToNextWindow(-1), | - | ||||||||||||
701 | indexToPreviousWindow(-1), | - | ||||||||||||
702 | indexToHighlighted(-1), | - | ||||||||||||
703 | indexToLastActiveTab(-1), | - | ||||||||||||
704 | resizeTimerId(-1), | - | ||||||||||||
705 | tabToPreviousTimerId(-1) | - | ||||||||||||
706 | { | - | ||||||||||||
707 | } | - | ||||||||||||
708 | - | |||||||||||||
709 | /*! | - | ||||||||||||
710 | \internal | - | ||||||||||||
711 | */ | - | ||||||||||||
712 | void QMdiAreaPrivate::_q_deactivateAllWindows(QMdiSubWindow *aboutToActivate) | - | ||||||||||||
713 | { | - | ||||||||||||
714 | if (ignoreWindowStateChange) | - | ||||||||||||
715 | return; | - | ||||||||||||
716 | - | |||||||||||||
717 | Q_Q(QMdiArea); | - | ||||||||||||
718 | if (!aboutToActivate) | - | ||||||||||||
719 | aboutToBecomeActive = qobject_cast<QMdiSubWindow *>(q->sender()); | - | ||||||||||||
720 | else | - | ||||||||||||
721 | aboutToBecomeActive = aboutToActivate; | - | ||||||||||||
722 | Q_ASSERT(aboutToBecomeActive); | - | ||||||||||||
723 | - | |||||||||||||
724 | foreach (QMdiSubWindow *child, childWindows) { | - | ||||||||||||
725 | if (!sanityCheck(child, "QMdiArea::deactivateAllWindows") || aboutToBecomeActive == child) | - | ||||||||||||
726 | continue; | - | ||||||||||||
727 | // We don't want to handle signals caused by child->showNormal(). | - | ||||||||||||
728 | ignoreWindowStateChange = true; | - | ||||||||||||
729 | if(!(options & QMdiArea::DontMaximizeSubWindowOnActivation) && !showActiveWindowMaximized) | - | ||||||||||||
730 | showActiveWindowMaximized = child->isMaximized() && child->isVisible(); | - | ||||||||||||
731 | if (showActiveWindowMaximized && child->isMaximized()) { | - | ||||||||||||
732 | if (q->updatesEnabled()) { | - | ||||||||||||
733 | updatesDisabledByUs = true; | - | ||||||||||||
734 | q->setUpdatesEnabled(false); | - | ||||||||||||
735 | } | - | ||||||||||||
736 | child->showNormal(); | - | ||||||||||||
737 | } | - | ||||||||||||
738 | if (child->isMinimized() && !child->isShaded() && !windowStaysOnTop(child)) | - | ||||||||||||
739 | child->lower(); | - | ||||||||||||
740 | ignoreWindowStateChange = false; | - | ||||||||||||
741 | child->d_func()->setActive(false); | - | ||||||||||||
742 | } | - | ||||||||||||
743 | } | - | ||||||||||||
744 | - | |||||||||||||
745 | /*! | - | ||||||||||||
746 | \internal | - | ||||||||||||
747 | */ | - | ||||||||||||
748 | void QMdiAreaPrivate::_q_processWindowStateChanged(Qt::WindowStates oldState, | - | ||||||||||||
749 | Qt::WindowStates newState) | - | ||||||||||||
750 | { | - | ||||||||||||
751 | if (ignoreWindowStateChange) | - | ||||||||||||
752 | return; | - | ||||||||||||
753 | - | |||||||||||||
754 | Q_Q(QMdiArea); | - | ||||||||||||
755 | QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(q->sender()); | - | ||||||||||||
756 | if (!child) | - | ||||||||||||
757 | return; | - | ||||||||||||
758 | - | |||||||||||||
759 | // windowActivated | - | ||||||||||||
760 | if (!(oldState & Qt::WindowActive) && (newState & Qt::WindowActive)) | - | ||||||||||||
761 | emitWindowActivated(child); | - | ||||||||||||
762 | // windowDeactivated | - | ||||||||||||
763 | else if ((oldState & Qt::WindowActive) && !(newState & Qt::WindowActive)) | - | ||||||||||||
764 | resetActiveWindow(child); | - | ||||||||||||
765 | - | |||||||||||||
766 | // windowMinimized | - | ||||||||||||
767 | if (!(oldState & Qt::WindowMinimized) && (newState & Qt::WindowMinimized)) { | - | ||||||||||||
768 | isSubWindowsTiled = false; | - | ||||||||||||
769 | arrangeMinimizedSubWindows(); | - | ||||||||||||
770 | // windowMaximized | - | ||||||||||||
771 | } else if (!(oldState & Qt::WindowMaximized) && (newState & Qt::WindowMaximized)) { | - | ||||||||||||
772 | internalRaise(child); | - | ||||||||||||
773 | // windowRestored | - | ||||||||||||
774 | } else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized))) { | - | ||||||||||||
775 | internalRaise(child); | - | ||||||||||||
776 | if (oldState & Qt::WindowMinimized) | - | ||||||||||||
777 | arrangeMinimizedSubWindows(); | - | ||||||||||||
778 | } | - | ||||||||||||
779 | } | - | ||||||||||||
780 | - | |||||||||||||
781 | void QMdiAreaPrivate::_q_currentTabChanged(int index) | - | ||||||||||||
782 | { | - | ||||||||||||
783 | #ifdef QT_NO_TABBAR | - | ||||||||||||
784 | Q_UNUSED(index); | - | ||||||||||||
785 | #else | - | ||||||||||||
786 | if (!tabBar || index < 0) | - | ||||||||||||
787 | return; | - | ||||||||||||
788 | - | |||||||||||||
789 | // If the previous active sub-window was hidden, disable the tab. | - | ||||||||||||
790 | if (indexToLastActiveTab >= 0 && indexToLastActiveTab < tabBar->count() | - | ||||||||||||
791 | && indexToLastActiveTab < childWindows.count()) { | - | ||||||||||||
792 | QMdiSubWindow *lastActive = childWindows.at(indexToLastActiveTab); | - | ||||||||||||
793 | if (lastActive && lastActive->isHidden()) | - | ||||||||||||
794 | tabBar->setTabEnabled(indexToLastActiveTab, false); | - | ||||||||||||
795 | } | - | ||||||||||||
796 | - | |||||||||||||
797 | indexToLastActiveTab = index; | - | ||||||||||||
798 | Q_ASSERT(childWindows.size() > index); | - | ||||||||||||
799 | QMdiSubWindow *subWindow = childWindows.at(index); | - | ||||||||||||
800 | Q_ASSERT(subWindow); | - | ||||||||||||
801 | activateWindow(subWindow); | - | ||||||||||||
802 | #endif // QT_NO_TABBAR | - | ||||||||||||
803 | } | - | ||||||||||||
804 | - | |||||||||||||
805 | void QMdiAreaPrivate::_q_closeTab(int index) | - | ||||||||||||
806 | { | - | ||||||||||||
807 | #ifdef QT_NO_TABBAR | - | ||||||||||||
808 | Q_UNUSED(index); | - | ||||||||||||
809 | #else | - | ||||||||||||
810 | QMdiSubWindow *subWindow = childWindows.at(index); | - | ||||||||||||
811 | Q_ASSERT(subWindow); | - | ||||||||||||
812 | subWindow->close(); | - | ||||||||||||
813 | #endif // QT_NO_TABBAR | - | ||||||||||||
814 | } | - | ||||||||||||
815 | - | |||||||||||||
816 | void QMdiAreaPrivate::_q_moveTab(int from, int to) | - | ||||||||||||
817 | { | - | ||||||||||||
818 | #ifdef QT_NO_TABBAR | - | ||||||||||||
819 | Q_UNUSED(from); | - | ||||||||||||
820 | Q_UNUSED(to); | - | ||||||||||||
821 | #else | - | ||||||||||||
822 | childWindows.move(from, to); | - | ||||||||||||
823 | #endif // QT_NO_TABBAR | - | ||||||||||||
824 | } | - | ||||||||||||
825 | - | |||||||||||||
826 | /*! | - | ||||||||||||
827 | \internal | - | ||||||||||||
828 | */ | - | ||||||||||||
829 | void QMdiAreaPrivate::appendChild(QMdiSubWindow *child) | - | ||||||||||||
830 | { | - | ||||||||||||
831 | Q_Q(QMdiArea); | - | ||||||||||||
832 | Q_ASSERT(child && childWindows.indexOf(child) == -1); | - | ||||||||||||
833 | - | |||||||||||||
834 | if (child->parent() != viewport) | - | ||||||||||||
835 | child->setParent(viewport, child->windowFlags()); | - | ||||||||||||
836 | childWindows.append(QPointer<QMdiSubWindow>(child)); | - | ||||||||||||
837 | - | |||||||||||||
838 | if (!child->testAttribute(Qt::WA_Resized) && q->isVisible()) { | - | ||||||||||||
839 | QSize newSize(child->sizeHint().boundedTo(viewport->size())); | - | ||||||||||||
840 | child->resize(newSize.expandedTo(qSmartMinSize(child))); | - | ||||||||||||
841 | } | - | ||||||||||||
842 | - | |||||||||||||
843 | if (!placer) | - | ||||||||||||
844 | placer = new MinOverlapPlacer; | - | ||||||||||||
845 | place(placer, child); | - | ||||||||||||
846 | - | |||||||||||||
847 | if (hbarpolicy != Qt::ScrollBarAlwaysOff) | - | ||||||||||||
848 | child->setOption(QMdiSubWindow::AllowOutsideAreaHorizontally, true); | - | ||||||||||||
849 | else | - | ||||||||||||
850 | child->setOption(QMdiSubWindow::AllowOutsideAreaHorizontally, false); | - | ||||||||||||
851 | - | |||||||||||||
852 | if (vbarpolicy != Qt::ScrollBarAlwaysOff) | - | ||||||||||||
853 | child->setOption(QMdiSubWindow::AllowOutsideAreaVertically, true); | - | ||||||||||||
854 | else | - | ||||||||||||
855 | child->setOption(QMdiSubWindow::AllowOutsideAreaVertically, false); | - | ||||||||||||
856 | - | |||||||||||||
857 | internalRaise(child); | - | ||||||||||||
858 | indicesToActivatedChildren.prepend(childWindows.size() - 1); | - | ||||||||||||
859 | Q_ASSERT(indicesToActivatedChildren.size() == childWindows.size()); | - | ||||||||||||
860 | - | |||||||||||||
861 | #ifndef QT_NO_TABBAR | - | ||||||||||||
862 | if (tabBar) { | - | ||||||||||||
863 | tabBar->addTab(child->windowIcon(), tabTextFor(child)); | - | ||||||||||||
864 | updateTabBarGeometry(); | - | ||||||||||||
865 | if (childWindows.count() == 1 && !(options & QMdiArea::DontMaximizeSubWindowOnActivation)) | - | ||||||||||||
866 | showActiveWindowMaximized = true; | - | ||||||||||||
867 | } | - | ||||||||||||
868 | #endif | - | ||||||||||||
869 | - | |||||||||||||
870 | if (!(child->windowFlags() & Qt::SubWindow)) | - | ||||||||||||
871 | child->setWindowFlags(Qt::SubWindow); | - | ||||||||||||
872 | child->installEventFilter(q); | - | ||||||||||||
873 | - | |||||||||||||
874 | QObject::connect(child, SIGNAL(aboutToActivate()), q, SLOT(_q_deactivateAllWindows())); | - | ||||||||||||
875 | QObject::connect(child, SIGNAL(windowStateChanged(Qt::WindowStates,Qt::WindowStates)), | - | ||||||||||||
876 | q, SLOT(_q_processWindowStateChanged(Qt::WindowStates,Qt::WindowStates))); | - | ||||||||||||
877 | } | - | ||||||||||||
878 | - | |||||||||||||
879 | /*! | - | ||||||||||||
880 | \internal | - | ||||||||||||
881 | */ | - | ||||||||||||
882 | void QMdiAreaPrivate::place(Placer *placer, QMdiSubWindow *child) | - | ||||||||||||
883 | { | - | ||||||||||||
884 | if (!placer || !child) | - | ||||||||||||
885 | return; | - | ||||||||||||
886 | - | |||||||||||||
887 | Q_Q(QMdiArea); | - | ||||||||||||
888 | if (!q->isVisible()) { | - | ||||||||||||
889 | // The window is only laid out when it's added to QMdiArea, | - | ||||||||||||
890 | // so there's no need to check that we don't have it in the | - | ||||||||||||
891 | // list already. appendChild() ensures that. | - | ||||||||||||
892 | pendingPlacements.append(child); | - | ||||||||||||
893 | return; | - | ||||||||||||
894 | } | - | ||||||||||||
895 | - | |||||||||||||
896 | QVector<QRect> rects; | - | ||||||||||||
897 | rects.reserve(childWindows.size()); | - | ||||||||||||
898 | QRect parentRect = q->rect(); | - | ||||||||||||
899 | foreach (QMdiSubWindow *window, childWindows) { | - | ||||||||||||
900 | if (!sanityCheck(window, "QMdiArea::place") || window == child || !window->isVisibleTo(q) | - | ||||||||||||
901 | || !window->testAttribute(Qt::WA_Moved)) { | - | ||||||||||||
902 | continue; | - | ||||||||||||
903 | } | - | ||||||||||||
904 | QRect occupiedGeometry; | - | ||||||||||||
905 | if (window->isMaximized()) { | - | ||||||||||||
906 | occupiedGeometry = QRect(window->d_func()->oldGeometry.topLeft(), | - | ||||||||||||
907 | window->d_func()->restoreSize); | - | ||||||||||||
908 | } else { | - | ||||||||||||
909 | occupiedGeometry = window->geometry(); | - | ||||||||||||
910 | } | - | ||||||||||||
911 | rects.append(QStyle::visualRect(child->layoutDirection(), parentRect, occupiedGeometry)); | - | ||||||||||||
912 | } | - | ||||||||||||
913 | QPoint newPos = placer->place(child->size(), rects, parentRect); | - | ||||||||||||
914 | QRect newGeometry = QRect(newPos.x(), newPos.y(), child->width(), child->height()); | - | ||||||||||||
915 | child->setGeometry(QStyle::visualRect(child->layoutDirection(), parentRect, newGeometry)); | - | ||||||||||||
916 | } | - | ||||||||||||
917 | - | |||||||||||||
918 | /*! | - | ||||||||||||
919 | \internal | - | ||||||||||||
920 | */ | - | ||||||||||||
921 | void QMdiAreaPrivate::rearrange(Rearranger *rearranger) | - | ||||||||||||
922 | { | - | ||||||||||||
923 | if (!rearranger)
| 0 | ||||||||||||
924 | return; never executed: return; | 0 | ||||||||||||
925 | - | |||||||||||||
926 | Q_Q(QMdiArea); | - | ||||||||||||
927 | if (!q->isVisible()) {
| 0 | ||||||||||||
928 | // Compress if we already have the rearranger in the list. | - | ||||||||||||
929 | int index = pendingRearrangements.indexOf(rearranger); | - | ||||||||||||
930 | if (index != -1)
| 0 | ||||||||||||
931 | pendingRearrangements.move(index, pendingRearrangements.size() - 1); never executed: pendingRearrangements.move(index, pendingRearrangements.size() - 1); | 0 | ||||||||||||
932 | else | - | ||||||||||||
933 | pendingRearrangements.append(rearranger); never executed: pendingRearrangements.append(rearranger); | 0 | ||||||||||||
934 | return; never executed: return; | 0 | ||||||||||||
935 | } | - | ||||||||||||
936 | - | |||||||||||||
937 | QList<QWidget *> widgets; | - | ||||||||||||
938 | const bool reverseList = rearranger->type() == Rearranger::RegularTiler; | - | ||||||||||||
939 | const QList<QMdiSubWindow *> subWindows = subWindowList(activationOrder, reverseList); | - | ||||||||||||
940 | QSize minSubWindowSize; | - | ||||||||||||
941 | foreach (QMdiSubWindow *child, subWindows) { | - | ||||||||||||
942 | if (!sanityCheck(child, "QMdiArea::rearrange") || !child->isVisible())
| 0 | ||||||||||||
943 | continue; never executed: continue; | 0 | ||||||||||||
944 | if (rearranger->type() == Rearranger::IconTiler) {
| 0 | ||||||||||||
945 | if (child->isMinimized() && !child->isShaded() && !(child->windowFlags() & Qt::FramelessWindowHint))())
| 0 | ||||||||||||
946 | widgets.append(child); never executed: widgets.append(child); | 0 | ||||||||||||
947 | } else { never executed: end of block | 0 | ||||||||||||
948 | if (child->isMinimized() && !child->isShaded())
| 0 | ||||||||||||
949 | continue; never executed: continue; | 0 | ||||||||||||
950 | if (child->isMaximized() || child->isShaded())
| 0 | ||||||||||||
951 | child->showNormal(); never executed: child->showNormal(); | 0 | ||||||||||||
952 | minSubWindowSize = minSubWindowSize.expandedTo(child->minimumSize()) | - | ||||||||||||
953 | .expandedTo(child->d_func()->internalMinimumSize); | - | ||||||||||||
954 | widgets.append(child); | - | ||||||||||||
955 | } never executed: end of block | 0 | ||||||||||||
956 | } | - | ||||||||||||
957 | - | |||||||||||||
958 | if (active && rearranger->type() == Rearranger::RegularTiler) {
| 0 | ||||||||||||
959 | // Move active window in front if necessary. That's the case if we | - | ||||||||||||
960 | // have any windows with staysOnTopHint set. | - | ||||||||||||
961 | int indexToActive = widgets.indexOf((QWidget *)active); | - | ||||||||||||
962 | if (indexToActive > 0)
| 0 | ||||||||||||
963 | widgets.move(indexToActive, 0); never executed: widgets.move(indexToActive, 0); | 0 | ||||||||||||
964 | } never executed: end of block | 0 | ||||||||||||
965 | - | |||||||||||||
966 | QRect domain = viewport->rect(); | - | ||||||||||||
967 | if (rearranger->type() == Rearranger::RegularTiler && !widgets.isEmpty())
| 0 | ||||||||||||
968 | domain = resizeToMinimumTileSize(minSubWindowSize, widgets.count()); never executed: domain = resizeToMinimumTileSize(minSubWindowSize, widgets.count()); | 0 | ||||||||||||
969 | - | |||||||||||||
970 | rearranger->rearrange(widgets, domain); | - | ||||||||||||
971 | - | |||||||||||||
972 | if (rearranger->type() == Rearranger::RegularTiler && !widgets.isEmpty()) {
| 0 | ||||||||||||
973 | isSubWindowsTiled = true; | - | ||||||||||||
974 | updateScrollBars(); | - | ||||||||||||
975 | } else if (rearranger->type() == Rearranger::SimpleCascader) { never executed: end of block
| 0 | ||||||||||||
976 | isSubWindowsTiled = false; | - | ||||||||||||
977 | } never executed: end of block | 0 | ||||||||||||
978 | } never executed: end of block | 0 | ||||||||||||
979 | - | |||||||||||||
980 | /*! | - | ||||||||||||
981 | \internal | - | ||||||||||||
982 | - | |||||||||||||
983 | Arranges all minimized windows at the bottom of the workspace. | - | ||||||||||||
984 | */ | - | ||||||||||||
985 | void QMdiAreaPrivate::arrangeMinimizedSubWindows() | - | ||||||||||||
986 | { | - | ||||||||||||
987 | if (!iconTiler) | - | ||||||||||||
988 | iconTiler = new IconTiler; | - | ||||||||||||
989 | rearrange(iconTiler); | - | ||||||||||||
990 | } | - | ||||||||||||
991 | - | |||||||||||||
992 | /*! | - | ||||||||||||
993 | \internal | - | ||||||||||||
994 | */ | - | ||||||||||||
995 | void QMdiAreaPrivate::activateWindow(QMdiSubWindow *child) | - | ||||||||||||
996 | { | - | ||||||||||||
997 | if (childWindows.isEmpty()) { | - | ||||||||||||
998 | Q_ASSERT(!child); | - | ||||||||||||
999 | Q_ASSERT(!active); | - | ||||||||||||
1000 | return; | - | ||||||||||||
1001 | } | - | ||||||||||||
1002 | - | |||||||||||||
1003 | if (!child) { | - | ||||||||||||
1004 | if (active) { | - | ||||||||||||
1005 | Q_ASSERT(active->d_func()->isActive); | - | ||||||||||||
1006 | active->d_func()->setActive(false); | - | ||||||||||||
1007 | resetActiveWindow(); | - | ||||||||||||
1008 | } | - | ||||||||||||
1009 | return; | - | ||||||||||||
1010 | } | - | ||||||||||||
1011 | - | |||||||||||||
1012 | if (child->isHidden() || child == active) | - | ||||||||||||
1013 | return; | - | ||||||||||||
1014 | child->d_func()->setActive(true); | - | ||||||||||||
1015 | } | - | ||||||||||||
1016 | - | |||||||||||||
1017 | /*! | - | ||||||||||||
1018 | \internal | - | ||||||||||||
1019 | */ | - | ||||||||||||
1020 | void QMdiAreaPrivate::activateCurrentWindow() | - | ||||||||||||
1021 | { | - | ||||||||||||
1022 | QMdiSubWindow *current = q_func()->currentSubWindow(); | - | ||||||||||||
1023 | if (current && !isExplicitlyDeactivated(current)) { | - | ||||||||||||
1024 | current->d_func()->activationEnabled = true; | - | ||||||||||||
1025 | current->d_func()->setActive(true, /*changeFocus=*/false); | - | ||||||||||||
1026 | } | - | ||||||||||||
1027 | } | - | ||||||||||||
1028 | - | |||||||||||||
1029 | void QMdiAreaPrivate::activateHighlightedWindow() | - | ||||||||||||
1030 | { | - | ||||||||||||
1031 | if (indexToHighlighted < 0) | - | ||||||||||||
1032 | return; | - | ||||||||||||
1033 | - | |||||||||||||
1034 | Q_ASSERT(indexToHighlighted < childWindows.size()); | - | ||||||||||||
1035 | if (tabToPreviousTimerId != -1) | - | ||||||||||||
1036 | activateWindow(nextVisibleSubWindow(-1, QMdiArea::ActivationHistoryOrder)); | - | ||||||||||||
1037 | else | - | ||||||||||||
1038 | activateWindow(childWindows.at(indexToHighlighted)); | - | ||||||||||||
1039 | #ifndef QT_NO_RUBBERBAND | - | ||||||||||||
1040 | hideRubberBand(); | - | ||||||||||||
1041 | #endif | - | ||||||||||||
1042 | } | - | ||||||||||||
1043 | - | |||||||||||||
1044 | /*! | - | ||||||||||||
1045 | \internal | - | ||||||||||||
1046 | */ | - | ||||||||||||
1047 | void QMdiAreaPrivate::emitWindowActivated(QMdiSubWindow *activeWindow) | - | ||||||||||||
1048 | { | - | ||||||||||||
1049 | Q_Q(QMdiArea); | - | ||||||||||||
1050 | Q_ASSERT(activeWindow); | - | ||||||||||||
1051 | if (activeWindow == active) | - | ||||||||||||
1052 | return; | - | ||||||||||||
1053 | Q_ASSERT(activeWindow->d_func()->isActive); | - | ||||||||||||
1054 | - | |||||||||||||
1055 | if (!aboutToBecomeActive) | - | ||||||||||||
1056 | _q_deactivateAllWindows(activeWindow); | - | ||||||||||||
1057 | Q_ASSERT(aboutToBecomeActive); | - | ||||||||||||
1058 | - | |||||||||||||
1059 | // This is true only if 'DontMaximizeSubWindowOnActivation' is disabled | - | ||||||||||||
1060 | // and the previous active window was maximized. | - | ||||||||||||
1061 | if (showActiveWindowMaximized) { | - | ||||||||||||
1062 | if (!activeWindow->isMaximized()) | - | ||||||||||||
1063 | activeWindow->showMaximized(); | - | ||||||||||||
1064 | showActiveWindowMaximized = false; | - | ||||||||||||
1065 | } | - | ||||||||||||
1066 | - | |||||||||||||
1067 | // Put in front to update activation order. | - | ||||||||||||
1068 | const int indexToActiveWindow = childWindows.indexOf(activeWindow); | - | ||||||||||||
1069 | Q_ASSERT(indexToActiveWindow != -1); | - | ||||||||||||
1070 | const int index = indicesToActivatedChildren.indexOf(indexToActiveWindow); | - | ||||||||||||
1071 | Q_ASSERT(index != -1); | - | ||||||||||||
1072 | indicesToActivatedChildren.move(index, 0); | - | ||||||||||||
1073 | internalRaise(activeWindow); | - | ||||||||||||
1074 | - | |||||||||||||
1075 | if (updatesDisabledByUs) { | - | ||||||||||||
1076 | q->setUpdatesEnabled(true); | - | ||||||||||||
1077 | updatesDisabledByUs = false; | - | ||||||||||||
1078 | } | - | ||||||||||||
1079 | - | |||||||||||||
1080 | Q_ASSERT(aboutToBecomeActive == activeWindow); | - | ||||||||||||
1081 | active = activeWindow; | - | ||||||||||||
1082 | aboutToBecomeActive = 0; | - | ||||||||||||
1083 | Q_ASSERT(active->d_func()->isActive); | - | ||||||||||||
1084 | - | |||||||||||||
1085 | #ifndef QT_NO_TABBAR | - | ||||||||||||
1086 | if (tabBar && tabBar->currentIndex() != indexToActiveWindow) | - | ||||||||||||
1087 | tabBar->setCurrentIndex(indexToActiveWindow); | - | ||||||||||||
1088 | #endif | - | ||||||||||||
1089 | - | |||||||||||||
1090 | if (active->isMaximized() && scrollBarsEnabled()) | - | ||||||||||||
1091 | updateScrollBars(); | - | ||||||||||||
1092 | - | |||||||||||||
1093 | emit q->subWindowActivated(active); | - | ||||||||||||
1094 | } | - | ||||||||||||
1095 | - | |||||||||||||
1096 | /*! | - | ||||||||||||
1097 | \internal | - | ||||||||||||
1098 | */ | - | ||||||||||||
1099 | void QMdiAreaPrivate::resetActiveWindow(QMdiSubWindow *deactivatedWindow) | - | ||||||||||||
1100 | { | - | ||||||||||||
1101 | Q_Q(QMdiArea); | - | ||||||||||||
1102 | if (deactivatedWindow) { | - | ||||||||||||
1103 | if (deactivatedWindow != active) | - | ||||||||||||
1104 | return; | - | ||||||||||||
1105 | active = 0; | - | ||||||||||||
1106 | if ((aboutToBecomeActive || isActivated || lastWindowAboutToBeDestroyed()) | - | ||||||||||||
1107 | && !isExplicitlyDeactivated(deactivatedWindow) && !q->window()->isMinimized()) { | - | ||||||||||||
1108 | return; | - | ||||||||||||
1109 | } | - | ||||||||||||
1110 | emit q->subWindowActivated(0); | - | ||||||||||||
1111 | return; | - | ||||||||||||
1112 | } | - | ||||||||||||
1113 | - | |||||||||||||
1114 | if (aboutToBecomeActive) | - | ||||||||||||
1115 | return; | - | ||||||||||||
1116 | - | |||||||||||||
1117 | active = 0; | - | ||||||||||||
1118 | emit q->subWindowActivated(0); | - | ||||||||||||
1119 | } | - | ||||||||||||
1120 | - | |||||||||||||
1121 | /*! | - | ||||||||||||
1122 | \internal | - | ||||||||||||
1123 | */ | - | ||||||||||||
1124 | void QMdiAreaPrivate::updateActiveWindow(int removedIndex, bool activeRemoved) | - | ||||||||||||
1125 | { | - | ||||||||||||
1126 | Q_ASSERT(indicesToActivatedChildren.size() == childWindows.size()); | - | ||||||||||||
1127 | - | |||||||||||||
1128 | #ifndef QT_NO_TABBAR | - | ||||||||||||
1129 | if (tabBar && removedIndex >= 0) { | - | ||||||||||||
1130 | const QSignalBlocker blocker(tabBar); | - | ||||||||||||
1131 | tabBar->removeTab(removedIndex); | - | ||||||||||||
1132 | updateTabBarGeometry(); | - | ||||||||||||
1133 | } | - | ||||||||||||
1134 | #endif | - | ||||||||||||
1135 | - | |||||||||||||
1136 | if (childWindows.isEmpty()) { | - | ||||||||||||
1137 | showActiveWindowMaximized = false; | - | ||||||||||||
1138 | resetActiveWindow(); | - | ||||||||||||
1139 | return; | - | ||||||||||||
1140 | } | - | ||||||||||||
1141 | - | |||||||||||||
1142 | if (indexToHighlighted >= 0) { | - | ||||||||||||
1143 | #ifndef QT_NO_RUBBERBAND | - | ||||||||||||
1144 | // Hide rubber band if highlighted window is removed. | - | ||||||||||||
1145 | if (indexToHighlighted == removedIndex) | - | ||||||||||||
1146 | hideRubberBand(); | - | ||||||||||||
1147 | else | - | ||||||||||||
1148 | #endif | - | ||||||||||||
1149 | // or update index if necessary. | - | ||||||||||||
1150 | if (indexToHighlighted > removedIndex) | - | ||||||||||||
1151 | --indexToHighlighted; | - | ||||||||||||
1152 | } | - | ||||||||||||
1153 | - | |||||||||||||
1154 | // Update indices list | - | ||||||||||||
1155 | for (int i = 0; i < indicesToActivatedChildren.size(); ++i) { | - | ||||||||||||
1156 | int *index = &indicesToActivatedChildren[i]; | - | ||||||||||||
1157 | if (*index > removedIndex) | - | ||||||||||||
1158 | --*index; | - | ||||||||||||
1159 | } | - | ||||||||||||
1160 | - | |||||||||||||
1161 | if (!activeRemoved) | - | ||||||||||||
1162 | return; | - | ||||||||||||
1163 | - | |||||||||||||
1164 | // Activate next window. | - | ||||||||||||
1165 | QMdiSubWindow *next = nextVisibleSubWindow(0, activationOrder, removedIndex); | - | ||||||||||||
1166 | if (next) | - | ||||||||||||
1167 | activateWindow(next); | - | ||||||||||||
1168 | } | - | ||||||||||||
1169 | - | |||||||||||||
1170 | /*! | - | ||||||||||||
1171 | \internal | - | ||||||||||||
1172 | */ | - | ||||||||||||
1173 | void QMdiAreaPrivate::updateScrollBars() | - | ||||||||||||
1174 | { | - | ||||||||||||
1175 | if (ignoreGeometryChange || !scrollBarsEnabled()) | - | ||||||||||||
1176 | return; | - | ||||||||||||
1177 | - | |||||||||||||
1178 | Q_Q(QMdiArea); | - | ||||||||||||
1179 | QSize maxSize = q->maximumViewportSize(); | - | ||||||||||||
1180 | QSize hbarExtent = hbar->sizeHint(); | - | ||||||||||||
1181 | QSize vbarExtent = vbar->sizeHint(); | - | ||||||||||||
1182 | - | |||||||||||||
1183 | if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, 0, q)) { | - | ||||||||||||
1184 | const int doubleFrameWidth = frameWidth * 2; | - | ||||||||||||
1185 | if (hbarpolicy == Qt::ScrollBarAlwaysOn) | - | ||||||||||||
1186 | maxSize.rheight() -= doubleFrameWidth; | - | ||||||||||||
1187 | if (vbarpolicy == Qt::ScrollBarAlwaysOn) | - | ||||||||||||
1188 | maxSize.rwidth() -= doubleFrameWidth; | - | ||||||||||||
1189 | hbarExtent.rheight() += doubleFrameWidth; | - | ||||||||||||
1190 | vbarExtent.rwidth() += doubleFrameWidth; | - | ||||||||||||
1191 | } | - | ||||||||||||
1192 | - | |||||||||||||
1193 | const QRect childrenRect = active && active->isMaximized() | - | ||||||||||||
1194 | ? active->geometry() : viewport->childrenRect(); | - | ||||||||||||
1195 | bool useHorizontalScrollBar = useScrollBar(childrenRect, maxSize, Qt::Horizontal); | - | ||||||||||||
1196 | bool useVerticalScrollBar = useScrollBar(childrenRect, maxSize, Qt::Vertical); | - | ||||||||||||
1197 | - | |||||||||||||
1198 | if (useHorizontalScrollBar && !useVerticalScrollBar) { | - | ||||||||||||
1199 | const QSize max = maxSize - QSize(0, hbarExtent.height()); | - | ||||||||||||
1200 | useVerticalScrollBar = useScrollBar(childrenRect, max, Qt::Vertical); | - | ||||||||||||
1201 | } | - | ||||||||||||
1202 | - | |||||||||||||
1203 | if (useVerticalScrollBar && !useHorizontalScrollBar) { | - | ||||||||||||
1204 | const QSize max = maxSize - QSize(vbarExtent.width(), 0); | - | ||||||||||||
1205 | useHorizontalScrollBar = useScrollBar(childrenRect, max, Qt::Horizontal); | - | ||||||||||||
1206 | } | - | ||||||||||||
1207 | - | |||||||||||||
1208 | if (useHorizontalScrollBar && hbarpolicy != Qt::ScrollBarAlwaysOn) | - | ||||||||||||
1209 | maxSize.rheight() -= hbarExtent.height(); | - | ||||||||||||
1210 | if (useVerticalScrollBar && vbarpolicy != Qt::ScrollBarAlwaysOn) | - | ||||||||||||
1211 | maxSize.rwidth() -= vbarExtent.width(); | - | ||||||||||||
1212 | - | |||||||||||||
1213 | QRect viewportRect(QPoint(0, 0), maxSize); | - | ||||||||||||
1214 | const int startX = q->isLeftToRight() ? childrenRect.left() : viewportRect.right() | - | ||||||||||||
1215 | - childrenRect.right(); | - | ||||||||||||
1216 | - | |||||||||||||
1217 | // Horizontal scroll bar. | - | ||||||||||||
1218 | if (isSubWindowsTiled && hbar->value() != 0) | - | ||||||||||||
1219 | hbar->setValue(0); | - | ||||||||||||
1220 | const int xOffset = startX + hbar->value(); | - | ||||||||||||
1221 | hbar->setRange(qMin(0, xOffset), | - | ||||||||||||
1222 | qMax(0, xOffset + childrenRect.width() - viewportRect.width())); | - | ||||||||||||
1223 | hbar->setPageStep(childrenRect.width()); | - | ||||||||||||
1224 | hbar->setSingleStep(childrenRect.width() / 20); | - | ||||||||||||
1225 | - | |||||||||||||
1226 | // Vertical scroll bar. | - | ||||||||||||
1227 | if (isSubWindowsTiled && vbar->value() != 0) | - | ||||||||||||
1228 | vbar->setValue(0); | - | ||||||||||||
1229 | const int yOffset = childrenRect.top() + vbar->value(); | - | ||||||||||||
1230 | vbar->setRange(qMin(0, yOffset), | - | ||||||||||||
1231 | qMax(0, yOffset + childrenRect.height() - viewportRect.height())); | - | ||||||||||||
1232 | vbar->setPageStep(childrenRect.height()); | - | ||||||||||||
1233 | vbar->setSingleStep(childrenRect.height() / 20); | - | ||||||||||||
1234 | } | - | ||||||||||||
1235 | - | |||||||||||||
1236 | /*! | - | ||||||||||||
1237 | \internal | - | ||||||||||||
1238 | */ | - | ||||||||||||
1239 | void QMdiAreaPrivate::internalRaise(QMdiSubWindow *mdiChild) const | - | ||||||||||||
1240 | { | - | ||||||||||||
1241 | if (!sanityCheck(mdiChild, "QMdiArea::internalRaise") || childWindows.size() < 2)
| 0 | ||||||||||||
1242 | return; never executed: return; | 0 | ||||||||||||
1243 | - | |||||||||||||
1244 | QMdiSubWindow *stackUnderChild = 0; | - | ||||||||||||
1245 | if (!windowStaysOnTop(mdiChild)) {
| 0 | ||||||||||||
1246 | foreachconst auto children = viewport->children(); // take a copy, as raising/stacking under changes the order | - | ||||||||||||
1247 | for (QObject *object , viewport->: children())) { | - | ||||||||||||
1248 | QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(object); | - | ||||||||||||
1249 | if (!child || !childWindows.contains(child))
| 0 | ||||||||||||
1250 | continue; never executed: continue; | 0 | ||||||||||||
1251 | if (!child->isHidden() && windowStaysOnTop(child)) {
| 0 | ||||||||||||
1252 | if (stackUnderChild)
| 0 | ||||||||||||
1253 | child->stackUnder(stackUnderChild); never executed: child->stackUnder(stackUnderChild); | 0 | ||||||||||||
1254 | else | - | ||||||||||||
1255 | child->raise(); never executed: child->raise(); | 0 | ||||||||||||
1256 | stackUnderChild = child; | - | ||||||||||||
1257 | } never executed: end of block | 0 | ||||||||||||
1258 | } never executed: end of block | 0 | ||||||||||||
1259 | } never executed: end of block | 0 | ||||||||||||
1260 | - | |||||||||||||
1261 | if (stackUnderChild)
| 0 | ||||||||||||
1262 | mdiChild->stackUnder(stackUnderChild); never executed: mdiChild->stackUnder(stackUnderChild); | 0 | ||||||||||||
1263 | else | - | ||||||||||||
1264 | mdiChild->raise(); never executed: mdiChild->raise(); | 0 | ||||||||||||
1265 | } | - | ||||||||||||
1266 | - | |||||||||||||
1267 | QRect QMdiAreaPrivate::resizeToMinimumTileSize(const QSize &minSubWindowSize, int subWindowCount) | - | ||||||||||||
1268 | { | - | ||||||||||||
1269 | Q_Q(QMdiArea); | - | ||||||||||||
1270 | if (!minSubWindowSize.isValid() || subWindowCount <= 0) | - | ||||||||||||
1271 | return viewport->rect(); | - | ||||||||||||
1272 | - | |||||||||||||
1273 | // Calculate minimum size. | - | ||||||||||||
1274 | const int columns = qMax(qCeil(qSqrt(qreal(subWindowCount))), 1); | - | ||||||||||||
1275 | const int rows = qMax((subWindowCount % columns) ? (subWindowCount / columns + 1) | - | ||||||||||||
1276 | : (subWindowCount / columns), 1); | - | ||||||||||||
1277 | const int minWidth = minSubWindowSize.width() * columns; | - | ||||||||||||
1278 | const int minHeight = minSubWindowSize.height() * rows; | - | ||||||||||||
1279 | - | |||||||||||||
1280 | // Increase area size if necessary. Scroll bars are provided if we're not able | - | ||||||||||||
1281 | // to resize to the minimum size. | - | ||||||||||||
1282 | if (!tileCalledFromResizeEvent) { | - | ||||||||||||
1283 | QWidget *topLevel = q; | - | ||||||||||||
1284 | // Find the topLevel for this area, either a real top-level or a sub-window. | - | ||||||||||||
1285 | while (topLevel && !topLevel->isWindow() && topLevel->windowType() != Qt::SubWindow) | - | ||||||||||||
1286 | topLevel = topLevel->parentWidget(); | - | ||||||||||||
1287 | // We don't want sub-subwindows to be placed at the edge, thus add 2 pixels. | - | ||||||||||||
1288 | int minAreaWidth = minWidth + left + right + 2; | - | ||||||||||||
1289 | int minAreaHeight = minHeight + top + bottom + 2; | - | ||||||||||||
1290 | if (hbar->isVisible()) | - | ||||||||||||
1291 | minAreaHeight += hbar->height(); | - | ||||||||||||
1292 | if (vbar->isVisible()) | - | ||||||||||||
1293 | minAreaWidth += vbar->width(); | - | ||||||||||||
1294 | if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, 0, q)) { | - | ||||||||||||
1295 | const int frame = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, q); | - | ||||||||||||
1296 | minAreaWidth += 2 * frame; | - | ||||||||||||
1297 | minAreaHeight += 2 * frame; | - | ||||||||||||
1298 | } | - | ||||||||||||
1299 | const QSize diff = QSize(minAreaWidth, minAreaHeight).expandedTo(q->size()) - q->size(); | - | ||||||||||||
1300 | topLevel->resize(topLevel->size() + diff); | - | ||||||||||||
1301 | } | - | ||||||||||||
1302 | - | |||||||||||||
1303 | QRect domain = viewport->rect(); | - | ||||||||||||
1304 | - | |||||||||||||
1305 | // Adjust domain width and provide horizontal scroll bar. | - | ||||||||||||
1306 | if (domain.width() < minWidth) { | - | ||||||||||||
1307 | domain.setWidth(minWidth); | - | ||||||||||||
1308 | if (hbarpolicy == Qt::ScrollBarAlwaysOff) | - | ||||||||||||
1309 | q->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); | - | ||||||||||||
1310 | else | - | ||||||||||||
1311 | hbar->setValue(0); | - | ||||||||||||
1312 | } | - | ||||||||||||
1313 | // Adjust domain height and provide vertical scroll bar. | - | ||||||||||||
1314 | if (domain.height() < minHeight) { | - | ||||||||||||
1315 | domain.setHeight(minHeight); | - | ||||||||||||
1316 | if (vbarpolicy == Qt::ScrollBarAlwaysOff) | - | ||||||||||||
1317 | q->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); | - | ||||||||||||
1318 | else | - | ||||||||||||
1319 | vbar->setValue(0); | - | ||||||||||||
1320 | } | - | ||||||||||||
1321 | return domain; | - | ||||||||||||
1322 | } | - | ||||||||||||
1323 | - | |||||||||||||
1324 | /*! | - | ||||||||||||
1325 | \internal | - | ||||||||||||
1326 | */ | - | ||||||||||||
1327 | bool QMdiAreaPrivate::scrollBarsEnabled() const | - | ||||||||||||
1328 | { | - | ||||||||||||
1329 | return hbarpolicy != Qt::ScrollBarAlwaysOff || vbarpolicy != Qt::ScrollBarAlwaysOff; | - | ||||||||||||
1330 | } | - | ||||||||||||
1331 | - | |||||||||||||
1332 | /*! | - | ||||||||||||
1333 | \internal | - | ||||||||||||
1334 | */ | - | ||||||||||||
1335 | bool QMdiAreaPrivate::lastWindowAboutToBeDestroyed() const | - | ||||||||||||
1336 | { | - | ||||||||||||
1337 | if (childWindows.count() != 1) | - | ||||||||||||
1338 | return false; | - | ||||||||||||
1339 | - | |||||||||||||
1340 | QMdiSubWindow *last = childWindows.at(0); | - | ||||||||||||
1341 | if (!last) | - | ||||||||||||
1342 | return true; | - | ||||||||||||
1343 | - | |||||||||||||
1344 | if (!last->testAttribute(Qt::WA_DeleteOnClose)) | - | ||||||||||||
1345 | return false; | - | ||||||||||||
1346 | - | |||||||||||||
1347 | return last->d_func()->data.is_closing; | - | ||||||||||||
1348 | } | - | ||||||||||||
1349 | - | |||||||||||||
1350 | /*! | - | ||||||||||||
1351 | \internal | - | ||||||||||||
1352 | */ | - | ||||||||||||
1353 | void QMdiAreaPrivate::setChildActivationEnabled(bool enable, bool onlyNextActivationEvent) const | - | ||||||||||||
1354 | { | - | ||||||||||||
1355 | foreach (QMdiSubWindow *subWindow, childWindows) { | - | ||||||||||||
1356 | if (!subWindow || !subWindow->isVisible()) | - | ||||||||||||
1357 | continue; | - | ||||||||||||
1358 | if (onlyNextActivationEvent) | - | ||||||||||||
1359 | subWindow->d_func()->ignoreNextActivationEvent = !enable; | - | ||||||||||||
1360 | else | - | ||||||||||||
1361 | subWindow->d_func()->activationEnabled = enable; | - | ||||||||||||
1362 | } | - | ||||||||||||
1363 | } | - | ||||||||||||
1364 | - | |||||||||||||
1365 | /*! | - | ||||||||||||
1366 | \internal | - | ||||||||||||
1367 | \reimp | - | ||||||||||||
1368 | */ | - | ||||||||||||
1369 | void QMdiAreaPrivate::scrollBarPolicyChanged(Qt::Orientation orientation, Qt::ScrollBarPolicy policy) | - | ||||||||||||
1370 | { | - | ||||||||||||
1371 | if (childWindows.isEmpty()) | - | ||||||||||||
1372 | return; | - | ||||||||||||
1373 | - | |||||||||||||
1374 | const QMdiSubWindow::SubWindowOption option = orientation == Qt::Horizontal ? | - | ||||||||||||
1375 | QMdiSubWindow::AllowOutsideAreaHorizontally : QMdiSubWindow::AllowOutsideAreaVertically; | - | ||||||||||||
1376 | const bool enable = policy != Qt::ScrollBarAlwaysOff; | - | ||||||||||||
1377 | foreach (QMdiSubWindow *child, childWindows) { | - | ||||||||||||
1378 | if (!sanityCheck(child, "QMdiArea::scrollBarPolicyChanged")) | - | ||||||||||||
1379 | continue; | - | ||||||||||||
1380 | child->setOption(option, enable); | - | ||||||||||||
1381 | } | - | ||||||||||||
1382 | updateScrollBars(); | - | ||||||||||||
1383 | } | - | ||||||||||||
1384 | - | |||||||||||||
1385 | QList<QMdiSubWindow*> | - | ||||||||||||
1386 | QMdiAreaPrivate::subWindowList(QMdiArea::WindowOrder order, bool reversed) const | - | ||||||||||||
1387 | { | - | ||||||||||||
1388 | QList<QMdiSubWindow *> list; | - | ||||||||||||
1389 | if (childWindows.isEmpty())
| 0 | ||||||||||||
1390 | return list; never executed: return list; | 0 | ||||||||||||
1391 | - | |||||||||||||
1392 | if (order == QMdiArea::CreationOrder) {
| 0 | ||||||||||||
1393 | foreach (QMdiSubWindow *child, childWindows) { | - | ||||||||||||
1394 | if (!child)
| 0 | ||||||||||||
1395 | continue; never executed: continue; | 0 | ||||||||||||
1396 | if (!reversed)
| 0 | ||||||||||||
1397 | list.append(child); never executed: list.append(child); | 0 | ||||||||||||
1398 | else | - | ||||||||||||
1399 | list.prepend(child); never executed: list.prepend(child); | 0 | ||||||||||||
1400 | } | - | ||||||||||||
1401 | } else if (order == QMdiArea::StackingOrder) { never executed: end of block
| 0 | ||||||||||||
1402 | foreachfor (QObject *object ,: viewport->children()) { | - | ||||||||||||
1403 | QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(object); | - | ||||||||||||
1404 | if (!child || !childWindows.contains(child))
| 0 | ||||||||||||
1405 | continue; never executed: continue; | 0 | ||||||||||||
1406 | if (!reversed)
| 0 | ||||||||||||
1407 | list.append(child); never executed: list.append(child); | 0 | ||||||||||||
1408 | else | - | ||||||||||||
1409 | list.prepend(child); never executed: list.prepend(child); | 0 | ||||||||||||
1410 | } | - | ||||||||||||
1411 | } else { // ActivationHistoryOrder never executed: end of block | 0 | ||||||||||||
1412 | Q_ASSERT(indicesToActivatedChildren.size() == childWindows.size()); | - | ||||||||||||
1413 | for (int i = indicesToActivatedChildren.count() - 1; i >= 0; --i) {
| 0 | ||||||||||||
1414 | QMdiSubWindow *child = childWindows.at(indicesToActivatedChildren.at(i)); | - | ||||||||||||
1415 | if (!child)
| 0 | ||||||||||||
1416 | continue; never executed: continue; | 0 | ||||||||||||
1417 | if (!reversed)
| 0 | ||||||||||||
1418 | list.append(child); never executed: list.append(child); | 0 | ||||||||||||
1419 | else | - | ||||||||||||
1420 | list.prepend(child); never executed: list.prepend(child); | 0 | ||||||||||||
1421 | } | - | ||||||||||||
1422 | } never executed: end of block | 0 | ||||||||||||
1423 | return list; never executed: return list; | 0 | ||||||||||||
1424 | } | - | ||||||||||||
1425 | - | |||||||||||||
1426 | /*! | - | ||||||||||||
1427 | \internal | - | ||||||||||||
1428 | */ | - | ||||||||||||
1429 | void QMdiAreaPrivate::disconnectSubWindow(QObject *subWindow) | - | ||||||||||||
1430 | { | - | ||||||||||||
1431 | if (!subWindow) | - | ||||||||||||
1432 | return; | - | ||||||||||||
1433 | - | |||||||||||||
1434 | Q_Q(QMdiArea); | - | ||||||||||||
1435 | QObject::disconnect(subWindow, 0, q, 0); | - | ||||||||||||
1436 | subWindow->removeEventFilter(q); | - | ||||||||||||
1437 | } | - | ||||||||||||
1438 | - | |||||||||||||
1439 | /*! | - | ||||||||||||
1440 | \internal | - | ||||||||||||
1441 | */ | - | ||||||||||||
1442 | QMdiSubWindow *QMdiAreaPrivate::nextVisibleSubWindow(int increaseFactor, QMdiArea::WindowOrder order, | - | ||||||||||||
1443 | int removedIndex, int fromIndex) const | - | ||||||||||||
1444 | { | - | ||||||||||||
1445 | if (childWindows.isEmpty()) | - | ||||||||||||
1446 | return 0; | - | ||||||||||||
1447 | - | |||||||||||||
1448 | Q_Q(const QMdiArea); | - | ||||||||||||
1449 | const QList<QMdiSubWindow *> subWindows = q->subWindowList(order); | - | ||||||||||||
1450 | QMdiSubWindow *current = 0; | - | ||||||||||||
1451 | - | |||||||||||||
1452 | if (removedIndex < 0) { | - | ||||||||||||
1453 | if (fromIndex >= 0 && fromIndex < subWindows.size()) | - | ||||||||||||
1454 | current = childWindows.at(fromIndex); | - | ||||||||||||
1455 | else | - | ||||||||||||
1456 | current = q->currentSubWindow(); | - | ||||||||||||
1457 | } | - | ||||||||||||
1458 | - | |||||||||||||
1459 | // There's no current sub-window (removed or deactivated), | - | ||||||||||||
1460 | // so we have to pick the last active or the next in creation order. | - | ||||||||||||
1461 | if (!current) { | - | ||||||||||||
1462 | if (removedIndex >= 0 && order == QMdiArea::CreationOrder) { | - | ||||||||||||
1463 | int candidateIndex = -1; | - | ||||||||||||
1464 | setIndex(&candidateIndex, removedIndex, 0, subWindows.size() - 1, true); | - | ||||||||||||
1465 | current = childWindows.at(candidateIndex); | - | ||||||||||||
1466 | } else { | - | ||||||||||||
1467 | current = subWindows.back(); | - | ||||||||||||
1468 | } | - | ||||||||||||
1469 | } | - | ||||||||||||
1470 | Q_ASSERT(current); | - | ||||||||||||
1471 | - | |||||||||||||
1472 | // Find the index for the current sub-window in the given activation order | - | ||||||||||||
1473 | const int indexToCurrent = subWindows.indexOf(current); | - | ||||||||||||
1474 | const bool increasing = increaseFactor > 0; | - | ||||||||||||
1475 | - | |||||||||||||
1476 | // and use that index + increseFactor as a candidate. | - | ||||||||||||
1477 | int index = -1; | - | ||||||||||||
1478 | setIndex(&index, indexToCurrent + increaseFactor, 0, subWindows.size() - 1, increasing); | - | ||||||||||||
1479 | Q_ASSERT(index != -1); | - | ||||||||||||
1480 | - | |||||||||||||
1481 | // Try to find another window if the candidate is hidden. | - | ||||||||||||
1482 | while (subWindows.at(index)->isHidden()) { | - | ||||||||||||
1483 | setIndex(&index, index + increaseFactor, 0, subWindows.size() - 1, increasing); | - | ||||||||||||
1484 | if (index == indexToCurrent) | - | ||||||||||||
1485 | break; | - | ||||||||||||
1486 | } | - | ||||||||||||
1487 | - | |||||||||||||
1488 | if (!subWindows.at(index)->isHidden()) | - | ||||||||||||
1489 | return subWindows.at(index); | - | ||||||||||||
1490 | return 0; | - | ||||||||||||
1491 | } | - | ||||||||||||
1492 | - | |||||||||||||
1493 | /*! | - | ||||||||||||
1494 | \internal | - | ||||||||||||
1495 | */ | - | ||||||||||||
1496 | void QMdiAreaPrivate::highlightNextSubWindow(int increaseFactor) | - | ||||||||||||
1497 | { | - | ||||||||||||
1498 | if (childWindows.size() == 1) | - | ||||||||||||
1499 | return; | - | ||||||||||||
1500 | - | |||||||||||||
1501 | Q_Q(QMdiArea); | - | ||||||||||||
1502 | // There's no highlighted sub-window atm, use current. | - | ||||||||||||
1503 | if (indexToHighlighted < 0) { | - | ||||||||||||
1504 | QMdiSubWindow *current = q->currentSubWindow(); | - | ||||||||||||
1505 | if (!current) | - | ||||||||||||
1506 | return; | - | ||||||||||||
1507 | indexToHighlighted = childWindows.indexOf(current); | - | ||||||||||||
1508 | } | - | ||||||||||||
1509 | - | |||||||||||||
1510 | Q_ASSERT(indexToHighlighted >= 0); | - | ||||||||||||
1511 | Q_ASSERT(indexToHighlighted < childWindows.size()); | - | ||||||||||||
1512 | - | |||||||||||||
1513 | QMdiSubWindow *highlight = nextVisibleSubWindow(increaseFactor, activationOrder, -1, indexToHighlighted); | - | ||||||||||||
1514 | if (!highlight) | - | ||||||||||||
1515 | return; | - | ||||||||||||
1516 | - | |||||||||||||
1517 | #ifndef QT_NO_RUBBERBAND | - | ||||||||||||
1518 | if (!rubberBand) { | - | ||||||||||||
1519 | rubberBand = new QRubberBand(QRubberBand::Rectangle, q); | - | ||||||||||||
1520 | // For accessibility to identify this special widget. | - | ||||||||||||
1521 | rubberBand->setObjectName(QLatin1String("qt_rubberband")); | - | ||||||||||||
1522 | rubberBand->setWindowFlags(rubberBand->windowFlags() | Qt::WindowStaysOnTopHint); | - | ||||||||||||
1523 | } | - | ||||||||||||
1524 | #endif | - | ||||||||||||
1525 | - | |||||||||||||
1526 | // Only highlight if we're not switching back to the previously active window (Ctrl-Tab once). | - | ||||||||||||
1527 | #ifndef QT_NO_RUBBERBAND | - | ||||||||||||
1528 | if (tabToPreviousTimerId == -1) | - | ||||||||||||
1529 | showRubberBandFor(highlight); | - | ||||||||||||
1530 | #endif | - | ||||||||||||
1531 | - | |||||||||||||
1532 | indexToHighlighted = childWindows.indexOf(highlight); | - | ||||||||||||
1533 | Q_ASSERT(indexToHighlighted >= 0); | - | ||||||||||||
1534 | } | - | ||||||||||||
1535 | - | |||||||||||||
1536 | void QMdiAreaPrivate::showRubberBandFor(QMdiSubWindow *subWindow) | - | ||||||||||||
1537 | { | - | ||||||||||||
1538 | if (!subWindow || !rubberBand) | - | ||||||||||||
1539 | return; | - | ||||||||||||
1540 | - | |||||||||||||
1541 | if (viewMode == QMdiArea::TabbedView) | - | ||||||||||||
1542 | rubberBand->setGeometry(tabBar->tabRect(childWindows.indexOf(subWindow))); | - | ||||||||||||
1543 | else | - | ||||||||||||
1544 | rubberBand->setGeometry(subWindow->geometry()); | - | ||||||||||||
1545 | - | |||||||||||||
1546 | rubberBand->raise(); | - | ||||||||||||
1547 | rubberBand->show(); | - | ||||||||||||
1548 | } | - | ||||||||||||
1549 | - | |||||||||||||
1550 | /*! | - | ||||||||||||
1551 | \internal | - | ||||||||||||
1552 | \since 4.4 | - | ||||||||||||
1553 | */ | - | ||||||||||||
1554 | void QMdiAreaPrivate::setViewMode(QMdiArea::ViewMode mode) | - | ||||||||||||
1555 | { | - | ||||||||||||
1556 | Q_Q(QMdiArea); | - | ||||||||||||
1557 | if (viewMode == mode || inViewModeChange) | - | ||||||||||||
1558 | return; | - | ||||||||||||
1559 | - | |||||||||||||
1560 | // Just a guard since we cannot set viewMode = mode here. | - | ||||||||||||
1561 | inViewModeChange = true; | - | ||||||||||||
1562 | - | |||||||||||||
1563 | #ifndef QT_NO_TABBAR | - | ||||||||||||
1564 | if (mode == QMdiArea::TabbedView) { | - | ||||||||||||
1565 | Q_ASSERT(!tabBar); | - | ||||||||||||
1566 | tabBar = new QMdiAreaTabBar(q); | - | ||||||||||||
1567 | tabBar->setDocumentMode(documentMode); | - | ||||||||||||
1568 | tabBar->setTabsClosable(tabsClosable); | - | ||||||||||||
1569 | tabBar->setMovable(tabsMovable); | - | ||||||||||||
1570 | #ifndef QT_NO_TABWIDGET | - | ||||||||||||
1571 | tabBar->setShape(tabBarShapeFrom(tabShape, tabPosition)); | - | ||||||||||||
1572 | #endif | - | ||||||||||||
1573 | - | |||||||||||||
1574 | isSubWindowsTiled = false; | - | ||||||||||||
1575 | - | |||||||||||||
1576 | foreach (QMdiSubWindow *subWindow, childWindows) | - | ||||||||||||
1577 | tabBar->addTab(subWindow->windowIcon(), tabTextFor(subWindow)); | - | ||||||||||||
1578 | - | |||||||||||||
1579 | QMdiSubWindow *current = q->currentSubWindow(); | - | ||||||||||||
1580 | if (current) { | - | ||||||||||||
1581 | tabBar->setCurrentIndex(childWindows.indexOf(current)); | - | ||||||||||||
1582 | // Restore sub-window (i.e. cleanup buttons in menu bar and window title). | - | ||||||||||||
1583 | if (current->isMaximized()) | - | ||||||||||||
1584 | current->showNormal(); | - | ||||||||||||
1585 | - | |||||||||||||
1586 | viewMode = mode; | - | ||||||||||||
1587 | - | |||||||||||||
1588 | // Now, maximize it. | - | ||||||||||||
1589 | if (!q->testOption(QMdiArea::DontMaximizeSubWindowOnActivation)) { | - | ||||||||||||
1590 | current->showMaximized(); | - | ||||||||||||
1591 | } | - | ||||||||||||
1592 | } else { | - | ||||||||||||
1593 | viewMode = mode; | - | ||||||||||||
1594 | } | - | ||||||||||||
1595 | - | |||||||||||||
1596 | if (q->isVisible()) | - | ||||||||||||
1597 | tabBar->show(); | - | ||||||||||||
1598 | updateTabBarGeometry(); | - | ||||||||||||
1599 | - | |||||||||||||
1600 | QObject::connect(tabBar, SIGNAL(currentChanged(int)), q, SLOT(_q_currentTabChanged(int))); | - | ||||||||||||
1601 | QObject::connect(tabBar, SIGNAL(tabCloseRequested(int)), q, SLOT(_q_closeTab(int))); | - | ||||||||||||
1602 | QObject::connect(tabBar, SIGNAL(tabMoved(int,int)), q, SLOT(_q_moveTab(int,int))); | - | ||||||||||||
1603 | } else | - | ||||||||||||
1604 | #endif // QT_NO_TABBAR | - | ||||||||||||
1605 | { // SubWindowView | - | ||||||||||||
1606 | #ifndef QT_NO_TABBAR | - | ||||||||||||
1607 | delete tabBar; | - | ||||||||||||
1608 | tabBar = 0; | - | ||||||||||||
1609 | #endif // QT_NO_TABBAR | - | ||||||||||||
1610 | - | |||||||||||||
1611 | viewMode = mode; | - | ||||||||||||
1612 | q->setViewportMargins(0, 0, 0, 0); | - | ||||||||||||
1613 | indexToLastActiveTab = -1; | - | ||||||||||||
1614 | - | |||||||||||||
1615 | QMdiSubWindow *current = q->currentSubWindow(); | - | ||||||||||||
1616 | if (current && current->isMaximized()) | - | ||||||||||||
1617 | current->showNormal(); | - | ||||||||||||
1618 | } | - | ||||||||||||
1619 | - | |||||||||||||
1620 | Q_ASSERT(viewMode == mode); | - | ||||||||||||
1621 | inViewModeChange = false; | - | ||||||||||||
1622 | } | - | ||||||||||||
1623 | - | |||||||||||||
1624 | #ifndef QT_NO_TABBAR | - | ||||||||||||
1625 | /*! | - | ||||||||||||
1626 | \internal | - | ||||||||||||
1627 | */ | - | ||||||||||||
1628 | void QMdiAreaPrivate::updateTabBarGeometry() | - | ||||||||||||
1629 | { | - | ||||||||||||
1630 | if (!tabBar) | - | ||||||||||||
1631 | return; | - | ||||||||||||
1632 | - | |||||||||||||
1633 | Q_Q(QMdiArea); | - | ||||||||||||
1634 | #ifndef QT_NO_TABWIDGET | - | ||||||||||||
1635 | Q_ASSERT(tabBarShapeFrom(tabShape, tabPosition) == tabBar->shape()); | - | ||||||||||||
1636 | #endif | - | ||||||||||||
1637 | const QSize tabBarSizeHint = tabBar->sizeHint(); | - | ||||||||||||
1638 | - | |||||||||||||
1639 | int areaHeight = q->height(); | - | ||||||||||||
1640 | if (hbar && hbar->isVisible()) | - | ||||||||||||
1641 | areaHeight -= hbar->height(); | - | ||||||||||||
1642 | - | |||||||||||||
1643 | int areaWidth = q->width(); | - | ||||||||||||
1644 | if (vbar && vbar->isVisible()) | - | ||||||||||||
1645 | areaWidth -= vbar->width(); | - | ||||||||||||
1646 | - | |||||||||||||
1647 | QRect tabBarRect; | - | ||||||||||||
1648 | #ifndef QT_NO_TABWIDGET | - | ||||||||||||
1649 | switch (tabPosition) { | - | ||||||||||||
1650 | case QTabWidget::North: | - | ||||||||||||
1651 | q->setViewportMargins(0, tabBarSizeHint.height(), 0, 0); | - | ||||||||||||
1652 | tabBarRect = QRect(0, 0, areaWidth, tabBarSizeHint.height()); | - | ||||||||||||
1653 | break; | - | ||||||||||||
1654 | case QTabWidget::South: | - | ||||||||||||
1655 | q->setViewportMargins(0, 0, 0, tabBarSizeHint.height()); | - | ||||||||||||
1656 | tabBarRect = QRect(0, areaHeight - tabBarSizeHint.height(), areaWidth, tabBarSizeHint.height()); | - | ||||||||||||
1657 | break; | - | ||||||||||||
1658 | case QTabWidget::East: | - | ||||||||||||
1659 | if (q->layoutDirection() == Qt::LeftToRight) | - | ||||||||||||
1660 | q->setViewportMargins(0, 0, tabBarSizeHint.width(), 0); | - | ||||||||||||
1661 | else | - | ||||||||||||
1662 | q->setViewportMargins(tabBarSizeHint.width(), 0, 0, 0); | - | ||||||||||||
1663 | tabBarRect = QRect(areaWidth - tabBarSizeHint.width(), 0, tabBarSizeHint.width(), areaHeight); | - | ||||||||||||
1664 | break; | - | ||||||||||||
1665 | case QTabWidget::West: | - | ||||||||||||
1666 | if (q->layoutDirection() == Qt::LeftToRight) | - | ||||||||||||
1667 | q->setViewportMargins(tabBarSizeHint.width(), 0, 0, 0); | - | ||||||||||||
1668 | else | - | ||||||||||||
1669 | q->setViewportMargins(0, 0, tabBarSizeHint.width(), 0); | - | ||||||||||||
1670 | tabBarRect = QRect(0, 0, tabBarSizeHint.width(), areaHeight); | - | ||||||||||||
1671 | break; | - | ||||||||||||
1672 | default: | - | ||||||||||||
1673 | break; | - | ||||||||||||
1674 | } | - | ||||||||||||
1675 | #endif // QT_NO_TABWIDGET | - | ||||||||||||
1676 | - | |||||||||||||
1677 | tabBar->setGeometry(QStyle::visualRect(q->layoutDirection(), q->contentsRect(), tabBarRect)); | - | ||||||||||||
1678 | } | - | ||||||||||||
1679 | - | |||||||||||||
1680 | /*! | - | ||||||||||||
1681 | \internal | - | ||||||||||||
1682 | */ | - | ||||||||||||
1683 | void QMdiAreaPrivate::refreshTabBar() | - | ||||||||||||
1684 | { | - | ||||||||||||
1685 | if (!tabBar) | - | ||||||||||||
1686 | return; | - | ||||||||||||
1687 | - | |||||||||||||
1688 | tabBar->setDocumentMode(documentMode); | - | ||||||||||||
1689 | tabBar->setTabsClosable(tabsClosable); | - | ||||||||||||
1690 | tabBar->setMovable(tabsMovable); | - | ||||||||||||
1691 | #ifndef QT_NO_TABWIDGET | - | ||||||||||||
1692 | tabBar->setShape(tabBarShapeFrom(tabShape, tabPosition)); | - | ||||||||||||
1693 | #endif | - | ||||||||||||
1694 | updateTabBarGeometry(); | - | ||||||||||||
1695 | } | - | ||||||||||||
1696 | #endif // QT_NO_TABBAR | - | ||||||||||||
1697 | - | |||||||||||||
1698 | /*! | - | ||||||||||||
1699 | Constructs an empty mdi area. \a parent is passed to QWidget's | - | ||||||||||||
1700 | constructor. | - | ||||||||||||
1701 | */ | - | ||||||||||||
1702 | QMdiArea::QMdiArea(QWidget *parent) | - | ||||||||||||
1703 | : QAbstractScrollArea(*new QMdiAreaPrivate, parent) | - | ||||||||||||
1704 | { | - | ||||||||||||
1705 | setBackground(palette().brush(QPalette::Dark)); | - | ||||||||||||
1706 | setFrameStyle(QFrame::NoFrame); | - | ||||||||||||
1707 | setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | - | ||||||||||||
1708 | setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | - | ||||||||||||
1709 | setViewport(0); | - | ||||||||||||
1710 | setFocusPolicy(Qt::NoFocus); | - | ||||||||||||
1711 | QApplication::instance()->installEventFilter(this); | - | ||||||||||||
1712 | } | - | ||||||||||||
1713 | - | |||||||||||||
1714 | /*! | - | ||||||||||||
1715 | Destroys the MDI area. | - | ||||||||||||
1716 | */ | - | ||||||||||||
1717 | QMdiArea::~QMdiArea() | - | ||||||||||||
1718 | { | - | ||||||||||||
1719 | Q_D(QMdiArea); | - | ||||||||||||
1720 | delete d->cascader; | - | ||||||||||||
1721 | d->cascader = 0; | - | ||||||||||||
1722 | - | |||||||||||||
1723 | delete d->regularTiler; | - | ||||||||||||
1724 | d->regularTiler = 0; | - | ||||||||||||
1725 | - | |||||||||||||
1726 | delete d->iconTiler; | - | ||||||||||||
1727 | d->iconTiler = 0; | - | ||||||||||||
1728 | - | |||||||||||||
1729 | delete d->placer; | - | ||||||||||||
1730 | d->placer = 0; | - | ||||||||||||
1731 | } | - | ||||||||||||
1732 | - | |||||||||||||
1733 | /*! | - | ||||||||||||
1734 | \reimp | - | ||||||||||||
1735 | */ | - | ||||||||||||
1736 | QSize QMdiArea::sizeHint() const | - | ||||||||||||
1737 | { | - | ||||||||||||
1738 | // Calculate a proper scale factor for QDesktopWidget::size(). | - | ||||||||||||
1739 | // This also takes into account that we can have nested workspaces. | - | ||||||||||||
1740 | int nestedCount = 0; | - | ||||||||||||
1741 | QWidget *widget = this->parentWidget(); | - | ||||||||||||
1742 | while (widget) {
| 0 | ||||||||||||
1743 | if (qobject_cast<QMdiArea *>(widget))
| 0 | ||||||||||||
1744 | ++nestedCount; never executed: ++nestedCount; | 0 | ||||||||||||
1745 | widget = widget->parentWidget(); | - | ||||||||||||
1746 | } never executed: end of block | 0 | ||||||||||||
1747 | const int scaleFactor = 3 * (nestedCount + 1); | - | ||||||||||||
1748 | - | |||||||||||||
1749 | QSize desktopSize = QApplication::desktop()->size(); | - | ||||||||||||
1750 | QSize size(desktopSize.width() * 2 / scaleFactor, desktopSize.height() * 2 / scaleFactor); | - | ||||||||||||
1751 | foreachfor (QMdiSubWindow *child ,: d_func()->childWindows) { | - | ||||||||||||
1752 | if (!sanityCheck(child, "QMdiArea::sizeHint"))
| 0 | ||||||||||||
1753 | continue; never executed: continue; | 0 | ||||||||||||
1754 | size = size.expandedTo(child->sizeHint()); | - | ||||||||||||
1755 | } never executed: end of block | 0 | ||||||||||||
1756 | return size.expandedTo(QApplication::globalStrut()); never executed: return size.expandedTo(QApplication::globalStrut()); | 0 | ||||||||||||
1757 | } | - | ||||||||||||
1758 | - | |||||||||||||
1759 | /*! | - | ||||||||||||
1760 | \reimp | - | ||||||||||||
1761 | */ | - | ||||||||||||
1762 | QSize QMdiArea::minimumSizeHint() const | - | ||||||||||||
1763 | { | - | ||||||||||||
1764 | Q_D(const QMdiArea); | - | ||||||||||||
1765 | QSize size(style()->pixelMetric(QStyle::PM_MdiSubWindowMinimizedWidth, 0, this), | - | ||||||||||||
1766 | style()->pixelMetric(QStyle::PM_TitleBarHeight, 0, this)); | - | ||||||||||||
1767 | size = size.expandedTo(QAbstractScrollArea::minimumSizeHint()); | - | ||||||||||||
1768 | if (!d->scrollBarsEnabled()) {
| 0 | ||||||||||||
1769 | foreachfor (QMdiSubWindow *child ,: d->childWindows) { | - | ||||||||||||
1770 | if (!sanityCheck(child, "QMdiArea::sizeHint"))
| 0 | ||||||||||||
1771 | continue; never executed: continue; | 0 | ||||||||||||
1772 | size = size.expandedTo(child->minimumSizeHint()); | - | ||||||||||||
1773 | } never executed: end of block | 0 | ||||||||||||
1774 | } never executed: end of block | 0 | ||||||||||||
1775 | return size.expandedTo(QApplication::globalStrut()); never executed: return size.expandedTo(QApplication::globalStrut()); | 0 | ||||||||||||
1776 | } | - | ||||||||||||
1777 | - | |||||||||||||
1778 | /*! | - | ||||||||||||
1779 | Returns a pointer to the current subwindow, or 0 if there is | - | ||||||||||||
1780 | no current subwindow. | - | ||||||||||||
1781 | - | |||||||||||||
1782 | This function will return the same as activeSubWindow() if | - | ||||||||||||
1783 | the QApplication containing QMdiArea is active. | - | ||||||||||||
1784 | - | |||||||||||||
1785 | \sa activeSubWindow(), QApplication::activeWindow() | - | ||||||||||||
1786 | */ | - | ||||||||||||
1787 | QMdiSubWindow *QMdiArea::currentSubWindow() const | - | ||||||||||||
1788 | { | - | ||||||||||||
1789 | Q_D(const QMdiArea); | - | ||||||||||||
1790 | if (d->childWindows.isEmpty()) | - | ||||||||||||
1791 | return 0; | - | ||||||||||||
1792 | - | |||||||||||||
1793 | if (d->active) | - | ||||||||||||
1794 | return d->active; | - | ||||||||||||
1795 | - | |||||||||||||
1796 | if (d->isActivated && !window()->isMinimized()) | - | ||||||||||||
1797 | return 0; | - | ||||||||||||
1798 | - | |||||||||||||
1799 | Q_ASSERT(d->indicesToActivatedChildren.count() > 0); | - | ||||||||||||
1800 | int index = d->indicesToActivatedChildren.at(0); | - | ||||||||||||
1801 | Q_ASSERT(index >= 0 && index < d->childWindows.size()); | - | ||||||||||||
1802 | QMdiSubWindow *current = d->childWindows.at(index); | - | ||||||||||||
1803 | Q_ASSERT(current); | - | ||||||||||||
1804 | return current; | - | ||||||||||||
1805 | } | - | ||||||||||||
1806 | - | |||||||||||||
1807 | /*! | - | ||||||||||||
1808 | Returns a pointer to the current active subwindow. If no | - | ||||||||||||
1809 | window is currently active, 0 is returned. | - | ||||||||||||
1810 | - | |||||||||||||
1811 | Subwindows are treated as top-level windows with respect to | - | ||||||||||||
1812 | window state, i.e., if a widget outside the MDI area is the active | - | ||||||||||||
1813 | window, no subwindow will be active. Note that if a widget in the | - | ||||||||||||
1814 | window in which the MDI area lives gains focus, the window will be | - | ||||||||||||
1815 | activated. | - | ||||||||||||
1816 | - | |||||||||||||
1817 | \sa setActiveSubWindow(), Qt::WindowState | - | ||||||||||||
1818 | */ | - | ||||||||||||
1819 | QMdiSubWindow *QMdiArea::activeSubWindow() const | - | ||||||||||||
1820 | { | - | ||||||||||||
1821 | Q_D(const QMdiArea); | - | ||||||||||||
1822 | return d->active; | - | ||||||||||||
1823 | } | - | ||||||||||||
1824 | - | |||||||||||||
1825 | /*! | - | ||||||||||||
1826 | Activates the subwindow \a window. If \a window is 0, any | - | ||||||||||||
1827 | current active window is deactivated. | - | ||||||||||||
1828 | - | |||||||||||||
1829 | \sa activeSubWindow() | - | ||||||||||||
1830 | */ | - | ||||||||||||
1831 | void QMdiArea::setActiveSubWindow(QMdiSubWindow *window) | - | ||||||||||||
1832 | { | - | ||||||||||||
1833 | Q_D(QMdiArea); | - | ||||||||||||
1834 | if (!window) {
| 0 | ||||||||||||
1835 | d->activateWindow(0); | - | ||||||||||||
1836 | return; never executed: return; | 0 | ||||||||||||
1837 | } | - | ||||||||||||
1838 | - | |||||||||||||
1839 | if (Q_UNLIKELY(d->childWindows.isEmpty())())) {
| 0 | ||||||||||||
1840 | qWarning("QMdiArea::setActiveSubWindow: workspace is empty"); | - | ||||||||||||
1841 | return; never executed: return; | 0 | ||||||||||||
1842 | } | - | ||||||||||||
1843 | - | |||||||||||||
1844 | if (Q_UNLIKELY(d->childWindows.indexOf(window) == -1))) {
| 0 | ||||||||||||
1845 | qWarning("QMdiArea::setActiveSubWindow: window is not inside workspace"); | - | ||||||||||||
1846 | return; never executed: return; | 0 | ||||||||||||
1847 | } | - | ||||||||||||
1848 | - | |||||||||||||
1849 | d->activateWindow(window); | - | ||||||||||||
1850 | } never executed: end of block | 0 | ||||||||||||
1851 | - | |||||||||||||
1852 | /*! | - | ||||||||||||
1853 | Closes the active subwindow. | - | ||||||||||||
1854 | - | |||||||||||||
1855 | \sa closeAllSubWindows() | - | ||||||||||||
1856 | */ | - | ||||||||||||
1857 | void QMdiArea::closeActiveSubWindow() | - | ||||||||||||
1858 | { | - | ||||||||||||
1859 | Q_D(QMdiArea); | - | ||||||||||||
1860 | if (d->active) | - | ||||||||||||
1861 | d->active->close(); | - | ||||||||||||
1862 | } | - | ||||||||||||
1863 | - | |||||||||||||
1864 | /*! | - | ||||||||||||
1865 | Returns a list of all subwindows in the MDI area. If \a order is | - | ||||||||||||
1866 | CreationOrder (the default), the windows are sorted in the order | - | ||||||||||||
1867 | in which they were inserted into the workspace. If \a order is | - | ||||||||||||
1868 | StackingOrder, the windows are listed in their stacking order, | - | ||||||||||||
1869 | with the topmost window as the last item in the list. If \a order | - | ||||||||||||
1870 | is ActivationHistoryOrder, the windows are listed according to | - | ||||||||||||
1871 | their recent activation history. | - | ||||||||||||
1872 | - | |||||||||||||
1873 | \sa WindowOrder | - | ||||||||||||
1874 | */ | - | ||||||||||||
1875 | QList<QMdiSubWindow *> QMdiArea::subWindowList(WindowOrder order) const | - | ||||||||||||
1876 | { | - | ||||||||||||
1877 | Q_D(const QMdiArea); | - | ||||||||||||
1878 | return d->subWindowList(order, false); | - | ||||||||||||
1879 | } | - | ||||||||||||
1880 | - | |||||||||||||
1881 | /*! | - | ||||||||||||
1882 | Closes all subwindows by sending a QCloseEvent to each window. | - | ||||||||||||
1883 | You may receive subWindowActivated() signals from subwindows | - | ||||||||||||
1884 | before they are closed (if the MDI area activates the subwindow | - | ||||||||||||
1885 | when another is closing). | - | ||||||||||||
1886 | - | |||||||||||||
1887 | Subwindows that ignore the close event will remain open. | - | ||||||||||||
1888 | - | |||||||||||||
1889 | \sa closeActiveSubWindow() | - | ||||||||||||
1890 | */ | - | ||||||||||||
1891 | void QMdiArea::closeAllSubWindows() | - | ||||||||||||
1892 | { | - | ||||||||||||
1893 | Q_D(QMdiArea); | - | ||||||||||||
1894 | if (d->childWindows.isEmpty()) | - | ||||||||||||
1895 | return; | - | ||||||||||||
1896 | - | |||||||||||||
1897 | d->isSubWindowsTiled = false; | - | ||||||||||||
1898 | foreach (QMdiSubWindow *child, d->childWindows) { | - | ||||||||||||
1899 | if (!sanityCheck(child, "QMdiArea::closeAllSubWindows")) | - | ||||||||||||
1900 | continue; | - | ||||||||||||
1901 | child->close(); | - | ||||||||||||
1902 | } | - | ||||||||||||
1903 | - | |||||||||||||
1904 | d->updateScrollBars(); | - | ||||||||||||
1905 | } | - | ||||||||||||
1906 | - | |||||||||||||
1907 | /*! | - | ||||||||||||
1908 | Gives the keyboard focus to another window in the list of child | - | ||||||||||||
1909 | windows. The window activated will be the next one determined | - | ||||||||||||
1910 | by the current \l{QMdiArea::WindowOrder} {activation order}. | - | ||||||||||||
1911 | - | |||||||||||||
1912 | \sa activatePreviousSubWindow(), QMdiArea::WindowOrder | - | ||||||||||||
1913 | */ | - | ||||||||||||
1914 | void QMdiArea::activateNextSubWindow() | - | ||||||||||||
1915 | { | - | ||||||||||||
1916 | Q_D(QMdiArea); | - | ||||||||||||
1917 | if (d->childWindows.isEmpty()) | - | ||||||||||||
1918 | return; | - | ||||||||||||
1919 | - | |||||||||||||
1920 | QMdiSubWindow *next = d->nextVisibleSubWindow(1, d->activationOrder); | - | ||||||||||||
1921 | if (next) | - | ||||||||||||
1922 | d->activateWindow(next); | - | ||||||||||||
1923 | } | - | ||||||||||||
1924 | - | |||||||||||||
1925 | /*! | - | ||||||||||||
1926 | Gives the keyboard focus to another window in the list of child | - | ||||||||||||
1927 | windows. The window activated will be the previous one determined | - | ||||||||||||
1928 | by the current \l{QMdiArea::WindowOrder} {activation order}. | - | ||||||||||||
1929 | - | |||||||||||||
1930 | \sa activateNextSubWindow(), QMdiArea::WindowOrder | - | ||||||||||||
1931 | */ | - | ||||||||||||
1932 | void QMdiArea::activatePreviousSubWindow() | - | ||||||||||||
1933 | { | - | ||||||||||||
1934 | Q_D(QMdiArea); | - | ||||||||||||
1935 | if (d->childWindows.isEmpty()) | - | ||||||||||||
1936 | return; | - | ||||||||||||
1937 | - | |||||||||||||
1938 | QMdiSubWindow *previous = d->nextVisibleSubWindow(-1, d->activationOrder); | - | ||||||||||||
1939 | if (previous) | - | ||||||||||||
1940 | d->activateWindow(previous); | - | ||||||||||||
1941 | } | - | ||||||||||||
1942 | - | |||||||||||||
1943 | /*! | - | ||||||||||||
1944 | Adds \a widget as a new subwindow to the MDI area. If \a | - | ||||||||||||
1945 | windowFlags are non-zero, they will override the flags set on the | - | ||||||||||||
1946 | widget. | - | ||||||||||||
1947 | - | |||||||||||||
1948 | The \a widget can be either a QMdiSubWindow or another QWidget | - | ||||||||||||
1949 | (in which case the MDI area will create a subwindow and set the \a | - | ||||||||||||
1950 | widget as the internal widget). | - | ||||||||||||
1951 | - | |||||||||||||
1952 | \note Once the subwindow has been added, its parent will be the | - | ||||||||||||
1953 | \e{viewport widget} of the QMdiArea. | - | ||||||||||||
1954 | - | |||||||||||||
1955 | \snippet mdiareasnippets.cpp 1 | - | ||||||||||||
1956 | - | |||||||||||||
1957 | When you create your own subwindow, you must set the | - | ||||||||||||
1958 | Qt::WA_DeleteOnClose widget attribute if you want the window to be | - | ||||||||||||
1959 | deleted when closed in the MDI area. If not, the window will be | - | ||||||||||||
1960 | hidden and the MDI area will not activate the next subwindow. | - | ||||||||||||
1961 | - | |||||||||||||
1962 | Returns the QMdiSubWindow that is added to the MDI area. | - | ||||||||||||
1963 | - | |||||||||||||
1964 | \sa removeSubWindow() | - | ||||||||||||
1965 | */ | - | ||||||||||||
1966 | QMdiSubWindow *QMdiArea::addSubWindow(QWidget *widget, Qt::WindowFlags windowFlags) | - | ||||||||||||
1967 | { | - | ||||||||||||
1968 | if (Q_UNLIKELY(!widget))) {
| 0 | ||||||||||||
1969 | qWarning("QMdiArea::addSubWindow: null pointer to widget"); | - | ||||||||||||
1970 | return 0; never executed: return 0; | 0 | ||||||||||||
1971 | } | - | ||||||||||||
1972 | - | |||||||||||||
1973 | Q_D(QMdiArea); | - | ||||||||||||
1974 | // QWidget::setParent clears focusWidget so store it | - | ||||||||||||
1975 | QWidget *childFocus = widget->focusWidget(); | - | ||||||||||||
1976 | QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(widget); | - | ||||||||||||
1977 | - | |||||||||||||
1978 | // Widget is already a QMdiSubWindow | - | ||||||||||||
1979 | if (child) {
| 0 | ||||||||||||
1980 | if (Q_UNLIKELY(d->childWindows.indexOf(child) != -1))) {
| 0 | ||||||||||||
1981 | qWarning("QMdiArea::addSubWindow: window is already added"); | - | ||||||||||||
1982 | return child; never executed: return child; | 0 | ||||||||||||
1983 | } | - | ||||||||||||
1984 | child->setParent(viewport(), windowFlags ? windowFlags : child->windowFlags()); | - | ||||||||||||
1985 | // Create a QMdiSubWindow | - | ||||||||||||
1986 | } else { never executed: end of block | 0 | ||||||||||||
1987 | child = new QMdiSubWindow(viewport(), windowFlags); | - | ||||||||||||
1988 | child->setAttribute(Qt::WA_DeleteOnClose); | - | ||||||||||||
1989 | child->setWidget(widget); | - | ||||||||||||
1990 | Q_ASSERT(child->testAttribute(Qt::WA_DeleteOnClose)); | - | ||||||||||||
1991 | } never executed: end of block | 0 | ||||||||||||
1992 | - | |||||||||||||
1993 | if (childFocus)
| 0 | ||||||||||||
1994 | childFocus->setFocus(); never executed: childFocus->setFocus(); | 0 | ||||||||||||
1995 | d->appendChild(child); | - | ||||||||||||
1996 | return child; never executed: return child; | 0 | ||||||||||||
1997 | } | - | ||||||||||||
1998 | - | |||||||||||||
1999 | /*! | - | ||||||||||||
2000 | Removes \a widget from the MDI area. The \a widget must be | - | ||||||||||||
2001 | either a QMdiSubWindow or a widget that is the internal widget of | - | ||||||||||||
2002 | a subwindow. Note \a widget is never actually deleted by QMdiArea. | - | ||||||||||||
2003 | If a QMdiSubWindow is passed in its parent is set to 0 and it is | - | ||||||||||||
2004 | removed, but if an internal widget is passed in the child widget | - | ||||||||||||
2005 | is set to 0 but the QMdiSubWindow is not removed. | - | ||||||||||||
2006 | - | |||||||||||||
2007 | \sa addSubWindow() | - | ||||||||||||
2008 | */ | - | ||||||||||||
2009 | void QMdiArea::removeSubWindow(QWidget *widget) | - | ||||||||||||
2010 | { | - | ||||||||||||
2011 | if (Q_UNLIKELY(!widget))) {
| 0 | ||||||||||||
2012 | qWarning("QMdiArea::removeSubWindow: null pointer to widget"); | - | ||||||||||||
2013 | return; never executed: return; | 0 | ||||||||||||
2014 | } | - | ||||||||||||
2015 | - | |||||||||||||
2016 | Q_D(QMdiArea); | - | ||||||||||||
2017 | if (d->childWindows.isEmpty())
| 0 | ||||||||||||
2018 | return; never executed: return; | 0 | ||||||||||||
2019 | - | |||||||||||||
2020 | if (QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(widget)) {
| 0 | ||||||||||||
2021 | int index = d->childWindows.indexOf(child); | - | ||||||||||||
2022 | if (Q_UNLIKELY(index == -1))) {
| 0 | ||||||||||||
2023 | qWarning("QMdiArea::removeSubWindow: window is not inside workspace"); | - | ||||||||||||
2024 | return; never executed: return; | 0 | ||||||||||||
2025 | } | - | ||||||||||||
2026 | d->disconnectSubWindow(child); | - | ||||||||||||
2027 | d->childWindows.removeAll(child); | - | ||||||||||||
2028 | d->indicesToActivatedChildren.removeAll(index); | - | ||||||||||||
2029 | d->updateActiveWindow(index, d->active == child); | - | ||||||||||||
2030 | child->setParent(0); | - | ||||||||||||
2031 | return; never executed: return; | 0 | ||||||||||||
2032 | } | - | ||||||||||||
2033 | - | |||||||||||||
2034 | bool found = false; | - | ||||||||||||
2035 | foreach (QMdiSubWindow *child, d->childWindows) { | - | ||||||||||||
2036 | if (!sanityCheck(child, "QMdiArea::removeSubWindow"))
| 0 | ||||||||||||
2037 | continue; never executed: continue; | 0 | ||||||||||||
2038 | if (child->widget() == widget) {
| 0 | ||||||||||||
2039 | child->setWidget(0); | - | ||||||||||||
2040 | Q_ASSERT(!child->widget()); | - | ||||||||||||
2041 | found = true; | - | ||||||||||||
2042 | break; never executed: break; | 0 | ||||||||||||
2043 | } | - | ||||||||||||
2044 | } never executed: end of block | 0 | ||||||||||||
2045 | - | |||||||||||||
2046 | if (Q_UNLIKELY(!found)))
| 0 | ||||||||||||
2047 | qWarning("QMdiArea::removeSubWindow: widget is not child of any window inside QMdiArea"); never executed: QMessageLogger(__FILE__, 2047, __PRETTY_FUNCTION__).warning("QMdiArea::removeSubWindow: widget is not child of any window inside QMdiArea"); | 0 | ||||||||||||
2048 | } never executed: end of block | 0 | ||||||||||||
2049 | - | |||||||||||||
2050 | /*! | - | ||||||||||||
2051 | \property QMdiArea::background | - | ||||||||||||
2052 | \brief the background brush for the workspace | - | ||||||||||||
2053 | - | |||||||||||||
2054 | This property sets the background brush for the workspace area | - | ||||||||||||
2055 | itself. By default, it is a gray color, but can be any brush | - | ||||||||||||
2056 | (e.g., colors, gradients or pixmaps). | - | ||||||||||||
2057 | */ | - | ||||||||||||
2058 | QBrush QMdiArea::background() const | - | ||||||||||||
2059 | { | - | ||||||||||||
2060 | return d_func()->background; | - | ||||||||||||
2061 | } | - | ||||||||||||
2062 | - | |||||||||||||
2063 | void QMdiArea::setBackground(const QBrush &brush) | - | ||||||||||||
2064 | { | - | ||||||||||||
2065 | Q_D(QMdiArea); | - | ||||||||||||
2066 | if (d->background != brush) { | - | ||||||||||||
2067 | d->background = brush; | - | ||||||||||||
2068 | d->viewport->setAttribute(Qt::WA_OpaquePaintEvent, brush.isOpaque()); | - | ||||||||||||
2069 | d->viewport->update(); | - | ||||||||||||
2070 | } | - | ||||||||||||
2071 | } | - | ||||||||||||
2072 | - | |||||||||||||
2073 | - | |||||||||||||
2074 | /*! | - | ||||||||||||
2075 | \property QMdiArea::activationOrder | - | ||||||||||||
2076 | \brief the ordering criteria for subwindow lists | - | ||||||||||||
2077 | \since 4.4 | - | ||||||||||||
2078 | - | |||||||||||||
2079 | This property specifies the ordering criteria for the list of | - | ||||||||||||
2080 | subwindows returned by subWindowList(). By default, it is the window | - | ||||||||||||
2081 | creation order. | - | ||||||||||||
2082 | - | |||||||||||||
2083 | \sa subWindowList() | - | ||||||||||||
2084 | */ | - | ||||||||||||
2085 | QMdiArea::WindowOrder QMdiArea::activationOrder() const | - | ||||||||||||
2086 | { | - | ||||||||||||
2087 | Q_D(const QMdiArea); | - | ||||||||||||
2088 | return d->activationOrder; | - | ||||||||||||
2089 | } | - | ||||||||||||
2090 | - | |||||||||||||
2091 | void QMdiArea::setActivationOrder(WindowOrder order) | - | ||||||||||||
2092 | { | - | ||||||||||||
2093 | Q_D(QMdiArea); | - | ||||||||||||
2094 | if (order != d->activationOrder) | - | ||||||||||||
2095 | d->activationOrder = order; | - | ||||||||||||
2096 | } | - | ||||||||||||
2097 | - | |||||||||||||
2098 | /*! | - | ||||||||||||
2099 | If \a on is true, \a option is enabled on the MDI area; otherwise | - | ||||||||||||
2100 | it is disabled. See AreaOption for the effect of each option. | - | ||||||||||||
2101 | - | |||||||||||||
2102 | \sa AreaOption, testOption() | - | ||||||||||||
2103 | */ | - | ||||||||||||
2104 | void QMdiArea::setOption(AreaOption option, bool on) | - | ||||||||||||
2105 | { | - | ||||||||||||
2106 | Q_D(QMdiArea); | - | ||||||||||||
2107 | if (on && !(d->options & option))d->options|= option; | - | ||||||||||||
else if (!on &&.setFlag(d->options & option)) | ||||||||||||||
d->options &= ~option;, on); | ||||||||||||||
2108 | } never executed: end of block | 0 | ||||||||||||
2109 | - | |||||||||||||
2110 | /*! | - | ||||||||||||
2111 | Returns \c true if \a option is enabled; otherwise returns \c false. | - | ||||||||||||
2112 | - | |||||||||||||
2113 | \sa AreaOption, setOption() | - | ||||||||||||
2114 | */ | - | ||||||||||||
2115 | bool QMdiArea::testOption(AreaOption option) const | - | ||||||||||||
2116 | { | - | ||||||||||||
2117 | return d_func()->options & option; | - | ||||||||||||
2118 | } | - | ||||||||||||
2119 | - | |||||||||||||
2120 | /*! | - | ||||||||||||
2121 | \property QMdiArea::viewMode | - | ||||||||||||
2122 | \brief the way sub-windows are displayed in the QMdiArea. | - | ||||||||||||
2123 | \since 4.4 | - | ||||||||||||
2124 | - | |||||||||||||
2125 | By default, the SubWindowView is used to display sub-windows. | - | ||||||||||||
2126 | - | |||||||||||||
2127 | \sa ViewMode, setTabShape(), setTabPosition() | - | ||||||||||||
2128 | */ | - | ||||||||||||
2129 | QMdiArea::ViewMode QMdiArea::viewMode() const | - | ||||||||||||
2130 | { | - | ||||||||||||
2131 | Q_D(const QMdiArea); | - | ||||||||||||
2132 | return d->viewMode; | - | ||||||||||||
2133 | } | - | ||||||||||||
2134 | - | |||||||||||||
2135 | void QMdiArea::setViewMode(ViewMode mode) | - | ||||||||||||
2136 | { | - | ||||||||||||
2137 | Q_D(QMdiArea); | - | ||||||||||||
2138 | d->setViewMode(mode); | - | ||||||||||||
2139 | } | - | ||||||||||||
2140 | - | |||||||||||||
2141 | #ifndef QT_NO_TABBAR | - | ||||||||||||
2142 | /*! | - | ||||||||||||
2143 | \property QMdiArea::documentMode | - | ||||||||||||
2144 | \brief whether the tab bar is set to document mode in tabbed view mode. | - | ||||||||||||
2145 | \since 4.5 | - | ||||||||||||
2146 | - | |||||||||||||
2147 | Document mode is disabled by default. | - | ||||||||||||
2148 | - | |||||||||||||
2149 | \sa QTabBar::documentMode, setViewMode() | - | ||||||||||||
2150 | */ | - | ||||||||||||
2151 | bool QMdiArea::documentMode() const | - | ||||||||||||
2152 | { | - | ||||||||||||
2153 | Q_D(const QMdiArea); | - | ||||||||||||
2154 | return d->documentMode; | - | ||||||||||||
2155 | } | - | ||||||||||||
2156 | - | |||||||||||||
2157 | void QMdiArea::setDocumentMode(bool enabled) | - | ||||||||||||
2158 | { | - | ||||||||||||
2159 | Q_D(QMdiArea); | - | ||||||||||||
2160 | if (d->documentMode == enabled) | - | ||||||||||||
2161 | return; | - | ||||||||||||
2162 | - | |||||||||||||
2163 | d->documentMode = enabled; | - | ||||||||||||
2164 | d->refreshTabBar(); | - | ||||||||||||
2165 | } | - | ||||||||||||
2166 | - | |||||||||||||
2167 | /*! | - | ||||||||||||
2168 | \property QMdiArea::tabsClosable | - | ||||||||||||
2169 | \brief whether the tab bar should place close buttons on each tab in tabbed view mode. | - | ||||||||||||
2170 | \since 4.8 | - | ||||||||||||
2171 | - | |||||||||||||
2172 | Tabs are not closable by default. | - | ||||||||||||
2173 | - | |||||||||||||
2174 | \sa QTabBar::tabsClosable, setViewMode() | - | ||||||||||||
2175 | */ | - | ||||||||||||
2176 | bool QMdiArea::tabsClosable() const | - | ||||||||||||
2177 | { | - | ||||||||||||
2178 | Q_D(const QMdiArea); | - | ||||||||||||
2179 | return d->tabsClosable; | - | ||||||||||||
2180 | } | - | ||||||||||||
2181 | - | |||||||||||||
2182 | void QMdiArea::setTabsClosable(bool closable) | - | ||||||||||||
2183 | { | - | ||||||||||||
2184 | Q_D(QMdiArea); | - | ||||||||||||
2185 | if (d->tabsClosable == closable) | - | ||||||||||||
2186 | return; | - | ||||||||||||
2187 | - | |||||||||||||
2188 | d->tabsClosable = closable; | - | ||||||||||||
2189 | d->refreshTabBar(); | - | ||||||||||||
2190 | } | - | ||||||||||||
2191 | - | |||||||||||||
2192 | /*! | - | ||||||||||||
2193 | \property QMdiArea::tabsMovable | - | ||||||||||||
2194 | \brief whether the user can move the tabs within the tabbar area in tabbed view mode. | - | ||||||||||||
2195 | \since 4.8 | - | ||||||||||||
2196 | - | |||||||||||||
2197 | Tabs are not movable by default. | - | ||||||||||||
2198 | - | |||||||||||||
2199 | \sa QTabBar::movable, setViewMode() | - | ||||||||||||
2200 | */ | - | ||||||||||||
2201 | bool QMdiArea::tabsMovable() const | - | ||||||||||||
2202 | { | - | ||||||||||||
2203 | Q_D(const QMdiArea); | - | ||||||||||||
2204 | return d->tabsMovable; | - | ||||||||||||
2205 | } | - | ||||||||||||
2206 | - | |||||||||||||
2207 | void QMdiArea::setTabsMovable(bool movable) | - | ||||||||||||
2208 | { | - | ||||||||||||
2209 | Q_D(QMdiArea); | - | ||||||||||||
2210 | if (d->tabsMovable == movable) | - | ||||||||||||
2211 | return; | - | ||||||||||||
2212 | - | |||||||||||||
2213 | d->tabsMovable = movable; | - | ||||||||||||
2214 | d->refreshTabBar(); | - | ||||||||||||
2215 | } | - | ||||||||||||
2216 | #endif // QT_NO_TABBAR | - | ||||||||||||
2217 | - | |||||||||||||
2218 | #ifndef QT_NO_TABWIDGET | - | ||||||||||||
2219 | /*! | - | ||||||||||||
2220 | \property QMdiArea::tabShape | - | ||||||||||||
2221 | \brief the shape of the tabs in tabbed view mode. | - | ||||||||||||
2222 | \since 4.4 | - | ||||||||||||
2223 | - | |||||||||||||
2224 | Possible values for this property are QTabWidget::Rounded | - | ||||||||||||
2225 | (default) or QTabWidget::Triangular. | - | ||||||||||||
2226 | - | |||||||||||||
2227 | \sa QTabWidget::TabShape, setViewMode() | - | ||||||||||||
2228 | */ | - | ||||||||||||
2229 | QTabWidget::TabShape QMdiArea::tabShape() const | - | ||||||||||||
2230 | { | - | ||||||||||||
2231 | Q_D(const QMdiArea); | - | ||||||||||||
2232 | return d->tabShape; | - | ||||||||||||
2233 | } | - | ||||||||||||
2234 | - | |||||||||||||
2235 | void QMdiArea::setTabShape(QTabWidget::TabShape shape) | - | ||||||||||||
2236 | { | - | ||||||||||||
2237 | Q_D(QMdiArea); | - | ||||||||||||
2238 | if (d->tabShape == shape) | - | ||||||||||||
2239 | return; | - | ||||||||||||
2240 | - | |||||||||||||
2241 | d->tabShape = shape; | - | ||||||||||||
2242 | d->refreshTabBar(); | - | ||||||||||||
2243 | } | - | ||||||||||||
2244 | - | |||||||||||||
2245 | /*! | - | ||||||||||||
2246 | \property QMdiArea::tabPosition | - | ||||||||||||
2247 | \brief the position of the tabs in tabbed view mode. | - | ||||||||||||
2248 | \since 4.4 | - | ||||||||||||
2249 | - | |||||||||||||
2250 | Possible values for this property are described by the | - | ||||||||||||
2251 | QTabWidget::TabPosition enum. | - | ||||||||||||
2252 | - | |||||||||||||
2253 | \sa QTabWidget::TabPosition, setViewMode() | - | ||||||||||||
2254 | */ | - | ||||||||||||
2255 | QTabWidget::TabPosition QMdiArea::tabPosition() const | - | ||||||||||||
2256 | { | - | ||||||||||||
2257 | Q_D(const QMdiArea); | - | ||||||||||||
2258 | return d->tabPosition; | - | ||||||||||||
2259 | } | - | ||||||||||||
2260 | - | |||||||||||||
2261 | void QMdiArea::setTabPosition(QTabWidget::TabPosition position) | - | ||||||||||||
2262 | { | - | ||||||||||||
2263 | Q_D(QMdiArea); | - | ||||||||||||
2264 | if (d->tabPosition == position) | - | ||||||||||||
2265 | return; | - | ||||||||||||
2266 | - | |||||||||||||
2267 | d->tabPosition = position; | - | ||||||||||||
2268 | d->refreshTabBar(); | - | ||||||||||||
2269 | } | - | ||||||||||||
2270 | #endif // QT_NO_TABWIDGET | - | ||||||||||||
2271 | - | |||||||||||||
2272 | /*! | - | ||||||||||||
2273 | \reimp | - | ||||||||||||
2274 | */ | - | ||||||||||||
2275 | void QMdiArea::childEvent(QChildEvent *childEvent) | - | ||||||||||||
2276 | { | - | ||||||||||||
2277 | Q_D(QMdiArea); | - | ||||||||||||
2278 | if (childEvent->type() == QEvent::ChildPolished) { | - | ||||||||||||
2279 | if (QMdiSubWindow *mdiChild = qobject_cast<QMdiSubWindow *>(childEvent->child())) { | - | ||||||||||||
2280 | if (d->childWindows.indexOf(mdiChild) == -1) | - | ||||||||||||
2281 | d->appendChild(mdiChild); | - | ||||||||||||
2282 | } | - | ||||||||||||
2283 | } | - | ||||||||||||
2284 | } | - | ||||||||||||
2285 | - | |||||||||||||
2286 | /*! | - | ||||||||||||
2287 | \reimp | - | ||||||||||||
2288 | */ | - | ||||||||||||
2289 | void QMdiArea::resizeEvent(QResizeEvent *resizeEvent) | - | ||||||||||||
2290 | { | - | ||||||||||||
2291 | Q_D(QMdiArea); | - | ||||||||||||
2292 | if (d->childWindows.isEmpty()) { | - | ||||||||||||
2293 | resizeEvent->ignore(); | - | ||||||||||||
2294 | return; | - | ||||||||||||
2295 | } | - | ||||||||||||
2296 | - | |||||||||||||
2297 | #ifndef QT_NO_TABBAR | - | ||||||||||||
2298 | d->updateTabBarGeometry(); | - | ||||||||||||
2299 | #endif | - | ||||||||||||
2300 | - | |||||||||||||
2301 | // Re-tile the views if we're in tiled mode. Re-tile means we will change | - | ||||||||||||
2302 | // the geometry of the children, which in turn means 'isSubWindowsTiled' | - | ||||||||||||
2303 | // is set to false, so we have to update the state at the end. | - | ||||||||||||
2304 | if (d->isSubWindowsTiled) { | - | ||||||||||||
2305 | d->tileCalledFromResizeEvent = true; | - | ||||||||||||
2306 | tileSubWindows(); | - | ||||||||||||
2307 | d->tileCalledFromResizeEvent = false; | - | ||||||||||||
2308 | d->isSubWindowsTiled = true; | - | ||||||||||||
2309 | d->startResizeTimer(); | - | ||||||||||||
2310 | // We don't have scroll bars or any maximized views. | - | ||||||||||||
2311 | return; | - | ||||||||||||
2312 | } | - | ||||||||||||
2313 | - | |||||||||||||
2314 | // Resize maximized views. | - | ||||||||||||
2315 | bool hasMaximizedSubWindow = false; | - | ||||||||||||
2316 | foreach (QMdiSubWindow *child, d->childWindows) { | - | ||||||||||||
2317 | if (sanityCheck(child, "QMdiArea::resizeEvent") && child->isMaximized() | - | ||||||||||||
2318 | && child->size() != resizeEvent->size()) { | - | ||||||||||||
2319 | child->resize(resizeEvent->size()); | - | ||||||||||||
2320 | if (!hasMaximizedSubWindow) | - | ||||||||||||
2321 | hasMaximizedSubWindow = true; | - | ||||||||||||
2322 | } | - | ||||||||||||
2323 | } | - | ||||||||||||
2324 | - | |||||||||||||
2325 | d->updateScrollBars(); | - | ||||||||||||
2326 | - | |||||||||||||
2327 | // Minimized views are stacked under maximized views so there's | - | ||||||||||||
2328 | // no need to re-arrange minimized views on-demand. Start a timer | - | ||||||||||||
2329 | // just to make things faster with subsequent resize events. | - | ||||||||||||
2330 | if (hasMaximizedSubWindow) | - | ||||||||||||
2331 | d->startResizeTimer(); | - | ||||||||||||
2332 | else | - | ||||||||||||
2333 | d->arrangeMinimizedSubWindows(); | - | ||||||||||||
2334 | } | - | ||||||||||||
2335 | - | |||||||||||||
2336 | /*! | - | ||||||||||||
2337 | \reimp | - | ||||||||||||
2338 | */ | - | ||||||||||||
2339 | void QMdiArea::timerEvent(QTimerEvent *timerEvent) | - | ||||||||||||
2340 | { | - | ||||||||||||
2341 | Q_D(QMdiArea); | - | ||||||||||||
2342 | if (timerEvent->timerId() == d->resizeTimerId) { | - | ||||||||||||
2343 | killTimer(d->resizeTimerId); | - | ||||||||||||
2344 | d->resizeTimerId = -1; | - | ||||||||||||
2345 | d->arrangeMinimizedSubWindows(); | - | ||||||||||||
2346 | } else if (timerEvent->timerId() == d->tabToPreviousTimerId) { | - | ||||||||||||
2347 | killTimer(d->tabToPreviousTimerId); | - | ||||||||||||
2348 | d->tabToPreviousTimerId = -1; | - | ||||||||||||
2349 | if (d->indexToHighlighted < 0) | - | ||||||||||||
2350 | return; | - | ||||||||||||
2351 | #ifndef QT_NO_RUBBERBAND | - | ||||||||||||
2352 | // We're not doing a "quick switch" ... show rubber band. | - | ||||||||||||
2353 | Q_ASSERT(d->indexToHighlighted < d->childWindows.size()); | - | ||||||||||||
2354 | Q_ASSERT(d->rubberBand); | - | ||||||||||||
2355 | d->showRubberBandFor(d->childWindows.at(d->indexToHighlighted)); | - | ||||||||||||
2356 | #endif | - | ||||||||||||
2357 | } | - | ||||||||||||
2358 | } | - | ||||||||||||
2359 | - | |||||||||||||
2360 | /*! | - | ||||||||||||
2361 | \reimp | - | ||||||||||||
2362 | */ | - | ||||||||||||
2363 | void QMdiArea::showEvent(QShowEvent *showEvent) | - | ||||||||||||
2364 | { | - | ||||||||||||
2365 | Q_D(QMdiArea); | - | ||||||||||||
2366 | if (!d->pendingRearrangements.isEmpty()) { | - | ||||||||||||
2367 | bool skipPlacement = false; | - | ||||||||||||
2368 | foreach (Rearranger *rearranger, d->pendingRearrangements) { | - | ||||||||||||
2369 | // If this is the case, we don't have to lay out pending child windows | - | ||||||||||||
2370 | // since the rearranger will find a placement for them. | - | ||||||||||||
2371 | if (rearranger->type() != Rearranger::IconTiler && !skipPlacement) | - | ||||||||||||
2372 | skipPlacement = true; | - | ||||||||||||
2373 | d->rearrange(rearranger); | - | ||||||||||||
2374 | } | - | ||||||||||||
2375 | d->pendingRearrangements.clear(); | - | ||||||||||||
2376 | - | |||||||||||||
2377 | if (skipPlacement && !d->pendingPlacements.isEmpty()) | - | ||||||||||||
2378 | d->pendingPlacements.clear(); | - | ||||||||||||
2379 | } | - | ||||||||||||
2380 | - | |||||||||||||
2381 | if (!d->pendingPlacements.isEmpty()) { | - | ||||||||||||
2382 | foreach (QMdiSubWindow *window, d->pendingPlacements) { | - | ||||||||||||
2383 | if (!window) | - | ||||||||||||
2384 | continue; | - | ||||||||||||
2385 | if (!window->testAttribute(Qt::WA_Resized)) { | - | ||||||||||||
2386 | QSize newSize(window->sizeHint().boundedTo(viewport()->size())); | - | ||||||||||||
2387 | window->resize(newSize.expandedTo(qSmartMinSize(window))); | - | ||||||||||||
2388 | } | - | ||||||||||||
2389 | if (!window->testAttribute(Qt::WA_Moved) && !window->isMinimized() | - | ||||||||||||
2390 | && !window->isMaximized()) { | - | ||||||||||||
2391 | d->place(d->placer, window); | - | ||||||||||||
2392 | } | - | ||||||||||||
2393 | } | - | ||||||||||||
2394 | d->pendingPlacements.clear(); | - | ||||||||||||
2395 | } | - | ||||||||||||
2396 | - | |||||||||||||
2397 | d->setChildActivationEnabled(true); | - | ||||||||||||
2398 | d->activateCurrentWindow(); | - | ||||||||||||
2399 | - | |||||||||||||
2400 | QAbstractScrollArea::showEvent(showEvent); | - | ||||||||||||
2401 | } | - | ||||||||||||
2402 | - | |||||||||||||
2403 | /*! | - | ||||||||||||
2404 | \reimp | - | ||||||||||||
2405 | */ | - | ||||||||||||
2406 | bool QMdiArea::viewportEvent(QEvent *event) | - | ||||||||||||
2407 | { | - | ||||||||||||
2408 | Q_D(QMdiArea); | - | ||||||||||||
2409 | switch (event->type()) { | - | ||||||||||||
2410 | case QEvent::ChildRemoved: { | - | ||||||||||||
2411 | d->isSubWindowsTiled = false; | - | ||||||||||||
2412 | QObject *removedChild = static_cast<QChildEvent *>(event)->child(); | - | ||||||||||||
2413 | for (int i = 0; i < d->childWindows.size(); ++i) { | - | ||||||||||||
2414 | QObject *child = d->childWindows.at(i); | - | ||||||||||||
2415 | if (!child || child == removedChild || !child->parent() | - | ||||||||||||
2416 | || child->parent() != viewport()) { | - | ||||||||||||
2417 | if (!testOption(DontMaximizeSubWindowOnActivation)) { | - | ||||||||||||
2418 | // In this case we can only rely on the child being a QObject | - | ||||||||||||
2419 | // (or 0), but let's try and see if we can get more information. | - | ||||||||||||
2420 | QWidget *mdiChild = qobject_cast<QWidget *>(removedChild); | - | ||||||||||||
2421 | if (mdiChild && mdiChild->isMaximized()) | - | ||||||||||||
2422 | d->showActiveWindowMaximized = true; | - | ||||||||||||
2423 | } | - | ||||||||||||
2424 | d->disconnectSubWindow(child); | - | ||||||||||||
2425 | const bool activeRemoved = i == d->indicesToActivatedChildren.at(0); | - | ||||||||||||
2426 | d->childWindows.removeAt(i); | - | ||||||||||||
2427 | d->indicesToActivatedChildren.removeAll(i); | - | ||||||||||||
2428 | d->updateActiveWindow(i, activeRemoved); | - | ||||||||||||
2429 | d->arrangeMinimizedSubWindows(); | - | ||||||||||||
2430 | break; | - | ||||||||||||
2431 | } | - | ||||||||||||
2432 | } | - | ||||||||||||
2433 | d->updateScrollBars(); | - | ||||||||||||
2434 | break; | - | ||||||||||||
2435 | } | - | ||||||||||||
2436 | case QEvent::Destroy: | - | ||||||||||||
2437 | d->isSubWindowsTiled = false; | - | ||||||||||||
2438 | d->resetActiveWindow(); | - | ||||||||||||
2439 | d->childWindows.clear(); | - | ||||||||||||
2440 | qWarning("QMdiArea: Deleting the view port is undefined, use setViewport instead."); | - | ||||||||||||
2441 | break; | - | ||||||||||||
2442 | default: | - | ||||||||||||
2443 | break; | - | ||||||||||||
2444 | } | - | ||||||||||||
2445 | return QAbstractScrollArea::viewportEvent(event); | - | ||||||||||||
2446 | } | - | ||||||||||||
2447 | - | |||||||||||||
2448 | /*! | - | ||||||||||||
2449 | \reimp | - | ||||||||||||
2450 | */ | - | ||||||||||||
2451 | void QMdiArea::scrollContentsBy(int dx, int dy) | - | ||||||||||||
2452 | { | - | ||||||||||||
2453 | Q_D(QMdiArea); | - | ||||||||||||
2454 | const bool wasSubWindowsTiled = d->isSubWindowsTiled; | - | ||||||||||||
2455 | d->ignoreGeometryChange = true; | - | ||||||||||||
2456 | viewport()->scroll(isLeftToRight() ? dx : -dx, dy); | - | ||||||||||||
2457 | d->arrangeMinimizedSubWindows(); | - | ||||||||||||
2458 | d->ignoreGeometryChange = false; | - | ||||||||||||
2459 | if (wasSubWindowsTiled) | - | ||||||||||||
2460 | d->isSubWindowsTiled = true; | - | ||||||||||||
2461 | } | - | ||||||||||||
2462 | - | |||||||||||||
2463 | /*! | - | ||||||||||||
2464 | Arranges all child windows in a tile pattern. | - | ||||||||||||
2465 | - | |||||||||||||
2466 | \sa cascadeSubWindows() | - | ||||||||||||
2467 | */ | - | ||||||||||||
2468 | void QMdiArea::tileSubWindows() | - | ||||||||||||
2469 | { | - | ||||||||||||
2470 | Q_D(QMdiArea); | - | ||||||||||||
2471 | if (!d->regularTiler) | - | ||||||||||||
2472 | d->regularTiler = new RegularTiler; | - | ||||||||||||
2473 | d->rearrange(d->regularTiler); | - | ||||||||||||
2474 | } | - | ||||||||||||
2475 | - | |||||||||||||
2476 | /*! | - | ||||||||||||
2477 | Arranges all the child windows in a cascade pattern. | - | ||||||||||||
2478 | - | |||||||||||||
2479 | \sa tileSubWindows() | - | ||||||||||||
2480 | */ | - | ||||||||||||
2481 | void QMdiArea::cascadeSubWindows() | - | ||||||||||||
2482 | { | - | ||||||||||||
2483 | Q_D(QMdiArea); | - | ||||||||||||
2484 | if (!d->cascader) | - | ||||||||||||
2485 | d->cascader = new SimpleCascader; | - | ||||||||||||
2486 | d->rearrange(d->cascader); | - | ||||||||||||
2487 | } | - | ||||||||||||
2488 | - | |||||||||||||
2489 | /*! | - | ||||||||||||
2490 | \reimp | - | ||||||||||||
2491 | */ | - | ||||||||||||
2492 | bool QMdiArea::event(QEvent *event) | - | ||||||||||||
2493 | { | - | ||||||||||||
2494 | Q_D(QMdiArea); | - | ||||||||||||
2495 | switch (event->type()) { | - | ||||||||||||
2496 | #ifdef Q_DEAD_CODE_FROM_QT4_WIN | - | ||||||||||||
2497 | // QWidgetPrivate::hide_helper activates another sub-window when closing a | - | ||||||||||||
2498 | // modal dialog on Windows (see activateWindow() inside the ifdef). | - | ||||||||||||
2499 | case QEvent::WindowUnblocked: | - | ||||||||||||
2500 | d->activateCurrentWindow(); | - | ||||||||||||
2501 | break; | - | ||||||||||||
2502 | #endif | - | ||||||||||||
2503 | case QEvent::WindowActivate: { | - | ||||||||||||
2504 | d->isActivated = true; | - | ||||||||||||
2505 | if (d->childWindows.isEmpty()) | - | ||||||||||||
2506 | break; | - | ||||||||||||
2507 | if (!d->active) | - | ||||||||||||
2508 | d->activateCurrentWindow(); | - | ||||||||||||
2509 | d->setChildActivationEnabled(false, true); | - | ||||||||||||
2510 | break; | - | ||||||||||||
2511 | } | - | ||||||||||||
2512 | case QEvent::WindowDeactivate: | - | ||||||||||||
2513 | d->isActivated = false; | - | ||||||||||||
2514 | d->setChildActivationEnabled(false, true); | - | ||||||||||||
2515 | break; | - | ||||||||||||
2516 | case QEvent::StyleChange: | - | ||||||||||||
2517 | // Re-tile the views if we're in tiled mode. Re-tile means we will change | - | ||||||||||||
2518 | // the geometry of the children, which in turn means 'isSubWindowsTiled' | - | ||||||||||||
2519 | // is set to false, so we have to update the state at the end. | - | ||||||||||||
2520 | if (d->isSubWindowsTiled) { | - | ||||||||||||
2521 | tileSubWindows(); | - | ||||||||||||
2522 | d->isSubWindowsTiled = true; | - | ||||||||||||
2523 | } | - | ||||||||||||
2524 | break; | - | ||||||||||||
2525 | case QEvent::WindowIconChange: | - | ||||||||||||
2526 | foreach (QMdiSubWindow *window, d->childWindows) { | - | ||||||||||||
2527 | if (sanityCheck(window, "QMdiArea::WindowIconChange")) | - | ||||||||||||
2528 | QApplication::sendEvent(window, event); | - | ||||||||||||
2529 | } | - | ||||||||||||
2530 | break; | - | ||||||||||||
2531 | case QEvent::Hide: | - | ||||||||||||
2532 | d->setActive(d->active, false, false); | - | ||||||||||||
2533 | d->setChildActivationEnabled(false); | - | ||||||||||||
2534 | break; | - | ||||||||||||
2535 | #ifndef QT_NO_TABBAR | - | ||||||||||||
2536 | case QEvent::LayoutDirectionChange: | - | ||||||||||||
2537 | d->updateTabBarGeometry(); | - | ||||||||||||
2538 | break; | - | ||||||||||||
2539 | #endif | - | ||||||||||||
2540 | default: | - | ||||||||||||
2541 | break; | - | ||||||||||||
2542 | } | - | ||||||||||||
2543 | return QAbstractScrollArea::event(event); | - | ||||||||||||
2544 | } | - | ||||||||||||
2545 | - | |||||||||||||
2546 | /*! | - | ||||||||||||
2547 | \reimp | - | ||||||||||||
2548 | */ | - | ||||||||||||
2549 | bool QMdiArea::eventFilter(QObject *object, QEvent *event) | - | ||||||||||||
2550 | { | - | ||||||||||||
2551 | if (!object) | - | ||||||||||||
2552 | return QAbstractScrollArea::eventFilter(object, event); | - | ||||||||||||
2553 | - | |||||||||||||
2554 | Q_D(QMdiArea); | - | ||||||||||||
2555 | // Global key events with Ctrl modifier. | - | ||||||||||||
2556 | if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { | - | ||||||||||||
2557 | - | |||||||||||||
2558 | QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); | - | ||||||||||||
2559 | // Ingore key events without a Ctrl modifier (except for press/release on the modifier itself). | - | ||||||||||||
2560 | #ifdef Q_DEAD_CODE_FROM_QT4_MAC | - | ||||||||||||
2561 | if (!(keyEvent->modifiers() & Qt::MetaModifier) && keyEvent->key() != Qt::Key_Meta) | - | ||||||||||||
2562 | #else | - | ||||||||||||
2563 | if (!(keyEvent->modifiers() & Qt::ControlModifier) && keyEvent->key() != Qt::Key_Control) | - | ||||||||||||
2564 | #endif | - | ||||||||||||
2565 | return QAbstractScrollArea::eventFilter(object, event); | - | ||||||||||||
2566 | - | |||||||||||||
2567 | // Find closest mdi area (in case we have a nested workspace). | - | ||||||||||||
2568 | QMdiArea *area = mdiAreaParent(static_cast<QWidget *>(object)); | - | ||||||||||||
2569 | if (!area) | - | ||||||||||||
2570 | return QAbstractScrollArea::eventFilter(object, event); | - | ||||||||||||
2571 | - | |||||||||||||
2572 | const bool keyPress = (event->type() == QEvent::KeyPress); | - | ||||||||||||
2573 | - | |||||||||||||
2574 | // 1) Ctrl-Tab once -> activate the previously active window. | - | ||||||||||||
2575 | // 2) Ctrl-Tab (Tab, Tab, ...) -> iterate through all windows (activateNextSubWindow()). | - | ||||||||||||
2576 | // 3) Ctrl-Shift-Tab (Tab, Tab, ...) -> iterate through all windows in the opposite | - | ||||||||||||
2577 | // direction (activatePreviousSubWindow()) | - | ||||||||||||
2578 | switch (keyEvent->key()) { | - | ||||||||||||
2579 | #ifdef Q_DEAD_CODE_FROM_QT4_MAC | - | ||||||||||||
2580 | case Qt::Key_Meta: | - | ||||||||||||
2581 | #else | - | ||||||||||||
2582 | case Qt::Key_Control: | - | ||||||||||||
2583 | #endif | - | ||||||||||||
2584 | if (keyPress) | - | ||||||||||||
2585 | area->d_func()->startTabToPreviousTimer(); | - | ||||||||||||
2586 | else | - | ||||||||||||
2587 | area->d_func()->activateHighlightedWindow(); | - | ||||||||||||
2588 | break; | - | ||||||||||||
2589 | case Qt::Key_Tab: | - | ||||||||||||
2590 | case Qt::Key_Backtab: | - | ||||||||||||
2591 | if (keyPress) | - | ||||||||||||
2592 | area->d_func()->highlightNextSubWindow(keyEvent->key() == Qt::Key_Tab ? 1 : -1); | - | ||||||||||||
2593 | return true; | - | ||||||||||||
2594 | #ifndef QT_NO_RUBBERBAND | - | ||||||||||||
2595 | case Qt::Key_Escape: | - | ||||||||||||
2596 | area->d_func()->hideRubberBand(); | - | ||||||||||||
2597 | break; | - | ||||||||||||
2598 | #endif | - | ||||||||||||
2599 | default: | - | ||||||||||||
2600 | break; | - | ||||||||||||
2601 | } | - | ||||||||||||
2602 | return QAbstractScrollArea::eventFilter(object, event); | - | ||||||||||||
2603 | } | - | ||||||||||||
2604 | - | |||||||||||||
2605 | QMdiSubWindow *subWindow = qobject_cast<QMdiSubWindow *>(object); | - | ||||||||||||
2606 | - | |||||||||||||
2607 | if (!subWindow) { | - | ||||||||||||
2608 | // QApplication events: | - | ||||||||||||
2609 | if (event->type() == QEvent::ApplicationActivate && !d->active | - | ||||||||||||
2610 | && isVisible() && !window()->isMinimized()) { | - | ||||||||||||
2611 | d->activateCurrentWindow(); | - | ||||||||||||
2612 | } else if (event->type() == QEvent::ApplicationDeactivate && d->active) { | - | ||||||||||||
2613 | d->setActive(d->active, false, false); | - | ||||||||||||
2614 | } | - | ||||||||||||
2615 | return QAbstractScrollArea::eventFilter(object, event); | - | ||||||||||||
2616 | } | - | ||||||||||||
2617 | - | |||||||||||||
2618 | if (subWindow->mdiArea() != this) | - | ||||||||||||
2619 | return QAbstractScrollArea::eventFilter(object, event); | - | ||||||||||||
2620 | - | |||||||||||||
2621 | // QMdiSubWindow events: | - | ||||||||||||
2622 | switch (event->type()) { | - | ||||||||||||
2623 | case QEvent::Move: | - | ||||||||||||
2624 | case QEvent::Resize: | - | ||||||||||||
2625 | if (d->tileCalledFromResizeEvent) | - | ||||||||||||
2626 | break; | - | ||||||||||||
2627 | d->updateScrollBars(); | - | ||||||||||||
2628 | if (!subWindow->isMinimized()) | - | ||||||||||||
2629 | d->isSubWindowsTiled = false; | - | ||||||||||||
2630 | break; | - | ||||||||||||
2631 | case QEvent::Show: | - | ||||||||||||
2632 | #ifndef QT_NO_TABBAR | - | ||||||||||||
2633 | if (d->tabBar) { | - | ||||||||||||
2634 | const int tabIndex = d->childWindows.indexOf(subWindow); | - | ||||||||||||
2635 | if (!d->tabBar->isTabEnabled(tabIndex)) | - | ||||||||||||
2636 | d->tabBar->setTabEnabled(tabIndex, true); | - | ||||||||||||
2637 | } | - | ||||||||||||
2638 | #endif // QT_NO_TABBAR | - | ||||||||||||
2639 | // fall through | - | ||||||||||||
2640 | case QEvent::Hide: | - | ||||||||||||
2641 | d->isSubWindowsTiled = false; | - | ||||||||||||
2642 | break; | - | ||||||||||||
2643 | #ifndef QT_NO_RUBBERBAND | - | ||||||||||||
2644 | case QEvent::Close: | - | ||||||||||||
2645 | if (d->childWindows.indexOf(subWindow) == d->indexToHighlighted) | - | ||||||||||||
2646 | d->hideRubberBand(); | - | ||||||||||||
2647 | break; | - | ||||||||||||
2648 | #endif | - | ||||||||||||
2649 | #ifndef QT_NO_TABBAR | - | ||||||||||||
2650 | case QEvent::WindowTitleChange: | - | ||||||||||||
2651 | case QEvent::ModifiedChange: | - | ||||||||||||
2652 | if (d->tabBar) | - | ||||||||||||
2653 | d->tabBar->setTabText(d->childWindows.indexOf(subWindow), tabTextFor(subWindow)); | - | ||||||||||||
2654 | break; | - | ||||||||||||
2655 | case QEvent::WindowIconChange: | - | ||||||||||||
2656 | if (d->tabBar) | - | ||||||||||||
2657 | d->tabBar->setTabIcon(d->childWindows.indexOf(subWindow), subWindow->windowIcon()); | - | ||||||||||||
2658 | break; | - | ||||||||||||
2659 | #endif // QT_NO_TABBAR | - | ||||||||||||
2660 | default: | - | ||||||||||||
2661 | break; | - | ||||||||||||
2662 | } | - | ||||||||||||
2663 | return QAbstractScrollArea::eventFilter(object, event); | - | ||||||||||||
2664 | } | - | ||||||||||||
2665 | - | |||||||||||||
2666 | /*! | - | ||||||||||||
2667 | \reimp | - | ||||||||||||
2668 | */ | - | ||||||||||||
2669 | void QMdiArea::paintEvent(QPaintEvent *paintEvent) | - | ||||||||||||
2670 | { | - | ||||||||||||
2671 | Q_D(QMdiArea); | - | ||||||||||||
2672 | QPainter painter(d->viewport); | - | ||||||||||||
2673 | const QVector<QRect> &exposedRects = paintEvent->region().rects(); | - | ||||||||||||
2674 | for (int i = 0; i < exposedRects.size(); ++i) | - | ||||||||||||
2675 | painter.fillRect(exposedRects.at(i), d->background); | - | ||||||||||||
2676 | } | - | ||||||||||||
2677 | - | |||||||||||||
2678 | /*! | - | ||||||||||||
2679 | This slot is called by QAbstractScrollArea after setViewport() has been | - | ||||||||||||
2680 | called. Reimplement this function in a subclass of QMdiArea to | - | ||||||||||||
2681 | initialize the new \a viewport before it is used. | - | ||||||||||||
2682 | - | |||||||||||||
2683 | \sa setViewport() | - | ||||||||||||
2684 | */ | - | ||||||||||||
2685 | void QMdiArea::setupViewport(QWidget *viewport) | - | ||||||||||||
2686 | { | - | ||||||||||||
2687 | Q_D(QMdiArea); | - | ||||||||||||
2688 | if (viewport) | - | ||||||||||||
2689 | viewport->setAttribute(Qt::WA_OpaquePaintEvent, d->background.isOpaque()); | - | ||||||||||||
2690 | foreach (QMdiSubWindow *child, d->childWindows) { | - | ||||||||||||
2691 | if (!sanityCheck(child, "QMdiArea::setupViewport")) | - | ||||||||||||
2692 | continue; | - | ||||||||||||
2693 | child->setParent(viewport, child->windowFlags()); | - | ||||||||||||
2694 | } | - | ||||||||||||
2695 | } | - | ||||||||||||
2696 | - | |||||||||||||
2697 | QT_END_NAMESPACE | - | ||||||||||||
2698 | - | |||||||||||||
2699 | #include "moc_qmdiarea.cpp" | - | ||||||||||||
2700 | - | |||||||||||||
2701 | #endif // QT_NO_MDIAREA | - | ||||||||||||
Source code | Switch to Preprocessed file |