source: trunk/src/gui/widgets/qworkspace.cpp@ 147

Last change on this file since 147 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 102.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qworkspace.h"
43#ifndef QT_NO_WORKSPACE
44#include "qapplication.h"
45#include "qbitmap.h"
46#include "qcursor.h"
47#include "qdatetime.h"
48#include "qdesktopwidget.h"
49#include "qevent.h"
50#include "qhash.h"
51#include "qicon.h"
52#include "qimage.h"
53#include "qlabel.h"
54#include "qlayout.h"
55#include "qmenubar.h"
56#include "qmenu.h"
57#include "qpainter.h"
58#include "qpointer.h"
59#include "qscrollbar.h"
60#include "qstyle.h"
61#include "qstyleoption.h"
62#include "qtooltip.h"
63#include "qdebug.h"
64#include <private/qwidget_p.h>
65#include <private/qwidgetresizehandler_p.h>
66#include <private/qlayoutengine_p.h>
67
68QT_BEGIN_NAMESPACE
69
70class QWorkspaceTitleBarPrivate;
71
72
73/**************************************************************
74* QMDIControl
75*
76* Used for displaying MDI controls in a maximized MDI window
77*
78*/
79class QMDIControl : public QWidget
80{
81 Q_OBJECT
82signals:
83 void _q_minimize();
84 void _q_restore();
85 void _q_close();
86
87public:
88 QMDIControl(QWidget *widget);
89
90private:
91 QSize sizeHint() const;
92 void paintEvent(QPaintEvent *event);
93 void mousePressEvent(QMouseEvent *event);
94 void mouseReleaseEvent(QMouseEvent *event);
95 void mouseMoveEvent(QMouseEvent *event);
96 void leaveEvent(QEvent *event);
97 bool event(QEvent *event);
98 void initStyleOption(QStyleOptionComplex *option) const;
99 QStyle::SubControl activeControl; //control locked by pressing and holding the mouse
100 QStyle::SubControl hoverControl; //previously active hover control, used for tracking repaints
101};
102
103bool QMDIControl::event(QEvent *event)
104{
105 if (event->type() == QEvent::ToolTip) {
106 QStyleOptionComplex opt;
107 initStyleOption(&opt);
108#ifndef QT_NO_TOOLTIP
109 QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
110 QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
111 helpEvent->pos(), this);
112 if (ctrl == QStyle::SC_MdiCloseButton)
113 QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Close"));
114 else if (ctrl == QStyle::SC_MdiMinButton)
115 QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Minimize"));
116 else if (ctrl == QStyle::SC_MdiNormalButton)
117 QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Restore Down"));
118 else
119 QToolTip::hideText();
120#endif // QT_NO_TOOLTIP
121 }
122 return QWidget::event(event);
123}
124
125void QMDIControl::initStyleOption(QStyleOptionComplex *option) const
126{
127 option->initFrom(this);
128 option->subControls = QStyle::SC_All;
129 option->activeSubControls = QStyle::SC_None;
130}
131
132QMDIControl::QMDIControl(QWidget *widget)
133 : QWidget(widget), activeControl(QStyle::SC_None),
134 hoverControl(QStyle::SC_None)
135{
136 setObjectName(QLatin1String("qt_maxcontrols"));
137 setFocusPolicy(Qt::NoFocus);
138 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
139 setMouseTracking(true);
140}
141
142QSize QMDIControl::sizeHint() const
143{
144 ensurePolished();
145 QStyleOptionComplex opt;
146 initStyleOption(&opt);
147 QSize size(48, 16);
148 return style()->sizeFromContents(QStyle::CT_MdiControls, &opt, size, this);
149}
150
151void QMDIControl::mousePressEvent(QMouseEvent *event)
152{
153 if (event->button() != Qt::LeftButton) {
154 event->ignore();
155 return;
156 }
157 QStyleOptionComplex opt;
158 initStyleOption(&opt);
159 QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
160 event->pos(), this);
161 activeControl = ctrl;
162 update();
163}
164
165void QMDIControl::mouseReleaseEvent(QMouseEvent *event)
166{
167 if (event->button() != Qt::LeftButton) {
168 event->ignore();
169 return;
170 }
171 QStyleOptionTitleBar opt;
172 initStyleOption(&opt);
173 QStyle::SubControl under_mouse = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
174 event->pos(), this);
175 if (under_mouse == activeControl) {
176 switch (activeControl) {
177 case QStyle::SC_MdiCloseButton:
178 emit _q_close();
179 break;
180 case QStyle::SC_MdiNormalButton:
181 emit _q_restore();
182 break;
183 case QStyle::SC_MdiMinButton:
184 emit _q_minimize();
185 break;
186 default:
187 break;
188 }
189 }
190 activeControl = QStyle::SC_None;
191 update();
192}
193
194void QMDIControl::leaveEvent(QEvent * /*event*/)
195{
196 hoverControl = QStyle::SC_None;
197 update();
198}
199
200void QMDIControl::mouseMoveEvent(QMouseEvent *event)
201{
202 QStyleOptionTitleBar opt;
203 initStyleOption(&opt);
204 QStyle::SubControl under_mouse = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
205 event->pos(), this);
206 //test if hover state changes
207 if (hoverControl != under_mouse) {
208 hoverControl = under_mouse;
209 update();
210 }
211}
212
213void QMDIControl::paintEvent(QPaintEvent *)
214{
215 QPainter p(this);
216 QStyleOptionComplex opt;
217 initStyleOption(&opt);
218 if (activeControl == hoverControl) {
219 opt.activeSubControls = activeControl;
220 opt.state |= QStyle::State_Sunken;
221 } else if (hoverControl != QStyle::SC_None && (activeControl == QStyle::SC_None)) {
222 opt.activeSubControls = hoverControl;
223 opt.state |= QStyle::State_MouseOver;
224 }
225 style()->drawComplexControl(QStyle::CC_MdiControls, &opt, &p, this);
226}
227
228class QWorkspaceTitleBar : public QWidget
229{
230 Q_OBJECT
231 Q_DECLARE_PRIVATE(QWorkspaceTitleBar)
232 Q_PROPERTY(bool autoRaise READ autoRaise WRITE setAutoRaise)
233 Q_PROPERTY(bool movable READ isMovable WRITE setMovable)
234
235public:
236 QWorkspaceTitleBar (QWidget *w, QWidget *parent, Qt::WindowFlags f = 0);
237 ~QWorkspaceTitleBar();
238
239 bool isActive() const;
240 bool usesActiveColor() const;
241
242 bool isMovable() const;
243 void setMovable(bool);
244
245 bool autoRaise() const;
246 void setAutoRaise(bool);
247
248 QWidget *window() const;
249 bool isTool() const;
250
251 QSize sizeHint() const;
252 void initStyleOption(QStyleOptionTitleBar *option) const;
253
254public slots:
255 void setActive(bool);
256
257signals:
258 void doActivate();
259 void doNormal();
260 void doClose();
261 void doMaximize();
262 void doMinimize();
263 void doShade();
264 void showOperationMenu();
265 void popupOperationMenu(const QPoint&);
266 void doubleClicked();
267
268protected:
269 bool event(QEvent *);
270#ifndef QT_NO_CONTEXTMENU
271 void contextMenuEvent(QContextMenuEvent *);
272#endif
273 void mousePressEvent(QMouseEvent *);
274 void mouseDoubleClickEvent(QMouseEvent *);
275 void mouseReleaseEvent(QMouseEvent *);
276 void mouseMoveEvent(QMouseEvent *);
277 void enterEvent(QEvent *e);
278 void leaveEvent(QEvent *e);
279 void paintEvent(QPaintEvent *p);
280
281private:
282 Q_DISABLE_COPY(QWorkspaceTitleBar)
283};
284
285
286class QWorkspaceTitleBarPrivate : public QWidgetPrivate
287{
288 Q_DECLARE_PUBLIC(QWorkspaceTitleBar)
289public:
290 QWorkspaceTitleBarPrivate()
291 :
292 lastControl(QStyle::SC_None),
293#ifndef QT_NO_TOOLTIP
294 toolTip(0),
295#endif
296 act(0), window(0), movable(1), pressed(0), autoraise(0), moving(0)
297 {
298 }
299
300 Qt::WindowFlags flags;
301 QStyle::SubControl buttonDown;
302 QStyle::SubControl lastControl;
303 QPoint moveOffset;
304#ifndef QT_NO_TOOLTIP
305 QToolTip *toolTip;
306#endif
307 bool act :1;
308 QPointer<QWidget> window;
309 bool movable :1;
310 bool pressed :1;
311 bool autoraise :1;
312 bool moving : 1;
313
314 int titleBarState() const;
315 void readColors();
316};
317
318inline int QWorkspaceTitleBarPrivate::titleBarState() const
319{
320 Q_Q(const QWorkspaceTitleBar);
321 uint state = window ? window->windowState() : static_cast<Qt::WindowStates>(Qt::WindowNoState);
322 state |= uint((act && q->isActiveWindow()) ? QStyle::State_Active : QStyle::State_None);
323 return (int)state;
324}
325
326void QWorkspaceTitleBar::initStyleOption(QStyleOptionTitleBar *option) const
327{
328 Q_D(const QWorkspaceTitleBar);
329 option->initFrom(this);
330 //################
331 if (d->window && (d->flags & Qt::WindowTitleHint)) {
332 option->text = d->window->windowTitle();
333 QIcon icon = d->window->windowIcon();
334 QSize s = icon.actualSize(QSize(64, 64));
335 option->icon = icon.pixmap(s);
336 }
337 option->subControls = QStyle::SC_All;
338 option->activeSubControls = QStyle::SC_None;
339 option->titleBarState = d->titleBarState();
340 option->titleBarFlags = d->flags;
341 option->state &= ~QStyle::State_MouseOver;
342}
343
344QWorkspaceTitleBar::QWorkspaceTitleBar(QWidget *w, QWidget *parent, Qt::WindowFlags f)
345 : QWidget(*new QWorkspaceTitleBarPrivate, parent, Qt::FramelessWindowHint)
346{
347 Q_D(QWorkspaceTitleBar);
348 if (f == 0 && w)
349 f = w->windowFlags();
350 d->flags = f;
351 d->window = w;
352 d->buttonDown = QStyle::SC_None;
353 d->act = 0;
354 if (w) {
355 if (w->maximumSize() != QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX))
356 d->flags &= ~Qt::WindowMaximizeButtonHint;
357 setWindowTitle(w->windowTitle());
358 }
359
360 d->readColors();
361 setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
362 setMouseTracking(true);
363 setAutoRaise(style()->styleHint(QStyle::SH_TitleBar_AutoRaise, 0, this));
364}
365
366QWorkspaceTitleBar::~QWorkspaceTitleBar()
367{
368}
369
370
371#ifdef Q_WS_WIN
372static inline QRgb colorref2qrgb(COLORREF col)
373{
374 return qRgb(GetRValue(col),GetGValue(col),GetBValue(col));
375}
376#endif
377
378void QWorkspaceTitleBarPrivate::readColors()
379{
380 Q_Q(QWorkspaceTitleBar);
381 QPalette pal = q->palette();
382
383 bool colorsInitialized = false;
384
385#ifdef Q_WS_WIN // ask system properties on windows
386#ifndef SPI_GETGRADIENTCAPTIONS
387#define SPI_GETGRADIENTCAPTIONS 0x1008
388#endif
389#ifndef COLOR_GRADIENTACTIVECAPTION
390#define COLOR_GRADIENTACTIVECAPTION 27
391#endif
392#ifndef COLOR_GRADIENTINACTIVECAPTION
393#define COLOR_GRADIENTINACTIVECAPTION 28
394#endif
395 if (QApplication::desktopSettingsAware()) {
396 pal.setColor(QPalette::Active, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION)));
397 pal.setColor(QPalette::Inactive, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)));
398 pal.setColor(QPalette::Active, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)));
399 pal.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)));
400 if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) {
401 colorsInitialized = true;
402 BOOL gradient;
403 QT_WA({
404 SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
405 } , {
406 SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
407 });
408 if (gradient) {
409 pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
410 pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
411 } else {
412 pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight));
413 pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight));
414 }
415 }
416 }
417#endif // Q_WS_WIN
418 if (!colorsInitialized) {
419 pal.setColor(QPalette::Active, QPalette::Highlight,
420 pal.color(QPalette::Active, QPalette::Highlight));
421 pal.setColor(QPalette::Active, QPalette::Base,
422 pal.color(QPalette::Active, QPalette::Highlight));
423 pal.setColor(QPalette::Inactive, QPalette::Highlight,
424 pal.color(QPalette::Inactive, QPalette::Dark));
425 pal.setColor(QPalette::Inactive, QPalette::Base,
426 pal.color(QPalette::Inactive, QPalette::Dark));
427 pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
428 pal.color(QPalette::Inactive, QPalette::Window));
429 }
430
431 q->setPalette(pal);
432 q->setActive(act);
433}
434
435void QWorkspaceTitleBar::mousePressEvent(QMouseEvent *e)
436{
437 Q_D(QWorkspaceTitleBar);
438 if (!d->act)
439 emit doActivate();
440 if (e->button() == Qt::LeftButton) {
441 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
442 && !rect().adjusted(5, 5, -5, 0).contains(e->pos())) {
443 // propagate border events to the QWidgetResizeHandler
444 e->ignore();
445 return;
446 }
447
448 d->pressed = true;
449 QStyleOptionTitleBar opt;
450 initStyleOption(&opt);
451 QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
452 e->pos(), this);
453 switch (ctrl) {
454 case QStyle::SC_TitleBarSysMenu:
455 if (d->flags & Qt::WindowSystemMenuHint) {
456 d->buttonDown = QStyle::SC_None;
457 static QTime *t = 0;
458 static QWorkspaceTitleBar *tc = 0;
459 if (!t)
460 t = new QTime;
461 if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) {
462 emit showOperationMenu();
463 t->start();
464 tc = this;
465 } else {
466 tc = 0;
467 emit doClose();
468 return;
469 }
470 }
471 break;
472
473 case QStyle::SC_TitleBarShadeButton:
474 case QStyle::SC_TitleBarUnshadeButton:
475 if (d->flags & Qt::WindowShadeButtonHint)
476 d->buttonDown = ctrl;
477 break;
478
479 case QStyle::SC_TitleBarNormalButton:
480 d->buttonDown = ctrl;
481 break;
482
483 case QStyle::SC_TitleBarMinButton:
484 if (d->flags & Qt::WindowMinimizeButtonHint)
485 d->buttonDown = ctrl;
486 break;
487
488 case QStyle::SC_TitleBarMaxButton:
489 if (d->flags & Qt::WindowMaximizeButtonHint)
490 d->buttonDown = ctrl;
491 break;
492
493 case QStyle::SC_TitleBarCloseButton:
494 if (d->flags & Qt::WindowSystemMenuHint)
495 d->buttonDown = ctrl;
496 break;
497
498 case QStyle::SC_TitleBarLabel:
499 d->buttonDown = ctrl;
500 d->moveOffset = mapToParent(e->pos());
501 break;
502
503 default:
504 break;
505 }
506 update();
507 } else {
508 d->pressed = false;
509 }
510}
511
512#ifndef QT_NO_CONTEXTMENU
513void QWorkspaceTitleBar::contextMenuEvent(QContextMenuEvent *e)
514{
515 QStyleOptionTitleBar opt;
516 initStyleOption(&opt);
517 QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(),
518 this);
519 if(ctrl == QStyle::SC_TitleBarLabel || ctrl == QStyle::SC_TitleBarSysMenu) {
520 e->accept();
521 emit popupOperationMenu(e->globalPos());
522 } else {
523 e->ignore();
524 }
525}
526#endif // QT_NO_CONTEXTMENU
527
528void QWorkspaceTitleBar::mouseReleaseEvent(QMouseEvent *e)
529{
530 Q_D(QWorkspaceTitleBar);
531 if (!d->window) {
532 // could have been deleted as part of a double click event on the sysmenu
533 return;
534 }
535 if (e->button() == Qt::LeftButton && d->pressed) {
536 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
537 && !rect().adjusted(5, 5, -5, 0).contains(e->pos())) {
538 // propagate border events to the QWidgetResizeHandler
539 e->ignore();
540 d->buttonDown = QStyle::SC_None;
541 d->pressed = false;
542 return;
543 }
544 e->accept();
545 QStyleOptionTitleBar opt;
546 initStyleOption(&opt);
547 QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
548 e->pos(), this);
549
550 if (d->pressed) {
551 update();
552 d->pressed = false;
553 d->moving = false;
554 }
555 if (ctrl == d->buttonDown) {
556 d->buttonDown = QStyle::SC_None;
557 switch(ctrl) {
558 case QStyle::SC_TitleBarShadeButton:
559 case QStyle::SC_TitleBarUnshadeButton:
560 if(d->flags & Qt::WindowShadeButtonHint)
561 emit doShade();
562 break;
563
564 case QStyle::SC_TitleBarNormalButton:
565 if(d->flags & Qt::WindowMinMaxButtonsHint)
566 emit doNormal();
567 break;
568
569 case QStyle::SC_TitleBarMinButton:
570 if(d->flags & Qt::WindowMinimizeButtonHint) {
571 if (d->window && d->window->isMinimized())
572 emit doNormal();
573 else
574 emit doMinimize();
575 }
576 break;
577
578 case QStyle::SC_TitleBarMaxButton:
579 if(d->flags & Qt::WindowMaximizeButtonHint) {
580 if(d->window && d->window->isMaximized())
581 emit doNormal();
582 else
583 emit doMaximize();
584 }
585 break;
586
587 case QStyle::SC_TitleBarCloseButton:
588 if(d->flags & Qt::WindowSystemMenuHint) {
589 d->buttonDown = QStyle::SC_None;
590 emit doClose();
591 return;
592 }
593 break;
594
595 default:
596 break;
597 }
598 }
599 } else {
600 e->ignore();
601 }
602}
603
604void QWorkspaceTitleBar::mouseMoveEvent(QMouseEvent *e)
605{
606 Q_D(QWorkspaceTitleBar);
607 e->ignore();
608 if ((e->buttons() & Qt::LeftButton) && style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
609 && !rect().adjusted(5, 5, -5, 0).contains(e->pos()) && !d->pressed) {
610 // propagate border events to the QWidgetResizeHandler
611 return;
612 }
613
614 QStyleOptionTitleBar opt;
615 initStyleOption(&opt);
616 QStyle::SubControl under_mouse = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
617 e->pos(), this);
618 if(under_mouse != d->lastControl) {
619 d->lastControl = under_mouse;
620 update();
621 }
622
623 switch (d->buttonDown) {
624 case QStyle::SC_None:
625 break;
626 case QStyle::SC_TitleBarSysMenu:
627 break;
628 case QStyle::SC_TitleBarLabel:
629 if (d->buttonDown == QStyle::SC_TitleBarLabel && d->movable && d->pressed) {
630 if (d->moving || (d->moveOffset - mapToParent(e->pos())).manhattanLength() >= 4) {
631 d->moving = true;
632 QPoint p = mapFromGlobal(e->globalPos());
633
634 QWidget *parent = d->window ? d->window->parentWidget() : 0;
635 if(parent && parent->inherits("QWorkspaceChild")) {
636 QWidget *workspace = parent->parentWidget();
637 p = workspace->mapFromGlobal(e->globalPos());
638 if (!workspace->rect().contains(p)) {
639 if (p.x() < 0)
640 p.rx() = 0;
641 if (p.y() < 0)
642 p.ry() = 0;
643 if (p.x() > workspace->width())
644 p.rx() = workspace->width();
645 if (p.y() > workspace->height())
646 p.ry() = workspace->height();
647 }
648 }
649
650 QPoint pp = p - d->moveOffset;
651 if (!parentWidget()->isMaximized())
652 parentWidget()->move(pp);
653 }
654 }
655 e->accept();
656 break;
657 default:
658 break;
659 }
660}
661
662bool QWorkspaceTitleBar::isTool() const
663{
664 Q_D(const QWorkspaceTitleBar);
665 return (d->flags & Qt::WindowType_Mask) == Qt::Tool;
666}
667
668// from qwidget.cpp
669extern QString qt_setWindowTitle_helperHelper(const QString &, const QWidget*);
670
671void QWorkspaceTitleBar::paintEvent(QPaintEvent *)
672{
673 Q_D(QWorkspaceTitleBar);
674 QStyleOptionTitleBar opt;
675 initStyleOption(&opt);
676 opt.subControls = QStyle::SC_TitleBarLabel;
677 opt.activeSubControls = d->buttonDown;
678
679 if (d->window && (d->flags & Qt::WindowTitleHint)) {
680 QString title = qt_setWindowTitle_helperHelper(opt.text, d->window);
681 int maxw = style()->subControlRect(QStyle::CC_TitleBar, &opt, QStyle::SC_TitleBarLabel,
682 this).width();
683 opt.text = fontMetrics().elidedText(title, Qt::ElideRight, maxw);
684 }
685
686 if (d->flags & Qt::WindowSystemMenuHint) {
687 opt.subControls |= QStyle::SC_TitleBarSysMenu | QStyle::SC_TitleBarCloseButton;
688 if (d->window && (d->flags & Qt::WindowShadeButtonHint)) {
689 if (d->window->isMinimized())
690 opt.subControls |= QStyle::SC_TitleBarUnshadeButton;
691 else
692 opt.subControls |= QStyle::SC_TitleBarShadeButton;
693 }
694 if (d->window && (d->flags & Qt::WindowMinMaxButtonsHint)) {
695 if(d->window && d->window->isMinimized())
696 opt.subControls |= QStyle::SC_TitleBarNormalButton;
697 else
698 opt.subControls |= QStyle::SC_TitleBarMinButton;
699 }
700 if (d->window && (d->flags & Qt::WindowMaximizeButtonHint) && !d->window->isMaximized())
701 opt.subControls |= QStyle::SC_TitleBarMaxButton;
702 }
703
704 QStyle::SubControl under_mouse = QStyle::SC_None;
705 under_mouse = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
706 mapFromGlobal(QCursor::pos()), this);
707 if ((d->buttonDown == under_mouse) && d->pressed) {
708 opt.state |= QStyle::State_Sunken;
709 } else if( autoRaise() && under_mouse != QStyle::SC_None && !d->pressed) {
710 opt.activeSubControls = under_mouse;
711 opt.state |= QStyle::State_MouseOver;
712 }
713 opt.palette.setCurrentColorGroup(usesActiveColor() ? QPalette::Active : QPalette::Inactive);
714
715 QPainter p(this);
716 style()->drawComplexControl(QStyle::CC_TitleBar, &opt, &p, this);
717}
718
719void QWorkspaceTitleBar::mouseDoubleClickEvent(QMouseEvent *e)
720{
721 Q_D(QWorkspaceTitleBar);
722 if (e->button() != Qt::LeftButton) {
723 e->ignore();
724 return;
725 }
726 e->accept();
727 QStyleOptionTitleBar opt;
728 initStyleOption(&opt);
729 switch (style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(), this)) {
730 case QStyle::SC_TitleBarLabel:
731 emit doubleClicked();
732 break;
733
734 case QStyle::SC_TitleBarSysMenu:
735 if (d->flags & Qt::WindowSystemMenuHint)
736 emit doClose();
737 break;
738
739 default:
740 break;
741 }
742}
743
744void QWorkspaceTitleBar::leaveEvent(QEvent *)
745{
746 Q_D(QWorkspaceTitleBar);
747 d->lastControl = QStyle::SC_None;
748 if(autoRaise() && !d->pressed)
749 update();
750}
751
752void QWorkspaceTitleBar::enterEvent(QEvent *)
753{
754 Q_D(QWorkspaceTitleBar);
755 if(autoRaise() && !d->pressed)
756 update();
757 QEvent e(QEvent::Leave);
758 QApplication::sendEvent(parentWidget(), &e);
759}
760
761void QWorkspaceTitleBar::setActive(bool active)
762{
763 Q_D(QWorkspaceTitleBar);
764 if (d->act == active)
765 return ;
766
767 d->act = active;
768 update();
769}
770
771bool QWorkspaceTitleBar::isActive() const
772{
773 Q_D(const QWorkspaceTitleBar);
774 return d->act;
775}
776
777bool QWorkspaceTitleBar::usesActiveColor() const
778{
779 return (isActive() && isActiveWindow()) ||
780 (!window() && QWidget::window()->isActiveWindow());
781}
782
783QWidget *QWorkspaceTitleBar::window() const
784{
785 Q_D(const QWorkspaceTitleBar);
786 return d->window;
787}
788
789bool QWorkspaceTitleBar::event(QEvent *e)
790{
791 Q_D(QWorkspaceTitleBar);
792 if (e->type() == QEvent::ApplicationPaletteChange) {
793 d->readColors();
794 } else if (e->type() == QEvent::WindowActivate
795 || e->type() == QEvent::WindowDeactivate) {
796 if (d->act)
797 update();
798 }
799 return QWidget::event(e);
800}
801
802void QWorkspaceTitleBar::setMovable(bool b)
803{
804 Q_D(QWorkspaceTitleBar);
805 d->movable = b;
806}
807
808bool QWorkspaceTitleBar::isMovable() const
809{
810 Q_D(const QWorkspaceTitleBar);
811 return d->movable;
812}
813
814void QWorkspaceTitleBar::setAutoRaise(bool b)
815{
816 Q_D(QWorkspaceTitleBar);
817 d->autoraise = b;
818}
819
820bool QWorkspaceTitleBar::autoRaise() const
821{
822 Q_D(const QWorkspaceTitleBar);
823 return d->autoraise;
824}
825
826QSize QWorkspaceTitleBar::sizeHint() const
827{
828 ensurePolished();
829 QStyleOptionTitleBar opt;
830 initStyleOption(&opt);
831 QRect menur = style()->subControlRect(QStyle::CC_TitleBar, &opt,
832 QStyle::SC_TitleBarSysMenu, this);
833 return QSize(menur.width(), style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, this));
834}
835
836/*!
837 \class QWorkspace
838 \obsolete
839 \brief The QWorkspace widget provides a workspace window that can be
840 used in an MDI application.
841 \ingroup application
842
843 This class is deprecated. Use QMdiArea instead.
844
845 Multiple Document Interface (MDI) applications are typically
846 composed of a main window containing a menu bar, a toolbar, and
847 a central QWorkspace widget. The workspace itself is used to display
848 a number of child windows, each of which is a widget.
849
850 The workspace itself is an ordinary Qt widget. It has a standard
851 constructor that takes a parent widget.
852 Workspaces can be placed in any layout, but are typically given
853 as the central widget in a QMainWindow:
854
855 \snippet doc/src/snippets/code/src_gui_widgets_qworkspace.cpp 0
856
857 Child windows (MDI windows) are standard Qt widgets that are
858 inserted into the workspace with addWindow(). As with top-level
859 widgets, you can call functions such as show(), hide(),
860 showMaximized(), and setWindowTitle() on a child window to change
861 its appearance within the workspace. You can also provide widget
862 flags to determine the layout of the decoration or the behavior of
863 the widget itself.
864
865 To change or retrieve the geometry of a child window, you must
866 operate on its parentWidget(). The parentWidget() provides
867 access to the decorated frame that contains the child window
868 widget. When a child window is maximised, its decorated frame
869 is hidden. If the top-level widget contains a menu bar, it will display
870 the maximised window's operations menu to the left of the menu
871 entries, and the window's controls to the right.
872
873 A child window becomes active when it gets the keyboard focus,
874 or when setFocus() is called. The user can activate a window by moving
875 focus in the usual ways, for example by clicking a window or by pressing
876 Tab. The workspace emits a signal windowActivated() when the active
877 window changes, and the function activeWindow() returns a pointer to the
878 active child window, or 0 if no window is active.
879
880 The convenience function windowList() returns a list of all child
881 windows. This information could be used in a popup menu
882 containing a list of windows, for example. This feature is also
883 available as part of the \l{Window Menu} Solution.
884
885 QWorkspace provides two built-in layout strategies for child
886 windows: cascade() and tile(). Both are slots so you can easily
887 connect menu entries to them.
888
889 \table
890 \row \o \inlineimage mdi-cascade.png
891 \o \inlineimage mdi-tile.png
892 \endtable
893
894 If you want your users to be able to work with child windows
895 larger than the visible workspace area, set the scrollBarsEnabled
896 property to true.
897
898 \sa QDockWidget, {MDI Example}
899*/
900
901
902class QWorkspaceChild : public QWidget
903{
904 Q_OBJECT
905
906 friend class QWorkspacePrivate;
907 friend class QWorkspace;
908 friend class QWorkspaceTitleBar;
909
910public:
911 QWorkspaceChild(QWidget* window, QWorkspace* parent=0, Qt::WindowFlags flags = 0);
912 ~QWorkspaceChild();
913
914 void setActive(bool);
915 bool isActive() const;
916
917 void adjustToFullscreen();
918
919 QWidget* windowWidget() const;
920 QWidget* iconWidget() const;
921
922 void doResize();
923 void doMove();
924
925 QSize sizeHint() const;
926 QSize minimumSizeHint() const;
927
928 QSize baseSize() const;
929
930 int frameWidth() const;
931
932 void show();
933
934 bool isWindowOrIconVisible() const;
935
936signals:
937 void showOperationMenu();
938 void popupOperationMenu(const QPoint&);
939
940public slots:
941 void activate();
942 void showMinimized();
943 void showMaximized();
944 void showNormal();
945 void showShaded();
946 void internalRaise();
947 void titleBarDoubleClicked();
948
949protected:
950 void enterEvent(QEvent *);
951 void leaveEvent(QEvent *);
952 void childEvent(QChildEvent*);
953 void resizeEvent(QResizeEvent *);
954 void moveEvent(QMoveEvent *);
955 bool eventFilter(QObject *, QEvent *);
956
957 void paintEvent(QPaintEvent *);
958 void changeEvent(QEvent *);
959
960private:
961 void updateMask();
962
963 Q_DISABLE_COPY(QWorkspaceChild)
964
965 QWidget *childWidget;
966 QWidgetResizeHandler *widgetResizeHandler;
967 QWorkspaceTitleBar *titlebar;
968 QPointer<QWorkspaceTitleBar> iconw;
969 QSize windowSize;
970 QSize shadeRestore;
971 QSize shadeRestoreMin;
972 bool act :1;
973 bool shademode :1;
974};
975
976int QWorkspaceChild::frameWidth() const
977{
978 return contentsRect().left();
979}
980
981
982
983class QWorkspacePrivate : public QWidgetPrivate {
984 Q_DECLARE_PUBLIC(QWorkspace)
985public:
986 QWorkspaceChild* active;
987 QList<QWorkspaceChild *> windows;
988 QList<QWorkspaceChild *> focus;
989 QList<QWidget *> icons;
990 QWorkspaceChild* maxWindow;
991 QRect maxRestore;
992 QPointer<QMDIControl> maxcontrols;
993 QPointer<QMenuBar> maxmenubar;
994 QHash<int, const char*> shortcutMap;
995
996 int px;
997 int py;
998 QWidget *becomeActive;
999 QPointer<QLabel> maxtools;
1000 QString topTitle;
1001
1002 QMenu *popup, *toolPopup;
1003 enum WSActs { RestoreAct, MoveAct, ResizeAct, MinimizeAct, MaximizeAct, CloseAct, StaysOnTopAct, ShadeAct, NCountAct };
1004 QAction *actions[NCountAct];
1005
1006 QScrollBar *vbar, *hbar;
1007 QWidget *corner;
1008 int yoffset, xoffset;
1009 QBrush background;
1010
1011 void init();
1012 void insertIcon(QWidget* w);
1013 void removeIcon(QWidget* w);
1014 void place(QWidget*);
1015
1016 QWorkspaceChild* findChild(QWidget* w);
1017 void showMaximizeControls();
1018 void hideMaximizeControls();
1019 void activateWindow(QWidget* w, bool change_focus = true);
1020 void hideChild(QWorkspaceChild *c);
1021 void showWindow(QWidget* w);
1022 void maximizeWindow(QWidget* w);
1023 void minimizeWindow(QWidget* w);
1024 void normalizeWindow(QWidget* w);
1025
1026 QRect updateWorkspace();
1027
1028private:
1029 void _q_normalizeActiveWindow();
1030 void _q_minimizeActiveWindow();
1031 void _q_showOperationMenu();
1032 void _q_popupOperationMenu(const QPoint&);
1033 void _q_operationMenuActivated(QAction *);
1034 void _q_scrollBarChanged();
1035 void _q_updateActions();
1036 bool inTitleChange;
1037};
1038
1039static bool isChildOf(QWidget * child, QWidget * parent)
1040{
1041 if (!parent || !child)
1042 return false;
1043 QWidget * w = child;
1044 while(w && w != parent)
1045 w = w->parentWidget();
1046 return w != 0;
1047}
1048
1049/*!
1050 Constructs a workspace with the given \a parent.
1051*/
1052QWorkspace::QWorkspace(QWidget *parent)
1053 : QWidget(*new QWorkspacePrivate, parent, 0)
1054{
1055 Q_D(QWorkspace);
1056 d->init();
1057}
1058
1059#ifdef QT3_SUPPORT
1060/*!
1061 Use one of the constructors that doesn't take the \a name
1062 argument and then use setObjectName() instead.
1063*/
1064QWorkspace::QWorkspace(QWidget *parent, const char *name)
1065 : QWidget(*new QWorkspacePrivate, parent, 0)
1066{
1067 Q_D(QWorkspace);
1068 setObjectName(QString::fromAscii(name));
1069 d->init();
1070}
1071#endif // QT3_SUPPORT
1072
1073/*!
1074 \internal
1075*/
1076void
1077QWorkspacePrivate::init()
1078{
1079 Q_Q(QWorkspace);
1080
1081 maxcontrols = 0;
1082 active = 0;
1083 maxWindow = 0;
1084 maxtools = 0;
1085 px = 0;
1086 py = 0;
1087 becomeActive = 0;
1088 popup = new QMenu(q);
1089 toolPopup = new QMenu(q);
1090 popup->setObjectName(QLatin1String("qt_internal_mdi_popup"));
1091 toolPopup->setObjectName(QLatin1String("qt_internal_mdi_tool_popup"));
1092
1093 actions[QWorkspacePrivate::RestoreAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarNormalButton, 0, q)),
1094 QWorkspace::tr("&Restore"), q);
1095 actions[QWorkspacePrivate::MoveAct] = new QAction(QWorkspace::tr("&Move"), q);
1096 actions[QWorkspacePrivate::ResizeAct] = new QAction(QWorkspace::tr("&Size"), q);
1097 actions[QWorkspacePrivate::MinimizeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarMinButton, 0, q)),
1098 QWorkspace::tr("Mi&nimize"), q);
1099 actions[QWorkspacePrivate::MaximizeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarMaxButton, 0, q)),
1100 QWorkspace::tr("Ma&ximize"), q);
1101 actions[QWorkspacePrivate::CloseAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, q)),
1102 QWorkspace::tr("&Close")
1103#ifndef QT_NO_SHORTCUT
1104 +QLatin1Char('\t')+(QString)QKeySequence(Qt::CTRL+Qt::Key_F4)
1105#endif
1106 ,q);
1107 QObject::connect(actions[QWorkspacePrivate::CloseAct], SIGNAL(triggered()), q, SLOT(closeActiveWindow()));
1108 actions[QWorkspacePrivate::StaysOnTopAct] = new QAction(QWorkspace::tr("Stay on &Top"), q);
1109 actions[QWorkspacePrivate::StaysOnTopAct]->setChecked(true);
1110 actions[QWorkspacePrivate::ShadeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarShadeButton, 0, q)),
1111 QWorkspace::tr("Sh&ade"), q);
1112
1113 QObject::connect(popup, SIGNAL(aboutToShow()), q, SLOT(_q_updateActions()));
1114 QObject::connect(popup, SIGNAL(triggered(QAction*)), q, SLOT(_q_operationMenuActivated(QAction*)));
1115 popup->addAction(actions[QWorkspacePrivate::RestoreAct]);
1116 popup->addAction(actions[QWorkspacePrivate::MoveAct]);
1117 popup->addAction(actions[QWorkspacePrivate::ResizeAct]);
1118 popup->addAction(actions[QWorkspacePrivate::MinimizeAct]);
1119 popup->addAction(actions[QWorkspacePrivate::MaximizeAct]);
1120 popup->addSeparator();
1121 popup->addAction(actions[QWorkspacePrivate::CloseAct]);
1122
1123 QObject::connect(toolPopup, SIGNAL(aboutToShow()), q, SLOT(_q_updateActions()));
1124 QObject::connect(toolPopup, SIGNAL(triggered(QAction*)), q, SLOT(_q_operationMenuActivated(QAction*)));
1125 toolPopup->addAction(actions[QWorkspacePrivate::MoveAct]);
1126 toolPopup->addAction(actions[QWorkspacePrivate::ResizeAct]);
1127 toolPopup->addAction(actions[QWorkspacePrivate::StaysOnTopAct]);
1128 toolPopup->addSeparator();
1129 toolPopup->addAction(actions[QWorkspacePrivate::ShadeAct]);
1130 toolPopup->addAction(actions[QWorkspacePrivate::CloseAct]);
1131
1132#ifndef QT_NO_SHORTCUT
1133 // Set up shortcut bindings (id -> slot), most used first
1134 QList <QKeySequence> shortcuts = QKeySequence::keyBindings(QKeySequence::NextChild);
1135 foreach (const QKeySequence &seq, shortcuts)
1136 shortcutMap.insert(q->grabShortcut(seq), "activateNextWindow");
1137
1138 shortcuts = QKeySequence::keyBindings(QKeySequence::PreviousChild);
1139 foreach (const QKeySequence &seq, shortcuts)
1140 shortcutMap.insert(q->grabShortcut(seq), "activatePreviousWindow");
1141
1142 shortcuts = QKeySequence::keyBindings(QKeySequence::Close);
1143 foreach (const QKeySequence &seq, shortcuts)
1144 shortcutMap.insert(q->grabShortcut(seq), "closeActiveWindow");
1145
1146 shortcutMap.insert(q->grabShortcut(QKeySequence(QLatin1String("ALT+-"))), "_q_showOperationMenu");
1147#endif // QT_NO_SHORTCUT
1148
1149 q->setBackgroundRole(QPalette::Dark);
1150 q->setAutoFillBackground(true);
1151 q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
1152
1153 hbar = vbar = 0;
1154 corner = 0;
1155 xoffset = yoffset = 0;
1156
1157 q->window()->installEventFilter(q);
1158
1159 inTitleChange = false;
1160 updateWorkspace();
1161}
1162
1163/*!
1164 Destroys the workspace and frees any allocated resources.
1165*/
1166
1167QWorkspace::~QWorkspace()
1168{
1169}
1170
1171/*! \reimp */
1172QSize QWorkspace::sizeHint() const
1173{
1174 QSize s(QApplication::desktop()->size());
1175 return QSize(s.width()*2/3, s.height()*2/3);
1176}
1177
1178
1179#ifdef QT3_SUPPORT
1180/*!
1181 Sets the background color to \a c.
1182 Use setBackground() instead.
1183*/
1184void QWorkspace::setPaletteBackgroundColor(const QColor & c)
1185{
1186 setBackground(c);
1187}
1188
1189/*!
1190 Sets the background pixmap to \a pm.
1191 Use setBackground() instead.
1192*/
1193void QWorkspace::setPaletteBackgroundPixmap(const QPixmap & pm)
1194{
1195 setBackground(pm);
1196}
1197#endif // QT3_SUPPORT
1198
1199/*!
1200 \property QWorkspace::background
1201 \brief the workspace's background
1202*/
1203QBrush QWorkspace::background() const
1204{
1205 Q_D(const QWorkspace);
1206 if (d->background.style() == Qt::NoBrush)
1207 return palette().dark();
1208 return d->background;
1209}
1210
1211void QWorkspace::setBackground(const QBrush &background)
1212{
1213 Q_D(QWorkspace);
1214 d->background = background;
1215 setAttribute(Qt::WA_OpaquePaintEvent, background.style() == Qt::NoBrush);
1216 update();
1217}
1218
1219/*!
1220 Adds widget \a w as new sub window to the workspace. If \a flags
1221 are non-zero, they will override the flags set on the widget.
1222
1223 Returns the widget used for the window frame.
1224
1225 To remove the widget \a w from the workspace, simply call
1226 setParent() with the new parent (or 0 to make it a stand-alone
1227 window).
1228*/
1229QWidget * QWorkspace::addWindow(QWidget *w, Qt::WindowFlags flags)
1230{
1231 Q_D(QWorkspace);
1232 if (!w)
1233 return 0;
1234
1235 w->setAutoFillBackground(true);
1236
1237 QWidgetPrivate::adjustFlags(flags);
1238
1239#if 0
1240 bool wasMaximized = w->isMaximized();
1241 bool wasMinimized = w->isMinimized();
1242#endif
1243 bool hasSize = w->testAttribute(Qt::WA_Resized);
1244 int x = w->x();
1245 int y = w->y();
1246 bool hasPos = w->testAttribute(Qt::WA_Moved);
1247 QSize s = w->size().expandedTo(qSmartMinSize(w));
1248 if (!hasSize && w->sizeHint().isValid())
1249 w->adjustSize();
1250
1251 QWorkspaceChild* child = new QWorkspaceChild(w, this, flags);
1252 child->setObjectName(QLatin1String("qt_workspacechild"));
1253 child->installEventFilter(this);
1254
1255 connect(child, SIGNAL(popupOperationMenu(QPoint)),
1256 this, SLOT(_q_popupOperationMenu(QPoint)));
1257 connect(child, SIGNAL(showOperationMenu()),
1258 this, SLOT(_q_showOperationMenu()));
1259 d->windows.append(child);
1260 if (child->isVisibleTo(this))
1261 d->focus.append(child);
1262 child->internalRaise();
1263
1264 if (!hasPos)
1265 d->place(child);
1266 if (!hasSize)
1267 child->adjustSize();
1268 if (hasPos)
1269 child->move(x, y);
1270
1271 return child;
1272
1273#if 0
1274 if (wasMaximized)
1275 w->showMaximized();
1276 else if (wasMinimized)
1277 w->showMinimized();
1278 else if (!hasBeenHidden)
1279 d->activateWindow(w);
1280
1281 d->updateWorkspace();
1282 return child;
1283#endif
1284}
1285
1286/*! \reimp */
1287void QWorkspace::childEvent(QChildEvent * e)
1288{
1289 Q_D(QWorkspace);
1290 if (e->removed()) {
1291 if (d->windows.removeAll(static_cast<QWorkspaceChild*>(e->child()))) {
1292 d->focus.removeAll(static_cast<QWorkspaceChild*>(e->child()));
1293 if (d->maxWindow == e->child())
1294 d->maxWindow = 0;
1295 d->updateWorkspace();
1296 }
1297 }
1298}
1299
1300/*! \reimp */
1301#ifndef QT_NO_WHEELEVENT
1302void QWorkspace::wheelEvent(QWheelEvent *e)
1303{
1304 Q_D(QWorkspace);
1305 if (!scrollBarsEnabled())
1306 return;
1307 // the scroll bars are children of the workspace, so if we receive
1308 // a wheel event we redirect to the scroll bars using a direct event
1309 // call, /not/ using sendEvent() because if the scroll bar ignores the
1310 // event QApplication::sendEvent() will propagate the event to the parent widget,
1311 // which is us, who /just/ sent it.
1312 if (d->vbar && d->vbar->isVisible() && !(e->modifiers() & Qt::AltModifier))
1313 d->vbar->event(e);
1314 else if (d->hbar && d->hbar->isVisible())
1315 d->hbar->event(e);
1316}
1317#endif
1318
1319void QWorkspacePrivate::activateWindow(QWidget* w, bool change_focus)
1320{
1321 Q_Q(QWorkspace);
1322 if (!w) {
1323 active = 0;
1324 emit q->windowActivated(0);
1325 return;
1326 }
1327 if (!q->isVisible()) {
1328 becomeActive = w;
1329 return;
1330 }
1331
1332 if (active && active->windowWidget() == w) {
1333 if (!isChildOf(q->focusWidget(), w)) // child window does not have focus
1334 active->setActive(true);
1335 return;
1336 }
1337
1338 active = 0;
1339 // First deactivate all other workspace clients
1340 QList<QWorkspaceChild *>::Iterator it(windows.begin());
1341 while (it != windows.end()) {
1342 QWorkspaceChild* c = *it;
1343 ++it;
1344 if (c->windowWidget() == w)
1345 active = c;
1346 else
1347 c->setActive(false);
1348 }
1349
1350 if (!active)
1351 return;
1352
1353 // Then activate the new one, so the focus is stored correctly
1354 active->setActive(true);
1355
1356 if (!active)
1357 return;
1358
1359 if (maxWindow && maxWindow != active && active->windowWidget() &&
1360 (active->windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint))
1361 active->showMaximized();
1362
1363 active->internalRaise();
1364
1365 if (change_focus) {
1366 int from = focus.indexOf(active);
1367 if (from >= 0)
1368 focus.move(from, focus.size() - 1);
1369 }
1370
1371 updateWorkspace();
1372 emit q->windowActivated(w);
1373}
1374
1375
1376/*!
1377 Returns a pointer to the widget corresponding to the active child
1378 window, or 0 if no window is active.
1379
1380 \sa setActiveWindow()
1381*/
1382QWidget* QWorkspace::activeWindow() const
1383{
1384 Q_D(const QWorkspace);
1385 return d->active? d->active->windowWidget() : 0;
1386}
1387
1388/*!
1389 Makes the child window that contains \a w the active child window.
1390
1391 \sa activeWindow()
1392*/
1393void QWorkspace::setActiveWindow(QWidget *w)
1394{
1395 Q_D(QWorkspace);
1396 d->activateWindow(w, true);
1397 if (w && w->isMinimized())
1398 w->setWindowState(w->windowState() & ~Qt::WindowMinimized);
1399}
1400
1401void QWorkspacePrivate::place(QWidget *w)
1402{
1403 Q_Q(QWorkspace);
1404
1405 QList<QWidget *> widgets;
1406 for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it)
1407 if (*it != w)
1408 widgets.append(*it);
1409
1410 int overlap, minOverlap = 0;
1411 int possible;
1412
1413 QRect r1(0, 0, 0, 0);
1414 QRect r2(0, 0, 0, 0);
1415 QRect maxRect = q->rect();
1416 int x = maxRect.left(), y = maxRect.top();
1417 QPoint wpos(maxRect.left(), maxRect.top());
1418
1419 bool firstPass = true;
1420
1421 do {
1422 if (y + w->height() > maxRect.bottom()) {
1423 overlap = -1;
1424 } else if(x + w->width() > maxRect.right()) {
1425 overlap = -2;
1426 } else {
1427 overlap = 0;
1428
1429 r1.setRect(x, y, w->width(), w->height());
1430
1431 QWidget *l;
1432 QList<QWidget *>::Iterator it(widgets.begin());
1433 while (it != widgets.end()) {
1434 l = *it;
1435 ++it;
1436
1437 if (maxWindow == l)
1438 r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
1439 else
1440 r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
1441 QRect(l->x(), l->y(), l->width(), l->height()));
1442
1443 if (r2.intersects(r1)) {
1444 r2.setCoords(qMax(r1.left(), r2.left()),
1445 qMax(r1.top(), r2.top()),
1446 qMin(r1.right(), r2.right()),
1447 qMin(r1.bottom(), r2.bottom())
1448 );
1449
1450 overlap += (r2.right() - r2.left()) *
1451 (r2.bottom() - r2.top());
1452 }
1453 }
1454 }
1455
1456 if (overlap == 0) {
1457 wpos = QPoint(x, y);
1458 break;
1459 }
1460
1461 if (firstPass) {
1462 firstPass = false;
1463 minOverlap = overlap;
1464 } else if (overlap >= 0 && overlap < minOverlap) {
1465 minOverlap = overlap;
1466 wpos = QPoint(x, y);
1467 }
1468
1469 if (overlap > 0) {
1470 possible = maxRect.right();
1471 if (possible - w->width() > x) possible -= w->width();
1472
1473 QWidget *l;
1474 QList<QWidget *>::Iterator it(widgets.begin());
1475 while (it != widgets.end()) {
1476 l = *it;
1477 ++it;
1478 if (maxWindow == l)
1479 r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
1480 else
1481 r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
1482 QRect(l->x(), l->y(), l->width(), l->height()));
1483
1484 if((y < r2.bottom()) && (r2.top() < w->height() + y)) {
1485 if(r2.right() > x)
1486 possible = possible < r2.right() ?
1487 possible : r2.right();
1488
1489 if(r2.left() - w->width() > x)
1490 possible = possible < r2.left() - w->width() ?
1491 possible : r2.left() - w->width();
1492 }
1493 }
1494
1495 x = possible;
1496 } else if (overlap == -2) {
1497 x = maxRect.left();
1498 possible = maxRect.bottom();
1499
1500 if (possible - w->height() > y) possible -= w->height();
1501
1502 QWidget *l;
1503 QList<QWidget *>::Iterator it(widgets.begin());
1504 while (it != widgets.end()) {
1505 l = *it;
1506 ++it;
1507 if (maxWindow == l)
1508 r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
1509 else
1510 r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
1511 QRect(l->x(), l->y(), l->width(), l->height()));
1512
1513 if(r2.bottom() > y)
1514 possible = possible < r2.bottom() ?
1515 possible : r2.bottom();
1516
1517 if(r2.top() - w->height() > y)
1518 possible = possible < r2.top() - w->height() ?
1519 possible : r2.top() - w->height();
1520 }
1521
1522 y = possible;
1523 }
1524 }
1525 while(overlap != 0 && overlap != -1);
1526
1527 QRect resultRect = w->geometry();
1528 resultRect.moveTo(wpos);
1529 w->setGeometry(QStyle::visualRect(q->layoutDirection(), maxRect, resultRect));
1530 updateWorkspace();
1531}
1532
1533
1534void QWorkspacePrivate::insertIcon(QWidget* w)
1535{
1536 Q_Q(QWorkspace);
1537 if (!w || icons.contains(w))
1538 return;
1539 icons.append(w);
1540 if (w->parentWidget() != q) {
1541 w->setParent(q, 0);
1542 w->move(0,0);
1543 }
1544 QRect cr = updateWorkspace();
1545 int x = 0;
1546 int y = cr.height() - w->height();
1547
1548 QList<QWidget *>::Iterator it(icons.begin());
1549 while (it != icons.end()) {
1550 QWidget* i = *it;
1551 ++it;
1552 if (x > 0 && x + i->width() > cr.width()){
1553 x = 0;
1554 y -= i->height();
1555 }
1556
1557 if (i != w &&
1558 i->geometry().intersects(QRect(x, y, w->width(), w->height())))
1559 x += i->width();
1560 }
1561 w->move(x, y);
1562
1563 if (q->isVisibleTo(q->parentWidget())) {
1564 w->show();
1565 w->lower();
1566 }
1567 updateWorkspace();
1568}
1569
1570
1571void QWorkspacePrivate::removeIcon(QWidget* w)
1572{
1573 if (icons.removeAll(w))
1574 w->hide();
1575}
1576
1577
1578/*! \reimp */
1579void QWorkspace::resizeEvent(QResizeEvent *)
1580{
1581 Q_D(QWorkspace);
1582 if (d->maxWindow) {
1583 d->maxWindow->adjustToFullscreen();
1584 if (d->maxWindow->windowWidget())
1585 d->maxWindow->windowWidget()->overrideWindowState(Qt::WindowMaximized);
1586 }
1587 d->updateWorkspace();
1588}
1589
1590/*! \reimp */
1591void QWorkspace::showEvent(QShowEvent *e)
1592{
1593 Q_D(QWorkspace);
1594 if (d->maxWindow)
1595 d->showMaximizeControls();
1596 QWidget::showEvent(e);
1597 if (d->becomeActive) {
1598 d->activateWindow(d->becomeActive);
1599 d->becomeActive = 0;
1600 } else if (d->windows.count() > 0 && !d->active) {
1601 d->activateWindow(d->windows.first()->windowWidget());
1602 }
1603
1604// // force a frame repaint - this is a workaround for what seems to be a bug
1605// // introduced when changing the QWidget::show() implementation. Might be
1606// // a windows bug as well though.
1607// for (int i = 0; i < d->windows.count(); ++i) {
1608// QWorkspaceChild* c = d->windows.at(i);
1609// c->update(c->rect());
1610// }
1611
1612 d->updateWorkspace();
1613}
1614
1615/*! \reimp */
1616void QWorkspace::hideEvent(QHideEvent *)
1617{
1618 Q_D(QWorkspace);
1619 if (!isVisible())
1620 d->hideMaximizeControls();
1621}
1622
1623/*! \reimp */
1624void QWorkspace::paintEvent(QPaintEvent *)
1625{
1626 Q_D(QWorkspace);
1627
1628 if (d->background.style() != Qt::NoBrush) {
1629 QPainter p(this);
1630 p.fillRect(0, 0, width(), height(), d->background);
1631 }
1632}
1633
1634void QWorkspacePrivate::minimizeWindow(QWidget* w)
1635{
1636 QWorkspaceChild* c = findChild(w);
1637
1638 if (!w || !(w->windowFlags() & Qt::WindowMinimizeButtonHint))
1639 return;
1640
1641 if (c) {
1642 bool wasMax = false;
1643 if (c == maxWindow) {
1644 wasMax = true;
1645 maxWindow = 0;
1646 hideMaximizeControls();
1647 for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it) {
1648 QWorkspaceChild* c = *it;
1649 if (c->titlebar)
1650 c->titlebar->setMovable(true);
1651 c->widgetResizeHandler->setActive(true);
1652 }
1653 }
1654 c->hide();
1655 if (wasMax)
1656 c->setGeometry(maxRestore);
1657 if (!focus.contains(c))
1658 focus.append(c);
1659 insertIcon(c->iconWidget());
1660
1661 if (!maxWindow)
1662 activateWindow(w);
1663
1664 updateWorkspace();
1665
1666 w->overrideWindowState(Qt::WindowMinimized);
1667 c->overrideWindowState(Qt::WindowMinimized);
1668 }
1669}
1670
1671void QWorkspacePrivate::normalizeWindow(QWidget* w)
1672{
1673 Q_Q(QWorkspace);
1674 QWorkspaceChild* c = findChild(w);
1675 if (!w)
1676 return;
1677 if (c) {
1678 w->overrideWindowState(Qt::WindowNoState);
1679 hideMaximizeControls();
1680 if (!maxmenubar || q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q) || !maxWindow) {
1681 if (w->minimumSize() != w->maximumSize())
1682 c->widgetResizeHandler->setActive(true);
1683 if (c->titlebar)
1684 c->titlebar->setMovable(true);
1685 }
1686 w->overrideWindowState(Qt::WindowNoState);
1687 c->overrideWindowState(Qt::WindowNoState);
1688
1689 if (c == maxWindow) {
1690 c->setGeometry(maxRestore);
1691 maxWindow = 0;
1692 } else {
1693 if (c->iconw)
1694 removeIcon(c->iconw->parentWidget());
1695 c->show();
1696 }
1697
1698 hideMaximizeControls();
1699 for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it) {
1700 QWorkspaceChild* c = *it;
1701 if (c->titlebar)
1702 c->titlebar->setMovable(true);
1703 if (c->childWidget && c->childWidget->minimumSize() != c->childWidget->maximumSize())
1704 c->widgetResizeHandler->setActive(true);
1705 }
1706 activateWindow(w, true);
1707 updateWorkspace();
1708 }
1709}
1710
1711void QWorkspacePrivate::maximizeWindow(QWidget* w)
1712{
1713 Q_Q(QWorkspace);
1714 QWorkspaceChild* c = findChild(w);
1715
1716 if (!w || !(w->windowFlags() & Qt::WindowMaximizeButtonHint))
1717 return;
1718
1719 if (!c || c == maxWindow)
1720 return;
1721
1722 bool updatesEnabled = q->updatesEnabled();
1723 q->setUpdatesEnabled(false);
1724
1725 if (c->iconw && icons.contains(c->iconw->parentWidget()))
1726 normalizeWindow(w);
1727 QRect r(c->geometry());
1728 QWorkspaceChild *oldMaxWindow = maxWindow;
1729 maxWindow = c;
1730
1731 showMaximizeControls();
1732
1733 c->adjustToFullscreen();
1734 c->show();
1735 c->internalRaise();
1736 if (oldMaxWindow != c) {
1737 if (oldMaxWindow) {
1738 oldMaxWindow->setGeometry(maxRestore);
1739 oldMaxWindow->overrideWindowState(Qt::WindowNoState);
1740 if(oldMaxWindow->windowWidget())
1741 oldMaxWindow->windowWidget()->overrideWindowState(Qt::WindowNoState);
1742 }
1743 maxRestore = r;
1744 }
1745
1746 activateWindow(w);
1747
1748 if(!maxmenubar || q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
1749 if (!active && becomeActive) {
1750 active = (QWorkspaceChild*)becomeActive->parentWidget();
1751 active->setActive(true);
1752 becomeActive = 0;
1753 emit q->windowActivated(active->windowWidget());
1754 }
1755 c->widgetResizeHandler->setActive(false);
1756 if (c->titlebar)
1757 c->titlebar->setMovable(false);
1758 }
1759 updateWorkspace();
1760
1761 w->overrideWindowState(Qt::WindowMaximized);
1762 c->overrideWindowState(Qt::WindowMaximized);
1763 q->setUpdatesEnabled(updatesEnabled);
1764}
1765
1766void QWorkspacePrivate::showWindow(QWidget* w)
1767{
1768 if (w->isMinimized() && (w->windowFlags() & Qt::WindowMinimizeButtonHint))
1769 minimizeWindow(w);
1770 else if ((maxWindow || w->isMaximized()) && w->windowFlags() & Qt::WindowMaximizeButtonHint)
1771 maximizeWindow(w);
1772 else if (w->windowFlags() & Qt::WindowMaximizeButtonHint)
1773 normalizeWindow(w);
1774 else
1775 w->parentWidget()->show();
1776 if (maxWindow)
1777 maxWindow->internalRaise();
1778 updateWorkspace();
1779}
1780
1781
1782QWorkspaceChild* QWorkspacePrivate::findChild(QWidget* w)
1783{
1784 QList<QWorkspaceChild *>::Iterator it(windows.begin());
1785 while (it != windows.end()) {
1786 QWorkspaceChild* c = *it;
1787 ++it;
1788 if (c->windowWidget() == w)
1789 return c;
1790 }
1791 return 0;
1792}
1793
1794/*!
1795 Returns a list of all visible or minimized child windows. If \a
1796 order is CreationOrder (the default), the windows are listed in
1797 the order in which they were inserted into the workspace. If \a
1798 order is StackingOrder, the windows are listed in their stacking
1799 order, with the topmost window as the last item in the list.
1800*/
1801QWidgetList QWorkspace::windowList(WindowOrder order) const
1802{
1803 Q_D(const QWorkspace);
1804 QWidgetList windows;
1805 if (order == StackingOrder) {
1806 QObjectList cl = children();
1807 for (int i = 0; i < cl.size(); ++i) {
1808 QWorkspaceChild *c = qobject_cast<QWorkspaceChild*>(cl.at(i));
1809 if (c && c->isWindowOrIconVisible())
1810 windows.append(c->windowWidget());
1811 }
1812 } else {
1813 QList<QWorkspaceChild *>::ConstIterator it(d->windows.begin());
1814 while (it != d->windows.end()) {
1815 QWorkspaceChild* c = *it;
1816 ++it;
1817 if (c && c->isWindowOrIconVisible())
1818 windows.append(c->windowWidget());
1819 }
1820 }
1821 return windows;
1822}
1823
1824
1825/*! \reimp */
1826bool QWorkspace::event(QEvent *e)
1827{
1828#ifndef QT_NO_SHORTCUT
1829 Q_D(QWorkspace);
1830 if (e->type() == QEvent::Shortcut) {
1831 QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
1832 const char *theSlot = d->shortcutMap.value(se->shortcutId(), 0);
1833 if (theSlot)
1834 QMetaObject::invokeMethod(this, theSlot);
1835 } else
1836#endif
1837 if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut){
1838 return true;
1839 }
1840 return QWidget::event(e);
1841}
1842
1843/*! \reimp */
1844bool QWorkspace::eventFilter(QObject *o, QEvent * e)
1845{
1846 Q_D(QWorkspace);
1847 static QTime* t = 0;
1848 static QWorkspace* tc = 0;
1849 if (o == d->maxtools) {
1850 switch (e->type()) {
1851 case QEvent::MouseButtonPress:
1852 {
1853 QMenuBar* b = (QMenuBar*)o->parent();
1854 if (!t)
1855 t = new QTime;
1856 if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) {
1857 if (isRightToLeft()) {
1858 QPoint p = b->mapToGlobal(QPoint(b->x() + b->width(), b->y() + b->height()));
1859 p.rx() -= d->popup->sizeHint().width();
1860 d->_q_popupOperationMenu(p);
1861 } else {
1862 d->_q_popupOperationMenu(b->mapToGlobal(QPoint(b->x(), b->y() + b->height())));
1863 }
1864 t->start();
1865 tc = this;
1866 } else {
1867 tc = 0;
1868 closeActiveWindow();
1869 }
1870 return true;
1871 }
1872 default:
1873 break;
1874 }
1875 return QWidget::eventFilter(o, e);
1876 }
1877 switch (e->type()) {
1878 case QEvent::HideToParent:
1879 break;
1880 case QEvent::ShowToParent:
1881 if (QWorkspaceChild *c = qobject_cast<QWorkspaceChild*>(o))
1882 if (!d->focus.contains(c))
1883 d->focus.append(c);
1884 d->updateWorkspace();
1885 break;
1886 case QEvent::WindowTitleChange:
1887 if (!d->inTitleChange) {
1888 if (o == window())
1889 d->topTitle = window()->windowTitle();
1890 if (d->maxWindow && d->maxWindow->windowWidget() && d->topTitle.size()) {
1891 d->inTitleChange = true;
1892 window()->setWindowTitle(tr("%1 - [%2]")
1893 .arg(d->topTitle).arg(d->maxWindow->windowWidget()->windowTitle()));
1894 d->inTitleChange = false;
1895 }
1896 }
1897 break;
1898
1899 case QEvent::ModifiedChange:
1900 if (o == d->maxWindow)
1901 window()->setWindowModified(d->maxWindow->isWindowModified());
1902 break;
1903
1904 case QEvent::Close:
1905 if (o == window())
1906 {
1907 QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
1908 while (it != d->windows.end()) {
1909 QWorkspaceChild* c = *it;
1910 ++it;
1911 if (c->shademode)
1912 c->showShaded();
1913 }
1914 } else if (qobject_cast<QWorkspaceChild*>(o)) {
1915 d->popup->hide();
1916 }
1917 d->updateWorkspace();
1918 break;
1919 default:
1920 break;
1921 }
1922 return QWidget::eventFilter(o, e);
1923}
1924
1925static QMenuBar *findMenuBar(QWidget *w)
1926{
1927 // don't search recursively to avoid finding a menu bar of a
1928 // mainwindow that happens to be a workspace window (like
1929 // a mainwindow in designer)
1930 QList<QObject *> children = w->children();
1931 for (int i = 0; i < children.count(); ++i) {
1932 QMenuBar *bar = qobject_cast<QMenuBar *>(children.at(i));
1933 if (bar)
1934 return bar;
1935 }
1936 return 0;
1937}
1938
1939void QWorkspacePrivate::showMaximizeControls()
1940{
1941 Q_Q(QWorkspace);
1942 Q_ASSERT(maxWindow);
1943
1944 // merge windowtitle and modified state
1945 if (!topTitle.size())
1946 topTitle = q->window()->windowTitle();
1947
1948 if (maxWindow->windowWidget()) {
1949 QString docTitle = maxWindow->windowWidget()->windowTitle();
1950 if (topTitle.size() && docTitle.size()) {
1951 inTitleChange = true;
1952 q->window()->setWindowTitle(QWorkspace::tr("%1 - [%2]").arg(topTitle).arg(docTitle));
1953 inTitleChange = false;
1954 }
1955 q->window()->setWindowModified(maxWindow->windowWidget()->isWindowModified());
1956 }
1957
1958 if (!q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
1959 QMenuBar* b = 0;
1960
1961 // Do a breadth-first search first on every parent,
1962 QWidget* w = q->parentWidget();
1963 while (w) {
1964 b = findMenuBar(w);
1965 if (b)
1966 break;
1967 w = w->parentWidget();
1968 }
1969
1970 // last attempt.
1971 if (!b)
1972 b = findMenuBar(q->window());
1973
1974 if (!b)
1975 return;
1976
1977 if (!maxcontrols) {
1978 maxmenubar = b;
1979 maxcontrols = new QMDIControl(b);
1980 QObject::connect(maxcontrols, SIGNAL(_q_minimize()),
1981 q, SLOT(_q_minimizeActiveWindow()));
1982 QObject::connect(maxcontrols, SIGNAL(_q_restore()),
1983 q, SLOT(_q_normalizeActiveWindow()));
1984 QObject::connect(maxcontrols, SIGNAL(_q_close()),
1985 q, SLOT(closeActiveWindow()));
1986 }
1987
1988 b->setCornerWidget(maxcontrols);
1989 if (b->isVisible())
1990 maxcontrols->show();
1991 if (!active && becomeActive) {
1992 active = (QWorkspaceChild*)becomeActive->parentWidget();
1993 active->setActive(true);
1994 becomeActive = 0;
1995 emit q->windowActivated(active->windowWidget());
1996 }
1997 if (active) {
1998 if (!maxtools) {
1999 maxtools = new QLabel(q->window());
2000 maxtools->setObjectName(QLatin1String("qt_maxtools"));
2001 maxtools->installEventFilter(q);
2002 }
2003 if (active->windowWidget() && !active->windowWidget()->windowIcon().isNull()) {
2004 QIcon icon = active->windowWidget()->windowIcon();
2005 int iconSize = maxcontrols->size().height();
2006 maxtools->setPixmap(icon.pixmap(QSize(iconSize, iconSize)));
2007 } else {
2008 QPixmap pm = q->style()->standardPixmap(QStyle::SP_TitleBarMenuButton, 0, q);
2009 if (pm.isNull()) {
2010 pm = QPixmap(14,14);
2011 pm.fill(Qt::black);
2012 }
2013 maxtools->setPixmap(pm);
2014 }
2015 b->setCornerWidget(maxtools, Qt::TopLeftCorner);
2016 if (b->isVisible())
2017 maxtools->show();
2018 }
2019 }
2020}
2021
2022
2023void QWorkspacePrivate::hideMaximizeControls()
2024{
2025 Q_Q(QWorkspace);
2026 if (maxmenubar && !q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
2027 if (maxmenubar) {
2028 maxmenubar->setCornerWidget(0, Qt::TopLeftCorner);
2029 maxmenubar->setCornerWidget(0, Qt::TopRightCorner);
2030 }
2031 if (maxcontrols) {
2032 maxcontrols->deleteLater();
2033 maxcontrols = 0;
2034 }
2035 if (maxtools) {
2036 maxtools->deleteLater();
2037 maxtools = 0;
2038 }
2039 }
2040
2041 //unmerge the title bar/modification state
2042 if (topTitle.size()) {
2043 inTitleChange = true;
2044 q->window()->setWindowTitle(topTitle);
2045 inTitleChange = false;
2046 }
2047 q->window()->setWindowModified(false);
2048}
2049
2050/*!
2051 Closes the child window that is currently active.
2052
2053 \sa closeAllWindows()
2054*/
2055void QWorkspace::closeActiveWindow()
2056{
2057 Q_D(QWorkspace);
2058 if (d->maxWindow && d->maxWindow->windowWidget())
2059 d->maxWindow->windowWidget()->close();
2060 else if (d->active && d->active->windowWidget())
2061 d->active->windowWidget()->close();
2062 d->updateWorkspace();
2063}
2064
2065/*!
2066 Closes all child windows.
2067
2068 If any child window fails to accept the close event, the remaining windows
2069 will remain open.
2070
2071 \sa closeActiveWindow()
2072*/
2073void QWorkspace::closeAllWindows()
2074{
2075 Q_D(QWorkspace);
2076 bool did_close = true;
2077 QList<QWorkspaceChild *>::const_iterator it = d->windows.constBegin();
2078 while (it != d->windows.constEnd() && did_close) {
2079 QWorkspaceChild *c = *it;
2080 ++it;
2081 if (c->windowWidget() && !c->windowWidget()->isHidden())
2082 did_close = c->windowWidget()->close();
2083 }
2084}
2085
2086void QWorkspacePrivate::_q_normalizeActiveWindow()
2087{
2088 if (maxWindow)
2089 maxWindow->showNormal();
2090 else if (active)
2091 active->showNormal();
2092}
2093
2094void QWorkspacePrivate::_q_minimizeActiveWindow()
2095{
2096 if (maxWindow)
2097 maxWindow->showMinimized();
2098 else if (active)
2099 active->showMinimized();
2100}
2101
2102void QWorkspacePrivate::_q_showOperationMenu()
2103{
2104 Q_Q(QWorkspace);
2105 if (!active || !active->windowWidget())
2106 return;
2107 Q_ASSERT((active->windowWidget()->windowFlags() & Qt::WindowSystemMenuHint));
2108 QPoint p;
2109 QMenu *popup = (active->titlebar && active->titlebar->isTool()) ? toolPopup : this->popup;
2110 if (q->isRightToLeft()) {
2111 p = QPoint(active->windowWidget()->mapToGlobal(QPoint(active->windowWidget()->width(),0)));
2112 p.rx() -= popup->sizeHint().width();
2113 } else {
2114 p = QPoint(active->windowWidget()->mapToGlobal(QPoint(0,0)));
2115 }
2116 if (!active->isVisible()) {
2117 p = active->iconWidget()->mapToGlobal(QPoint(0,0));
2118 p.ry() -= popup->sizeHint().height();
2119 }
2120 _q_popupOperationMenu(p);
2121}
2122
2123void QWorkspacePrivate::_q_popupOperationMenu(const QPoint& p)
2124{
2125 if (!active || !active->windowWidget() || !(active->windowWidget()->windowFlags() & Qt::WindowSystemMenuHint))
2126 return;
2127 if (active->titlebar && active->titlebar->isTool())
2128 toolPopup->popup(p);
2129 else
2130 popup->popup(p);
2131}
2132
2133void QWorkspacePrivate::_q_updateActions()
2134{
2135 Q_Q(QWorkspace);
2136 for (int i = 1; i < NCountAct-1; i++) {
2137 bool enable = active != 0;
2138 actions[i]->setEnabled(enable);
2139 }
2140
2141 if (!active || !active->windowWidget())
2142 return;
2143
2144 QWidget *windowWidget = active->windowWidget();
2145 bool canResize = windowWidget->maximumSize() != windowWidget->minimumSize();
2146 actions[QWorkspacePrivate::ResizeAct]->setEnabled(canResize);
2147 actions[QWorkspacePrivate::MinimizeAct]->setEnabled((windowWidget->windowFlags() & Qt::WindowMinimizeButtonHint));
2148 actions[QWorkspacePrivate::MaximizeAct]->setEnabled((windowWidget->windowFlags() & Qt::WindowMaximizeButtonHint) && canResize);
2149
2150 if (active == maxWindow) {
2151 actions[QWorkspacePrivate::MoveAct]->setEnabled(false);
2152 actions[QWorkspacePrivate::ResizeAct]->setEnabled(false);
2153 actions[QWorkspacePrivate::MaximizeAct]->setEnabled(false);
2154 actions[QWorkspacePrivate::RestoreAct]->setEnabled(true);
2155 } else if (active->isVisible()){
2156 actions[QWorkspacePrivate::RestoreAct]->setEnabled(false);
2157 } else {
2158 actions[QWorkspacePrivate::MoveAct]->setEnabled(false);
2159 actions[QWorkspacePrivate::ResizeAct]->setEnabled(false);
2160 actions[QWorkspacePrivate::MinimizeAct]->setEnabled(false);
2161 actions[QWorkspacePrivate::RestoreAct]->setEnabled(true);
2162 }
2163 if (active->shademode) {
2164 actions[QWorkspacePrivate::ShadeAct]->setIcon(
2165 QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarUnshadeButton, 0, q)));
2166 actions[QWorkspacePrivate::ShadeAct]->setText(QWorkspace::tr("&Unshade"));
2167 } else {
2168 actions[QWorkspacePrivate::ShadeAct]->setIcon(
2169 QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarShadeButton, 0, q)));
2170 actions[QWorkspacePrivate::ShadeAct]->setText(QWorkspace::tr("Sh&ade"));
2171 }
2172 actions[QWorkspacePrivate::StaysOnTopAct]->setEnabled(!active->shademode && canResize);
2173 actions[QWorkspacePrivate::StaysOnTopAct]->setChecked(
2174 (active->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint));
2175}
2176
2177void QWorkspacePrivate::_q_operationMenuActivated(QAction *action)
2178{
2179 if (!active)
2180 return;
2181 if(action == actions[QWorkspacePrivate::RestoreAct]) {
2182 active->showNormal();
2183 } else if(action == actions[QWorkspacePrivate::MoveAct]) {
2184 active->doMove();
2185 } else if(action == actions[QWorkspacePrivate::ResizeAct]) {
2186 if (active->shademode)
2187 active->showShaded();
2188 active->doResize();
2189 } else if(action == actions[QWorkspacePrivate::MinimizeAct]) {
2190 active->showMinimized();
2191 } else if(action == actions[QWorkspacePrivate::MaximizeAct]) {
2192 active->showMaximized();
2193 } else if(action == actions[QWorkspacePrivate::ShadeAct]) {
2194 active->showShaded();
2195 } else if(action == actions[QWorkspacePrivate::StaysOnTopAct]) {
2196 if(QWidget* w = active->windowWidget()) {
2197 if ((w->windowFlags() & Qt::WindowStaysOnTopHint)) {
2198 w->overrideWindowFlags(w->windowFlags() & ~Qt::WindowStaysOnTopHint);
2199 } else {
2200 w->overrideWindowFlags(w->windowFlags() | Qt::WindowStaysOnTopHint);
2201 w->parentWidget()->raise();
2202 }
2203 }
2204 }
2205}
2206
2207
2208void QWorkspacePrivate::hideChild(QWorkspaceChild *c)
2209{
2210 Q_Q(QWorkspace);
2211
2212// bool updatesEnabled = q->updatesEnabled();
2213// q->setUpdatesEnabled(false);
2214 focus.removeAll(c);
2215 QRect restore;
2216 if (maxWindow == c)
2217 restore = maxRestore;
2218 if (active == c) {
2219 q->setFocus();
2220 q->activatePreviousWindow();
2221 }
2222 if (active == c)
2223 activateWindow(0);
2224 if (maxWindow == c) {
2225 hideMaximizeControls();
2226 maxWindow = 0;
2227 }
2228 c->hide();
2229 if (!restore.isEmpty())
2230 c->setGeometry(restore);
2231// q->setUpdatesEnabled(updatesEnabled);
2232}
2233
2234/*!
2235 Gives the input focus to the next window in the list of child
2236 windows.
2237
2238 \sa activatePreviousWindow()
2239*/
2240void QWorkspace::activateNextWindow()
2241{
2242 Q_D(QWorkspace);
2243
2244 if (d->focus.isEmpty())
2245 return;
2246 if (!d->active) {
2247 if (d->focus.first())
2248 d->activateWindow(d->focus.first()->windowWidget(), false);
2249 return;
2250 }
2251
2252 int a = d->focus.indexOf(d->active) + 1;
2253
2254 a = a % d->focus.count();
2255
2256 if (d->focus.at(a))
2257 d->activateWindow(d->focus.at(a)->windowWidget(), false);
2258 else
2259 d->activateWindow(0);
2260}
2261
2262/*!
2263 Gives the input focus to the previous window in the list of child
2264 windows.
2265
2266 \sa activateNextWindow()
2267*/
2268void QWorkspace::activatePreviousWindow()
2269{
2270 Q_D(QWorkspace);
2271
2272 if (d->focus.isEmpty())
2273 return;
2274 if (!d->active) {
2275 if (d->focus.last())
2276 d->activateWindow(d->focus.first()->windowWidget(), false);
2277 else
2278 d->activateWindow(0);
2279 return;
2280 }
2281
2282 int a = d->focus.indexOf(d->active) - 1;
2283 if (a < 0)
2284 a = d->focus.count()-1;
2285
2286 if (d->focus.at(a))
2287 d->activateWindow(d->focus.at(a)->windowWidget(), false);
2288 else
2289 d->activateWindow(0);
2290}
2291
2292
2293/*!
2294 \fn void QWorkspace::windowActivated(QWidget* w)
2295
2296 This signal is emitted when the child window \a w becomes active.
2297 Note that \a w can be 0, and that more than one signal may be
2298 emitted for a single activation event.
2299
2300 \sa activeWindow(), windowList()
2301*/
2302
2303/*!
2304 Arranges all the child windows in a cascade pattern.
2305
2306 \sa tile(), arrangeIcons()
2307*/
2308void QWorkspace::cascade()
2309{
2310 Q_D(QWorkspace);
2311 blockSignals(true);
2312 if (d->maxWindow)
2313 d->maxWindow->showNormal();
2314
2315 if (d->vbar) {
2316 d->vbar->blockSignals(true);
2317 d->vbar->setValue(0);
2318 d->vbar->blockSignals(false);
2319 d->hbar->blockSignals(true);
2320 d->hbar->setValue(0);
2321 d->hbar->blockSignals(false);
2322 d->_q_scrollBarChanged();
2323 }
2324
2325 const int xoffset = 13;
2326 const int yoffset = 20;
2327
2328 // make a list of all relevant mdi clients
2329 QList<QWorkspaceChild *> widgets;
2330 QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
2331 QWorkspaceChild* wc = 0;
2332
2333 for (it = d->focus.begin(); it != d->focus.end(); ++it) {
2334 wc = *it;
2335 if (wc->windowWidget()->isVisibleTo(this) && !(wc->titlebar && wc->titlebar->isTool()))
2336 widgets.append(wc);
2337 }
2338
2339 int x = 0;
2340 int y = 0;
2341
2342 it = widgets.begin();
2343 while (it != widgets.end()) {
2344 QWorkspaceChild *child = *it;
2345 ++it;
2346
2347 QSize prefSize = child->windowWidget()->sizeHint().expandedTo(qSmartMinSize(child->windowWidget()));
2348 if (!prefSize.isValid())
2349 prefSize = child->windowWidget()->size();
2350 prefSize = prefSize.expandedTo(qSmartMinSize(child->windowWidget()));
2351 if (prefSize.isValid())
2352 prefSize += QSize(child->baseSize().width(), child->baseSize().height());
2353
2354 int w = prefSize.width();
2355 int h = prefSize.height();
2356
2357 child->showNormal();
2358 if (y + h > height())
2359 y = 0;
2360 if (x + w > width())
2361 x = 0;
2362 child->setGeometry(x, y, w, h);
2363 x += xoffset;
2364 y += yoffset;
2365 child->internalRaise();
2366 }
2367 d->updateWorkspace();
2368 blockSignals(false);
2369}
2370
2371/*!
2372 Arranges all child windows in a tile pattern.
2373
2374 \sa cascade(), arrangeIcons()
2375*/
2376void QWorkspace::tile()
2377{
2378 Q_D(QWorkspace);
2379 blockSignals(true);
2380 QWidget *oldActive = d->active ? d->active->windowWidget() : 0;
2381 if (d->maxWindow)
2382 d->maxWindow->showNormal();
2383
2384 if (d->vbar) {
2385 d->vbar->blockSignals(true);
2386 d->vbar->setValue(0);
2387 d->vbar->blockSignals(false);
2388 d->hbar->blockSignals(true);
2389 d->hbar->setValue(0);
2390 d->hbar->blockSignals(false);
2391 d->_q_scrollBarChanged();
2392 }
2393
2394 int rows = 1;
2395 int cols = 1;
2396 int n = 0;
2397 QWorkspaceChild* c;
2398
2399 QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
2400 while (it != d->windows.end()) {
2401 c = *it;
2402 ++it;
2403 if (!c->windowWidget()->isHidden()
2404 && !(c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)
2405 && !c->iconw)
2406 n++;
2407 }
2408
2409 while (rows * cols < n) {
2410 if (cols <= rows)
2411 cols++;
2412 else
2413 rows++;
2414 }
2415 int add = cols * rows - n;
2416 bool* used = new bool[cols*rows];
2417 for (int i = 0; i < rows*cols; i++)
2418 used[i] = false;
2419
2420 int row = 0;
2421 int col = 0;
2422 int w = width() / cols;
2423 int h = height() / rows;
2424
2425 it = d->windows.begin();
2426 while (it != d->windows.end()) {
2427 c = *it;
2428 ++it;
2429 if (c->iconw || c->windowWidget()->isHidden() || (c->titlebar && c->titlebar->isTool()))
2430 continue;
2431 if (!row && !col) {
2432 w -= c->baseSize().width();
2433 h -= c->baseSize().height();
2434 }
2435 if ((c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
2436 QPoint p = c->pos();
2437 if (p.x()+c->width() < 0)
2438 p.setX(0);
2439 if (p.x() > width())
2440 p.setX(width() - c->width());
2441 if (p.y() + 10 < 0)
2442 p.setY(0);
2443 if (p.y() > height())
2444 p.setY(height() - c->height());
2445
2446 if (p != c->pos())
2447 c->QWidget::move(p);
2448 } else {
2449 c->showNormal();
2450 used[row*cols+col] = true;
2451 QSize sz(w, h);
2452 QSize bsize(c->baseSize());
2453 sz = sz.expandedTo(c->windowWidget()->minimumSize()).boundedTo(c->windowWidget()->maximumSize());
2454 sz += bsize;
2455
2456 if ( add ) {
2457 if (sz.height() == h + bsize.height()) // no relevant constrains
2458 sz.rheight() *= 2;
2459 used[(row+1)*cols+col] = true;
2460 add--;
2461 }
2462
2463 c->setGeometry(col*w + col*bsize.width(), row*h + row*bsize.height(), sz.width(), sz.height());
2464
2465 while(row < rows && col < cols && used[row*cols+col]) {
2466 col++;
2467 if (col == cols) {
2468 col = 0;
2469 row++;
2470 }
2471 }
2472 }
2473 }
2474 delete [] used;
2475
2476 d->activateWindow(oldActive);
2477 d->updateWorkspace();
2478 blockSignals(false);
2479}
2480
2481/*!
2482 Arranges all iconified windows at the bottom of the workspace.
2483
2484 \sa cascade(), tile()
2485*/
2486void QWorkspace::arrangeIcons()
2487{
2488 Q_D(QWorkspace);
2489
2490 QRect cr = d->updateWorkspace();
2491 int x = 0;
2492 int y = -1;
2493
2494 QList<QWidget *>::Iterator it(d->icons.begin());
2495 while (it != d->icons.end()) {
2496 QWidget* i = *it;
2497 if (y == -1)
2498 y = cr.height() - i->height();
2499 if (x > 0 && x + i->width() > cr.width()) {
2500 x = 0;
2501 y -= i->height();
2502 }
2503 i->move(x, y);
2504 x += i->width();
2505 ++it;
2506 }
2507 d->updateWorkspace();
2508}
2509
2510
2511QWorkspaceChild::QWorkspaceChild(QWidget* window, QWorkspace *parent, Qt::WindowFlags flags)
2512 : QWidget(parent,
2513 Qt::FramelessWindowHint | Qt::SubWindow)
2514{
2515 setAttribute(Qt::WA_DeleteOnClose);
2516 setAttribute(Qt::WA_NoMousePropagation);
2517 setMouseTracking(true);
2518 act = false;
2519 iconw = 0;
2520 shademode = false;
2521 titlebar = 0;
2522 setAutoFillBackground(true);
2523
2524 setBackgroundRole(QPalette::Window);
2525 if (window) {
2526 flags |= (window->windowFlags() & Qt::MSWindowsOwnDC);
2527 if (flags)
2528 window->setParent(this, flags & ~Qt::WindowType_Mask);
2529 else
2530 window->setParent(this);
2531 }
2532
2533 if (window && (flags & (Qt::WindowTitleHint
2534 | Qt::WindowSystemMenuHint
2535 | Qt::WindowMinimizeButtonHint
2536 | Qt::WindowMaximizeButtonHint
2537 | Qt::WindowContextHelpButtonHint))) {
2538 titlebar = new QWorkspaceTitleBar(window, this, flags);
2539 connect(titlebar, SIGNAL(doActivate()),
2540 this, SLOT(activate()));
2541 connect(titlebar, SIGNAL(doClose()),
2542 window, SLOT(close()));
2543 connect(titlebar, SIGNAL(doMinimize()),
2544 this, SLOT(showMinimized()));
2545 connect(titlebar, SIGNAL(doNormal()),
2546 this, SLOT(showNormal()));
2547 connect(titlebar, SIGNAL(doMaximize()),
2548 this, SLOT(showMaximized()));
2549 connect(titlebar, SIGNAL(popupOperationMenu(QPoint)),
2550 this, SIGNAL(popupOperationMenu(QPoint)));
2551 connect(titlebar, SIGNAL(showOperationMenu()),
2552 this, SIGNAL(showOperationMenu()));
2553 connect(titlebar, SIGNAL(doShade()),
2554 this, SLOT(showShaded()));
2555 connect(titlebar, SIGNAL(doubleClicked()),
2556 this, SLOT(titleBarDoubleClicked()));
2557 }
2558
2559 setMinimumSize(128, 0);
2560 int fw = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
2561 setContentsMargins(fw, fw, fw, fw);
2562
2563 childWidget = window;
2564 if (!childWidget)
2565 return;
2566
2567 setWindowTitle(childWidget->windowTitle());
2568
2569 QPoint p;
2570 QSize s;
2571 QSize cs;
2572
2573 bool hasBeenResized = childWidget->testAttribute(Qt::WA_Resized);
2574
2575 if (!hasBeenResized)
2576 cs = childWidget->sizeHint().expandedTo(childWidget->minimumSizeHint()).expandedTo(childWidget->minimumSize()).boundedTo(childWidget->maximumSize());
2577 else
2578 cs = childWidget->size();
2579
2580 windowSize = cs;
2581
2582 int th = titlebar ? titlebar->sizeHint().height() : 0;
2583 if (titlebar) {
2584 if (!childWidget->windowIcon().isNull())
2585 titlebar->setWindowIcon(childWidget->windowIcon());
2586
2587 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
2588 th -= contentsRect().y();
2589
2590 p = QPoint(contentsRect().x(),
2591 th + contentsRect().y());
2592 s = QSize(cs.width() + 2*frameWidth(),
2593 cs.height() + 2*frameWidth() + th);
2594 } else {
2595 p = QPoint(contentsRect().x(), contentsRect().y());
2596 s = QSize(cs.width() + 2*frameWidth(),
2597 cs.height() + 2*frameWidth());
2598 }
2599
2600 childWidget->move(p);
2601 resize(s);
2602
2603 childWidget->installEventFilter(this);
2604
2605 widgetResizeHandler = new QWidgetResizeHandler(this, window);
2606 widgetResizeHandler->setSizeProtection(!parent->scrollBarsEnabled());
2607 widgetResizeHandler->setFrameWidth(frameWidth());
2608 connect(widgetResizeHandler, SIGNAL(activate()),
2609 this, SLOT(activate()));
2610 if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
2611 widgetResizeHandler->setExtraHeight(th + contentsRect().y() - 2*frameWidth());
2612 else
2613 widgetResizeHandler->setExtraHeight(th + contentsRect().y() - frameWidth());
2614 if (childWidget->minimumSize() == childWidget->maximumSize())
2615 widgetResizeHandler->setActive(QWidgetResizeHandler::Resize, false);
2616 setBaseSize(baseSize());
2617}
2618
2619QWorkspaceChild::~QWorkspaceChild()
2620{
2621 QWorkspace *workspace = qobject_cast<QWorkspace*>(parentWidget());
2622 if (iconw) {
2623 if (workspace)
2624 workspace->d_func()->removeIcon(iconw->parentWidget());
2625 delete iconw->parentWidget();
2626 }
2627
2628 if (workspace) {
2629 workspace->d_func()->focus.removeAll(this);
2630 if (workspace->d_func()->active == this)
2631 workspace->activatePreviousWindow();
2632 if (workspace->d_func()->active == this)
2633 workspace->d_func()->activateWindow(0);
2634 if (workspace->d_func()->maxWindow == this) {
2635 workspace->d_func()->hideMaximizeControls();
2636 workspace->d_func()->maxWindow = 0;
2637 }
2638 }
2639}
2640
2641void QWorkspaceChild::moveEvent(QMoveEvent *)
2642{
2643 ((QWorkspace*)parentWidget())->d_func()->updateWorkspace();
2644}
2645
2646void QWorkspaceChild::resizeEvent(QResizeEvent *)
2647{
2648 bool wasMax = isMaximized();
2649 QRect r = contentsRect();
2650 QRect cr;
2651
2652 updateMask();
2653
2654 if (titlebar) {
2655 int th = titlebar->sizeHint().height();
2656 QRect tbrect(0, 0, width(), th);
2657 if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
2658 tbrect = QRect(r.x(), r.y(), r.width(), th);
2659 titlebar->setGeometry(tbrect);
2660
2661 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
2662 th -= frameWidth();
2663 cr = QRect(r.x(), r.y() + th + (shademode ? (frameWidth() * 3) : 0),
2664 r.width(), r.height() - th);
2665 } else {
2666 cr = r;
2667 }
2668
2669 if (!childWidget)
2670 return;
2671
2672 bool doContentsResize = (windowSize == childWidget->size()
2673 || !(childWidget->testAttribute(Qt::WA_Resized) && childWidget->testAttribute(Qt::WA_PendingResizeEvent))
2674 ||childWidget->isMaximized());
2675
2676 windowSize = cr.size();
2677 childWidget->move(cr.topLeft());
2678 if (doContentsResize)
2679 childWidget->resize(cr.size());
2680 ((QWorkspace*)parentWidget())->d_func()->updateWorkspace();
2681
2682 if (wasMax) {
2683 overrideWindowState(Qt::WindowMaximized);
2684 childWidget->overrideWindowState(Qt::WindowMaximized);
2685 }
2686}
2687
2688QSize QWorkspaceChild::baseSize() const
2689{
2690 int th = titlebar ? titlebar->sizeHint().height() : 0;
2691 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
2692 th -= frameWidth();
2693 return QSize(2*frameWidth(), 2*frameWidth() + th);
2694}
2695
2696QSize QWorkspaceChild::sizeHint() const
2697{
2698 if (!childWidget)
2699 return QWidget::sizeHint() + baseSize();
2700
2701 QSize prefSize = windowWidget()->sizeHint().expandedTo(windowWidget()->minimumSizeHint());
2702 prefSize = prefSize.expandedTo(windowWidget()->minimumSize()).boundedTo(windowWidget()->maximumSize());
2703 prefSize += baseSize();
2704
2705 return prefSize;
2706}
2707
2708QSize QWorkspaceChild::minimumSizeHint() const
2709{
2710 if (!childWidget)
2711 return QWidget::minimumSizeHint() + baseSize();
2712 QSize s = childWidget->minimumSize();
2713 if (s.isEmpty())
2714 s = childWidget->minimumSizeHint();
2715 return s + baseSize();
2716}
2717
2718void QWorkspaceChild::activate()
2719{
2720 ((QWorkspace*)parentWidget())->d_func()->activateWindow(windowWidget());
2721}
2722
2723bool QWorkspaceChild::eventFilter(QObject * o, QEvent * e)
2724{
2725 if (!isActive()
2726 && (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::FocusIn)) {
2727 if (iconw) {
2728 ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
2729 if (iconw) {
2730 ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
2731 delete iconw->parentWidget();
2732 iconw = 0;
2733 }
2734 }
2735 activate();
2736 }
2737
2738 // for all widgets except the window, that's the only thing we
2739 // process, and if we have no childWidget we skip totally
2740 if (o != childWidget || childWidget == 0)
2741 return false;
2742
2743 switch (e->type()) {
2744 case QEvent::ShowToParent:
2745 if (((QWorkspace*)parentWidget())->d_func()->focus.indexOf(this) < 0)
2746 ((QWorkspace*)parentWidget())->d_func()->focus.append(this);
2747
2748 if (windowWidget() && (windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
2749 internalRaise();
2750 show();
2751 }
2752 ((QWorkspace*)parentWidget())->d_func()->showWindow(windowWidget());
2753 break;
2754 case QEvent::WindowStateChange: {
2755 if (static_cast<QWindowStateChangeEvent*>(e)->isOverride())
2756 break;
2757 Qt::WindowStates state = windowWidget()->windowState();
2758
2759 if (state & Qt::WindowMinimized) {
2760 ((QWorkspace*)parentWidget())->d_func()->minimizeWindow(windowWidget());
2761 } else if (state & Qt::WindowMaximized) {
2762 if (windowWidget()->maximumSize().isValid() &&
2763 (windowWidget()->maximumWidth() < parentWidget()->width() ||
2764 windowWidget()->maximumHeight() < parentWidget()->height())) {
2765 windowWidget()->resize(windowWidget()->maximumSize());
2766 windowWidget()->overrideWindowState(Qt::WindowNoState);
2767 if (titlebar)
2768 titlebar->update();
2769 break;
2770 }
2771 if ((windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint))
2772 ((QWorkspace*)parentWidget())->d_func()->maximizeWindow(windowWidget());
2773 else
2774 ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
2775 } else {
2776 ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
2777 if (iconw) {
2778 ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
2779 delete iconw->parentWidget();
2780 }
2781 }
2782 } break;
2783 case QEvent::HideToParent:
2784 {
2785 QWidget * w = iconw;
2786 if (w && (w = w->parentWidget())) {
2787 ((QWorkspace*)parentWidget())->d_func()->removeIcon(w);
2788 delete w;
2789 }
2790 ((QWorkspace*)parentWidget())->d_func()->hideChild(this);
2791 } break;
2792 case QEvent::WindowIconChange:
2793 {
2794 QWorkspace* ws = (QWorkspace*)parentWidget();
2795 if (ws->d_func()->maxtools && ws->d_func()->maxWindow == this) {
2796 int iconSize = ws->d_func()->maxtools->size().height();
2797 ws->d_func()->maxtools->setPixmap(childWidget->windowIcon().pixmap(QSize(iconSize, iconSize)));
2798 }
2799 }
2800 // fall through
2801 case QEvent::WindowTitleChange:
2802 setWindowTitle(windowWidget()->windowTitle());
2803 if (titlebar)
2804 titlebar->update();
2805 if (iconw)
2806 iconw->update();
2807 break;
2808 case QEvent::ModifiedChange:
2809 setWindowModified(windowWidget()->isWindowModified());
2810 if (titlebar)
2811 titlebar->update();
2812 if (iconw)
2813 iconw->update();
2814 break;
2815 case QEvent::Resize:
2816 {
2817 QResizeEvent* re = (QResizeEvent*)e;
2818 if (re->size() != windowSize && !shademode) {
2819 resize(re->size() + baseSize());
2820 childWidget->update(); //workaround
2821 }
2822 }
2823 break;
2824
2825 case QEvent::WindowDeactivate:
2826 if (titlebar && titlebar->isActive()) {
2827 update();
2828 }
2829 break;
2830
2831 case QEvent::WindowActivate:
2832 if (titlebar && titlebar->isActive()) {
2833 update();
2834 }
2835 break;
2836
2837 default:
2838 break;
2839 }
2840
2841 return QWidget::eventFilter(o, e);
2842}
2843
2844void QWorkspaceChild::childEvent(QChildEvent* e)
2845{
2846 if (e->type() == QEvent::ChildRemoved && e->child() == childWidget) {
2847 childWidget = 0;
2848 if (iconw) {
2849 ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
2850 delete iconw->parentWidget();
2851 }
2852 close();
2853 }
2854}
2855
2856
2857void QWorkspaceChild::doResize()
2858{
2859 widgetResizeHandler->doResize();
2860}
2861
2862void QWorkspaceChild::doMove()
2863{
2864 widgetResizeHandler->doMove();
2865}
2866
2867void QWorkspaceChild::enterEvent(QEvent *)
2868{
2869}
2870
2871void QWorkspaceChild::leaveEvent(QEvent *)
2872{
2873#ifndef QT_NO_CURSOR
2874 if (!widgetResizeHandler->isButtonDown())
2875 setCursor(Qt::ArrowCursor);
2876#endif
2877}
2878
2879void QWorkspaceChild::paintEvent(QPaintEvent *)
2880{
2881 QPainter p(this);
2882 QStyleOptionFrame opt;
2883 opt.rect = rect();
2884 opt.palette = palette();
2885 opt.state = QStyle::State_None;
2886 opt.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
2887 opt.midLineWidth = 1;
2888
2889 if (titlebar && titlebar->isActive() && isActiveWindow())
2890 opt.state |= QStyle::State_Active;
2891
2892 style()->drawPrimitive(QStyle::PE_FrameWindow, &opt, &p, this);
2893}
2894
2895void QWorkspaceChild::changeEvent(QEvent *ev)
2896{
2897 if(ev->type() == QEvent::StyleChange) {
2898 resizeEvent(0);
2899 if (iconw) {
2900 QFrame *frame = qobject_cast<QFrame*>(iconw->parentWidget());
2901 Q_ASSERT(frame);
2902 if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar)) {
2903 frame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
2904 frame->resize(196+2*frame->frameWidth(), 20 + 2*frame->frameWidth());
2905 } else {
2906 frame->resize(196, 20);
2907 }
2908 }
2909 updateMask();
2910 }
2911 QWidget::changeEvent(ev);
2912}
2913
2914void QWorkspaceChild::setActive(bool b)
2915{
2916 if (!childWidget)
2917 return;
2918
2919 bool hasFocus = isChildOf(window()->focusWidget(), this);
2920 if (act == b && (act == hasFocus))
2921 return;
2922
2923 act = b;
2924
2925 if (titlebar)
2926 titlebar->setActive(act);
2927 if (iconw)
2928 iconw->setActive(act);
2929 update();
2930
2931 QList<QWidget*> wl = qFindChildren<QWidget*>(childWidget);
2932 if (act) {
2933 for (int i = 0; i < wl.size(); ++i) {
2934 QWidget *w = wl.at(i);
2935 w->removeEventFilter(this);
2936 }
2937 if (!hasFocus) {
2938 QWidget *lastfocusw = childWidget->focusWidget();
2939 if (lastfocusw && lastfocusw->focusPolicy() != Qt::NoFocus) {
2940 lastfocusw->setFocus();
2941 } else if (childWidget->focusPolicy() != Qt::NoFocus) {
2942 childWidget->setFocus();
2943 } else {
2944 // find something, anything, that accepts focus, and use that.
2945 for (int i = 0; i < wl.size(); ++i) {
2946 QWidget *w = wl.at(i);
2947 if(w->focusPolicy() != Qt::NoFocus) {
2948 w->setFocus();
2949 hasFocus = true;
2950 break;
2951 }
2952 }
2953 if (!hasFocus)
2954 setFocus();
2955 }
2956 }
2957 } else {
2958 for (int i = 0; i < wl.size(); ++i) {
2959 QWidget *w = wl.at(i);
2960 w->removeEventFilter(this);
2961 w->installEventFilter(this);
2962 }
2963 }
2964}
2965
2966bool QWorkspaceChild::isActive() const
2967{
2968 return act;
2969}
2970
2971QWidget* QWorkspaceChild::windowWidget() const
2972{
2973 return childWidget;
2974}
2975
2976bool QWorkspaceChild::isWindowOrIconVisible() const
2977{
2978 return childWidget && (!isHidden() || (iconw && !iconw->isHidden()));
2979}
2980
2981void QWorkspaceChild::updateMask()
2982{
2983 QStyleOptionTitleBar titleBarOptions;
2984 titleBarOptions.rect = rect();
2985 titleBarOptions.titleBarFlags = windowFlags();
2986 titleBarOptions.titleBarState = windowState();
2987
2988 QStyleHintReturnMask frameMask;
2989 if (style()->styleHint(QStyle::SH_WindowFrame_Mask, &titleBarOptions, this, &frameMask)) {
2990 setMask(frameMask.region);
2991 } else if (!mask().isEmpty()) {
2992 clearMask();
2993 }
2994
2995 if (iconw) {
2996 QFrame *frame = qobject_cast<QFrame *>(iconw->parentWidget());
2997 Q_ASSERT(frame);
2998
2999 titleBarOptions.rect = frame->rect();
3000 titleBarOptions.titleBarFlags = frame->windowFlags();
3001 titleBarOptions.titleBarState = frame->windowState() | Qt::WindowMinimized;
3002 if (style()->styleHint(QStyle::SH_WindowFrame_Mask, &titleBarOptions, frame, &frameMask)) {
3003 frame->setMask(frameMask.region);
3004 } else if (!frame->mask().isEmpty()) {
3005 frame->clearMask();
3006 }
3007 }
3008}
3009
3010QWidget* QWorkspaceChild::iconWidget() const
3011{
3012 if (!iconw) {
3013 QWorkspaceChild* that = (QWorkspaceChild*) this;
3014
3015 QFrame* frame = new QFrame(that, Qt::Window);
3016 QVBoxLayout *vbox = new QVBoxLayout(frame);
3017 vbox->setMargin(0);
3018 QWorkspaceTitleBar *tb = new QWorkspaceTitleBar(windowWidget(), frame);
3019 vbox->addWidget(tb);
3020 tb->setObjectName(QLatin1String("_workspacechild_icon_"));
3021 QStyleOptionTitleBar opt;
3022 tb->initStyleOption(&opt);
3023 int th = style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, tb);
3024 int iconSize = style()->pixelMetric(QStyle::PM_MdiSubWindowMinimizedWidth, 0, this);
3025 if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar)) {
3026 frame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
3027 frame->resize(iconSize+2*frame->frameWidth(), th+2*frame->frameWidth());
3028 } else {
3029 frame->resize(iconSize, th);
3030 }
3031
3032 that->iconw = tb;
3033 that->updateMask();
3034 iconw->setActive(isActive());
3035
3036 connect(iconw, SIGNAL(doActivate()),
3037 this, SLOT(activate()));
3038 connect(iconw, SIGNAL(doClose()),
3039 windowWidget(), SLOT(close()));
3040 connect(iconw, SIGNAL(doNormal()),
3041 this, SLOT(showNormal()));
3042 connect(iconw, SIGNAL(doMaximize()),
3043 this, SLOT(showMaximized()));
3044 connect(iconw, SIGNAL(popupOperationMenu(QPoint)),
3045 this, SIGNAL(popupOperationMenu(QPoint)));
3046 connect(iconw, SIGNAL(showOperationMenu()),
3047 this, SIGNAL(showOperationMenu()));
3048 connect(iconw, SIGNAL(doubleClicked()),
3049 this, SLOT(titleBarDoubleClicked()));
3050 }
3051 if (windowWidget()) {
3052 iconw->setWindowTitle(windowWidget()->windowTitle());
3053 }
3054 return iconw->parentWidget();
3055}
3056
3057void QWorkspaceChild::showMinimized()
3058{
3059 windowWidget()->setWindowState(Qt::WindowMinimized | (windowWidget()->windowState() & ~Qt::WindowMaximized));
3060}
3061
3062void QWorkspaceChild::showMaximized()
3063{
3064 windowWidget()->setWindowState(Qt::WindowMaximized | (windowWidget()->windowState() & ~Qt::WindowMinimized));
3065}
3066
3067void QWorkspaceChild::showNormal()
3068{
3069 windowWidget()->setWindowState(windowWidget()->windowState() & ~(Qt::WindowMinimized|Qt::WindowMaximized));
3070}
3071
3072void QWorkspaceChild::showShaded()
3073{
3074 if (!titlebar)
3075 return;
3076 ((QWorkspace*)parentWidget())->d_func()->activateWindow(windowWidget());
3077 QWidget* w = windowWidget();
3078 if (shademode) {
3079 w->overrideWindowState(Qt::WindowNoState);
3080 overrideWindowState(Qt::WindowNoState);
3081
3082 shademode = false;
3083 resize(shadeRestore.expandedTo(minimumSizeHint()));
3084 setMinimumSize(shadeRestoreMin);
3085 style()->polish(this);
3086 } else {
3087 shadeRestore = size();
3088 shadeRestoreMin = minimumSize();
3089 setMinimumHeight(0);
3090 shademode = true;
3091 w->overrideWindowState(Qt::WindowMinimized);
3092 overrideWindowState(Qt::WindowMinimized);
3093
3094 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
3095 resize(width(), titlebar->height());
3096 else
3097 resize(width(), titlebar->height() + 2*frameWidth() + 1);
3098 style()->polish(this);
3099 }
3100 titlebar->update();
3101}
3102
3103void QWorkspaceChild::titleBarDoubleClicked()
3104{
3105 if (!windowWidget())
3106 return;
3107 if (iconw)
3108 showNormal();
3109 else if (windowWidget()->windowFlags() & Qt::WindowShadeButtonHint)
3110 showShaded();
3111 else if (windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint)
3112 showMaximized();
3113}
3114
3115void QWorkspaceChild::adjustToFullscreen()
3116{
3117 if (!childWidget)
3118 return;
3119
3120 if(!((QWorkspace*)parentWidget())->d_func()->maxmenubar || style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, this)) {
3121 setGeometry(parentWidget()->rect());
3122 } else {
3123 int fw = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
3124 bool noBorder = style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar);
3125 int th = titlebar ? titlebar->sizeHint().height() : 0;
3126 int w = parentWidget()->width() + 2*fw;
3127 int h = parentWidget()->height() + (noBorder ? fw : 2*fw) + th;
3128 w = qMax(w, childWidget->minimumWidth());
3129 h = qMax(h, childWidget->minimumHeight());
3130 setGeometry(-fw, (noBorder ? 0 : -fw) - th, w, h);
3131 }
3132 childWidget->overrideWindowState(Qt::WindowMaximized);
3133 overrideWindowState(Qt::WindowMaximized);
3134}
3135
3136void QWorkspaceChild::internalRaise()
3137{
3138
3139 QWidget *stackUnderWidget = 0;
3140 if (!windowWidget() || (windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint) == 0) {
3141
3142 QList<QWorkspaceChild *>::Iterator it(((QWorkspace*)parent())->d_func()->windows.begin());
3143 while (it != ((QWorkspace*)parent())->d_func()->windows.end()) {
3144 QWorkspaceChild* c = *it;
3145 ++it;
3146 if (c->windowWidget() &&
3147 !c->windowWidget()->isHidden() &&
3148 (c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
3149 if (stackUnderWidget)
3150 c->stackUnder(stackUnderWidget);
3151 else
3152 c->raise();
3153 stackUnderWidget = c;
3154 }
3155 }
3156 }
3157
3158 if (stackUnderWidget) {
3159 if (iconw)
3160 iconw->parentWidget()->stackUnder(stackUnderWidget);
3161 stackUnder(stackUnderWidget);
3162 } else {
3163 if (iconw)
3164 iconw->parentWidget()->raise();
3165 raise();
3166 }
3167
3168}
3169
3170void QWorkspaceChild::show()
3171{
3172 if (childWidget && childWidget->isHidden())
3173 childWidget->show();
3174 QWidget::show();
3175}
3176
3177bool QWorkspace::scrollBarsEnabled() const
3178{
3179 Q_D(const QWorkspace);
3180 return d->vbar != 0;
3181}
3182
3183/*!
3184 \property QWorkspace::scrollBarsEnabled
3185 \brief whether the workspace provides scroll bars
3186
3187 If this property is true, the workspace will provide scroll bars if any
3188 of the child windows extend beyond the edges of the visible
3189 workspace. The workspace area will automatically increase to
3190 contain child windows if they are resized beyond the right or
3191 bottom edges of the visible area.
3192
3193 If this property is false (the default), resizing child windows
3194 out of the visible area of the workspace is not permitted, although
3195 it is still possible to position them partially outside the visible area.
3196*/
3197void QWorkspace::setScrollBarsEnabled(bool enable)
3198{
3199 Q_D(QWorkspace);
3200 if ((d->vbar != 0) == enable)
3201 return;
3202
3203 d->xoffset = d->yoffset = 0;
3204 if (enable) {
3205 d->vbar = new QScrollBar(Qt::Vertical, this);
3206 d->vbar->setObjectName(QLatin1String("vertical scrollbar"));
3207 connect(d->vbar, SIGNAL(valueChanged(int)), this, SLOT(_q_scrollBarChanged()));
3208 d->hbar = new QScrollBar(Qt::Horizontal, this);
3209 d->hbar->setObjectName(QLatin1String("horizontal scrollbar"));
3210 connect(d->hbar, SIGNAL(valueChanged(int)), this, SLOT(_q_scrollBarChanged()));
3211 d->corner = new QWidget(this);
3212 d->corner->setBackgroundRole(QPalette::Window);
3213 d->corner->setObjectName(QLatin1String("qt_corner"));
3214 d->updateWorkspace();
3215 } else {
3216 delete d->vbar;
3217 delete d->hbar;
3218 delete d->corner;
3219 d->vbar = d->hbar = 0;
3220 d->corner = 0;
3221 }
3222
3223 QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
3224 while (it != d->windows.end()) {
3225 QWorkspaceChild *child = *it;
3226 ++it;
3227 child->widgetResizeHandler->setSizeProtection(!enable);
3228 }
3229}
3230
3231QRect QWorkspacePrivate::updateWorkspace()
3232{
3233 Q_Q(QWorkspace);
3234 QRect cr(q->rect());
3235
3236 if (q->scrollBarsEnabled() && !maxWindow) {
3237 corner->raise();
3238 vbar->raise();
3239 hbar->raise();
3240 if (maxWindow)
3241 maxWindow->internalRaise();
3242
3243 QRect r(0, 0, 0, 0);
3244 QList<QWorkspaceChild *>::Iterator it(windows.begin());
3245 while (it != windows.end()) {
3246 QWorkspaceChild *child = *it;
3247 ++it;
3248 if (!child->isHidden())
3249 r = r.unite(child->geometry());
3250 }
3251 vbar->blockSignals(true);
3252 hbar->blockSignals(true);
3253
3254 int hsbExt = hbar->sizeHint().height();
3255 int vsbExt = vbar->sizeHint().width();
3256
3257
3258 bool showv = yoffset || yoffset + r.bottom() - q->height() + 1 > 0 || yoffset + r.top() < 0;
3259 bool showh = xoffset || xoffset + r.right() - q->width() + 1 > 0 || xoffset + r.left() < 0;
3260
3261 if (showh && !showv)
3262 showv = yoffset + r.bottom() - q->height() + hsbExt + 1 > 0;
3263 if (showv && !showh)
3264 showh = xoffset + r.right() - q->width() + vsbExt + 1 > 0;
3265
3266 if (!showh)
3267 hsbExt = 0;
3268 if (!showv)
3269 vsbExt = 0;
3270
3271 if (showv) {
3272 vbar->setSingleStep(qMax(q->height() / 12, 30));
3273 vbar->setPageStep(q->height() - hsbExt);
3274 vbar->setMinimum(qMin(0, yoffset + qMin(0, r.top())));
3275 vbar->setMaximum(qMax(0, yoffset + qMax(0, r.bottom() - q->height() + hsbExt + 1)));
3276 vbar->setGeometry(q->width() - vsbExt, 0, vsbExt, q->height() - hsbExt);
3277 vbar->setValue(yoffset);
3278 vbar->show();
3279 } else {
3280 vbar->hide();
3281 }
3282
3283 if (showh) {
3284 hbar->setSingleStep(qMax(q->width() / 12, 30));
3285 hbar->setPageStep(q->width() - vsbExt);
3286 hbar->setMinimum(qMin(0, xoffset + qMin(0, r.left())));
3287 hbar->setMaximum(qMax(0, xoffset + qMax(0, r.right() - q->width() + vsbExt + 1)));
3288 hbar->setGeometry(0, q->height() - hsbExt, q->width() - vsbExt, hsbExt);
3289 hbar->setValue(xoffset);
3290 hbar->show();
3291 } else {
3292 hbar->hide();
3293 }
3294
3295 if (showh && showv) {
3296 corner->setGeometry(q->width() - vsbExt, q->height() - hsbExt, vsbExt, hsbExt);
3297 corner->show();
3298 } else {
3299 corner->hide();
3300 }
3301
3302 vbar->blockSignals(false);
3303 hbar->blockSignals(false);
3304
3305 cr.setRect(0, 0, q->width() - vsbExt, q->height() - hsbExt);
3306 }
3307
3308 QList<QWidget *>::Iterator ii(icons.begin());
3309 while (ii != icons.end()) {
3310 QWidget* w = *ii;
3311 ++ii;
3312 int x = w->x();
3313 int y = w->y();
3314 bool m = false;
3315 if (x+w->width() > cr.width()) {
3316 m = true;
3317 x = cr.width() - w->width();
3318 }
3319 if (y+w->height() > cr.height()) {
3320 y = cr.height() - w->height();
3321 m = true;
3322 }
3323 if (m) {
3324 if (QWorkspaceChild *child = qobject_cast<QWorkspaceChild*>(w))
3325 child->move(x, y);
3326 else
3327 w->move(x, y);
3328 }
3329 }
3330
3331 return cr;
3332
3333}
3334
3335void QWorkspacePrivate::_q_scrollBarChanged()
3336{
3337 int ver = yoffset - vbar->value();
3338 int hor = xoffset - hbar->value();
3339 yoffset = vbar->value();
3340 xoffset = hbar->value();
3341
3342 QList<QWorkspaceChild *>::Iterator it(windows.begin());
3343 while (it != windows.end()) {
3344 QWorkspaceChild *child = *it;
3345 ++it;
3346 // we do not use move() due to the reimplementation in QWorkspaceChild
3347 child->setGeometry(child->x() + hor, child->y() + ver, child->width(), child->height());
3348 }
3349 updateWorkspace();
3350}
3351
3352/*!
3353 \enum QWorkspace::WindowOrder
3354
3355 Specifies the order in which child windows are returned from windowList().
3356
3357 \value CreationOrder The windows are returned in the order of their creation
3358 \value StackingOrder The windows are returned in the order of their stacking
3359*/
3360
3361/*!\reimp */
3362void QWorkspace::changeEvent(QEvent *ev)
3363{
3364 Q_D(QWorkspace);
3365 if(ev->type() == QEvent::StyleChange) {
3366 if (isVisible() && d->maxWindow && d->maxmenubar) {
3367 if(style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, this)) {
3368 d->hideMaximizeControls(); //hide any visible maximized controls
3369 d->showMaximizeControls(); //updates the modification state as well
3370 }
3371 }
3372 }
3373 QWidget::changeEvent(ev);
3374}
3375
3376QT_END_NAMESPACE
3377
3378#include "moc_qworkspace.cpp"
3379
3380#include "qworkspace.moc"
3381
3382#endif // QT_NO_WORKSPACE
Note: See TracBrowser for help on using the repository browser.