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

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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