src/gui/widgets/qworkspace.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/widgets/qworkspace.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,3377 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qworkspace.h"
+#ifndef QT_NO_WORKSPACE
+#include "qapplication.h"
+#include "qbitmap.h"
+#include "qcursor.h"
+#include "qdatetime.h"
+#include "qdesktopwidget.h"
+#include "qevent.h"
+#include "qhash.h"
+#include "qicon.h"
+#include "qimage.h"
+#include "qlabel.h"
+#include "qlayout.h"
+#include "qmenubar.h"
+#include "qmenu.h"
+#include "qpainter.h"
+#include "qpointer.h"
+#include "qscrollbar.h"
+#include "qstyle.h"
+#include "qstyleoption.h"
+#include "qtooltip.h"
+#include "qdebug.h"
+#include <private/qwidget_p.h>
+#include <private/qwidgetresizehandler_p.h>
+#include <private/qlayoutengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWorkspaceTitleBarPrivate;
+
+
+/**************************************************************
+* QMDIControl
+*
+* Used for displaying MDI controls in a maximized MDI window
+*
+*/
+class QMDIControl : public QWidget
+{
+    Q_OBJECT
+signals:
+    void _q_minimize();
+    void _q_restore();
+    void _q_close();
+
+public:
+    QMDIControl(QWidget *widget);
+
+private:
+    QSize sizeHint() const;
+    void paintEvent(QPaintEvent *event);
+    void mousePressEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+    void mouseMoveEvent(QMouseEvent *event);
+    void leaveEvent(QEvent *event);
+    bool event(QEvent *event);
+    void initStyleOption(QStyleOptionComplex *option) const;
+    QStyle::SubControl activeControl; //control locked by pressing and holding the mouse
+    QStyle::SubControl hoverControl; //previously active hover control, used for tracking repaints
+};
+
+bool QMDIControl::event(QEvent *event)
+{
+    if (event->type() == QEvent::ToolTip) {
+        QStyleOptionComplex opt;
+        initStyleOption(&opt);
+#ifndef QT_NO_TOOLTIP
+        QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
+        QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
+                                                                 helpEvent->pos(), this);
+        if (ctrl == QStyle::SC_MdiCloseButton)
+            QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Close"), this);
+        else if (ctrl == QStyle::SC_MdiMinButton)
+            QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Minimize"), this);
+        else if (ctrl == QStyle::SC_MdiNormalButton)
+            QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Restore Down"), this);
+        else
+            QToolTip::hideText();
+#endif // QT_NO_TOOLTIP
+    }
+    return QWidget::event(event);
+}
+
+void QMDIControl::initStyleOption(QStyleOptionComplex *option) const
+{
+    option->initFrom(this);
+    option->subControls = QStyle::SC_All;
+    option->activeSubControls = QStyle::SC_None;
+}
+
+QMDIControl::QMDIControl(QWidget *widget)
+    : QWidget(widget), activeControl(QStyle::SC_None),
+      hoverControl(QStyle::SC_None)
+{
+    setObjectName(QLatin1String("qt_maxcontrols"));
+    setFocusPolicy(Qt::NoFocus);
+    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+    setMouseTracking(true);
+}
+
+QSize QMDIControl::sizeHint() const
+{
+    ensurePolished();
+    QStyleOptionComplex opt;
+    initStyleOption(&opt);
+    QSize size(48, 16);
+    return style()->sizeFromContents(QStyle::CT_MdiControls, &opt, size, this);
+}
+
+void QMDIControl::mousePressEvent(QMouseEvent *event)
+{
+    if (event->button() != Qt::LeftButton) {
+        event->ignore();
+        return;
+    }
+    QStyleOptionComplex opt;
+    initStyleOption(&opt);
+    QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
+                                                             event->pos(), this);
+    activeControl = ctrl;
+    update();
+}
+
+void QMDIControl::mouseReleaseEvent(QMouseEvent *event)
+{
+    if (event->button() != Qt::LeftButton) {
+        event->ignore();
+        return;
+    }
+    QStyleOptionTitleBar opt;
+    initStyleOption(&opt);
+    QStyle::SubControl under_mouse = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
+                                                                    event->pos(), this);
+    if (under_mouse == activeControl) {
+        switch (activeControl) {
+        case QStyle::SC_MdiCloseButton:
+            emit _q_close();
+            break;
+        case QStyle::SC_MdiNormalButton:
+            emit _q_restore();
+            break;
+        case QStyle::SC_MdiMinButton:
+            emit _q_minimize();
+            break;
+        default:
+            break;
+        }
+    }
+    activeControl = QStyle::SC_None;
+    update();
+}
+
+void QMDIControl::leaveEvent(QEvent * /*event*/)
+{
+    hoverControl = QStyle::SC_None;
+    update();
+}
+
+void QMDIControl::mouseMoveEvent(QMouseEvent *event)
+{
+    QStyleOptionTitleBar opt;
+    initStyleOption(&opt);
+    QStyle::SubControl under_mouse = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
+                                                                    event->pos(), this);
+    //test if hover state changes
+    if (hoverControl != under_mouse) {
+        hoverControl = under_mouse;
+        update();
+    }
+}
+
+void QMDIControl::paintEvent(QPaintEvent *)
+{
+    QPainter p(this);
+    QStyleOptionComplex opt;
+    initStyleOption(&opt);
+    if (activeControl == hoverControl) {
+        opt.activeSubControls = activeControl;
+        opt.state |= QStyle::State_Sunken;
+    } else if (hoverControl != QStyle::SC_None && (activeControl == QStyle::SC_None)) {
+        opt.activeSubControls = hoverControl;
+        opt.state |= QStyle::State_MouseOver;
+    }
+    style()->drawComplexControl(QStyle::CC_MdiControls, &opt, &p, this);
+}
+
+class QWorkspaceTitleBar : public QWidget
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QWorkspaceTitleBar)
+    Q_PROPERTY(bool autoRaise READ autoRaise WRITE setAutoRaise)
+    Q_PROPERTY(bool movable READ isMovable WRITE setMovable)
+
+public:
+    QWorkspaceTitleBar (QWidget *w, QWidget *parent, Qt::WindowFlags f = 0);
+    ~QWorkspaceTitleBar();
+
+    bool isActive() const;
+    bool usesActiveColor() const;
+
+    bool isMovable() const;
+    void setMovable(bool);
+
+    bool autoRaise() const;
+    void setAutoRaise(bool);
+
+    QWidget *window() const;
+    bool isTool() const;
+
+    QSize sizeHint() const;
+    void initStyleOption(QStyleOptionTitleBar *option) const;
+
+public slots:
+    void setActive(bool);
+
+signals:
+    void doActivate();
+    void doNormal();
+    void doClose();
+    void doMaximize();
+    void doMinimize();
+    void doShade();
+    void showOperationMenu();
+    void popupOperationMenu(const QPoint&);
+    void doubleClicked();
+
+protected:
+    bool event(QEvent *);
+#ifndef QT_NO_CONTEXTMENU
+    void contextMenuEvent(QContextMenuEvent *);
+#endif
+    void mousePressEvent(QMouseEvent *);
+    void mouseDoubleClickEvent(QMouseEvent *);
+    void mouseReleaseEvent(QMouseEvent *);
+    void mouseMoveEvent(QMouseEvent *);
+    void enterEvent(QEvent *e);
+    void leaveEvent(QEvent *e);
+    void paintEvent(QPaintEvent *p);
+
+private:
+    Q_DISABLE_COPY(QWorkspaceTitleBar)
+};
+
+
+class QWorkspaceTitleBarPrivate : public QWidgetPrivate
+{
+    Q_DECLARE_PUBLIC(QWorkspaceTitleBar)
+public:
+    QWorkspaceTitleBarPrivate()
+        :
+        lastControl(QStyle::SC_None),
+#ifndef QT_NO_TOOLTIP
+        toolTip(0),
+#endif
+        act(0), window(0), movable(1), pressed(0), autoraise(0), moving(0)
+    {
+    }
+
+    Qt::WindowFlags flags;
+    QStyle::SubControl buttonDown;
+    QStyle::SubControl lastControl;
+    QPoint moveOffset;
+#ifndef QT_NO_TOOLTIP
+    QToolTip *toolTip;
+#endif
+    bool act                    :1;
+    QPointer<QWidget> window;
+    bool movable            :1;
+    bool pressed            :1;
+    bool autoraise          :1;
+    bool moving : 1;
+
+    int titleBarState() const;
+    void readColors();
+};
+
+inline int QWorkspaceTitleBarPrivate::titleBarState() const
+{
+    Q_Q(const QWorkspaceTitleBar);
+    uint state = window ? window->windowState() : static_cast<Qt::WindowStates>(Qt::WindowNoState);
+    state |= uint((act && q->isActiveWindow()) ? QStyle::State_Active : QStyle::State_None);
+    return (int)state;
+}
+
+void QWorkspaceTitleBar::initStyleOption(QStyleOptionTitleBar *option) const
+{
+    Q_D(const QWorkspaceTitleBar);
+    option->initFrom(this);
+    //################
+    if (d->window && (d->flags & Qt::WindowTitleHint)) {
+        option->text = d->window->windowTitle();
+        QIcon icon = d->window->windowIcon();
+        QSize s = icon.actualSize(QSize(64, 64));
+        option->icon = icon.pixmap(s);
+    }
+    option->subControls = QStyle::SC_All;
+    option->activeSubControls = QStyle::SC_None;
+    option->titleBarState = d->titleBarState();
+    option->titleBarFlags = d->flags;
+    option->state &= ~QStyle::State_MouseOver;
+}
+
+QWorkspaceTitleBar::QWorkspaceTitleBar(QWidget *w, QWidget *parent, Qt::WindowFlags f)
+    : QWidget(*new QWorkspaceTitleBarPrivate, parent, Qt::FramelessWindowHint)
+{
+    Q_D(QWorkspaceTitleBar);
+    if (f == 0 && w)
+        f = w->windowFlags();
+    d->flags = f;
+    d->window = w;
+    d->buttonDown = QStyle::SC_None;
+    d->act = 0;
+    if (w) {
+        if (w->maximumSize() != QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX))
+            d->flags &= ~Qt::WindowMaximizeButtonHint;
+        setWindowTitle(w->windowTitle());
+    }
+
+    d->readColors();
+    setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+    setMouseTracking(true);
+    setAutoRaise(style()->styleHint(QStyle::SH_TitleBar_AutoRaise, 0, this));
+}
+
+QWorkspaceTitleBar::~QWorkspaceTitleBar()
+{
+}
+
+
+#ifdef Q_WS_WIN
+static inline QRgb colorref2qrgb(COLORREF col)
+{
+    return qRgb(GetRValue(col),GetGValue(col),GetBValue(col));
+}
+#endif
+
+void QWorkspaceTitleBarPrivate::readColors()
+{
+    Q_Q(QWorkspaceTitleBar);
+    QPalette pal = q->palette();
+
+    bool colorsInitialized = false;
+
+#ifdef Q_WS_WIN // ask system properties on windows
+#ifndef SPI_GETGRADIENTCAPTIONS
+#define SPI_GETGRADIENTCAPTIONS 0x1008
+#endif
+#ifndef COLOR_GRADIENTACTIVECAPTION
+#define COLOR_GRADIENTACTIVECAPTION 27
+#endif
+#ifndef COLOR_GRADIENTINACTIVECAPTION
+#define COLOR_GRADIENTINACTIVECAPTION 28
+#endif
+    if (QApplication::desktopSettingsAware()) {
+        pal.setColor(QPalette::Active, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION)));
+        pal.setColor(QPalette::Inactive, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)));
+        pal.setColor(QPalette::Active, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)));
+        pal.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)));
+
+        colorsInitialized = true;
+        BOOL gradient = false;
+        SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
+
+        if (gradient) {
+            pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
+            pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
+        } else {
+            pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight));
+            pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight));
+        }
+    }
+#endif // Q_WS_WIN
+    if (!colorsInitialized) {
+        pal.setColor(QPalette::Active, QPalette::Highlight,
+                      pal.color(QPalette::Active, QPalette::Highlight));
+        pal.setColor(QPalette::Active, QPalette::Base,
+                      pal.color(QPalette::Active, QPalette::Highlight));
+        pal.setColor(QPalette::Inactive, QPalette::Highlight,
+                      pal.color(QPalette::Inactive, QPalette::Dark));
+        pal.setColor(QPalette::Inactive, QPalette::Base,
+                      pal.color(QPalette::Inactive, QPalette::Dark));
+        pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
+                      pal.color(QPalette::Inactive, QPalette::Window));
+    }
+
+    q->setPalette(pal);
+    q->setActive(act);
+}
+
+void QWorkspaceTitleBar::mousePressEvent(QMouseEvent *e)
+{
+    Q_D(QWorkspaceTitleBar);
+    if (!d->act)
+        emit doActivate();
+    if (e->button() == Qt::LeftButton) {
+        if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
+            && !rect().adjusted(5, 5, -5, 0).contains(e->pos())) {
+            // propagate border events to the QWidgetResizeHandler
+            e->ignore();
+            return;
+        }
+
+        d->pressed = true;
+        QStyleOptionTitleBar opt;
+        initStyleOption(&opt);
+        QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
+                                                                 e->pos(), this);
+        switch (ctrl) {
+        case QStyle::SC_TitleBarSysMenu:
+            if (d->flags & Qt::WindowSystemMenuHint) {
+                d->buttonDown = QStyle::SC_None;
+                static QTime *t = 0;
+                static QWorkspaceTitleBar *tc = 0;
+                if (!t)
+                    t = new QTime;
+                if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) {
+                    emit showOperationMenu();
+                    t->start();
+                    tc = this;
+                } else {
+                    tc = 0;
+                    emit doClose();
+                    return;
+                }
+            }
+            break;
+
+        case QStyle::SC_TitleBarShadeButton:
+        case QStyle::SC_TitleBarUnshadeButton:
+            if (d->flags & Qt::WindowShadeButtonHint)
+                d->buttonDown = ctrl;
+            break;
+
+        case QStyle::SC_TitleBarNormalButton:
+                d->buttonDown = ctrl;
+            break;
+
+        case QStyle::SC_TitleBarMinButton:
+            if (d->flags & Qt::WindowMinimizeButtonHint)
+                d->buttonDown = ctrl;
+            break;
+
+        case QStyle::SC_TitleBarMaxButton:
+            if (d->flags & Qt::WindowMaximizeButtonHint)
+                d->buttonDown = ctrl;
+            break;
+
+        case QStyle::SC_TitleBarCloseButton:
+            if (d->flags & Qt::WindowSystemMenuHint)
+                d->buttonDown = ctrl;
+            break;
+
+        case QStyle::SC_TitleBarLabel:
+            d->buttonDown = ctrl;
+            d->moveOffset = mapToParent(e->pos());
+            break;
+
+        default:
+            break;
+        }
+        update();
+    } else {
+        d->pressed = false;
+    }
+}
+
+#ifndef QT_NO_CONTEXTMENU
+void QWorkspaceTitleBar::contextMenuEvent(QContextMenuEvent *e)
+{
+    QStyleOptionTitleBar opt;
+    initStyleOption(&opt);
+    QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(),
+                                                             this);
+    if(ctrl == QStyle::SC_TitleBarLabel || ctrl == QStyle::SC_TitleBarSysMenu) {
+        e->accept();
+        emit popupOperationMenu(e->globalPos());
+    } else {
+        e->ignore();
+    }
+}
+#endif // QT_NO_CONTEXTMENU
+
+void QWorkspaceTitleBar::mouseReleaseEvent(QMouseEvent *e)
+{
+    Q_D(QWorkspaceTitleBar);
+    if (!d->window) {
+        // could have been deleted as part of a double click event on the sysmenu
+        return;
+    }
+    if (e->button() == Qt::LeftButton && d->pressed) {
+        if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
+            && !rect().adjusted(5, 5, -5, 0).contains(e->pos())) {
+            // propagate border events to the QWidgetResizeHandler
+            e->ignore();
+            d->buttonDown = QStyle::SC_None;
+            d->pressed = false;
+            return;
+        }
+        e->accept();
+        QStyleOptionTitleBar opt;
+        initStyleOption(&opt);
+        QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
+                                                                 e->pos(), this);
+
+        if (d->pressed) {
+            update();
+            d->pressed = false;
+            d->moving = false;
+        }
+        if (ctrl == d->buttonDown) {
+            d->buttonDown = QStyle::SC_None;
+            switch(ctrl) {
+            case QStyle::SC_TitleBarShadeButton:
+            case QStyle::SC_TitleBarUnshadeButton:
+                if(d->flags & Qt::WindowShadeButtonHint)
+                    emit doShade();
+                break;
+
+            case QStyle::SC_TitleBarNormalButton:
+                if(d->flags & Qt::WindowMinMaxButtonsHint)
+                    emit doNormal();
+                break;
+
+            case QStyle::SC_TitleBarMinButton:
+                if(d->flags & Qt::WindowMinimizeButtonHint) {
+                    if (d->window && d->window->isMinimized())
+                        emit doNormal();
+                    else
+                        emit doMinimize();
+                }
+                break;
+
+            case QStyle::SC_TitleBarMaxButton:
+                if(d->flags & Qt::WindowMaximizeButtonHint) {
+                    if(d->window && d->window->isMaximized())
+                        emit doNormal();
+                    else
+                        emit doMaximize();
+                }
+                break;
+
+            case QStyle::SC_TitleBarCloseButton:
+                if(d->flags & Qt::WindowSystemMenuHint) {
+                    d->buttonDown = QStyle::SC_None;
+                    emit doClose();
+                    return;
+                }
+                break;
+
+            default:
+                break;
+            }
+        }
+    } else {
+        e->ignore();
+    }
+}
+
+void QWorkspaceTitleBar::mouseMoveEvent(QMouseEvent *e)
+{
+    Q_D(QWorkspaceTitleBar);
+    e->ignore();
+    if ((e->buttons() & Qt::LeftButton) && style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
+        && !rect().adjusted(5, 5, -5, 0).contains(e->pos()) && !d->pressed) {
+        // propagate border events to the QWidgetResizeHandler
+        return;
+    }
+
+    QStyleOptionTitleBar opt;
+    initStyleOption(&opt);
+    QStyle::SubControl under_mouse = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
+                                                                    e->pos(), this);
+    if(under_mouse != d->lastControl) {
+        d->lastControl = under_mouse;
+        update();
+    }
+
+    switch (d->buttonDown) {
+    case QStyle::SC_None:
+        break;
+    case QStyle::SC_TitleBarSysMenu:
+        break;
+    case QStyle::SC_TitleBarLabel:
+        if (d->buttonDown == QStyle::SC_TitleBarLabel && d->movable && d->pressed) {
+            if (d->moving || (d->moveOffset - mapToParent(e->pos())).manhattanLength() >= 4) {
+                d->moving = true;
+                QPoint p = mapFromGlobal(e->globalPos());
+
+                QWidget *parent = d->window ? d->window->parentWidget() : 0;
+                if(parent && parent->inherits("QWorkspaceChild")) {
+                    QWidget *workspace = parent->parentWidget();
+                    p = workspace->mapFromGlobal(e->globalPos());
+                    if (!workspace->rect().contains(p)) {
+                        if (p.x() < 0)
+                            p.rx() = 0;
+                        if (p.y() < 0)
+                            p.ry() = 0;
+                        if (p.x() > workspace->width())
+                            p.rx() = workspace->width();
+                        if (p.y() > workspace->height())
+                            p.ry() = workspace->height();
+                    }
+                }
+
+                QPoint pp = p - d->moveOffset;
+                if (!parentWidget()->isMaximized())
+                    parentWidget()->move(pp);
+            }
+        }
+        e->accept();
+        break;
+    default:
+        break;
+    }
+}
+
+bool QWorkspaceTitleBar::isTool() const
+{
+    Q_D(const QWorkspaceTitleBar);
+    return (d->flags & Qt::WindowType_Mask) == Qt::Tool;
+}
+
+// from qwidget.cpp
+extern QString qt_setWindowTitle_helperHelper(const QString &, const QWidget*);
+
+void QWorkspaceTitleBar::paintEvent(QPaintEvent *)
+{
+    Q_D(QWorkspaceTitleBar);
+    QStyleOptionTitleBar opt;
+    initStyleOption(&opt);
+    opt.subControls = QStyle::SC_TitleBarLabel;
+    opt.activeSubControls = d->buttonDown;
+
+    if (d->window && (d->flags & Qt::WindowTitleHint)) {
+        QString title = qt_setWindowTitle_helperHelper(opt.text, d->window);
+        int maxw = style()->subControlRect(QStyle::CC_TitleBar, &opt, QStyle::SC_TitleBarLabel,
+                                       this).width();
+        opt.text = fontMetrics().elidedText(title, Qt::ElideRight, maxw);
+    }
+
+    if (d->flags & Qt::WindowSystemMenuHint) {
+        opt.subControls |= QStyle::SC_TitleBarSysMenu | QStyle::SC_TitleBarCloseButton;
+        if (d->window && (d->flags & Qt::WindowShadeButtonHint)) {
+            if (d->window->isMinimized())
+                opt.subControls |= QStyle::SC_TitleBarUnshadeButton;
+            else
+                opt.subControls |= QStyle::SC_TitleBarShadeButton;
+        }
+        if (d->window && (d->flags & Qt::WindowMinMaxButtonsHint)) {
+            if(d->window && d->window->isMinimized())
+                opt.subControls |= QStyle::SC_TitleBarNormalButton;
+            else
+                opt.subControls |= QStyle::SC_TitleBarMinButton;
+        }
+        if (d->window && (d->flags & Qt::WindowMaximizeButtonHint) && !d->window->isMaximized())
+            opt.subControls |= QStyle::SC_TitleBarMaxButton;
+    }
+
+    QStyle::SubControl under_mouse = QStyle::SC_None;
+    under_mouse = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
+                                                     mapFromGlobal(QCursor::pos()), this);
+    if ((d->buttonDown == under_mouse) && d->pressed) {
+        opt.state |= QStyle::State_Sunken;
+    } else if( autoRaise() && under_mouse != QStyle::SC_None && !d->pressed) {
+        opt.activeSubControls = under_mouse;
+        opt.state |= QStyle::State_MouseOver;
+    }
+    opt.palette.setCurrentColorGroup(usesActiveColor() ? QPalette::Active : QPalette::Inactive);
+
+    QPainter p(this);
+    style()->drawComplexControl(QStyle::CC_TitleBar, &opt, &p, this);
+}
+
+void QWorkspaceTitleBar::mouseDoubleClickEvent(QMouseEvent *e)
+{
+    Q_D(QWorkspaceTitleBar);
+    if (e->button() != Qt::LeftButton) {
+        e->ignore();
+        return;
+    }
+    e->accept();
+    QStyleOptionTitleBar opt;
+    initStyleOption(&opt);
+    switch (style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(), this)) {
+    case QStyle::SC_TitleBarLabel:
+        emit doubleClicked();
+        break;
+
+    case QStyle::SC_TitleBarSysMenu:
+        if (d->flags & Qt::WindowSystemMenuHint)
+            emit doClose();
+        break;
+
+    default:
+        break;
+    }
+}
+
+void QWorkspaceTitleBar::leaveEvent(QEvent *)
+{
+    Q_D(QWorkspaceTitleBar);
+    d->lastControl = QStyle::SC_None;
+    if(autoRaise() && !d->pressed)
+        update();
+}
+
+void QWorkspaceTitleBar::enterEvent(QEvent *)
+{
+    Q_D(QWorkspaceTitleBar);
+    if(autoRaise() && !d->pressed)
+        update();
+    QEvent e(QEvent::Leave);
+    QApplication::sendEvent(parentWidget(), &e);
+}
+
+void QWorkspaceTitleBar::setActive(bool active)
+{
+    Q_D(QWorkspaceTitleBar);
+    if (d->act == active)
+        return ;
+
+    d->act = active;
+    update();
+}
+
+bool QWorkspaceTitleBar::isActive() const
+{
+    Q_D(const QWorkspaceTitleBar);
+    return d->act;
+}
+
+bool QWorkspaceTitleBar::usesActiveColor() const
+{
+    return (isActive() && isActiveWindow()) ||
+        (!window() && QWidget::window()->isActiveWindow());
+}
+
+QWidget *QWorkspaceTitleBar::window() const
+{
+    Q_D(const QWorkspaceTitleBar);
+    return d->window;
+}
+
+bool QWorkspaceTitleBar::event(QEvent *e)
+{
+    Q_D(QWorkspaceTitleBar);
+    if (e->type() == QEvent::ApplicationPaletteChange) {
+        d->readColors();
+    } else if (e->type() == QEvent::WindowActivate
+               || e->type() == QEvent::WindowDeactivate) {
+        if (d->act)
+            update();
+    }
+    return QWidget::event(e);
+}
+
+void QWorkspaceTitleBar::setMovable(bool b)
+{
+    Q_D(QWorkspaceTitleBar);
+    d->movable = b;
+}
+
+bool QWorkspaceTitleBar::isMovable() const
+{
+    Q_D(const QWorkspaceTitleBar);
+    return d->movable;
+}
+
+void QWorkspaceTitleBar::setAutoRaise(bool b)
+{
+    Q_D(QWorkspaceTitleBar);
+    d->autoraise = b;
+}
+
+bool QWorkspaceTitleBar::autoRaise() const
+{
+    Q_D(const QWorkspaceTitleBar);
+    return d->autoraise;
+}
+
+QSize QWorkspaceTitleBar::sizeHint() const
+{
+    ensurePolished();
+    QStyleOptionTitleBar opt;
+    initStyleOption(&opt);
+    QRect menur = style()->subControlRect(QStyle::CC_TitleBar, &opt,
+                                          QStyle::SC_TitleBarSysMenu, this);
+    return QSize(menur.width(), style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, this));
+}
+
+/*!
+    \class QWorkspace
+    \obsolete
+    \brief The QWorkspace widget provides a workspace window that can be
+    used in an MDI application.
+
+    This class is deprecated. Use QMdiArea instead.
+
+    Multiple Document Interface (MDI) applications are typically
+    composed of a main window containing a menu bar, a toolbar, and
+    a central QWorkspace widget. The workspace itself is used to display
+    a number of child windows, each of which is a widget.
+
+    The workspace itself is an ordinary Qt widget. It has a standard
+    constructor that takes a parent widget.
+    Workspaces can be placed in any layout, but are typically given
+    as the central widget in a QMainWindow:
+
+    \snippet doc/src/snippets/code/src_gui_widgets_qworkspace.cpp 0
+
+    Child windows (MDI windows) are standard Qt widgets that are
+    inserted into the workspace with addWindow(). As with top-level
+    widgets, you can call functions such as show(), hide(),
+    showMaximized(), and setWindowTitle() on a child window to change
+    its appearance within the workspace. You can also provide widget
+    flags to determine the layout of the decoration or the behavior of
+    the widget itself.
+
+    To change or retrieve the geometry of a child window, you must
+    operate on its parentWidget(). The parentWidget() provides
+    access to the decorated frame that contains the child window
+    widget. When a child window is maximised, its decorated frame
+    is hidden. If the top-level widget contains a menu bar, it will display
+    the maximised window's operations menu to the left of the menu
+    entries, and the window's controls to the right.
+
+    A child window becomes active when it gets the keyboard focus,
+    or when setFocus() is called. The user can activate a window by moving
+    focus in the usual ways, for example by clicking a window or by pressing
+    Tab. The workspace emits a signal windowActivated() when the active
+    window changes, and the function activeWindow() returns a pointer to the
+    active child window, or 0 if no window is active.
+
+    The convenience function windowList() returns a list of all child
+    windows. This information could be used in a popup menu
+    containing a list of windows, for example. This feature is also
+    available as part of the \l{Window Menu} Solution.
+
+    QWorkspace provides two built-in layout strategies for child
+    windows: cascade() and tile(). Both are slots so you can easily
+    connect menu entries to them.
+
+    \table
+    \row \o \inlineimage mdi-cascade.png
+         \o \inlineimage mdi-tile.png
+    \endtable
+
+    If you want your users to be able to work with child windows
+    larger than the visible workspace area, set the scrollBarsEnabled
+    property to true.
+
+    \sa QDockWidget, {MDI Example}
+*/
+
+
+class QWorkspaceChild : public QWidget
+{
+    Q_OBJECT
+
+    friend class QWorkspacePrivate;
+    friend class QWorkspace;
+    friend class QWorkspaceTitleBar;
+
+public:
+    QWorkspaceChild(QWidget* window, QWorkspace* parent=0, Qt::WindowFlags flags = 0);
+    ~QWorkspaceChild();
+
+    void setActive(bool);
+    bool isActive() const;
+
+    void adjustToFullscreen();
+
+    QWidget* windowWidget() const;
+    QWidget* iconWidget() const;
+
+    void doResize();
+    void doMove();
+
+    QSize sizeHint() const;
+    QSize minimumSizeHint() const;
+
+    QSize baseSize() const;
+
+    int frameWidth() const;
+
+    void show();
+
+    bool isWindowOrIconVisible() const;
+
+signals:
+    void showOperationMenu();
+    void popupOperationMenu(const QPoint&);
+
+public slots:
+    void activate();
+    void showMinimized();
+    void showMaximized();
+    void showNormal();
+    void showShaded();
+    void internalRaise();
+    void titleBarDoubleClicked();
+
+protected:
+    void enterEvent(QEvent *);
+    void leaveEvent(QEvent *);
+    void childEvent(QChildEvent*);
+    void resizeEvent(QResizeEvent *);
+    void moveEvent(QMoveEvent *);
+    bool eventFilter(QObject *, QEvent *);
+
+    void paintEvent(QPaintEvent *);
+    void changeEvent(QEvent *);
+
+private:
+    void updateMask();
+
+    Q_DISABLE_COPY(QWorkspaceChild)
+
+    QWidget *childWidget;
+    QWidgetResizeHandler *widgetResizeHandler;
+    QWorkspaceTitleBar *titlebar;
+    QPointer<QWorkspaceTitleBar> iconw;
+    QSize windowSize;
+    QSize shadeRestore;
+    QSize shadeRestoreMin;
+    bool act                  :1;
+    bool shademode            :1;
+};
+
+int QWorkspaceChild::frameWidth() const
+{
+    return contentsRect().left();
+}
+
+
+
+class QWorkspacePrivate : public QWidgetPrivate {
+    Q_DECLARE_PUBLIC(QWorkspace)
+public:
+    QWorkspaceChild* active;
+    QList<QWorkspaceChild *> windows;
+    QList<QWorkspaceChild *> focus;
+    QList<QWidget *> icons;
+    QWorkspaceChild* maxWindow;
+    QRect maxRestore;
+    QPointer<QMDIControl> maxcontrols;
+    QPointer<QMenuBar> maxmenubar;
+    QHash<int, const char*> shortcutMap;
+
+    int px;
+    int py;
+    QWidget *becomeActive;
+    QPointer<QLabel> maxtools;
+    QString topTitle;
+
+    QMenu *popup, *toolPopup;
+    enum WSActs { RestoreAct, MoveAct, ResizeAct, MinimizeAct, MaximizeAct, CloseAct, StaysOnTopAct, ShadeAct, NCountAct };
+    QAction *actions[NCountAct];
+
+    QScrollBar *vbar, *hbar;
+    QWidget *corner;
+    int yoffset, xoffset;
+    QBrush background;
+
+    void init();
+    void insertIcon(QWidget* w);
+    void removeIcon(QWidget* w);
+    void place(QWidget*);
+
+    QWorkspaceChild* findChild(QWidget* w);
+    void showMaximizeControls();
+    void hideMaximizeControls();
+    void activateWindow(QWidget* w, bool change_focus = true);
+    void hideChild(QWorkspaceChild *c);
+    void showWindow(QWidget* w);
+    void maximizeWindow(QWidget* w);
+    void minimizeWindow(QWidget* w);
+    void normalizeWindow(QWidget* w);
+
+    QRect updateWorkspace();
+
+private:
+    void _q_normalizeActiveWindow();
+    void _q_minimizeActiveWindow();
+    void _q_showOperationMenu();
+    void _q_popupOperationMenu(const QPoint&);
+    void _q_operationMenuActivated(QAction *);
+    void _q_scrollBarChanged();
+    void _q_updateActions();
+    bool inTitleChange;
+};
+
+static bool isChildOf(QWidget * child, QWidget * parent)
+{
+    if (!parent || !child)
+        return false;
+    QWidget * w = child;
+    while(w && w != parent)
+        w = w->parentWidget();
+    return w != 0;
+}
+
+/*!
+    Constructs a workspace with the given \a parent.
+*/
+QWorkspace::QWorkspace(QWidget *parent)
+    : QWidget(*new QWorkspacePrivate, parent, 0)
+{
+    Q_D(QWorkspace);
+    d->init();
+}
+
+#ifdef QT3_SUPPORT
+/*!
+    Use one of the constructors that doesn't take the \a name
+    argument and then use setObjectName() instead.
+*/
+QWorkspace::QWorkspace(QWidget *parent, const char *name)
+    : QWidget(*new QWorkspacePrivate, parent, 0)
+{
+    Q_D(QWorkspace);
+    setObjectName(QString::fromAscii(name));
+    d->init();
+}
+#endif // QT3_SUPPORT
+
+/*!
+    \internal
+*/
+void
+QWorkspacePrivate::init()
+{
+    Q_Q(QWorkspace);
+
+    maxcontrols = 0;
+    active = 0;
+    maxWindow = 0;
+    maxtools = 0;
+    px = 0;
+    py = 0;
+    becomeActive = 0;
+    popup = new QMenu(q);
+    toolPopup = new QMenu(q);
+    popup->setObjectName(QLatin1String("qt_internal_mdi_popup"));
+    toolPopup->setObjectName(QLatin1String("qt_internal_mdi_tool_popup"));
+
+    actions[QWorkspacePrivate::RestoreAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarNormalButton, 0, q)),
+                                                         QWorkspace::tr("&Restore"), q);
+    actions[QWorkspacePrivate::MoveAct] = new QAction(QWorkspace::tr("&Move"), q);
+    actions[QWorkspacePrivate::ResizeAct] = new QAction(QWorkspace::tr("&Size"), q);
+    actions[QWorkspacePrivate::MinimizeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarMinButton, 0, q)),
+                                                          QWorkspace::tr("Mi&nimize"), q);
+    actions[QWorkspacePrivate::MaximizeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarMaxButton, 0, q)),
+                                                          QWorkspace::tr("Ma&ximize"), q);
+    actions[QWorkspacePrivate::CloseAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, q)),
+                                                          QWorkspace::tr("&Close")
+#ifndef QT_NO_SHORTCUT
+                                                          +QLatin1Char('\t')+(QString)QKeySequence(Qt::CTRL+Qt::Key_F4)
+#endif
+                                                          ,q);
+    QObject::connect(actions[QWorkspacePrivate::CloseAct], SIGNAL(triggered()), q, SLOT(closeActiveWindow()));
+    actions[QWorkspacePrivate::StaysOnTopAct] = new QAction(QWorkspace::tr("Stay on &Top"), q);
+    actions[QWorkspacePrivate::StaysOnTopAct]->setChecked(true);
+    actions[QWorkspacePrivate::ShadeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarShadeButton, 0, q)),
+                                                          QWorkspace::tr("Sh&ade"), q);
+
+    QObject::connect(popup, SIGNAL(aboutToShow()), q, SLOT(_q_updateActions()));
+    QObject::connect(popup, SIGNAL(triggered(QAction*)), q, SLOT(_q_operationMenuActivated(QAction*)));
+    popup->addAction(actions[QWorkspacePrivate::RestoreAct]);
+    popup->addAction(actions[QWorkspacePrivate::MoveAct]);
+    popup->addAction(actions[QWorkspacePrivate::ResizeAct]);
+    popup->addAction(actions[QWorkspacePrivate::MinimizeAct]);
+    popup->addAction(actions[QWorkspacePrivate::MaximizeAct]);
+    popup->addSeparator();
+    popup->addAction(actions[QWorkspacePrivate::CloseAct]);
+
+    QObject::connect(toolPopup, SIGNAL(aboutToShow()), q, SLOT(_q_updateActions()));
+    QObject::connect(toolPopup, SIGNAL(triggered(QAction*)), q, SLOT(_q_operationMenuActivated(QAction*)));
+    toolPopup->addAction(actions[QWorkspacePrivate::MoveAct]);
+    toolPopup->addAction(actions[QWorkspacePrivate::ResizeAct]);
+    toolPopup->addAction(actions[QWorkspacePrivate::StaysOnTopAct]);
+    toolPopup->addSeparator();
+    toolPopup->addAction(actions[QWorkspacePrivate::ShadeAct]);
+    toolPopup->addAction(actions[QWorkspacePrivate::CloseAct]);
+
+#ifndef QT_NO_SHORTCUT
+    // Set up shortcut bindings (id -> slot), most used first
+    QList <QKeySequence> shortcuts = QKeySequence::keyBindings(QKeySequence::NextChild);
+    foreach (const QKeySequence &seq, shortcuts)
+        shortcutMap.insert(q->grabShortcut(seq), "activateNextWindow");
+
+    shortcuts = QKeySequence::keyBindings(QKeySequence::PreviousChild);
+    foreach (const QKeySequence &seq, shortcuts)
+        shortcutMap.insert(q->grabShortcut(seq), "activatePreviousWindow");
+
+    shortcuts = QKeySequence::keyBindings(QKeySequence::Close);
+    foreach (const QKeySequence &seq, shortcuts)
+        shortcutMap.insert(q->grabShortcut(seq), "closeActiveWindow");
+
+    shortcutMap.insert(q->grabShortcut(QKeySequence(QLatin1String("ALT+-"))), "_q_showOperationMenu");
+#endif // QT_NO_SHORTCUT
+
+    q->setBackgroundRole(QPalette::Dark);
+    q->setAutoFillBackground(true);
+    q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
+
+    hbar = vbar = 0;
+    corner = 0;
+    xoffset = yoffset = 0;
+
+    q->window()->installEventFilter(q);
+
+    inTitleChange = false;
+    updateWorkspace();
+}
+
+/*!
+    Destroys the workspace and frees any allocated resources.
+*/
+
+QWorkspace::~QWorkspace()
+{
+}
+
+/*! \reimp */
+QSize QWorkspace::sizeHint() const
+{
+    QSize s(QApplication::desktop()->size());
+    return QSize(s.width()*2/3, s.height()*2/3);
+}
+
+
+#ifdef QT3_SUPPORT
+/*!
+    Sets the background color to \a c.
+    Use setBackground() instead.
+*/
+void QWorkspace::setPaletteBackgroundColor(const QColor & c)
+{
+    setBackground(c);
+}
+
+/*!
+    Sets the background pixmap to \a pm.
+    Use setBackground() instead.
+*/
+void QWorkspace::setPaletteBackgroundPixmap(const QPixmap & pm)
+{
+    setBackground(pm);
+}
+#endif // QT3_SUPPORT
+
+/*!
+    \property QWorkspace::background
+    \brief the workspace's background
+*/
+QBrush QWorkspace::background() const
+{
+    Q_D(const QWorkspace);
+    if (d->background.style() == Qt::NoBrush)
+        return palette().dark();
+    return d->background;
+}
+
+void QWorkspace::setBackground(const QBrush &background)
+{
+    Q_D(QWorkspace);
+    d->background = background;
+    setAttribute(Qt::WA_OpaquePaintEvent, background.style() == Qt::NoBrush);
+    update();
+}
+
+/*!
+    Adds widget \a w as new sub window to the workspace.  If \a flags
+    are non-zero, they will override the flags set on the widget.
+
+    Returns the widget used for the window frame.
+
+    To remove the widget \a w from the workspace, simply call
+    setParent() with the new parent (or 0 to make it a stand-alone
+    window).
+*/
+QWidget * QWorkspace::addWindow(QWidget *w, Qt::WindowFlags flags)
+{
+    Q_D(QWorkspace);
+    if (!w)
+        return 0;
+
+    w->setAutoFillBackground(true);
+
+    QWidgetPrivate::adjustFlags(flags);
+
+#if 0
+    bool wasMaximized = w->isMaximized();
+    bool wasMinimized = w->isMinimized();
+#endif
+    bool hasSize = w->testAttribute(Qt::WA_Resized);
+    int x = w->x();
+    int y = w->y();
+    bool hasPos = w->testAttribute(Qt::WA_Moved);
+    QSize s = w->size().expandedTo(qSmartMinSize(w));
+    if (!hasSize && w->sizeHint().isValid())
+        w->adjustSize();
+
+    QWorkspaceChild* child = new QWorkspaceChild(w, this, flags);
+    child->setObjectName(QLatin1String("qt_workspacechild"));
+    child->installEventFilter(this);
+
+    connect(child, SIGNAL(popupOperationMenu(QPoint)),
+            this, SLOT(_q_popupOperationMenu(QPoint)));
+    connect(child, SIGNAL(showOperationMenu()),
+            this, SLOT(_q_showOperationMenu()));
+    d->windows.append(child);
+    if (child->isVisibleTo(this))
+        d->focus.append(child);
+    child->internalRaise();
+
+    if (!hasPos)
+        d->place(child);
+    if (!hasSize)
+        child->adjustSize();
+    if (hasPos)
+        child->move(x, y);
+
+    return child;
+
+#if 0
+    if (wasMaximized)
+        w->showMaximized();
+    else if (wasMinimized)
+        w->showMinimized();
+    else if (!hasBeenHidden)
+        d->activateWindow(w);
+
+    d->updateWorkspace();
+    return child;
+#endif
+}
+
+/*! \reimp */
+void QWorkspace::childEvent(QChildEvent * e)
+{
+    Q_D(QWorkspace);
+    if (e->removed()) {
+        if (d->windows.removeAll(static_cast<QWorkspaceChild*>(e->child()))) {
+            d->focus.removeAll(static_cast<QWorkspaceChild*>(e->child()));
+            if (d->maxWindow == e->child())
+                d->maxWindow = 0;
+            d->updateWorkspace();
+        }
+    }
+}
+
+/*! \reimp */
+#ifndef QT_NO_WHEELEVENT
+void QWorkspace::wheelEvent(QWheelEvent *e)
+{
+    Q_D(QWorkspace);
+    if (!scrollBarsEnabled())
+        return;
+    // the scroll bars are children of the workspace, so if we receive
+    // a wheel event we redirect to the scroll bars using a direct event
+    // call, /not/ using sendEvent() because if the scroll bar ignores the
+    // event QApplication::sendEvent() will propagate the event to the parent widget,
+    // which is us, who /just/ sent it.
+    if (d->vbar && d->vbar->isVisible() && !(e->modifiers() & Qt::AltModifier))
+        d->vbar->event(e);
+    else if (d->hbar && d->hbar->isVisible())
+        d->hbar->event(e);
+}
+#endif
+
+void QWorkspacePrivate::activateWindow(QWidget* w, bool change_focus)
+{
+    Q_Q(QWorkspace);
+    if (!w) {
+        active = 0;
+        emit q->windowActivated(0);
+        return;
+    }
+    if (!q->isVisible()) {
+        becomeActive = w;
+        return;
+    }
+
+    if (active && active->windowWidget() == w) {
+        if (!isChildOf(q->focusWidget(), w)) // child window does not have focus
+            active->setActive(true);
+        return;
+    }
+
+    active = 0;
+    // First deactivate all other workspace clients
+    QList<QWorkspaceChild *>::Iterator it(windows.begin());
+    while (it != windows.end()) {
+        QWorkspaceChild* c = *it;
+        ++it;
+        if (c->windowWidget() == w)
+            active = c;
+        else
+            c->setActive(false);
+    }
+
+    if (!active)
+        return;
+
+    // Then activate the new one, so the focus is stored correctly
+    active->setActive(true);
+
+    if (!active)
+        return;
+
+    if (maxWindow && maxWindow != active && active->windowWidget() &&
+        (active->windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint))
+        active->showMaximized();
+
+    active->internalRaise();
+
+    if (change_focus) {
+        int from = focus.indexOf(active);
+        if (from >= 0)
+            focus.move(from, focus.size() - 1);
+    }
+
+    updateWorkspace();
+    emit q->windowActivated(w);
+}
+
+
+/*!
+    Returns a pointer to the widget corresponding to the active child
+    window, or 0 if no window is active.
+
+    \sa setActiveWindow()
+*/
+QWidget* QWorkspace::activeWindow() const
+{
+    Q_D(const QWorkspace);
+    return d->active? d->active->windowWidget() : 0;
+}
+
+/*!
+    Makes the child window that contains \a w the active child window.
+
+    \sa activeWindow()
+*/
+void QWorkspace::setActiveWindow(QWidget *w)
+{
+    Q_D(QWorkspace);
+    d->activateWindow(w, true);
+    if (w && w->isMinimized())
+        w->setWindowState(w->windowState() & ~Qt::WindowMinimized);
+}
+
+void QWorkspacePrivate::place(QWidget *w)
+{
+    Q_Q(QWorkspace);
+
+    QList<QWidget *> widgets;
+    for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it)
+        if (*it != w)
+            widgets.append(*it);
+
+    int overlap, minOverlap = 0;
+    int possible;
+
+    QRect r1(0, 0, 0, 0);
+    QRect r2(0, 0, 0, 0);
+    QRect maxRect = q->rect();
+    int x = maxRect.left(), y = maxRect.top();
+    QPoint wpos(maxRect.left(), maxRect.top());
+
+    bool firstPass = true;
+
+    do {
+        if (y + w->height() > maxRect.bottom()) {
+            overlap = -1;
+        } else if(x + w->width() > maxRect.right()) {
+            overlap = -2;
+        } else {
+            overlap = 0;
+
+            r1.setRect(x, y, w->width(), w->height());
+
+            QWidget *l;
+            QList<QWidget *>::Iterator it(widgets.begin());
+            while (it != widgets.end()) {
+                l = *it;
+                ++it;
+
+                if (maxWindow == l)
+                    r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
+                else
+                    r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
+                                            QRect(l->x(), l->y(), l->width(), l->height()));
+
+                if (r2.intersects(r1)) {
+                    r2.setCoords(qMax(r1.left(), r2.left()),
+                                 qMax(r1.top(), r2.top()),
+                                 qMin(r1.right(), r2.right()),
+                                 qMin(r1.bottom(), r2.bottom())
+                                );
+
+                    overlap += (r2.right() - r2.left()) *
+                               (r2.bottom() - r2.top());
+                }
+            }
+        }
+
+        if (overlap == 0) {
+            wpos = QPoint(x, y);
+            break;
+        }
+
+        if (firstPass) {
+            firstPass = false;
+            minOverlap = overlap;
+        } else if (overlap >= 0 && overlap < minOverlap) {
+            minOverlap = overlap;
+            wpos = QPoint(x, y);
+        }
+
+        if (overlap > 0) {
+            possible = maxRect.right();
+            if (possible - w->width() > x) possible -= w->width();
+
+            QWidget *l;
+            QList<QWidget *>::Iterator it(widgets.begin());
+            while (it != widgets.end()) {
+                l = *it;
+                ++it;
+                if (maxWindow == l)
+                    r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
+                else
+                    r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
+                                            QRect(l->x(), l->y(), l->width(), l->height()));
+
+                if((y < r2.bottom()) && (r2.top() < w->height() + y)) {
+                    if(r2.right() > x)
+                        possible = possible < r2.right() ?
+                                   possible : r2.right();
+
+                    if(r2.left() - w->width() > x)
+                        possible = possible < r2.left() - w->width() ?
+                                   possible : r2.left() - w->width();
+                }
+            }
+
+            x = possible;
+        } else if (overlap == -2) {
+            x = maxRect.left();
+            possible = maxRect.bottom();
+
+            if (possible - w->height() > y) possible -= w->height();
+
+            QWidget *l;
+            QList<QWidget *>::Iterator it(widgets.begin());
+            while (it != widgets.end()) {
+                l = *it;
+                ++it;
+                if (maxWindow == l)
+                    r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
+                else
+                    r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
+                                            QRect(l->x(), l->y(), l->width(), l->height()));
+
+                if(r2.bottom() > y)
+                    possible = possible < r2.bottom() ?
+                               possible : r2.bottom();
+
+                if(r2.top() - w->height() > y)
+                    possible = possible < r2.top() - w->height() ?
+                               possible : r2.top() - w->height();
+            }
+
+            y = possible;
+        }
+    }
+    while(overlap != 0 && overlap != -1);
+
+    QRect resultRect = w->geometry();
+    resultRect.moveTo(wpos);
+    w->setGeometry(QStyle::visualRect(q->layoutDirection(), maxRect, resultRect));
+    updateWorkspace();
+}
+
+
+void QWorkspacePrivate::insertIcon(QWidget* w)
+{
+    Q_Q(QWorkspace);
+    if (!w || icons.contains(w))
+        return;
+    icons.append(w);
+    if (w->parentWidget() != q) {
+        w->setParent(q, 0);
+        w->move(0,0);
+    }
+    QRect cr = updateWorkspace();
+    int x = 0;
+    int y = cr.height() - w->height();
+
+    QList<QWidget *>::Iterator it(icons.begin());
+    while (it != icons.end()) {
+        QWidget* i = *it;
+        ++it;
+        if (x > 0 && x + i->width() > cr.width()){
+            x = 0;
+            y -= i->height();
+        }
+
+        if (i != w &&
+            i->geometry().intersects(QRect(x, y, w->width(), w->height())))
+            x += i->width();
+    }
+    w->move(x, y);
+
+    if (q->isVisibleTo(q->parentWidget())) {
+        w->show();
+        w->lower();
+    }
+    updateWorkspace();
+}
+
+
+void QWorkspacePrivate::removeIcon(QWidget* w)
+{
+    if (icons.removeAll(w))
+        w->hide();
+}
+
+
+/*! \reimp  */
+void QWorkspace::resizeEvent(QResizeEvent *)
+{
+    Q_D(QWorkspace);
+    if (d->maxWindow) {
+        d->maxWindow->adjustToFullscreen();
+        if (d->maxWindow->windowWidget())
+            d->maxWindow->windowWidget()->overrideWindowState(Qt::WindowMaximized);
+    }
+    d->updateWorkspace();
+}
+
+/*! \reimp */
+void QWorkspace::showEvent(QShowEvent *e)
+{
+    Q_D(QWorkspace);
+    if (d->maxWindow)
+        d->showMaximizeControls();
+    QWidget::showEvent(e);
+    if (d->becomeActive) {
+        d->activateWindow(d->becomeActive);
+        d->becomeActive = 0;
+    } else if (d->windows.count() > 0 && !d->active) {
+        d->activateWindow(d->windows.first()->windowWidget());
+    }
+
+//     // force a frame repaint - this is a workaround for what seems to be a bug
+//     // introduced when changing the QWidget::show() implementation. Might be
+//     // a windows bug as well though.
+//     for (int i = 0; i < d->windows.count(); ++i) {
+//      QWorkspaceChild* c = d->windows.at(i);
+//         c->update(c->rect());
+//     }
+
+    d->updateWorkspace();
+}
+
+/*! \reimp */
+void QWorkspace::hideEvent(QHideEvent *)
+{
+    Q_D(QWorkspace);
+    if (!isVisible())
+        d->hideMaximizeControls();
+}
+
+/*! \reimp */
+void QWorkspace::paintEvent(QPaintEvent *)
+{
+    Q_D(QWorkspace);
+
+    if (d->background.style() != Qt::NoBrush) {
+        QPainter p(this);
+        p.fillRect(0, 0, width(), height(), d->background);
+    }
+}
+
+void QWorkspacePrivate::minimizeWindow(QWidget* w)
+{
+    QWorkspaceChild* c = findChild(w);
+
+    if (!w || !(w->windowFlags() & Qt::WindowMinimizeButtonHint))
+        return;
+
+    if (c) {
+        bool wasMax = false;
+        if (c == maxWindow) {
+            wasMax = true;
+            maxWindow = 0;
+            hideMaximizeControls();
+            for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it) {
+                QWorkspaceChild* c = *it;
+                if (c->titlebar)
+                    c->titlebar->setMovable(true);
+                c->widgetResizeHandler->setActive(true);
+            }
+        }
+        c->hide();
+        if (wasMax)
+            c->setGeometry(maxRestore);
+        if (!focus.contains(c))
+            focus.append(c);
+        insertIcon(c->iconWidget());
+
+        if (!maxWindow)
+            activateWindow(w);
+
+        updateWorkspace();
+
+        w->overrideWindowState(Qt::WindowMinimized);
+        c->overrideWindowState(Qt::WindowMinimized);
+    }
+}
+
+void QWorkspacePrivate::normalizeWindow(QWidget* w)
+{
+    Q_Q(QWorkspace);
+    QWorkspaceChild* c = findChild(w);
+    if (!w)
+        return;
+    if (c) {
+        w->overrideWindowState(Qt::WindowNoState);
+        hideMaximizeControls();
+        if (!maxmenubar || q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q) || !maxWindow) {
+            if (w->minimumSize() != w->maximumSize())
+                c->widgetResizeHandler->setActive(true);
+            if (c->titlebar)
+                c->titlebar->setMovable(true);
+        }
+        w->overrideWindowState(Qt::WindowNoState);
+        c->overrideWindowState(Qt::WindowNoState);
+
+        if (c == maxWindow) {
+            c->setGeometry(maxRestore);
+            maxWindow = 0;
+        } else {
+            if (c->iconw)
+                removeIcon(c->iconw->parentWidget());
+            c->show();
+        }
+
+        hideMaximizeControls();
+        for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it) {
+            QWorkspaceChild* c = *it;
+            if (c->titlebar)
+                c->titlebar->setMovable(true);
+            if (c->childWidget && c->childWidget->minimumSize() != c->childWidget->maximumSize())
+                c->widgetResizeHandler->setActive(true);
+        }
+        activateWindow(w, true);
+        updateWorkspace();
+    }
+}
+
+void QWorkspacePrivate::maximizeWindow(QWidget* w)
+{
+    Q_Q(QWorkspace);
+    QWorkspaceChild* c = findChild(w);
+
+    if (!w || !(w->windowFlags() & Qt::WindowMaximizeButtonHint))
+        return;
+
+    if (!c || c == maxWindow)
+        return;
+
+    bool updatesEnabled = q->updatesEnabled();
+    q->setUpdatesEnabled(false);
+
+    if (c->iconw && icons.contains(c->iconw->parentWidget()))
+        normalizeWindow(w);
+    QRect r(c->geometry());
+    QWorkspaceChild *oldMaxWindow = maxWindow;
+    maxWindow = c;
+
+    showMaximizeControls();
+
+    c->adjustToFullscreen();
+    c->show();
+    c->internalRaise();
+    if (oldMaxWindow != c) {
+        if (oldMaxWindow) {
+            oldMaxWindow->setGeometry(maxRestore);
+            oldMaxWindow->overrideWindowState(Qt::WindowNoState);
+            if(oldMaxWindow->windowWidget())
+                oldMaxWindow->windowWidget()->overrideWindowState(Qt::WindowNoState);
+        }
+        maxRestore = r;
+    }
+
+    activateWindow(w);
+
+    if(!maxmenubar || q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
+        if (!active && becomeActive) {
+            active = (QWorkspaceChild*)becomeActive->parentWidget();
+            active->setActive(true);
+            becomeActive = 0;
+            emit q->windowActivated(active->windowWidget());
+        }
+        c->widgetResizeHandler->setActive(false);
+        if (c->titlebar)
+            c->titlebar->setMovable(false);
+    }
+    updateWorkspace();
+
+    w->overrideWindowState(Qt::WindowMaximized);
+    c->overrideWindowState(Qt::WindowMaximized);
+    q->setUpdatesEnabled(updatesEnabled);
+}
+
+void QWorkspacePrivate::showWindow(QWidget* w)
+{
+    if (w->isMinimized() && (w->windowFlags() & Qt::WindowMinimizeButtonHint))
+        minimizeWindow(w);
+    else if ((maxWindow || w->isMaximized()) && w->windowFlags() & Qt::WindowMaximizeButtonHint)
+        maximizeWindow(w);
+    else if (w->windowFlags() & Qt::WindowMaximizeButtonHint)
+        normalizeWindow(w);
+    else
+        w->parentWidget()->show();
+    if (maxWindow)
+        maxWindow->internalRaise();
+    updateWorkspace();
+}
+
+
+QWorkspaceChild* QWorkspacePrivate::findChild(QWidget* w)
+{
+    QList<QWorkspaceChild *>::Iterator it(windows.begin());
+    while (it != windows.end()) {
+        QWorkspaceChild* c = *it;
+        ++it;
+        if (c->windowWidget() == w)
+            return c;
+    }
+    return 0;
+}
+
+/*!
+    Returns a list of all visible or minimized child windows. If \a
+    order is CreationOrder (the default), the windows are listed in
+    the order in which they were inserted into the workspace. If \a
+    order is StackingOrder, the windows are listed in their stacking
+    order, with the topmost window as the last item in the list.
+*/
+QWidgetList QWorkspace::windowList(WindowOrder order) const
+{
+    Q_D(const QWorkspace);
+    QWidgetList windows;
+    if (order == StackingOrder) {
+        QObjectList cl = children();
+        for (int i = 0; i < cl.size(); ++i) {
+            QWorkspaceChild *c = qobject_cast<QWorkspaceChild*>(cl.at(i));
+            if (c && c->isWindowOrIconVisible())
+                windows.append(c->windowWidget());
+        }
+    } else {
+        QList<QWorkspaceChild *>::ConstIterator it(d->windows.begin());
+        while (it != d->windows.end()) {
+            QWorkspaceChild* c = *it;
+            ++it;
+            if (c && c->isWindowOrIconVisible())
+                windows.append(c->windowWidget());
+        }
+    }
+    return windows;
+}
+
+
+/*! \reimp */
+bool QWorkspace::event(QEvent *e)
+{
+#ifndef QT_NO_SHORTCUT
+    Q_D(QWorkspace);
+    if (e->type() == QEvent::Shortcut) {
+        QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
+        const char *theSlot = d->shortcutMap.value(se->shortcutId(), 0);
+        if (theSlot)
+            QMetaObject::invokeMethod(this, theSlot);
+    } else
+#endif
+    if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut){
+        return true;
+    }
+    return QWidget::event(e);
+}
+
+/*! \reimp */
+bool QWorkspace::eventFilter(QObject *o, QEvent * e)
+{
+    Q_D(QWorkspace);
+    static QTime* t = 0;
+    static QWorkspace* tc = 0;
+    if (o == d->maxtools) {
+        switch (e->type()) {
+        case QEvent::MouseButtonPress:
+            {
+                QMenuBar* b = (QMenuBar*)o->parent();
+                if (!t)
+                    t = new QTime;
+                if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) {
+                    if (isRightToLeft()) {
+                        QPoint p = b->mapToGlobal(QPoint(b->x() + b->width(), b->y() + b->height()));
+                        p.rx() -= d->popup->sizeHint().width();
+                        d->_q_popupOperationMenu(p);
+                    } else {
+                        d->_q_popupOperationMenu(b->mapToGlobal(QPoint(b->x(), b->y() + b->height())));
+                    }
+                    t->start();
+                    tc = this;
+                } else {
+                    tc = 0;
+                    closeActiveWindow();
+                }
+                return true;
+            }
+        default:
+            break;
+        }
+        return QWidget::eventFilter(o, e);
+    }
+    switch (e->type()) {
+    case QEvent::HideToParent:
+        break;
+    case QEvent::ShowToParent:
+        if (QWorkspaceChild *c = qobject_cast<QWorkspaceChild*>(o))
+            if (!d->focus.contains(c))
+                d->focus.append(c);
+        d->updateWorkspace();
+        break;
+    case QEvent::WindowTitleChange:
+        if (!d->inTitleChange) {
+            if (o == window())
+                d->topTitle = window()->windowTitle();
+            if (d->maxWindow && d->maxWindow->windowWidget() && d->topTitle.size()) {
+                d->inTitleChange = true;
+                window()->setWindowTitle(tr("%1 - [%2]")
+                                         .arg(d->topTitle).arg(d->maxWindow->windowWidget()->windowTitle()));
+                d->inTitleChange = false;
+            }
+        }
+        break;
+
+    case QEvent::ModifiedChange:
+        if (o == d->maxWindow)
+            window()->setWindowModified(d->maxWindow->isWindowModified());
+        break;
+
+    case QEvent::Close:
+        if (o == window())
+        {
+            QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
+            while (it != d->windows.end()) {
+                QWorkspaceChild* c = *it;
+                ++it;
+                if (c->shademode)
+                    c->showShaded();
+            }
+        } else if (qobject_cast<QWorkspaceChild*>(o)) {
+            d->popup->hide();
+        }
+        d->updateWorkspace();
+        break;
+    default:
+        break;
+    }
+    return QWidget::eventFilter(o, e);
+}
+
+static QMenuBar *findMenuBar(QWidget *w)
+{
+    // don't search recursively to avoid finding a menu bar of a
+    // mainwindow that happens to be a workspace window (like
+    // a mainwindow in designer)
+    QList<QObject *> children = w->children();
+    for (int i = 0; i < children.count(); ++i) {
+        QMenuBar *bar = qobject_cast<QMenuBar *>(children.at(i));
+        if (bar)
+            return bar;
+    }
+    return 0;
+}
+
+void QWorkspacePrivate::showMaximizeControls()
+{
+    Q_Q(QWorkspace);
+    Q_ASSERT(maxWindow);
+
+    // merge windowtitle and modified state
+    if (!topTitle.size())
+        topTitle = q->window()->windowTitle();
+
+    if (maxWindow->windowWidget()) {
+        QString docTitle = maxWindow->windowWidget()->windowTitle();
+        if (topTitle.size() && docTitle.size()) {
+            inTitleChange = true;
+            q->window()->setWindowTitle(QWorkspace::tr("%1 - [%2]").arg(topTitle).arg(docTitle));
+            inTitleChange = false;
+        }
+        q->window()->setWindowModified(maxWindow->windowWidget()->isWindowModified());
+    }
+
+    if (!q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
+        QMenuBar* b = 0;
+
+        // Do a breadth-first search first on every parent,
+        QWidget* w = q->parentWidget();
+        while (w) {
+            b = findMenuBar(w);
+            if (b)
+                break;
+            w = w->parentWidget();
+        }
+
+        // last attempt.
+        if (!b)
+            b = findMenuBar(q->window());
+
+        if (!b)
+            return;
+
+        if (!maxcontrols) {
+            maxmenubar = b;
+            maxcontrols = new QMDIControl(b);
+            QObject::connect(maxcontrols, SIGNAL(_q_minimize()),
+                             q, SLOT(_q_minimizeActiveWindow()));
+            QObject::connect(maxcontrols, SIGNAL(_q_restore()),
+                             q, SLOT(_q_normalizeActiveWindow()));
+            QObject::connect(maxcontrols, SIGNAL(_q_close()),
+                             q, SLOT(closeActiveWindow()));
+        }
+
+        b->setCornerWidget(maxcontrols);
+        if (b->isVisible())
+            maxcontrols->show();
+        if (!active && becomeActive) {
+            active = (QWorkspaceChild*)becomeActive->parentWidget();
+            active->setActive(true);
+            becomeActive = 0;
+            emit q->windowActivated(active->windowWidget());
+        }
+        if (active) {
+            if (!maxtools) {
+                maxtools = new QLabel(q->window());
+                maxtools->setObjectName(QLatin1String("qt_maxtools"));
+                maxtools->installEventFilter(q);
+            }
+            if (active->windowWidget() && !active->windowWidget()->windowIcon().isNull()) {
+                QIcon icon = active->windowWidget()->windowIcon();
+                int iconSize = maxcontrols->size().height();
+                maxtools->setPixmap(icon.pixmap(QSize(iconSize, iconSize)));
+            } else {
+                QPixmap pm = q->style()->standardPixmap(QStyle::SP_TitleBarMenuButton, 0, q);
+                if (pm.isNull()) {
+                    pm = QPixmap(14,14);
+                    pm.fill(Qt::black);
+                }
+                maxtools->setPixmap(pm);
+            }
+            b->setCornerWidget(maxtools, Qt::TopLeftCorner);
+            if (b->isVisible())
+                maxtools->show();
+        }
+    }
+}
+
+
+void QWorkspacePrivate::hideMaximizeControls()
+{
+    Q_Q(QWorkspace);
+    if (maxmenubar && !q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
+        if (maxmenubar) {
+            maxmenubar->setCornerWidget(0, Qt::TopLeftCorner);
+            maxmenubar->setCornerWidget(0, Qt::TopRightCorner);
+        }
+        if (maxcontrols) {
+            maxcontrols->deleteLater();
+            maxcontrols = 0;
+        }
+        if (maxtools) {
+            maxtools->deleteLater();
+            maxtools = 0;
+        }
+    }
+
+    //unmerge the title bar/modification state
+    if (topTitle.size()) {
+        inTitleChange = true;
+        q->window()->setWindowTitle(topTitle);
+        inTitleChange = false;
+    }
+    q->window()->setWindowModified(false);
+}
+
+/*!
+    Closes the child window that is currently active.
+
+    \sa closeAllWindows()
+*/
+void QWorkspace::closeActiveWindow()
+{
+    Q_D(QWorkspace);
+    if (d->maxWindow && d->maxWindow->windowWidget())
+        d->maxWindow->windowWidget()->close();
+    else if (d->active && d->active->windowWidget())
+        d->active->windowWidget()->close();
+    d->updateWorkspace();
+}
+
+/*!
+    Closes all child windows.
+
+    If any child window fails to accept the close event, the remaining windows
+    will remain open.
+
+    \sa closeActiveWindow()
+*/
+void QWorkspace::closeAllWindows()
+{
+    Q_D(QWorkspace);
+    bool did_close = true;
+    QList<QWorkspaceChild *>::const_iterator it = d->windows.constBegin();
+    while (it != d->windows.constEnd() && did_close) {
+        QWorkspaceChild *c = *it;
+        ++it;
+        if (c->windowWidget() && !c->windowWidget()->isHidden())
+            did_close = c->windowWidget()->close();
+    }
+}
+
+void QWorkspacePrivate::_q_normalizeActiveWindow()
+{
+    if (maxWindow)
+        maxWindow->showNormal();
+    else if (active)
+        active->showNormal();
+}
+
+void QWorkspacePrivate::_q_minimizeActiveWindow()
+{
+    if (maxWindow)
+        maxWindow->showMinimized();
+    else if (active)
+        active->showMinimized();
+}
+
+void QWorkspacePrivate::_q_showOperationMenu()
+{
+    Q_Q(QWorkspace);
+    if  (!active || !active->windowWidget())
+        return;
+    Q_ASSERT((active->windowWidget()->windowFlags() & Qt::WindowSystemMenuHint));
+    QPoint p;
+    QMenu *popup = (active->titlebar && active->titlebar->isTool()) ? toolPopup : this->popup;
+    if (q->isRightToLeft()) {
+        p = QPoint(active->windowWidget()->mapToGlobal(QPoint(active->windowWidget()->width(),0)));
+        p.rx() -= popup->sizeHint().width();
+    } else {
+        p = QPoint(active->windowWidget()->mapToGlobal(QPoint(0,0)));
+    }
+    if (!active->isVisible()) {
+        p = active->iconWidget()->mapToGlobal(QPoint(0,0));
+        p.ry() -= popup->sizeHint().height();
+    }
+    _q_popupOperationMenu(p);
+}
+
+void QWorkspacePrivate::_q_popupOperationMenu(const QPoint&  p)
+{
+    if (!active || !active->windowWidget() || !(active->windowWidget()->windowFlags() & Qt::WindowSystemMenuHint))
+        return;
+    if (active->titlebar && active->titlebar->isTool())
+        toolPopup->popup(p);
+    else
+        popup->popup(p);
+}
+
+void QWorkspacePrivate::_q_updateActions()
+{
+    Q_Q(QWorkspace);
+    for (int i = 1; i < NCountAct-1; i++) {
+        bool enable = active != 0;
+        actions[i]->setEnabled(enable);
+    }
+
+    if (!active || !active->windowWidget())
+        return;
+
+    QWidget *windowWidget = active->windowWidget();
+    bool canResize = windowWidget->maximumSize() != windowWidget->minimumSize();
+    actions[QWorkspacePrivate::ResizeAct]->setEnabled(canResize);
+    actions[QWorkspacePrivate::MinimizeAct]->setEnabled((windowWidget->windowFlags() & Qt::WindowMinimizeButtonHint));
+    actions[QWorkspacePrivate::MaximizeAct]->setEnabled((windowWidget->windowFlags() & Qt::WindowMaximizeButtonHint) && canResize);
+
+    if (active == maxWindow) {
+        actions[QWorkspacePrivate::MoveAct]->setEnabled(false);
+        actions[QWorkspacePrivate::ResizeAct]->setEnabled(false);
+        actions[QWorkspacePrivate::MaximizeAct]->setEnabled(false);
+        actions[QWorkspacePrivate::RestoreAct]->setEnabled(true);
+    } else if (active->isVisible()){
+        actions[QWorkspacePrivate::RestoreAct]->setEnabled(false);
+    } else {
+        actions[QWorkspacePrivate::MoveAct]->setEnabled(false);
+        actions[QWorkspacePrivate::ResizeAct]->setEnabled(false);
+        actions[QWorkspacePrivate::MinimizeAct]->setEnabled(false);
+        actions[QWorkspacePrivate::RestoreAct]->setEnabled(true);
+    }
+    if (active->shademode) {
+        actions[QWorkspacePrivate::ShadeAct]->setIcon(
+            QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarUnshadeButton, 0, q)));
+        actions[QWorkspacePrivate::ShadeAct]->setText(QWorkspace::tr("&Unshade"));
+    } else {
+        actions[QWorkspacePrivate::ShadeAct]->setIcon(
+            QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarShadeButton, 0, q)));
+        actions[QWorkspacePrivate::ShadeAct]->setText(QWorkspace::tr("Sh&ade"));
+    }
+    actions[QWorkspacePrivate::StaysOnTopAct]->setEnabled(!active->shademode && canResize);
+    actions[QWorkspacePrivate::StaysOnTopAct]->setChecked(
+        (active->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint));
+}
+
+void QWorkspacePrivate::_q_operationMenuActivated(QAction *action)
+{
+    if (!active)
+        return;
+    if(action == actions[QWorkspacePrivate::RestoreAct]) {
+        active->showNormal();
+    } else if(action == actions[QWorkspacePrivate::MoveAct]) {
+        active->doMove();
+    } else if(action == actions[QWorkspacePrivate::ResizeAct]) {
+        if (active->shademode)
+            active->showShaded();
+        active->doResize();
+    } else if(action == actions[QWorkspacePrivate::MinimizeAct]) {
+        active->showMinimized();
+    } else if(action == actions[QWorkspacePrivate::MaximizeAct]) {
+        active->showMaximized();
+    } else if(action == actions[QWorkspacePrivate::ShadeAct]) {
+        active->showShaded();
+    } else if(action == actions[QWorkspacePrivate::StaysOnTopAct]) {
+        if(QWidget* w = active->windowWidget()) {
+            if ((w->windowFlags() & Qt::WindowStaysOnTopHint)) {
+                w->overrideWindowFlags(w->windowFlags() & ~Qt::WindowStaysOnTopHint);
+            } else {
+                w->overrideWindowFlags(w->windowFlags() | Qt::WindowStaysOnTopHint);
+                w->parentWidget()->raise();
+            }
+        }
+    }
+}
+
+
+void QWorkspacePrivate::hideChild(QWorkspaceChild *c)
+{
+    Q_Q(QWorkspace);
+
+//     bool updatesEnabled = q->updatesEnabled();
+//     q->setUpdatesEnabled(false);
+    focus.removeAll(c);
+    QRect restore;
+    if (maxWindow == c)
+        restore = maxRestore;
+    if (active == c) {
+        q->setFocus();
+        q->activatePreviousWindow();
+    }
+    if (active == c)
+        activateWindow(0);
+    if (maxWindow == c) {
+        hideMaximizeControls();
+        maxWindow = 0;
+    }
+    c->hide();
+    if (!restore.isEmpty())
+        c->setGeometry(restore);
+//     q->setUpdatesEnabled(updatesEnabled);
+}
+
+/*!
+    Gives the input focus to the next window in the list of child
+    windows.
+
+    \sa activatePreviousWindow()
+*/
+void QWorkspace::activateNextWindow()
+{
+    Q_D(QWorkspace);
+
+    if (d->focus.isEmpty())
+        return;
+    if (!d->active) {
+        if (d->focus.first())
+            d->activateWindow(d->focus.first()->windowWidget(), false);
+        return;
+    }
+
+    int a = d->focus.indexOf(d->active) + 1;
+
+    a = a % d->focus.count();
+
+    if (d->focus.at(a))
+        d->activateWindow(d->focus.at(a)->windowWidget(), false);
+    else
+        d->activateWindow(0);
+}
+
+/*!
+    Gives the input focus to the previous window in the list of child
+    windows.
+
+    \sa activateNextWindow()
+*/
+void QWorkspace::activatePreviousWindow()
+{
+    Q_D(QWorkspace);
+
+    if (d->focus.isEmpty())
+        return;
+    if (!d->active) {
+        if (d->focus.last())
+            d->activateWindow(d->focus.first()->windowWidget(), false);
+        else
+            d->activateWindow(0);
+        return;
+    }
+
+    int a = d->focus.indexOf(d->active) - 1;
+    if (a < 0)
+        a = d->focus.count()-1;
+
+    if (d->focus.at(a))
+        d->activateWindow(d->focus.at(a)->windowWidget(), false);
+    else
+        d->activateWindow(0);
+}
+
+
+/*!
+    \fn void QWorkspace::windowActivated(QWidget* w)
+
+    This signal is emitted when the child window \a w becomes active.
+    Note that \a w can be 0, and that more than one signal may be
+    emitted for a single activation event.
+
+    \sa activeWindow(), windowList()
+*/
+
+/*!
+    Arranges all the child windows in a cascade pattern.
+
+    \sa tile(), arrangeIcons()
+*/
+void QWorkspace::cascade()
+{
+    Q_D(QWorkspace);
+    blockSignals(true);
+    if  (d->maxWindow)
+        d->maxWindow->showNormal();
+
+    if (d->vbar) {
+        d->vbar->blockSignals(true);
+        d->vbar->setValue(0);
+        d->vbar->blockSignals(false);
+        d->hbar->blockSignals(true);
+        d->hbar->setValue(0);
+        d->hbar->blockSignals(false);
+        d->_q_scrollBarChanged();
+    }
+
+    const int xoffset = 13;
+    const int yoffset = 20;
+
+    // make a list of all relevant mdi clients
+    QList<QWorkspaceChild *> widgets;
+    QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
+    QWorkspaceChild* wc = 0;
+
+    for (it = d->focus.begin(); it != d->focus.end(); ++it) {
+        wc = *it;
+        if (wc->windowWidget()->isVisibleTo(this) && !(wc->titlebar && wc->titlebar->isTool()))
+            widgets.append(wc);
+    }
+
+    int x = 0;
+    int y = 0;
+
+    it = widgets.begin();
+    while (it != widgets.end()) {
+        QWorkspaceChild *child = *it;
+        ++it;
+
+        QSize prefSize = child->windowWidget()->sizeHint().expandedTo(qSmartMinSize(child->windowWidget()));
+        if (!prefSize.isValid())
+            prefSize = child->windowWidget()->size();
+        prefSize = prefSize.expandedTo(qSmartMinSize(child->windowWidget()));
+        if (prefSize.isValid())
+            prefSize += QSize(child->baseSize().width(), child->baseSize().height());
+
+        int w = prefSize.width();
+        int h = prefSize.height();
+
+        child->showNormal();
+        if (y + h > height())
+            y = 0;
+        if (x + w > width())
+            x = 0;
+        child->setGeometry(x, y, w, h);
+        x += xoffset;
+        y += yoffset;
+        child->internalRaise();
+    }
+    d->updateWorkspace();
+    blockSignals(false);
+}
+
+/*!
+    Arranges all child windows in a tile pattern.
+
+    \sa cascade(), arrangeIcons()
+*/
+void QWorkspace::tile()
+{
+    Q_D(QWorkspace);
+    blockSignals(true);
+    QWidget *oldActive = d->active ? d->active->windowWidget() : 0;
+    if  (d->maxWindow)
+        d->maxWindow->showNormal();
+
+    if (d->vbar) {
+        d->vbar->blockSignals(true);
+        d->vbar->setValue(0);
+        d->vbar->blockSignals(false);
+        d->hbar->blockSignals(true);
+        d->hbar->setValue(0);
+        d->hbar->blockSignals(false);
+        d->_q_scrollBarChanged();
+    }
+
+    int rows = 1;
+    int cols = 1;
+    int n = 0;
+    QWorkspaceChild* c;
+
+    QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
+    while (it != d->windows.end()) {
+        c = *it;
+        ++it;
+        if (!c->windowWidget()->isHidden()
+            && !(c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)
+            && !c->iconw)
+            n++;
+    }
+
+    while (rows * cols < n) {
+        if (cols <= rows)
+            cols++;
+        else
+            rows++;
+    }
+    int add = cols * rows - n;
+    bool* used = new bool[cols*rows];
+    for (int i = 0; i < rows*cols; i++)
+        used[i] = false;
+
+    int row = 0;
+    int col = 0;
+    int w = width() / cols;
+    int h = height() / rows;
+
+    it = d->windows.begin();
+    while (it != d->windows.end()) {
+        c = *it;
+        ++it;
+        if (c->iconw || c->windowWidget()->isHidden() || (c->titlebar && c->titlebar->isTool()))
+            continue;
+        if (!row && !col) {
+            w -= c->baseSize().width();
+            h -= c->baseSize().height();
+        }
+        if ((c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
+            QPoint p = c->pos();
+            if (p.x()+c->width() < 0)
+                p.setX(0);
+            if (p.x() > width())
+                p.setX(width() - c->width());
+            if (p.y() + 10 < 0)
+                p.setY(0);
+            if (p.y() > height())
+                p.setY(height() - c->height());
+
+            if (p != c->pos())
+                c->QWidget::move(p);
+        } else {
+            c->showNormal();
+            used[row*cols+col] = true;
+            QSize sz(w, h);
+            QSize bsize(c->baseSize());
+            sz = sz.expandedTo(c->windowWidget()->minimumSize()).boundedTo(c->windowWidget()->maximumSize());
+            sz += bsize;
+
+            if ( add ) {
+                if (sz.height() == h + bsize.height()) // no relevant constrains
+                    sz.rheight() *= 2;
+                used[(row+1)*cols+col] = true;
+                add--;
+            }
+
+            c->setGeometry(col*w + col*bsize.width(), row*h + row*bsize.height(), sz.width(), sz.height());
+
+            while(row < rows && col < cols && used[row*cols+col]) {
+                col++;
+                if (col == cols) {
+                    col = 0;
+                    row++;
+                }
+            }
+        }
+    }
+    delete [] used;
+
+    d->activateWindow(oldActive);
+    d->updateWorkspace();
+    blockSignals(false);
+}
+
+/*!
+    Arranges all iconified windows at the bottom of the workspace.
+
+    \sa cascade(), tile()
+*/
+void QWorkspace::arrangeIcons()
+{
+    Q_D(QWorkspace);
+
+    QRect cr = d->updateWorkspace();
+    int x = 0;
+    int y = -1;
+
+    QList<QWidget *>::Iterator it(d->icons.begin());
+    while (it != d->icons.end()) {
+        QWidget* i = *it;
+        if (y == -1)
+            y = cr.height() - i->height();
+        if (x > 0 && x + i->width() > cr.width()) {
+            x = 0;
+            y -= i->height();
+        }
+        i->move(x, y);
+        x += i->width();
+        ++it;
+    }
+    d->updateWorkspace();
+}
+
+
+QWorkspaceChild::QWorkspaceChild(QWidget* window, QWorkspace *parent, Qt::WindowFlags flags)
+    : QWidget(parent,
+             Qt::FramelessWindowHint | Qt::SubWindow)
+{
+    setAttribute(Qt::WA_DeleteOnClose);
+    setAttribute(Qt::WA_NoMousePropagation);
+    setMouseTracking(true);
+    act = false;
+    iconw = 0;
+    shademode = false;
+    titlebar = 0;
+    setAutoFillBackground(true);
+
+    setBackgroundRole(QPalette::Window);
+    if (window) {
+        flags |= (window->windowFlags() & Qt::MSWindowsOwnDC);
+        if (flags)
+            window->setParent(this, flags & ~Qt::WindowType_Mask);
+        else
+            window->setParent(this);
+    }
+
+    if (window && (flags & (Qt::WindowTitleHint
+                            | Qt::WindowSystemMenuHint
+                            | Qt::WindowMinimizeButtonHint
+                            | Qt::WindowMaximizeButtonHint
+                            | Qt::WindowContextHelpButtonHint))) {
+        titlebar = new QWorkspaceTitleBar(window, this, flags);
+        connect(titlebar, SIGNAL(doActivate()),
+                 this, SLOT(activate()));
+        connect(titlebar, SIGNAL(doClose()),
+                 window, SLOT(close()));
+        connect(titlebar, SIGNAL(doMinimize()),
+                 this, SLOT(showMinimized()));
+        connect(titlebar, SIGNAL(doNormal()),
+                 this, SLOT(showNormal()));
+        connect(titlebar, SIGNAL(doMaximize()),
+                 this, SLOT(showMaximized()));
+        connect(titlebar, SIGNAL(popupOperationMenu(QPoint)),
+                 this, SIGNAL(popupOperationMenu(QPoint)));
+        connect(titlebar, SIGNAL(showOperationMenu()),
+                 this, SIGNAL(showOperationMenu()));
+        connect(titlebar, SIGNAL(doShade()),
+                 this, SLOT(showShaded()));
+        connect(titlebar, SIGNAL(doubleClicked()),
+                 this, SLOT(titleBarDoubleClicked()));
+    }
+
+    setMinimumSize(128, 0);
+    int fw =  style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
+    setContentsMargins(fw, fw, fw, fw);
+
+    childWidget = window;
+    if (!childWidget)
+        return;
+
+    setWindowTitle(childWidget->windowTitle());
+
+    QPoint p;
+    QSize s;
+    QSize cs;
+
+    bool hasBeenResized = childWidget->testAttribute(Qt::WA_Resized);
+
+    if (!hasBeenResized)
+        cs = childWidget->sizeHint().expandedTo(childWidget->minimumSizeHint()).expandedTo(childWidget->minimumSize()).boundedTo(childWidget->maximumSize());
+    else
+        cs = childWidget->size();
+
+    windowSize = cs;
+
+    int th = titlebar ? titlebar->sizeHint().height() : 0;
+    if (titlebar) {
+        if (!childWidget->windowIcon().isNull())
+            titlebar->setWindowIcon(childWidget->windowIcon());
+
+        if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
+            th -= contentsRect().y();
+
+        p = QPoint(contentsRect().x(),
+                    th + contentsRect().y());
+        s = QSize(cs.width() + 2*frameWidth(),
+                   cs.height() + 2*frameWidth() + th);
+    } else {
+        p = QPoint(contentsRect().x(), contentsRect().y());
+        s = QSize(cs.width() + 2*frameWidth(),
+                   cs.height() + 2*frameWidth());
+    }
+
+    childWidget->move(p);
+    resize(s);
+
+    childWidget->installEventFilter(this);
+
+    widgetResizeHandler = new QWidgetResizeHandler(this, window);
+    widgetResizeHandler->setSizeProtection(!parent->scrollBarsEnabled());
+    widgetResizeHandler->setFrameWidth(frameWidth());
+    connect(widgetResizeHandler, SIGNAL(activate()),
+             this, SLOT(activate()));
+    if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
+        widgetResizeHandler->setExtraHeight(th + contentsRect().y() - 2*frameWidth());
+    else
+        widgetResizeHandler->setExtraHeight(th + contentsRect().y() - frameWidth());
+    if (childWidget->minimumSize() == childWidget->maximumSize())
+        widgetResizeHandler->setActive(QWidgetResizeHandler::Resize, false);
+    setBaseSize(baseSize());
+}
+
+QWorkspaceChild::~QWorkspaceChild()
+{
+    QWorkspace *workspace = qobject_cast<QWorkspace*>(parentWidget());
+    if (iconw) {
+        if (workspace)
+            workspace->d_func()->removeIcon(iconw->parentWidget());
+        delete iconw->parentWidget();
+    }
+
+    if (workspace) {
+        workspace->d_func()->focus.removeAll(this);
+        if (workspace->d_func()->active == this)
+            workspace->activatePreviousWindow();
+        if (workspace->d_func()->active == this)
+            workspace->d_func()->activateWindow(0);
+        if (workspace->d_func()->maxWindow == this) {
+            workspace->d_func()->hideMaximizeControls();
+            workspace->d_func()->maxWindow = 0;
+        }
+    }
+}
+
+void QWorkspaceChild::moveEvent(QMoveEvent *)
+{
+    ((QWorkspace*)parentWidget())->d_func()->updateWorkspace();
+}
+
+void QWorkspaceChild::resizeEvent(QResizeEvent *)
+{
+    bool wasMax = isMaximized();
+    QRect r = contentsRect();
+    QRect cr;
+
+    updateMask();
+
+    if (titlebar) {
+        int th = titlebar->sizeHint().height();
+        QRect tbrect(0, 0, width(), th);
+        if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
+            tbrect = QRect(r.x(), r.y(), r.width(), th);
+        titlebar->setGeometry(tbrect);
+
+        if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
+            th -= frameWidth();
+        cr = QRect(r.x(), r.y() + th + (shademode ? (frameWidth() * 3) : 0),
+                    r.width(), r.height() - th);
+    } else {
+        cr = r;
+    }
+
+    if (!childWidget)
+        return;
+
+    bool doContentsResize = (windowSize == childWidget->size()
+                             || !(childWidget->testAttribute(Qt::WA_Resized) && childWidget->testAttribute(Qt::WA_PendingResizeEvent))
+                             ||childWidget->isMaximized());
+
+    windowSize = cr.size();
+    childWidget->move(cr.topLeft());
+    if (doContentsResize)
+        childWidget->resize(cr.size());
+    ((QWorkspace*)parentWidget())->d_func()->updateWorkspace();
+
+    if (wasMax) {
+        overrideWindowState(Qt::WindowMaximized);
+        childWidget->overrideWindowState(Qt::WindowMaximized);
+    }
+}
+
+QSize QWorkspaceChild::baseSize() const
+{
+    int th = titlebar ? titlebar->sizeHint().height() : 0;
+    if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
+        th -= frameWidth();
+    return QSize(2*frameWidth(), 2*frameWidth() + th);
+}
+
+QSize QWorkspaceChild::sizeHint() const
+{
+    if (!childWidget)
+        return QWidget::sizeHint() + baseSize();
+
+    QSize prefSize = windowWidget()->sizeHint().expandedTo(windowWidget()->minimumSizeHint());
+    prefSize = prefSize.expandedTo(windowWidget()->minimumSize()).boundedTo(windowWidget()->maximumSize());
+    prefSize += baseSize();
+
+    return prefSize;
+}
+
+QSize QWorkspaceChild::minimumSizeHint() const
+{
+    if (!childWidget)
+        return QWidget::minimumSizeHint() + baseSize();
+    QSize s = childWidget->minimumSize();
+    if (s.isEmpty())
+        s = childWidget->minimumSizeHint();
+    return s + baseSize();
+}
+
+void QWorkspaceChild::activate()
+{
+    ((QWorkspace*)parentWidget())->d_func()->activateWindow(windowWidget());
+}
+
+bool QWorkspaceChild::eventFilter(QObject * o, QEvent * e)
+{
+    if (!isActive()
+        && (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::FocusIn)) {
+        if (iconw) {
+            ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
+            if (iconw) {
+                ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
+                delete iconw->parentWidget();
+                iconw = 0;
+            }
+        }
+        activate();
+    }
+
+    // for all widgets except the window, that's the only thing we
+    // process, and if we have no childWidget we skip totally
+    if (o != childWidget || childWidget == 0)
+        return false;
+
+    switch (e->type()) {
+    case QEvent::ShowToParent:
+        if (((QWorkspace*)parentWidget())->d_func()->focus.indexOf(this) < 0)
+            ((QWorkspace*)parentWidget())->d_func()->focus.append(this);
+
+        if (windowWidget() && (windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
+            internalRaise();
+            show();
+        }
+        ((QWorkspace*)parentWidget())->d_func()->showWindow(windowWidget());
+        break;
+    case QEvent::WindowStateChange: {
+        if (static_cast<QWindowStateChangeEvent*>(e)->isOverride())
+            break;
+        Qt::WindowStates state = windowWidget()->windowState();
+
+        if (state & Qt::WindowMinimized) {
+            ((QWorkspace*)parentWidget())->d_func()->minimizeWindow(windowWidget());
+        } else if (state & Qt::WindowMaximized) {
+            if (windowWidget()->maximumSize().isValid() &&
+                (windowWidget()->maximumWidth() < parentWidget()->width() ||
+                 windowWidget()->maximumHeight() < parentWidget()->height())) {
+                windowWidget()->resize(windowWidget()->maximumSize());
+                windowWidget()->overrideWindowState(Qt::WindowNoState);
+                if (titlebar)
+                    titlebar->update();
+                break;
+            }
+            if ((windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint))
+                ((QWorkspace*)parentWidget())->d_func()->maximizeWindow(windowWidget());
+            else
+                ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
+        } else {
+            ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
+            if (iconw) {
+                ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
+                delete iconw->parentWidget();
+            }
+        }
+    } break;
+    case QEvent::HideToParent:
+    {
+        QWidget * w = iconw;
+        if (w && (w = w->parentWidget())) {
+            ((QWorkspace*)parentWidget())->d_func()->removeIcon(w);
+            delete w;
+        }
+        ((QWorkspace*)parentWidget())->d_func()->hideChild(this);
+    } break;
+    case QEvent::WindowIconChange:
+        {
+            QWorkspace* ws = (QWorkspace*)parentWidget();
+            if (ws->d_func()->maxtools && ws->d_func()->maxWindow == this) {
+                int iconSize = ws->d_func()->maxtools->size().height();
+                ws->d_func()->maxtools->setPixmap(childWidget->windowIcon().pixmap(QSize(iconSize, iconSize)));
+            }
+        }
+        // fall through
+    case QEvent::WindowTitleChange:
+        setWindowTitle(windowWidget()->windowTitle());
+        if (titlebar)
+            titlebar->update();
+        if (iconw)
+            iconw->update();
+        break;
+    case QEvent::ModifiedChange:
+        setWindowModified(windowWidget()->isWindowModified());
+        if (titlebar)
+            titlebar->update();
+        if (iconw)
+            iconw->update();
+        break;
+    case QEvent::Resize:
+        {
+            QResizeEvent* re = (QResizeEvent*)e;
+            if (re->size() != windowSize && !shademode) {
+                resize(re->size() + baseSize());
+                childWidget->update(); //workaround
+            }
+        }
+        break;
+
+    case QEvent::WindowDeactivate:
+        if (titlebar && titlebar->isActive()) {
+            update();
+        }
+        break;
+
+    case QEvent::WindowActivate:
+        if (titlebar && titlebar->isActive()) {
+            update();
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return QWidget::eventFilter(o, e);
+}
+
+void QWorkspaceChild::childEvent(QChildEvent* e)
+{
+    if (e->type() == QEvent::ChildRemoved && e->child() == childWidget) {
+        childWidget = 0;
+        if (iconw) {
+            ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
+            delete iconw->parentWidget();
+        }
+        close();
+    }
+}
+
+
+void QWorkspaceChild::doResize()
+{
+    widgetResizeHandler->doResize();
+}
+
+void QWorkspaceChild::doMove()
+{
+    widgetResizeHandler->doMove();
+}
+
+void QWorkspaceChild::enterEvent(QEvent *)
+{
+}
+
+void QWorkspaceChild::leaveEvent(QEvent *)
+{
+#ifndef QT_NO_CURSOR
+    if (!widgetResizeHandler->isButtonDown())
+        setCursor(Qt::ArrowCursor);
+#endif
+}
+
+void QWorkspaceChild::paintEvent(QPaintEvent *)
+{
+    QPainter p(this);
+    QStyleOptionFrame opt;
+    opt.rect = rect();
+    opt.palette = palette();
+    opt.state = QStyle::State_None;
+    opt.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
+    opt.midLineWidth = 1;
+
+    if (titlebar && titlebar->isActive() && isActiveWindow())
+        opt.state |= QStyle::State_Active;
+
+    style()->drawPrimitive(QStyle::PE_FrameWindow, &opt, &p, this);
+}
+
+void QWorkspaceChild::changeEvent(QEvent *ev)
+{
+    if(ev->type() == QEvent::StyleChange) {
+        resizeEvent(0);
+        if (iconw) {
+            QFrame *frame = qobject_cast<QFrame*>(iconw->parentWidget());
+            Q_ASSERT(frame);
+            if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar)) {
+                frame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
+                frame->resize(196+2*frame->frameWidth(), 20 + 2*frame->frameWidth());
+            } else {
+                frame->resize(196, 20);
+            }
+        }
+        updateMask();
+    }
+    QWidget::changeEvent(ev);
+}
+
+void QWorkspaceChild::setActive(bool b)
+{
+    if (!childWidget)
+        return;
+
+    bool hasFocus = isChildOf(window()->focusWidget(), this);
+    if (act == b && (act == hasFocus))
+        return;
+
+    act = b;
+
+    if (titlebar)
+        titlebar->setActive(act);
+    if (iconw)
+        iconw->setActive(act);
+    update();
+
+    QList<QWidget*> wl = qFindChildren<QWidget*>(childWidget);
+    if (act) {
+        for (int i = 0; i < wl.size(); ++i) {
+            QWidget *w = wl.at(i);
+            w->removeEventFilter(this);
+        }
+        if (!hasFocus) {
+            QWidget *lastfocusw = childWidget->focusWidget();
+            if (lastfocusw && lastfocusw->focusPolicy() != Qt::NoFocus) {
+                lastfocusw->setFocus();
+            } else if (childWidget->focusPolicy() != Qt::NoFocus) {
+                childWidget->setFocus();
+            } else {
+                // find something, anything, that accepts focus, and use that.
+                for (int i = 0; i < wl.size(); ++i) {
+                    QWidget *w = wl.at(i);
+                    if(w->focusPolicy() != Qt::NoFocus) {
+                        w->setFocus();
+                        hasFocus = true;
+                        break;
+                    }
+                }
+                if (!hasFocus)
+                    setFocus();
+            }
+        }
+    } else {
+        for (int i = 0; i < wl.size(); ++i) {
+            QWidget *w = wl.at(i);
+            w->removeEventFilter(this);
+            w->installEventFilter(this);
+        }
+    }
+}
+
+bool QWorkspaceChild::isActive() const
+{
+    return act;
+}
+
+QWidget* QWorkspaceChild::windowWidget() const
+{
+    return childWidget;
+}
+
+bool QWorkspaceChild::isWindowOrIconVisible() const
+{
+    return childWidget && (!isHidden()  || (iconw && !iconw->isHidden()));
+}
+
+void QWorkspaceChild::updateMask()
+{
+    QStyleOptionTitleBar titleBarOptions;
+    titleBarOptions.rect = rect();
+    titleBarOptions.titleBarFlags = windowFlags();
+    titleBarOptions.titleBarState = windowState();
+
+    QStyleHintReturnMask frameMask;
+    if (style()->styleHint(QStyle::SH_WindowFrame_Mask, &titleBarOptions, this, &frameMask)) {
+        setMask(frameMask.region);
+    } else if (!mask().isEmpty()) {
+        clearMask();
+    }
+
+    if (iconw) {
+        QFrame *frame = qobject_cast<QFrame *>(iconw->parentWidget());
+        Q_ASSERT(frame);
+
+        titleBarOptions.rect = frame->rect();
+        titleBarOptions.titleBarFlags = frame->windowFlags();
+        titleBarOptions.titleBarState = frame->windowState() | Qt::WindowMinimized;
+        if (style()->styleHint(QStyle::SH_WindowFrame_Mask, &titleBarOptions, frame, &frameMask)) {
+            frame->setMask(frameMask.region);
+        } else if (!frame->mask().isEmpty()) {
+            frame->clearMask();
+        }
+    }
+}
+
+QWidget* QWorkspaceChild::iconWidget() const
+{
+    if (!iconw) {
+        QWorkspaceChild* that = (QWorkspaceChild*) this;
+
+        QFrame* frame = new QFrame(that, Qt::Window);
+        QVBoxLayout *vbox = new QVBoxLayout(frame);
+        vbox->setMargin(0);
+        QWorkspaceTitleBar *tb = new QWorkspaceTitleBar(windowWidget(), frame);
+        vbox->addWidget(tb);
+        tb->setObjectName(QLatin1String("_workspacechild_icon_"));
+        QStyleOptionTitleBar opt;
+        tb->initStyleOption(&opt);
+        int th = style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, tb);
+        int iconSize = style()->pixelMetric(QStyle::PM_MdiSubWindowMinimizedWidth, 0, this);
+        if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar)) {
+            frame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
+            frame->resize(iconSize+2*frame->frameWidth(), th+2*frame->frameWidth());
+        } else {
+            frame->resize(iconSize, th);
+        }
+
+        that->iconw = tb;
+        that->updateMask();
+        iconw->setActive(isActive());
+
+        connect(iconw, SIGNAL(doActivate()),
+                 this, SLOT(activate()));
+        connect(iconw, SIGNAL(doClose()),
+                 windowWidget(), SLOT(close()));
+        connect(iconw, SIGNAL(doNormal()),
+                 this, SLOT(showNormal()));
+        connect(iconw, SIGNAL(doMaximize()),
+                 this, SLOT(showMaximized()));
+        connect(iconw, SIGNAL(popupOperationMenu(QPoint)),
+                 this, SIGNAL(popupOperationMenu(QPoint)));
+        connect(iconw, SIGNAL(showOperationMenu()),
+                 this, SIGNAL(showOperationMenu()));
+        connect(iconw, SIGNAL(doubleClicked()),
+                 this, SLOT(titleBarDoubleClicked()));
+    }
+    if (windowWidget()) {
+        iconw->setWindowTitle(windowWidget()->windowTitle());
+    }
+    return iconw->parentWidget();
+}
+
+void QWorkspaceChild::showMinimized()
+{
+    windowWidget()->setWindowState(Qt::WindowMinimized | (windowWidget()->windowState() & ~Qt::WindowMaximized));
+}
+
+void QWorkspaceChild::showMaximized()
+{
+    windowWidget()->setWindowState(Qt::WindowMaximized | (windowWidget()->windowState() & ~Qt::WindowMinimized));
+}
+
+void QWorkspaceChild::showNormal()
+{
+    windowWidget()->setWindowState(windowWidget()->windowState() & ~(Qt::WindowMinimized|Qt::WindowMaximized));
+}
+
+void QWorkspaceChild::showShaded()
+{
+    if (!titlebar)
+        return;
+    ((QWorkspace*)parentWidget())->d_func()->activateWindow(windowWidget());
+    QWidget* w = windowWidget();
+    if (shademode) {
+        w->overrideWindowState(Qt::WindowNoState);
+        overrideWindowState(Qt::WindowNoState);
+
+        shademode = false;
+        resize(shadeRestore.expandedTo(minimumSizeHint()));
+        setMinimumSize(shadeRestoreMin);
+        style()->polish(this);
+    } else {
+        shadeRestore = size();
+        shadeRestoreMin = minimumSize();
+        setMinimumHeight(0);
+        shademode = true;
+        w->overrideWindowState(Qt::WindowMinimized);
+        overrideWindowState(Qt::WindowMinimized);
+
+        if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
+            resize(width(), titlebar->height());
+        else
+            resize(width(), titlebar->height() + 2*frameWidth() + 1);
+        style()->polish(this);
+    }
+    titlebar->update();
+}
+
+void QWorkspaceChild::titleBarDoubleClicked()
+{
+    if (!windowWidget())
+        return;
+    if (iconw)
+        showNormal();
+    else if (windowWidget()->windowFlags() & Qt::WindowShadeButtonHint)
+            showShaded();
+    else if (windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint)
+        showMaximized();
+}
+
+void QWorkspaceChild::adjustToFullscreen()
+{
+    if (!childWidget)
+        return;
+
+    if(!((QWorkspace*)parentWidget())->d_func()->maxmenubar || style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, this)) {
+        setGeometry(parentWidget()->rect());
+    } else {
+        int fw =  style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
+        bool noBorder = style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar);
+        int th = titlebar ? titlebar->sizeHint().height() : 0;
+        int w = parentWidget()->width() + 2*fw;
+        int h = parentWidget()->height() + (noBorder ? fw : 2*fw) + th;
+        w = qMax(w, childWidget->minimumWidth());
+        h = qMax(h, childWidget->minimumHeight());
+        setGeometry(-fw, (noBorder ? 0 : -fw) - th, w, h);
+    }
+    childWidget->overrideWindowState(Qt::WindowMaximized);
+    overrideWindowState(Qt::WindowMaximized);
+}
+
+void QWorkspaceChild::internalRaise()
+{
+
+    QWidget *stackUnderWidget = 0;
+    if (!windowWidget() || (windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint) == 0) {
+
+        QList<QWorkspaceChild *>::Iterator it(((QWorkspace*)parent())->d_func()->windows.begin());
+        while (it != ((QWorkspace*)parent())->d_func()->windows.end()) {
+            QWorkspaceChild* c = *it;
+            ++it;
+            if (c->windowWidget() &&
+                !c->windowWidget()->isHidden() &&
+                (c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
+                if (stackUnderWidget)
+                    c->stackUnder(stackUnderWidget);
+                else
+                    c->raise();
+                stackUnderWidget = c;
+            }
+        }
+    }
+
+    if (stackUnderWidget) {
+        if (iconw)
+            iconw->parentWidget()->stackUnder(stackUnderWidget);
+        stackUnder(stackUnderWidget);
+    } else {
+        if (iconw)
+            iconw->parentWidget()->raise();
+        raise();
+    }
+
+}
+
+void QWorkspaceChild::show()
+{
+    if (childWidget && childWidget->isHidden())
+        childWidget->show();
+    QWidget::show();
+}
+
+bool QWorkspace::scrollBarsEnabled() const
+{
+    Q_D(const QWorkspace);
+    return d->vbar != 0;
+}
+
+/*!
+    \property QWorkspace::scrollBarsEnabled
+    \brief whether the workspace provides scroll bars
+
+    If this property is true, the workspace will provide scroll bars if any
+    of the child windows extend beyond the edges of the visible
+    workspace. The workspace area will automatically increase to
+    contain child windows if they are resized beyond the right or
+    bottom edges of the visible area.
+
+    If this property is false (the default), resizing child windows
+    out of the visible area of the workspace is not permitted, although
+    it is still possible to position them partially outside the visible area.
+*/
+void QWorkspace::setScrollBarsEnabled(bool enable)
+{
+    Q_D(QWorkspace);
+    if ((d->vbar != 0) == enable)
+        return;
+
+    d->xoffset = d->yoffset = 0;
+    if (enable) {
+        d->vbar = new QScrollBar(Qt::Vertical, this);
+        d->vbar->setObjectName(QLatin1String("vertical scrollbar"));
+        connect(d->vbar, SIGNAL(valueChanged(int)), this, SLOT(_q_scrollBarChanged()));
+        d->hbar = new QScrollBar(Qt::Horizontal, this);
+        d->hbar->setObjectName(QLatin1String("horizontal scrollbar"));
+        connect(d->hbar, SIGNAL(valueChanged(int)), this, SLOT(_q_scrollBarChanged()));
+        d->corner = new QWidget(this);
+        d->corner->setBackgroundRole(QPalette::Window);
+        d->corner->setObjectName(QLatin1String("qt_corner"));
+        d->updateWorkspace();
+    } else {
+        delete d->vbar;
+        delete d->hbar;
+        delete d->corner;
+        d->vbar = d->hbar = 0;
+        d->corner = 0;
+    }
+
+    QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
+    while (it != d->windows.end()) {
+        QWorkspaceChild *child = *it;
+        ++it;
+        child->widgetResizeHandler->setSizeProtection(!enable);
+    }
+}
+
+QRect QWorkspacePrivate::updateWorkspace()
+{
+    Q_Q(QWorkspace);
+    QRect cr(q->rect());
+
+    if (q->scrollBarsEnabled() && !maxWindow) {
+        corner->raise();
+        vbar->raise();
+        hbar->raise();
+        if (maxWindow)
+            maxWindow->internalRaise();
+
+        QRect r(0, 0, 0, 0);
+        QList<QWorkspaceChild *>::Iterator it(windows.begin());
+        while (it != windows.end()) {
+            QWorkspaceChild *child = *it;
+            ++it;
+            if (!child->isHidden())
+                r = r.unite(child->geometry());
+        }
+        vbar->blockSignals(true);
+        hbar->blockSignals(true);
+
+        int hsbExt = hbar->sizeHint().height();
+        int vsbExt = vbar->sizeHint().width();
+
+
+        bool showv = yoffset || yoffset + r.bottom() - q->height() + 1 > 0 || yoffset + r.top() < 0;
+        bool showh = xoffset || xoffset + r.right() - q->width() + 1 > 0 || xoffset + r.left() < 0;
+
+        if (showh && !showv)
+            showv = yoffset + r.bottom() - q->height() + hsbExt + 1 > 0;
+        if (showv && !showh)
+            showh = xoffset + r.right() - q->width() + vsbExt  + 1 > 0;
+
+        if (!showh)
+            hsbExt = 0;
+        if (!showv)
+            vsbExt = 0;
+
+        if (showv) {
+            vbar->setSingleStep(qMax(q->height() / 12, 30));
+            vbar->setPageStep(q->height() - hsbExt);
+            vbar->setMinimum(qMin(0, yoffset + qMin(0, r.top())));
+            vbar->setMaximum(qMax(0, yoffset + qMax(0, r.bottom() - q->height() + hsbExt + 1)));
+            vbar->setGeometry(q->width() - vsbExt, 0, vsbExt, q->height() - hsbExt);
+            vbar->setValue(yoffset);
+            vbar->show();
+        } else {
+            vbar->hide();
+        }
+
+        if (showh) {
+            hbar->setSingleStep(qMax(q->width() / 12, 30));
+            hbar->setPageStep(q->width() - vsbExt);
+            hbar->setMinimum(qMin(0, xoffset + qMin(0, r.left())));
+            hbar->setMaximum(qMax(0, xoffset + qMax(0, r.right() - q->width() + vsbExt  + 1)));
+            hbar->setGeometry(0, q->height() - hsbExt, q->width() - vsbExt, hsbExt);
+            hbar->setValue(xoffset);
+            hbar->show();
+        } else {
+            hbar->hide();
+        }
+
+        if (showh && showv) {
+            corner->setGeometry(q->width() - vsbExt, q->height() - hsbExt, vsbExt, hsbExt);
+            corner->show();
+        } else {
+            corner->hide();
+        }
+
+        vbar->blockSignals(false);
+        hbar->blockSignals(false);
+
+        cr.setRect(0, 0, q->width() - vsbExt, q->height() - hsbExt);
+    }
+
+    QList<QWidget *>::Iterator ii(icons.begin());
+    while (ii != icons.end()) {
+        QWidget* w = *ii;
+        ++ii;
+        int x = w->x();
+        int y = w->y();
+        bool m = false;
+        if (x+w->width() > cr.width()) {
+            m = true;
+            x =  cr.width() - w->width();
+        }
+        if (y+w->height() >  cr.height()) {
+            y =  cr.height() - w->height();
+            m = true;
+        }
+        if (m) {
+            if (QWorkspaceChild *child = qobject_cast<QWorkspaceChild*>(w))
+                child->move(x, y);
+            else
+                w->move(x, y);
+        }
+    }
+
+    return cr;
+
+}
+
+void QWorkspacePrivate::_q_scrollBarChanged()
+{
+    int ver = yoffset - vbar->value();
+    int hor = xoffset - hbar->value();
+    yoffset = vbar->value();
+    xoffset = hbar->value();
+
+    QList<QWorkspaceChild *>::Iterator it(windows.begin());
+    while (it != windows.end()) {
+        QWorkspaceChild *child = *it;
+        ++it;
+        // we do not use move() due to the reimplementation in QWorkspaceChild
+        child->setGeometry(child->x() + hor, child->y() + ver, child->width(), child->height());
+    }
+    updateWorkspace();
+}
+
+/*!
+    \enum QWorkspace::WindowOrder
+
+    Specifies the order in which child windows are returned from windowList().
+
+    \value CreationOrder The windows are returned in the order of their creation
+    \value StackingOrder The windows are returned in the order of their stacking
+*/
+
+/*!\reimp */
+void QWorkspace::changeEvent(QEvent *ev)
+{
+    Q_D(QWorkspace);
+    if(ev->type() == QEvent::StyleChange) {
+        if (isVisible() && d->maxWindow && d->maxmenubar) {
+            if(style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, this)) {
+                d->hideMaximizeControls(); //hide any visible maximized controls
+                d->showMaximizeControls(); //updates the modification state as well
+            }
+        }
+    }
+    QWidget::changeEvent(ev);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qworkspace.cpp"
+
+#include "qworkspace.moc"
+
+#endif // QT_NO_WORKSPACE