src/qt3support/widgets/q3dockwindow.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/qt3support/widgets/q3dockwindow.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,2115 @@
+/****************************************************************************
+**
+** 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 Qt3Support 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 "q3dockwindow.h"
+
+#ifndef QT_NO_MAINWINDOW
+#include "qapplication.h"
+#include "qcursor.h"
+#include "qdesktopwidget.h"
+#include "q3dockarea.h"
+#include "qevent.h"
+#include "qlayout.h"
+#include "q3mainwindow.h"
+#include "qpainter.h"
+#include "qpointer.h"
+#include "qstyle.h"
+#include "qstyleoption.h"
+#include "qtimer.h"
+#include "q3toolbar.h"
+#include "qtoolbutton.h"
+#include "qtooltip.h"
+#include <private/q3titlebar_p.h>
+#include <private/qwidgetresizehandler_p.h>
+#include <qrubberband.h>
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_WS_MAC
+static bool default_opaque = true;
+#else
+static bool default_opaque = false;
+#endif
+
+class Q3DockWindowPrivate
+{
+};
+
+class Q3DockWindowResizeHandle : public QWidget
+{
+    Q_OBJECT
+
+public:
+    Q3DockWindowResizeHandle(Qt::Orientation o, QWidget *parent, Q3DockWindow *w, const char* /*name*/=0);
+    void setOrientation(Qt::Orientation o);
+    Qt::Orientation orientation() const { return orient; }
+
+    QSize sizeHint() const;
+
+protected:
+    void paintEvent(QPaintEvent *);
+    void mouseMoveEvent(QMouseEvent *);
+    void mousePressEvent(QMouseEvent *);
+    void mouseReleaseEvent(QMouseEvent *);
+    bool event(QEvent *event);
+
+private:
+    void startLineDraw();
+    void endLineDraw();
+    void drawLine(const QPoint &globalPos);
+
+private:
+    Qt::Orientation orient;
+    bool mousePressed;
+    QRubberBand *rubberBand;
+    QPoint lastPos, firstPos;
+    Q3DockWindow *dockWindow;
+    bool mouseOver;
+};
+
+Q3DockWindowResizeHandle::Q3DockWindowResizeHandle(Qt::Orientation o, QWidget *parent,
+                                                  Q3DockWindow *w, const char *)
+    : QWidget(parent, "qt_dockwidget_internal"), mousePressed(false), rubberBand(0), dockWindow(w),
+      mouseOver(false)
+{
+    setOrientation(o);
+}
+
+QSize Q3DockWindowResizeHandle::sizeHint() const
+{
+    QStyleOptionQ3DockWindow opt;
+    opt.init(this);
+    if (!dockWindow->area() || dockWindow->area()->orientation() == Qt::Horizontal)
+        opt.state |= QStyle::State_Horizontal;
+
+    opt.rect = rect();
+    opt.docked = dockWindow->area();
+    opt.closeEnabled = dockWindow->isCloseEnabled();
+    int sw = 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, &opt, this) / 3;
+    return (style()->sizeFromContents(QStyle::CT_Q3DockWindow, &opt, QSize(sw, sw), this).expandedTo(QApplication::globalStrut()));
+}
+
+void Q3DockWindowResizeHandle::setOrientation(Qt::Orientation o)
+{
+    orient = o;
+    if (o == Qt::Horizontal) {
+#ifndef QT_NO_CURSOR
+        setCursor(Qt::splitVCursor);
+#endif
+        setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+    } else {
+#ifndef QT_NO_CURSOR
+        setCursor(Qt::splitHCursor);
+#endif
+        setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding));
+    }
+}
+
+void Q3DockWindowResizeHandle::mousePressEvent(QMouseEvent *e)
+{
+    e->ignore();
+    if (e->button() != Qt::LeftButton)
+        return;
+    e->accept();
+    mousePressed = true;
+    if (!dockWindow->opaqueMoving())
+        startLineDraw();
+    lastPos = firstPos = e->globalPos();
+    if (!dockWindow->opaqueMoving())
+        drawLine(e->globalPos());
+}
+
+void Q3DockWindowResizeHandle::mouseMoveEvent(QMouseEvent *e)
+{
+    if (!mousePressed)
+        return;
+    if (!dockWindow->opaqueMoving()) {
+        if (orientation() != dockWindow->area()->orientation()) {
+            if (orientation() == Qt::Horizontal) {
+                int minpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).y();
+                int maxpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).y() + dockWindow->area()->height();
+                if (e->globalPos().y() < minpos || e->globalPos().y() > maxpos)
+                    return;
+            } else {
+                int minpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).x();
+                int maxpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).x() + dockWindow->area()->width();
+                if (e->globalPos().x() < minpos || e->globalPos().x() > maxpos)
+                    return;
+            }
+        } else {
+            QWidget *w = dockWindow->area()->window();
+            if (w) {
+                if (orientation() == Qt::Horizontal) {
+                    int minpos = w->mapToGlobal(QPoint(0, 0)).y();
+                    int maxpos = w->mapToGlobal(QPoint(0, 0)).y() + w->height();
+                    if (e->globalPos().y() < minpos || e->globalPos().y() > maxpos)
+                        return;
+                } else {
+                    int minpos = w->mapToGlobal(QPoint(0, 0)).x();
+                    int maxpos = w->mapToGlobal(QPoint(0, 0)).x() + w->width();
+                    if (e->globalPos().x() < minpos || e->globalPos().x() > maxpos)
+                        return;
+                }
+            }
+        }
+    }
+
+    if (!dockWindow->opaqueMoving())
+        drawLine(lastPos);
+    lastPos = e->globalPos();
+    if (dockWindow->opaqueMoving()) {
+        mouseReleaseEvent(e);
+        mousePressed = true;
+        firstPos = e->globalPos();
+    }
+    if (!dockWindow->opaqueMoving())
+        drawLine(e->globalPos());
+}
+
+void Q3DockWindowResizeHandle::mouseReleaseEvent(QMouseEvent *e)
+{
+    if (mousePressed) {
+        if (!dockWindow->opaqueMoving()) {
+            drawLine(lastPos);
+            endLineDraw();
+        }
+        if (orientation() != dockWindow->area()->orientation())
+            dockWindow->area()->invalidNextOffset(dockWindow);
+        if (orientation() == Qt::Horizontal) {
+            int dy;
+            if (dockWindow->area()->handlePosition() == Q3DockArea::Normal || orientation() != dockWindow->area()->orientation())
+                dy = e->globalPos().y() - firstPos.y();
+            else
+                dy =  firstPos.y() - e->globalPos().y();
+            int d = dockWindow->height() + dy;
+            if (orientation() != dockWindow->area()->orientation()) {
+                dockWindow->setFixedExtentHeight(-1);
+                d = qMax(d, dockWindow->minimumHeight());
+                int ms = dockWindow->area()->maxSpace(d, dockWindow);
+                d = qMin(d, ms);
+                dockWindow->setFixedExtentHeight(d);
+            } else {
+                dockWindow->area()->setFixedExtent(d, dockWindow);
+            }
+        } else {
+            int dx;
+            if (dockWindow->area()->handlePosition() == Q3DockArea::Normal || orientation() != dockWindow->area()->orientation())
+                dx = e->globalPos().x() - firstPos.x();
+            else
+                dx = firstPos.x() - e->globalPos().x();
+            int d = dockWindow->width() + dx;
+            if (orientation() != dockWindow->area()->orientation()) {
+                dockWindow->setFixedExtentWidth(-1);
+                d = qMax(d, dockWindow->minimumWidth());
+                int ms = dockWindow->area()->maxSpace(d, dockWindow);
+                d = qMin(d, ms);
+                dockWindow->setFixedExtentWidth(d);
+            } else {
+                dockWindow->area()->setFixedExtent(d, dockWindow);
+            }
+        }
+    }
+
+    QApplication::postEvent(dockWindow->area(), new QEvent(QEvent::LayoutHint));
+    mousePressed = false;
+}
+
+bool Q3DockWindowResizeHandle::event(QEvent *event)
+{
+    switch (event->type()) {
+    case QEvent::HoverEnter:
+        if (!mouseOver) {
+            mouseOver = true;
+            update();
+        }
+        break;
+    case QEvent::HoverLeave:
+        if (mouseOver) {
+            mouseOver = false;
+            update();
+        }
+        break;
+    default:
+        break;
+    }
+    return QWidget::event(event);
+}
+
+void Q3DockWindowResizeHandle::paintEvent(QPaintEvent *)
+{
+    QPainter p(this);
+    QStyleOption opt(0);
+    opt.init(this);
+    if (orientation() == Qt::Horizontal)
+        opt.state |= QStyle::State_Horizontal;
+    style()->drawPrimitive(QStyle::PE_IndicatorDockWidgetResizeHandle, &opt, &p, this);
+}
+
+void Q3DockWindowResizeHandle::startLineDraw()
+{
+    if (rubberBand)
+        endLineDraw();
+    rubberBand = new QRubberBand(QRubberBand::Line);
+    rubberBand->setGeometry(-1, -1, 1, 1);
+    rubberBand->show();
+}
+
+void Q3DockWindowResizeHandle::endLineDraw()
+{
+    delete rubberBand;
+    rubberBand = 0;
+}
+
+void Q3DockWindowResizeHandle::drawLine(const QPoint &globalPos)
+{
+    QPoint start = mapToGlobal(QPoint(0, 0));
+    QPoint starta = dockWindow->area()->mapToGlobal(QPoint(0, 0));
+    QPoint end = globalPos;
+    if (orientation() == Qt::Horizontal) {
+        if (orientation() == dockWindow->orientation())
+            rubberBand->setGeometry(starta.x(), end.y(), dockWindow->area()->width(), height());
+        else
+            rubberBand->setGeometry(start.x(), end.y(), width(), height());
+    } else {
+        if (orientation() == dockWindow->orientation())
+            rubberBand->setGeometry(end.x(), starta.y(), width(), dockWindow->area()->height());
+        else
+            rubberBand->setGeometry(end.x(), start.y(), width(), height());
+    }
+}
+
+static QPoint realWidgetPos(Q3DockWindow *w)
+{
+    if (!w->parentWidget() || w->place() == Q3DockWindow::OutsideDock)
+        return w->pos();
+    return w->parentWidget()->mapToGlobal(w->geometry().topLeft());
+}
+
+class Q3DockWindowHandle : public QWidget
+{
+    Q_OBJECT
+    Q_PROPERTY(QString windowTitle READ windowTitle)
+    friend class Q3DockWindow;
+    friend class Q3DockWindowTitleBar;
+
+public:
+    Q3DockWindowHandle(Q3DockWindow *dw);
+    void updateGui();
+
+    QSize minimumSizeHint() const;
+    QSize minimumSize() const { return minimumSizeHint(); }
+    QSize sizeHint() const { return minimumSize(); }
+    void setOpaqueMoving(bool b) { opaque = b; }
+
+    QString windowTitle() const { return dockWindow->windowTitle(); }
+
+signals:
+    void doubleClicked();
+
+protected:
+    void paintEvent(QPaintEvent *e);
+    void resizeEvent(QResizeEvent *e);
+    void mousePressEvent(QMouseEvent *e);
+    void mouseMoveEvent(QMouseEvent *e);
+    void mouseReleaseEvent(QMouseEvent *e);
+    void mouseDoubleClickEvent(QMouseEvent *e);
+    void keyPressEvent(QKeyEvent *e);
+    void keyReleaseEvent(QKeyEvent *e);
+    void changeEvent(QEvent *);
+
+private slots:
+    void minimize();
+
+private:
+    Q3DockWindow *dockWindow;
+    QPoint offset;
+    QToolButton *closeButton;
+    QTimer *timer;
+    uint opaque                : 1;
+    uint mousePressed        : 1;
+    uint hadDblClick        : 1;
+    uint ctrlDown : 1;
+    QPointer<QWidget> oldFocus;
+};
+
+class Q3DockWindowTitleBar : public Q3TitleBar
+{
+    Q_OBJECT
+    friend class Q3DockWindow;
+    friend class Q3DockWindowHandle;
+
+public:
+    Q3DockWindowTitleBar(Q3DockWindow *dw);
+    void updateGui();
+    void setOpaqueMoving(bool b) { opaque = b; }
+
+protected:
+    void resizeEvent(QResizeEvent *e);
+    void mousePressEvent(QMouseEvent *e);
+    void mouseMoveEvent(QMouseEvent *e);
+    void mouseReleaseEvent(QMouseEvent *e);
+    void mouseDoubleClickEvent(QMouseEvent *e);
+    void keyPressEvent(QKeyEvent *e);
+    void keyReleaseEvent(QKeyEvent *e);
+
+private:
+    Q3DockWindow *dockWindow;
+    QPoint offset;
+    uint mousePressed : 1;
+    uint hadDblClick : 1;
+    uint opaque : 1;
+    uint ctrlDown : 1;
+    QPointer<QWidget> oldFocus;
+
+};
+
+Q3DockWindowHandle::Q3DockWindowHandle(Q3DockWindow *dw)
+    : QWidget(dw, "qt_dockwidget_internal"), dockWindow(dw),
+      closeButton(0), opaque(default_opaque), mousePressed(false)
+{
+    ctrlDown = false;
+    timer = new QTimer(this);
+    connect(timer, SIGNAL(timeout()), this, SLOT(minimize()));
+#ifdef Q_WS_WIN
+    setCursor(Qt::SizeAllCursor);
+#endif
+}
+
+void Q3DockWindowHandle::paintEvent(QPaintEvent *e)
+{
+    if (!dockWindow->dockArea && !opaque)
+        return;
+    QPainter p(this);
+    QStyleOptionQ3DockWindow opt;
+    opt.init(this);
+    if (!dockWindow->area() || dockWindow->area()->orientation() == Qt::Horizontal)
+        opt.state |= QStyle::State_Horizontal;
+
+    opt.rect = rect();
+    opt.docked = dockWindow->area();
+    opt.closeEnabled = dockWindow->isCloseEnabled();
+    opt.rect = QStyle::visualRect(opt.direction, opt.rect,
+                                  style()->subElementRect(QStyle::SE_Q3DockWindowHandleRect, &opt, this));
+    style()->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p, this);
+    QWidget::paintEvent(e);
+}
+
+void Q3DockWindowHandle::keyPressEvent(QKeyEvent *e)
+{
+    if (!mousePressed)
+        return;
+    if (e->key() == Qt::Key_Control) {
+        ctrlDown = true;
+        dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
+    }
+}
+
+void Q3DockWindowHandle::keyReleaseEvent(QKeyEvent *e)
+{
+    if (!mousePressed)
+        return;
+    if (e->key() == Qt::Key_Control) {
+        ctrlDown = false;
+        dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
+    }
+}
+
+void Q3DockWindowHandle::mousePressEvent(QMouseEvent *e)
+{
+    if (!dockWindow->dockArea)
+        return;
+    ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
+    oldFocus = qApp->focusWidget();
+    setFocus();
+    e->ignore();
+    if (e->button() != Qt::LeftButton)
+        return;
+    e->accept();
+    hadDblClick = false;
+    mousePressed = true;
+    offset = e->pos();
+    dockWindow->startRectDraw(mapToGlobal(e->pos()), !opaque);
+    if (!opaque)
+        qApp->installEventFilter(dockWindow);
+}
+
+void Q3DockWindowHandle::mouseMoveEvent(QMouseEvent *e)
+{
+    if (!mousePressed || e->pos() == offset)
+        return;
+    ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
+    dockWindow->handleMove(e->pos() - offset, e->globalPos(), !opaque);
+    if (opaque)
+        dockWindow->updatePosition(e->globalPos());
+}
+
+void Q3DockWindowHandle::mouseReleaseEvent(QMouseEvent *e)
+{
+    ctrlDown = false;
+    qApp->removeEventFilter(dockWindow);
+    if (oldFocus)
+        oldFocus->setFocus();
+    if (!mousePressed)
+        return;
+    dockWindow->endRectDraw(!opaque);
+    mousePressed = false;
+#ifdef Q_WS_MAC
+    releaseMouse();
+#endif
+    if (!hadDblClick && offset == e->pos()) {
+        timer->start(QApplication::doubleClickInterval(), true);
+    } else if (!hadDblClick) {
+        dockWindow->updatePosition(e->globalPos());
+    }
+    if (opaque)
+        dockWindow->titleBar->mousePressed = false;
+    if (dockWindow->parentWidget())
+        QApplication::postEvent(dockWindow->parentWidget(), new QEvent(QEvent::LayoutHint));
+}
+
+void Q3DockWindowHandle::minimize()
+{
+    if (!dockWindow->area())
+        return;
+
+    Q3MainWindow *mw = qobject_cast<Q3MainWindow*>(dockWindow->area()->parentWidget());
+    if (mw && mw->isDockEnabled(dockWindow, Qt::DockMinimized))
+        mw->moveDockWindow(dockWindow, Qt::DockMinimized);
+}
+
+void Q3DockWindowHandle::resizeEvent(QResizeEvent *)
+{
+    updateGui();
+}
+
+void Q3DockWindowHandle::updateGui()
+{
+    updateGeometry();
+
+    if (!closeButton) {
+        closeButton = new QToolButton(this, "qt_close_button1");
+#ifndef QT_NO_CURSOR
+        closeButton->setCursor(Qt::ArrowCursor);
+#endif
+        QStyleOption opt(0);
+        opt.init(closeButton);
+        closeButton->setIcon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton, &opt,
+                                                    closeButton));
+        closeButton->setFixedSize(12, 12);
+        connect(closeButton, SIGNAL(clicked()),
+                 dockWindow, SLOT(hide()));
+    }
+
+    if (dockWindow->isCloseEnabled() && dockWindow->area())
+        closeButton->show();
+    else
+        closeButton->hide();
+
+    if (!dockWindow->area())
+        return;
+
+    if (dockWindow->area()->orientation() == Qt::Horizontal) {
+        int off = (width() - closeButton->width() - 1) / 2;
+        closeButton->move(off, 2);
+    } else {
+        int off = (height() - closeButton->height() - 1) / 2;
+        int x = QApplication::reverseLayout() ? 2 : width() - closeButton->width() - 2;
+        closeButton->move(x, off);
+    }
+}
+
+void Q3DockWindowHandle::changeEvent(QEvent *ev)
+{
+    if(ev->type() == QEvent::StyleChange) {
+        if (closeButton) {
+            QStyleOption opt(0);
+            opt.init(closeButton);
+            closeButton->setIcon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton,
+                                                        &opt, closeButton));
+        }
+    }
+    QWidget::changeEvent(ev);
+}
+
+QSize Q3DockWindowHandle::minimumSizeHint() const
+{
+    if (!dockWindow->dockArea)
+        return QSize(0, 0);
+    int wh = dockWindow->isCloseEnabled() ? 17 : style()->pixelMetric(QStyle::PM_ToolBarHandleExtent, 0, this);
+    if (dockWindow->orientation() == Qt::Horizontal)
+        return QSize(wh, 0);
+    return QSize(0, wh);
+}
+
+void Q3DockWindowHandle::mouseDoubleClickEvent(QMouseEvent *e)
+{
+    e->ignore();
+    if (e->button() != Qt::LeftButton)
+        return;
+    e->accept();
+    timer->stop();
+    emit doubleClicked();
+    hadDblClick = true;
+    if (dockWindow->parentWidget())
+        QApplication::postEvent(dockWindow->parentWidget(), new QEvent(QEvent::LayoutHint));
+}
+
+Q3DockWindowTitleBar::Q3DockWindowTitleBar(Q3DockWindow *dw)
+    : Q3TitleBar(0, dw), dockWindow(dw),
+      mousePressed(false), hadDblClick(false), opaque(default_opaque)
+{
+    setObjectName(QLatin1String("qt_dockwidget_internal"));
+    ctrlDown = false;
+    setMouseTracking(true);
+    QStyleOptionTitleBar opt = getStyleOption();
+    setFixedHeight(style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, this));
+    connect(this, SIGNAL(doClose()), dockWindow, SLOT(hide()));
+}
+
+void Q3DockWindowTitleBar::keyPressEvent(QKeyEvent *e)
+{
+    if (!mousePressed)
+        return;
+    if (e->key() == Qt::Key_Control) {
+        ctrlDown = true;
+        dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
+    }
+}
+
+void Q3DockWindowTitleBar::keyReleaseEvent(QKeyEvent *e)
+{
+    if (!mousePressed)
+        return;
+    if (e->key() == Qt::Key_Control) {
+        ctrlDown = false;
+        dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
+    }
+}
+
+void Q3DockWindowTitleBar::mousePressEvent(QMouseEvent *e)
+{
+    QStyleOptionTitleBar opt;
+    opt.init(this);
+    opt.subControls = QStyle::SC_All;
+    opt.activeSubControls = QStyle::SC_None;
+    opt.text = windowTitle();
+    //################
+    QIcon icon = windowIcon();
+    QSize s = icon.actualSize(QSize(64, 64));
+    opt.icon = icon.pixmap(s);
+    opt.titleBarState = window() ? window()->windowState() : static_cast<Qt::WindowStates>(Qt::WindowNoState);
+    opt.titleBarFlags = fakeWindowFlags();
+    QStyle::SubControl tbctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
+                                                               e->pos(), this);
+
+    if (tbctrl < QStyle::SC_TitleBarLabel && tbctrl != QStyle::SC_None) {
+        Q3TitleBar::mousePressEvent(e);
+        return;
+    }
+
+    ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
+    oldFocus = qApp->focusWidget();
+// setFocus activates the window, which deactivates the main window
+// not what we want, and not required anyway on Windows
+#ifndef Q_WS_WIN
+    setFocus();
+#endif
+
+    e->ignore();
+    if (e->button() != Qt::LeftButton)
+        return;
+    if (e->y() < 3 && dockWindow->isResizeEnabled())
+        return;
+
+    e->accept();
+    bool oldPressed = mousePressed;
+    mousePressed = true;
+    hadDblClick = false;
+    offset = e->pos();
+    dockWindow->startRectDraw(mapToGlobal(e->pos()), !opaque);
+// grabMouse resets the Windows mouse press count, so we never receive a double click on Windows
+// not required on Windows, and did work on X11, too, but no problem there in the first place
+#ifndef Q_WS_WIN
+    if(!oldPressed && dockWindow->opaqueMoving())
+        grabMouse();
+#else
+    Q_UNUSED(oldPressed);
+#endif
+}
+
+void Q3DockWindowTitleBar::mouseMoveEvent(QMouseEvent *e)
+{
+    if (!mousePressed) {
+        Q3TitleBar::mouseMoveEvent(e);
+        return;
+    }
+
+    ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
+    e->accept();
+    dockWindow->handleMove(e->pos() - offset, e->globalPos(), !opaque);
+}
+
+void Q3DockWindowTitleBar::mouseReleaseEvent(QMouseEvent *e)
+{
+    if (!mousePressed) {
+        Q3TitleBar::mouseReleaseEvent(e);
+        return;
+    }
+
+    ctrlDown = false;
+    qApp->removeEventFilter(dockWindow);
+    if (oldFocus)
+        oldFocus->setFocus();
+
+    if (dockWindow->place() == Q3DockWindow::OutsideDock)
+        dockWindow->raise();
+
+    if(dockWindow->opaqueMoving())
+        releaseMouse();
+    if (!mousePressed)
+        return;
+    dockWindow->endRectDraw(!opaque);
+    mousePressed = false;
+    if (!hadDblClick)
+        dockWindow->updatePosition(e->globalPos());
+    if (opaque) {
+        dockWindow->horHandle->mousePressed = false;
+        dockWindow->verHandle->mousePressed = false;
+    }
+    if (dockWindow->parentWidget())
+        QApplication::postEvent(dockWindow->parentWidget(), new QEvent(QEvent::LayoutHint));
+}
+
+void Q3DockWindowTitleBar::resizeEvent(QResizeEvent *e)
+{
+    updateGui();
+    Q3TitleBar::resizeEvent(e);
+}
+
+void Q3DockWindowTitleBar::updateGui()
+{
+    if (dockWindow->isCloseEnabled()) {
+        setFakeWindowFlags(fakeWindowFlags() | Qt::WStyle_SysMenu);
+    } else {
+        setFakeWindowFlags(fakeWindowFlags() & ~Qt::WStyle_SysMenu);
+    }
+}
+
+void Q3DockWindowTitleBar::mouseDoubleClickEvent(QMouseEvent *)
+{
+    emit doubleClicked();
+    hadDblClick = true;
+    if (dockWindow->parentWidget())
+        QApplication::postEvent(dockWindow->parentWidget(), new QEvent(QEvent::LayoutHint));
+}
+
+/*!
+    \class Q3DockWindow
+    \brief The Q3DockWindow class provides a widget which can be docked
+    inside a Q3DockArea or floated as a top level window on the
+    desktop.
+
+    \compat
+
+    This class handles moving, resizing, docking and undocking dock
+    windows. Q3ToolBar is a subclass of Q3DockWindow so the
+    functionality provided for dock windows is available with the same
+    API for toolbars.
+
+    \img qmainwindow-qdockareas.png Q3DockWindows in a Q3DockArea
+    \caption Two Q3DockWindows (\l{Q3ToolBar}s) in a \l Q3DockArea
+
+    \img qdockwindow.png A Q3DockWindow
+    \caption A Floating Q3DockWindow
+
+    If the user drags the dock window into the dock area the dock
+    window will be docked. If the user drags the dock area outside any
+    dock areas the dock window will be undocked (floated) and will
+    become a top level window. Double clicking a floating dock
+    window's title bar will dock the dock window to the last dock area
+    it was docked in. Double clicking a docked dock window's handle
+    will undock (float) the dock window.
+    \omit
+    Single clicking a docked dock window's handle will minimize the
+    dock window (only its handle will appear, below the menu bar).
+    Single clicking the minimized handle will restore the dock window
+    to the last dock area that it was docked in.
+    \endomit
+    If the user clicks the close button (which appears on floating
+    dock windows by default) the dock window will disappear. You can
+    control whether or not a dock window has a close button with
+    setCloseMode().
+
+    Q3MainWindow provides four dock areas (top, left, right and bottom)
+    which can be used by dock windows. For many applications using the
+    dock areas provided by Q3MainWindow is sufficient. (See the \l
+    Q3DockArea documentation if you want to create your own dock
+    areas.) In Q3MainWindow a right-click popup menu (the dock window
+    menu) is available which lists dock windows and can be used to
+    show or hide them. (The popup menu only lists dock windows that
+    have a \link QWidget::setWindowTitle() caption\endlink.)
+
+    When you construct a dock window you \e must pass it a Q3DockArea
+    or a Q3MainWindow as its parent if you want it docked. Pass 0 for
+    the parent if you want it floated.
+
+    \snippet doc/src/snippets/code/src_qt3support_widgets_q3dockwindow.cpp 0
+
+    In the example above we create a new Q3ToolBar in the constructor
+    of a Q3MainWindow subclass (so that the \e this pointer points to
+    the Q3MainWindow). By default the toolbar will be added to the \c
+    Top dock area, but we've moved it to the \c Left dock area.
+
+    A dock window is often used to contain a single widget. In these
+    cases the widget can be set by calling setWidget(). If you're
+    constructing a dock window that contains multiple widgets, e.g. a
+    toolbar, arrange the widgets within a box layout inside the dock
+    window. To do this use the boxLayout() function to get a pointer
+    to the dock window's box layout, then add widgets to the layout
+    using the box layout's QBoxLayout::addWidget() function. The dock
+    window will dynamically set the orientation of the layout to be
+    vertical or horizontal as necessary, although you can control this
+    yourself with setOrientation().
+
+    Although a common use of dock windows is for toolbars, they can be
+    used with any widgets. When using larger
+    widgets it may make sense for the dock window to be resizable by
+    calling setResizeEnabled(). Resizable dock windows are given
+    splitter-like handles to allow the user to resize them within
+    their dock area. When resizable dock windows are undocked they
+    become top level windows and can be resized like any other top
+    level windows, e.g. by dragging a corner or edge.
+
+    Qt::Dock windows can be docked and undocked using dock() and undock().
+    A dock window's orientation can be set with setOrientation(). You
+    can also use Q3DockArea::moveDockWindow(). If you're using a
+    Q3MainWindow, Q3MainWindow::moveDockWindow() and
+    Q3MainWindow::removeDockWindow() are available.
+
+    A dock window can have some preferred settings, for example, you
+    can set a preferred offset from the left edge (or top edge for
+    vertical dock areas) of the dock area using setOffset(). If you'd
+    prefer a dock window to start on a new line when it is docked use
+    setNewLine(). The setFixedExtentWidth() and setFixedExtentHeight()
+    functions can be used to define the dock window's preferred size,
+    and the setHorizontallyStretchable() and setVerticallyStretchable()
+    functions set whether the dock window can be stretched or not.
+    Dock windows can be moved by default, but this can be changed with
+    setMovingEnabled(). When a dock window is moved it is shown as a
+    rectangular outline, but it can be shown normally using
+    setOpaqueMoving().
+
+    When a dock window's visibility changes, i.e. it is shown or
+    hidden, the visibilityChanged() signal is emitted. When a dock
+    window is docked, undocked or moved inside the dock area the
+    placeChanged() signal is emitted.
+*/
+
+/*!
+    \enum Q3DockWindow::Place
+
+    This enum specifies the possible locations for a Q3DockWindow:
+
+    \value InDock  Inside a Q3DockArea.
+    \value OutsideDock  Floating as a top level window on the desktop.
+*/
+
+/*!
+    \enum Q3DockWindow::CloseMode
+
+    This enum type specifies when (if ever) a dock window has a close
+    button.
+
+    \value Never  The dock window never has a close button and cannot
+    be closed by the user.
+    \value Docked  The dock window has a close button only when
+    docked.
+    \value Undocked  The dock window has a close button only when
+    floating.
+    \value Always The dock window always has a close button.
+    \omit
+    Note that dock windows can always be minimized if the user clicks
+    their dock window handle when they are docked.
+    \endomit
+*/
+
+/*!
+    \fn void Q3DockWindow::setHorizontalStretchable(bool b)
+
+    If \a b is true the dock window is set to be horizontally
+    stretchable.
+*/
+/*!
+    \fn void Q3DockWindow::setVerticalStretchable(bool b)
+
+    If \a b is true the dock window is set to be vertically
+    stretchable.
+*/
+/*!
+    \fn bool Q3DockWindow::isHorizontalStretchable() const
+
+    Returns true if the dock window can be stretched horizontally;
+    otherwise returns false.
+*/
+/*!
+    \fn bool Q3DockWindow::isVerticalStretchable() const
+
+    Returns true if the dock window can be stretched vertically;
+    otherwise returns false.
+*/
+/*!
+    \fn void Q3DockWindow::orientationChanged(Qt::Orientation o)
+
+    This signal is emitted when the orientation of the dock window is
+    changed. The new orientation is \a o.
+*/
+
+/*!
+    \fn void Q3DockWindow::placeChanged(Q3DockWindow::Place p)
+
+    This signal is emitted when the dock window is docked (\a p is \c
+    InDock), undocked (\a p is \c OutsideDock) or moved inside the
+    the dock area.
+
+    \sa Q3DockArea::moveDockWindow(), Q3DockArea::removeDockWindow(),
+    Q3MainWindow::moveDockWindow(), Q3MainWindow::removeDockWindow()
+*/
+
+/*!
+    \fn void Q3DockWindow::visibilityChanged(bool visible)
+
+    This signal is emitted when the visibility of the dock window
+    relatively to its dock area is changed. If \a visible is true, the
+    Q3DockWindow is now visible to the dock area, otherwise it has been
+    hidden.
+
+    A dock window can be hidden if it has a close button which the
+    user has clicked. In the case of a Q3MainWindow a dock window can
+    have its visibility changed (hidden or shown) by clicking its name
+    in the dock window menu that lists the Q3MainWindow's dock windows.
+*/
+
+/*!
+    \fn Q3DockArea *Q3DockWindow::area() const
+
+    Returns the dock area in which this dock window is docked, or 0 if
+    the dock window is floating.
+*/
+
+/*!
+    \property Q3DockWindow::place
+    \brief the location where the dock window is placed
+
+    This is either \c InDock or \c OutsideDock.
+
+    \sa Q3DockArea::moveDockWindow(), Q3DockArea::removeDockWindow(),
+        Q3MainWindow::moveDockWindow(), Q3MainWindow::removeDockWindow()
+*/
+
+/*!
+    Constructs a Q3DockWindow with parent \a parent, called \a name and
+    with widget flags \a f.
+*/
+
+Q3DockWindow::Q3DockWindow(QWidget* parent, const char* name, Qt::WindowFlags f)
+    : Q3Frame(parent, name, f | Qt::WType_Dialog | Qt::WStyle_Customize | Qt::WStyle_NoBorder)
+{
+    curPlace = InDock;
+    isToolbar = false;
+    init();
+}
+
+/*!
+    Constructs a Q3DockWindow with parent \a parent, called \a name and
+    with widget flags \a f.
+
+    If \a p is \c InDock, the dock window is docked into a dock area
+    and \a parent \e must be a Q3DockArea or a Q3MainWindow. If the \a
+    parent is a Q3MainWindow the dock window will be docked in the main
+    window's \c Top dock area.
+
+    If \a p is \c OutsideDock, the dock window is created as a floating
+    window.
+
+    We recommend creating the dock area \c InDock with a Q3MainWindow
+    as parent then calling Q3MainWindow::moveDockWindow() to move the
+    dock window where you want it.
+*/
+
+Q3DockWindow::Q3DockWindow(Place p, QWidget *parent, const char *name, Qt::WindowFlags f)
+    : Q3Frame(parent, name, f | Qt::WType_Dialog | Qt::WStyle_Customize | Qt::WStyle_NoBorder)
+{
+    curPlace = p;
+    isToolbar = false;
+    init();
+}
+
+/*! \internal
+*/
+
+Q3DockWindow::Q3DockWindow(Place p, QWidget *parent, const char *name, Qt::WindowFlags f, bool toolbar)
+    : Q3Frame(parent, name, f | Qt::WType_Dialog | Qt::WStyle_Customize | Qt::WStyle_NoBorder)
+{
+    curPlace = p;
+    isToolbar = toolbar;
+    init();
+}
+
+class Q3DockWindowGridLayout : public QGridLayout
+{
+public:
+    Q3DockWindowGridLayout(QWidget *parent, int nRows, int nCols)
+        : QGridLayout(parent, nRows, nCols) {};
+
+    Qt::Orientations expandingDirections() const
+    {
+        return 0;
+    }
+};
+
+void Q3DockWindow::init()
+{
+    wid = 0;
+    rubberBand = 0;
+    dockArea = 0;
+    tmpDockArea = 0;
+    resizeEnabled = false;
+    moveEnabled = true;
+    nl = false;
+    opaque = default_opaque;
+    cMode = Never;
+    offs = 0;
+    fExtent = QSize(-1, -1);
+    dockWindowData = 0;
+    lastPos = QPoint(-1, -1);
+    lastSize = QSize(-1, -1);
+    stretchable[Qt::Horizontal] = false;
+    stretchable[Qt::Vertical] = false;
+
+    widgetResizeHandler = new QWidgetResizeHandler(this);
+    widgetResizeHandler->setMovingEnabled(false);
+
+    titleBar      = new Q3DockWindowTitleBar(this);
+    verHandle     = new Q3DockWindowHandle(this);
+    verHandle->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
+    horHandle     = new Q3DockWindowHandle(this);
+    horHandle->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+
+    vHandleLeft   = new Q3DockWindowResizeHandle(Qt::Vertical, this, this, "vert. handle");
+    vHandleRight  = new Q3DockWindowResizeHandle(Qt::Vertical, this, this, "vert. handle");
+    hHandleTop    = new Q3DockWindowResizeHandle(Qt::Horizontal, this, this, "horz. handle");
+    hHandleBottom = new Q3DockWindowResizeHandle(Qt::Horizontal, this, this, "horz. handle");
+
+    // Creating inner layout
+    hbox          = new QVBoxLayout();
+    vbox          = new QHBoxLayout();
+    childBox          = new QBoxLayout(QBoxLayout::LeftToRight);
+    vbox->addSpacing(2);
+    vbox->addWidget(verHandle);
+    vbox->addStretch(0);
+    vbox->addLayout(childBox, 1);
+    vbox->addStretch(0);
+
+    hbox->setResizeMode(QLayout::FreeResize);
+    hbox->setMargin(isResizeEnabled() || curPlace == OutsideDock ? 2 : 0);
+    hbox->setSpacing(1);
+    hbox->addWidget(titleBar);
+    hbox->addWidget(horHandle);
+    hbox->addLayout(vbox);
+
+    // Set up the initial handle layout for Qt::Vertical
+    // Handle layout will change on calls to setOrienation()
+    QGridLayout *glayout = new Q3DockWindowGridLayout(this, 3, 3);
+    glayout->setResizeMode(QLayout::Minimum);
+    glayout->addMultiCellWidget(hHandleTop,    0, 0, 1, 1);
+    glayout->addMultiCellWidget(hHandleBottom, 2, 2, 1, 1);
+    glayout->addMultiCellWidget(vHandleLeft,   0, 2, 0, 0);
+    glayout->addMultiCellWidget(vHandleRight,  0, 2, 2, 2);
+    glayout->addLayout(hbox, 1, 1);
+    glayout->setRowStretch(1, 1);
+    glayout->setColStretch(1, 1);
+
+    hHandleBottom->hide();
+    vHandleRight->hide();
+    hHandleTop->hide();
+    vHandleLeft->hide();
+    setFrameStyle(Q3Frame::StyledPanel | Q3Frame::Raised);
+    setLineWidth(2);
+
+    if (parentWidget())
+        parentWidget()->installEventFilter(this);
+    QWidget *mw = parentWidget();
+    Q3DockArea *da = qobject_cast<Q3DockArea*>(parentWidget());
+    if (da) {
+        if (curPlace == InDock)
+            da->moveDockWindow(this);
+        mw = da->parentWidget();
+    }
+    if (qobject_cast<Q3MainWindow*>(mw)) {
+        if (place() == InDock) {
+            Qt::Dock myDock = Qt::DockTop;
+            // make sure we put the window in the correct dock.
+            if (dockArea) {
+                Q3MainWindow *mainw = (Q3MainWindow*)mw;
+                // I'm not checking if it matches the top because I've
+                // done the assignment to it above.
+                if (dockArea == mainw->leftDock())
+                    myDock = Qt::DockLeft;
+                else if (dockArea == mainw->rightDock())
+                    myDock = Qt::DockRight;
+                else if (dockArea == mainw->bottomDock())
+                    myDock = Qt::DockBottom;
+            }
+            ((Q3MainWindow*)mw)->addDockWindow(this, myDock);
+        }
+        moveEnabled = ((Q3MainWindow*)mw)->dockWindowsMovable();
+        opaque = ((Q3MainWindow*)mw)->opaqueMoving();
+    }
+
+    updateGui();
+
+    connect(titleBar, SIGNAL(doubleClicked()), this, SLOT(dock()));
+    connect(verHandle, SIGNAL(doubleClicked()), this, SLOT(undock()));
+    connect(horHandle, SIGNAL(doubleClicked()), this, SLOT(undock()));
+    connect(this, SIGNAL(orientationChanged(Qt::Orientation)),
+             this, SLOT(setOrientation(Qt::Orientation)));
+}
+
+/*!
+    Sets the orientation of the dock window to \a o. The orientation
+    is propagated to the layout boxLayout().
+
+    \warning All undocked Q3ToolBars will always have a horizontal orientation.
+*/
+
+void Q3DockWindow::setOrientation(Qt::Orientation o)
+{
+    QGridLayout *glayout = (QGridLayout*)layout();
+    glayout->removeWidget(hHandleTop);
+    glayout->removeWidget(hHandleBottom);
+    glayout->removeWidget(vHandleLeft);
+    glayout->removeWidget(vHandleRight);
+
+    if (o == Qt::Horizontal) {
+        // Set up the new layout as
+        //   3 3 3      1 = vHandleLeft   4 = hHandleBottom
+        //   1 X 2      2 = vHandleRight  X = Inner Layout
+        //   4 4 4      3 = hHandleTop
+        glayout->addMultiCellWidget(hHandleTop,    0, 0, 0, 2);
+        glayout->addMultiCellWidget(hHandleBottom, 2, 2, 0, 2);
+        glayout->addMultiCellWidget(vHandleLeft,   1, 1, 0, 0);
+        glayout->addMultiCellWidget(vHandleRight,  1, 1, 2, 2);
+    } else {
+        // Set up the new layout as
+        //   1 3 2      1 = vHandleLeft   4 = hHandleBottom
+        //   1 X 2      2 = vHandleRight  X = Inner Layout
+        //   1 4 2      3 = hHandleTop
+        glayout->addMultiCellWidget(hHandleTop,    0, 0, 1, 1);
+        glayout->addMultiCellWidget(hHandleBottom, 2, 2, 1, 1);
+        glayout->addMultiCellWidget(vHandleLeft,   0, 2, 0, 0);
+        glayout->addMultiCellWidget(vHandleRight,  0, 2, 2, 2);
+    }
+    boxLayout()->setDirection(o == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom);
+    QApplication::sendPostedEvents(this, QEvent::LayoutHint);
+    QEvent *e = new QEvent(QEvent::LayoutHint);
+    QApplication::postEvent(this, e);
+}
+
+/*!
+    Destroys the dock window and its child widgets.
+*/
+
+Q3DockWindow::~Q3DockWindow()
+{
+    qApp->removeEventFilter(this);
+    if (area())
+        area()->removeDockWindow(this, false, false);
+    Q3DockArea *a = area();
+    if (!a && dockWindowData)
+        a = ((Q3DockArea::DockWindowData*)dockWindowData)->area;
+    Q3MainWindow *mw = a ? qobject_cast<Q3MainWindow*>(a->parentWidget()) : 0;
+    if (mw)
+        mw->removeDockWindow(this);
+
+    delete (Q3DockArea::DockWindowData*)dockWindowData;
+}
+
+/*!  \reimp
+*/
+
+void Q3DockWindow::resizeEvent(QResizeEvent *e)
+{
+    Q3Frame::resizeEvent(e);
+    updateGui();
+}
+
+
+void Q3DockWindow::swapRect(QRect &r, Qt::Orientation o, const QPoint &offset, Q3DockArea *)
+{
+    r.setSize(QSize(r.height(), r.width()));
+    bool reverse = QApplication::reverseLayout();
+    if (o == Qt::Horizontal)
+        r.moveBy(-r.width()/2, 0);
+    else
+        r.moveBy(reverse ? - r.width() : 0, -r.height() / 2 );
+    r.moveBy(offset.x(), offset.y());
+}
+
+QWidget *Q3DockWindow::areaAt(const QPoint &gp)
+{
+    QWidget *w = qApp->widgetAt(gp);
+
+    if (w && (w == this || w == titleBar) && parentWidget())
+        w = parentWidget()->childAt(parentWidget()->mapFromGlobal(gp));
+
+    while (w) {
+        if (qobject_cast<Q3DockArea*>(w)) {
+            Q3DockArea *a = (Q3DockArea*)w;
+            if (a->isDockWindowAccepted(this))
+                return w;
+        }
+        if (qobject_cast<Q3MainWindow*>(w)) {
+            Q3MainWindow *mw = (Q3MainWindow*)w;
+            Q3DockArea *a = mw->dockingArea(mw->mapFromGlobal(gp));
+            if (a && a->isDockWindowAccepted(this))
+                return a;
+        }
+        w = w->isWindow() ? 0 : (QWidget *)w->parent();
+    }
+    return 0;
+}
+
+void Q3DockWindow::handleMove(const QPoint &pos, const QPoint &gp, bool drawRect)
+{
+    if (!rubberBand)
+        return;
+
+    currRect = QRect(realWidgetPos(this), size());
+    QWidget *w = areaAt(gp);
+    if (titleBar->ctrlDown || horHandle->ctrlDown || verHandle->ctrlDown)
+        w = 0;
+    currRect.moveBy(pos.x(), pos.y());
+    if (!qobject_cast<Q3DockArea*>(w)) {
+        if (startOrientation != Qt::Horizontal && qobject_cast<Q3ToolBar*>(this))
+            swapRect(currRect, Qt::Horizontal, startOffset, (Q3DockArea*)w);
+        if (drawRect) {
+            rubberBand->setGeometry(currRect);
+        } else {
+            QPoint mp(mapToGlobal(pos));
+            if(place() == InDock) {
+                undock();
+                if(titleBar) {
+                    mp = QPoint(titleBar->width() / 2, titleBar->height() / 2);
+                    QMouseEvent me(QEvent::MouseButtonPress, mp, Qt::LeftButton, 0);
+                    QApplication::sendEvent(titleBar, &me);
+                    mp = titleBar->mapToGlobal(mp);
+                }
+            }
+            move(mp);
+        }
+        state = OutsideDock;
+        return;
+    }
+
+    Q3DockArea *area = (Q3DockArea*)w;
+    if(area->isVisible()) {
+        state = InDock;
+        Qt::Orientation o = (area ? area->orientation() :
+                          (boxLayout()->direction() == QBoxLayout::LeftToRight ||
+                            boxLayout()->direction() == QBoxLayout::RightToLeft ?
+                            Qt::Horizontal : Qt::Vertical));
+        if (startOrientation != o)
+            swapRect(currRect, o, startOffset, area);
+        if (drawRect) {
+            rubberBand->setGeometry(currRect);
+        }
+        tmpDockArea = area;
+    }
+}
+
+void Q3DockWindow::updateGui()
+{
+    if (curPlace == OutsideDock) {
+        hbox->setMargin(2);
+        horHandle->hide();
+        verHandle->hide();
+        if (moveEnabled)
+            titleBar->show();
+        else
+            titleBar->hide();
+        titleBar->updateGui();
+        hHandleTop->hide();
+        vHandleLeft->hide();
+        hHandleBottom->hide();
+        vHandleRight->hide();
+        setLineWidth(2);
+        widgetResizeHandler->setActive(isResizeEnabled());
+    } else {
+        hbox->setMargin(0);
+        titleBar->hide();
+        if (orientation() == Qt::Horizontal) {
+            horHandle->hide();
+            if (moveEnabled)
+                verHandle->show();
+            else
+                verHandle->hide();
+#ifdef Q_WS_MAC
+            if(horHandle->mousePressed) {
+                horHandle->mousePressed = false;
+                verHandle->mousePressed = true;
+                verHandle->grabMouse();
+            }
+#endif
+            verHandle->updateGui();
+        } else {
+            if (moveEnabled)
+                horHandle->show();
+            else
+                horHandle->hide();
+            horHandle->updateGui();
+#ifdef Q_WS_MAC
+            if(verHandle->mousePressed) {
+                verHandle->mousePressed = false;
+                horHandle->mousePressed = true;
+                horHandle->grabMouse();
+            }
+#endif
+            verHandle->hide();
+        }
+        if (isResizeEnabled()) {
+            if (orientation() == Qt::Horizontal) {
+                hHandleBottom->raise();
+                hHandleTop->raise();
+            } else {
+                vHandleRight->raise();
+                vHandleLeft->raise();
+            }
+
+            if (area()) {
+                if (orientation() == Qt::Horizontal) {
+                    if (area()->handlePosition() == Q3DockArea::Normal) {
+                        hHandleBottom->show();
+                        hHandleTop->hide();
+                    } else {
+                        hHandleTop->show();
+                        hHandleBottom->hide();
+                    }
+                    if (!area()->isLastDockWindow(this))
+                        vHandleRight->show();
+                    else
+                        vHandleRight->hide();
+                    vHandleLeft->hide();
+                } else {
+                    if ((area()->handlePosition() == Q3DockArea::Normal) != QApplication::reverseLayout()) {
+                        vHandleRight->show();
+                        vHandleLeft->hide();
+                    } else {
+                        vHandleLeft->show();
+                        vHandleRight->hide();
+                    }
+                    if (!area()->isLastDockWindow(this))
+                        hHandleBottom->show();
+                    else
+                        hHandleBottom->hide();
+                    hHandleTop->hide();
+                }
+            }
+        }
+#ifndef Q_OS_WINCE
+        if (moveEnabled)
+            setLineWidth(1);
+        else
+            setLineWidth(0);
+#endif
+        widgetResizeHandler->setActive(false);
+    }
+}
+
+void Q3DockWindow::updatePosition(const QPoint &globalPos)
+{
+    if (curPlace == OutsideDock && state == InDock)
+        lastSize = size();
+
+    bool doAdjustSize = curPlace != state && state == OutsideDock;
+    bool doUpdate = true;
+    bool doOrientationChange = true;
+    if (state != curPlace && state == InDock) {
+        doUpdate = false;
+        curPlace = state;
+        updateGui();
+        QApplication::sendPostedEvents();
+    }
+    Qt::Orientation oo = orientation();
+
+    if (state == InDock) {
+        if (tmpDockArea) {
+            bool differentDocks = false;
+            if (dockArea && dockArea != tmpDockArea) {
+                differentDocks = true;
+                delete (Q3DockArea::DockWindowData*)dockWindowData;
+                dockWindowData = dockArea->dockWindowData(this);
+                dockArea->removeDockWindow(this, false, false);
+            }
+            dockArea = tmpDockArea;
+            if (differentDocks) {
+                if (doUpdate) {
+                    doUpdate = false;
+                    curPlace = state;
+                    updateGui();
+                }
+                emit orientationChanged(tmpDockArea->orientation());
+                doOrientationChange = false;
+            } else {
+                updateGui();
+            }
+            dockArea->moveDockWindow(this, globalPos, currRect, startOrientation != oo);
+        }
+    } else {
+        if (dockArea) {
+            Q3MainWindow *mw = (Q3MainWindow*)dockArea->parentWidget();
+            if (qobject_cast<Q3MainWindow*>(mw) &&
+                 (!mw->isDockEnabled(Qt::DockTornOff) ||
+                   !mw->isDockEnabled(this, Qt::DockTornOff)))
+                return;
+            delete (Q3DockArea::DockWindowData*)dockWindowData;
+            dockWindowData = dockArea->dockWindowData(this);
+            dockArea->removeDockWindow(this, true,
+                startOrientation != Qt::Horizontal && qobject_cast<Q3ToolBar*>(this));
+        }
+        dockArea = 0;
+        QPoint topLeft = currRect.topLeft();
+        QRect screen = qApp->desktop()->availableGeometry(topLeft);
+        if (!screen.contains(topLeft)) {
+            topLeft.setY(qMax(topLeft.y(), screen.top()));
+            topLeft.setY(qMin(topLeft.y(), screen.bottom()-height()));
+            topLeft.setX(qMax(topLeft.x(), screen.left()));
+            topLeft.setX(qMin(topLeft.x(), screen.right()-width()));
+        }
+        move(topLeft);
+    }
+
+    if (curPlace == InDock && state == OutsideDock && !qobject_cast<Q3ToolBar*>(this)) {
+        if (lastSize != QSize(-1, -1))
+            resize(lastSize);
+    }
+
+    if (doUpdate) {
+        curPlace = state;
+        updateGui();
+    }
+    if (doOrientationChange)
+        emit orientationChanged(orientation());
+    tmpDockArea = 0;
+    if (doAdjustSize) {
+        QApplication::sendPostedEvents(this, QEvent::LayoutHint);
+        if (qobject_cast<Q3ToolBar*>(this))
+            adjustSize();
+        if (lastSize == QSize(-1, -1))
+            setAttribute(Qt::WA_Resized, false); // Ensures size is recalculated (non-opaque).
+        show();
+        if (parentWidget() && isWindow())
+            parentWidget()->setActiveWindow();
+
+    }
+
+    emit placeChanged(curPlace);
+}
+
+/*!
+    Sets the dock window's main widget to \a w.
+
+    \sa boxLayout()
+*/
+
+void Q3DockWindow::setWidget(QWidget *w)
+{
+    wid = w;
+    boxLayout()->addWidget(w);
+    updateGui();
+}
+
+/*!
+    Returns the dock window's main widget.
+
+    \sa setWidget()
+*/
+
+QWidget *Q3DockWindow::widget() const
+{
+    return wid;
+}
+
+void Q3DockWindow::startRectDraw(const QPoint &so, bool drawRect)
+{
+    state = place();
+    if (rubberBand)
+        endRectDraw(!opaque);
+    rubberBand = new QRubberBand(QRubberBand::Rectangle);
+    currRect = QRect(realWidgetPos(this), size());
+    if (drawRect) {
+        rubberBand->setGeometry(currRect);
+    }
+    startOrientation = orientation();
+    startOffset = mapFromGlobal(so);
+    rubberBand->show();
+}
+
+void Q3DockWindow::endRectDraw(bool)
+{
+    delete rubberBand;
+    rubberBand = 0;
+}
+
+/*!
+  \reimp
+*/
+void Q3DockWindow::drawFrame(QPainter *p)
+{
+    if (place() == InDock) {
+        Q3Frame::drawFrame(p);
+        return;
+    }
+
+    QStyleOptionFrame opt;
+    opt.rect = rect();
+    opt.palette = palette();
+    opt.state = QStyle::State_None;
+    if (titleBar->isActive())
+        opt.state |= QStyle::State_Active;
+    opt.lineWidth = lineWidth();
+    opt.midLineWidth = midLineWidth();
+
+    style()->drawPrimitive(QStyle::PE_FrameWindow, &opt, p, this);
+}
+
+/*!
+  \reimp
+*/
+void Q3DockWindow::drawContents(QPainter *p)
+{
+    // This is only used by the PocketPC style. We probably need to revist later.
+    QStyleOption opt(0, QStyleOption::SO_Default);
+    opt.init(this);
+    if (titleBar->isActive())
+        opt.state |= QStyle::State_Active;
+    style()->drawControl(QStyle::CE_Q3DockWindowEmptyArea, &opt, p, this);
+}
+
+/*!
+    \property Q3DockWindow::resizeEnabled
+    \brief whether the dock window is resizeable
+
+    A resizeable dock window can be resized using splitter-like
+    handles inside a dock area and like every other top level window
+    when floating.
+
+    A dock window is both horizontally and vertically stretchable if
+    you call setResizeEnabled(true).
+
+    This property is false by default.
+
+    \sa setVerticallyStretchable() setHorizontallyStretchable()
+*/
+
+void Q3DockWindow::setResizeEnabled(bool b)
+{
+    resizeEnabled = b;
+    updateGui();
+}
+
+/*!
+    \property Q3DockWindow::movingEnabled
+    \brief whether the user can move the dock window within the dock
+    area, move the dock window to another dock area, or float the dock
+    window.
+
+    This property is true by default.
+*/
+
+void Q3DockWindow::setMovingEnabled(bool b)
+{
+    moveEnabled = b;
+    updateGui();
+}
+
+bool Q3DockWindow::isResizeEnabled() const
+{
+    return resizeEnabled;
+}
+
+bool Q3DockWindow::isMovingEnabled() const
+{
+    return moveEnabled;
+}
+
+/*!
+    \property Q3DockWindow::closeMode
+    \brief the close mode of a dock window
+
+    Defines when (if ever) the dock window has a close button. The
+    choices are \c Never, \c Docked (i.e. only when docked), \c
+    Undocked (only when undocked, i.e. floated) or \c Always.
+
+    The default is \c Never.
+*/
+
+void Q3DockWindow::setCloseMode(int m)
+{
+    cMode = m;
+    if (place() == InDock) {
+        horHandle->updateGui();
+        verHandle->updateGui();
+    } else {
+        titleBar->updateGui();
+    }
+}
+
+/*!
+    Returns true if the dock window has a close button; otherwise
+    returns false. The result depends on the dock window's \l Place
+    and its \l CloseMode.
+
+    \sa setCloseMode()
+*/
+
+bool Q3DockWindow::isCloseEnabled() const
+{
+    return  (((cMode & Docked) == Docked && place() == InDock) ||
+              ((cMode & Undocked) == Undocked && place() == OutsideDock));
+}
+
+int Q3DockWindow::closeMode() const
+{
+    return cMode;
+}
+
+/*!
+    \property Q3DockWindow::horizontallyStretchable
+    \brief whether the dock window is horizontally stretchable.
+
+    A dock window is horizontally stretchable if you call
+    setHorizontallyStretchable(true) or setResizeEnabled(true).
+
+    \warning Stretchability is broken. You must call
+    setResizeEnabled(true) to get proper behavior and even then
+    Q3DockWindow does not limit stretchablilty.
+
+    \sa setResizeEnabled()
+*/
+
+void Q3DockWindow::setHorizontallyStretchable(bool b)
+{
+    stretchable[Qt::Horizontal] = b;
+}
+
+/*!
+    \property Q3DockWindow::verticallyStretchable
+    \brief whether the dock window is vertically stretchable.
+
+    A dock window is vertically stretchable if you call
+    setVerticallyStretchable(true) or setResizeEnabled(true).
+
+    \sa setResizeEnabled()
+
+    \warning Stretchability is broken. You must call
+    setResizeEnabled(true) to get proper behavior and even then
+    Q3DockWindow does not limit stretchablilty.
+*/
+
+void Q3DockWindow::setVerticallyStretchable(bool b)
+{
+    stretchable[Qt::Vertical] = b;
+}
+
+bool Q3DockWindow::isHorizontallyStretchable() const
+{
+    return isResizeEnabled() || stretchable[Qt::Horizontal];
+}
+
+bool Q3DockWindow::isVerticallyStretchable() const
+{
+    return isResizeEnabled() || stretchable[Qt::Vertical];
+}
+
+/*!
+    \property Q3DockWindow::stretchable
+    \brief whether the dock window is stretchable in the current
+    orientation()
+
+    This property can be set using setHorizontallyStretchable() and
+    setVerticallyStretchable(), or with setResizeEnabled().
+
+    \warning Stretchability is broken. You must call
+    setResizeEnabled(true) to get proper behavior and even then
+    Q3DockWindow does not limit stretchablilty.
+
+    \sa setResizeEnabled()
+*/
+
+bool Q3DockWindow::isStretchable() const
+{
+    if (orientation() == Qt::Horizontal)
+        return isHorizontallyStretchable();
+    return isVerticallyStretchable();
+}
+
+/*!
+    Returns the orientation of the dock window.
+
+    \sa orientationChanged()
+*/
+
+Qt::Orientation Q3DockWindow::orientation() const
+{
+    if (dockArea)
+        return dockArea->orientation();
+    if (qobject_cast<const Q3ToolBar*>(this))
+        return Qt::Horizontal;
+    return (((Q3DockWindow*)this)->boxLayout()->direction() == QBoxLayout::LeftToRight ||
+             ((Q3DockWindow*)this)->boxLayout()->direction() == QBoxLayout::RightToLeft ?
+             Qt::Horizontal : Qt::Vertical);
+}
+
+int Q3DockWindow::offset() const
+{
+    return offs;
+}
+
+/*!
+    \property Q3DockWindow::offset
+    \brief the dock window's preferred offset from the dock area's
+    left edge (top edge for vertical dock areas)
+
+    The default is 0.
+*/
+
+void Q3DockWindow::setOffset(int o)
+{
+    offs = o;
+}
+
+/*!
+    Returns the dock window's preferred size (fixed extent).
+
+    \sa setFixedExtentWidth() setFixedExtentHeight()
+*/
+
+QSize Q3DockWindow::fixedExtent() const
+{
+    return fExtent;
+}
+
+/*!
+    Sets the dock window's preferred width for its fixed extent (size)
+    to \a w.
+
+    \sa setFixedExtentHeight()
+*/
+
+void Q3DockWindow::setFixedExtentWidth(int w)
+{
+    fExtent.setWidth(w);
+}
+
+/*!
+    Sets the dock window's preferred height for its fixed extent
+    (size) to \a h.
+
+    \sa setFixedExtentWidth()
+*/
+
+void Q3DockWindow::setFixedExtentHeight(int h)
+{
+    fExtent.setHeight(h);
+}
+
+/*!
+    \property Q3DockWindow::newLine
+    \brief whether the dock window prefers to start a new line in the
+    dock area.
+
+    The default is false, i.e. the dock window doesn't require a new
+    line in the dock area.
+*/
+
+void Q3DockWindow::setNewLine(bool b)
+{
+    nl = b;
+}
+
+bool Q3DockWindow::newLine() const
+{
+    return nl;
+}
+
+/*!
+    Returns the layout which is used for adding widgets to the dock
+    window. The layout's orientation is set automatically to match the
+    orientation of the dock window. You can add widgets to the layout
+    using the box layout's QBoxLayout::addWidget() function.
+
+    If the dock window only needs to contain a single widget use
+    setWidget() instead.
+
+    \sa setWidget() setOrientation()
+*/
+
+QBoxLayout *Q3DockWindow::boxLayout()
+{
+    return childBox;
+}
+
+/*! \reimp
+ */
+
+QSize Q3DockWindow::sizeHint() const
+{
+    QSize sh(Q3Frame::sizeHint());
+    if (place() == InDock)
+        sh = sh.expandedTo(fixedExtent());
+    sh = sh.expandedTo(QSize(16, 16));
+    if (area()) {
+        if (area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible())
+            sh.setWidth(sh.width() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
+        else if (area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible())
+            sh.setHeight(sh.height() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
+    }
+    return sh;
+}
+
+/*! \internal
+ */
+
+QSize Q3DockWindow::minimumSize() const
+{
+    QSize ms(Q3Frame::minimumSize());
+    if (place() == InDock)
+        ms = ms.expandedTo(fixedExtent());
+    ms = ms.expandedTo(QSize(16, 16));
+    if (area()) {
+        if (area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible())
+            ms.setWidth(ms.width() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
+        else if (area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible())
+            ms.setHeight(ms.height() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
+    }
+    return ms;
+}
+
+/*! \reimp
+ */
+
+QSize Q3DockWindow::minimumSizeHint() const
+{
+    QSize msh(Q3Frame::minimumSize());
+    if (place() == InDock)
+        msh = msh.expandedTo(fixedExtent());
+    msh = msh.expandedTo(QSize(16, 16));
+    if (area()) {
+        if (area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible())
+            msh.setWidth(msh.width() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
+        else if (area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible())
+            msh.setHeight(msh.height() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
+    }
+    return msh;
+}
+
+/*!
+    \fn void Q3DockWindow::undock()
+
+    Undocks the Q3DockWindow from its current dock area if it is
+    docked; otherwise does nothing.
+
+    \sa dock() Q3DockArea::moveDockWindow(),
+    Q3DockArea::removeDockWindow(), Q3MainWindow::moveDockWindow(),
+    Q3MainWindow::removeDockWindow()
+*/
+
+/*!
+    \fn void Q3DockWindow::undock(QWidget *widget)
+
+    Undocks the specified \a widget from its current dock area if it is
+    docked; otherwise does nothing.
+
+    \sa dock() Q3DockArea::moveDockWindow(),
+    Q3DockArea::removeDockWindow(), Q3MainWindow::moveDockWindow(),
+    Q3MainWindow::removeDockWindow()
+*/
+void Q3DockWindow::undock(QWidget *w)
+{
+    Q3MainWindow *mw = 0;
+    if (area())
+        mw = qobject_cast<Q3MainWindow*>(area()->parentWidget());
+    if (mw && !mw->isDockEnabled(this, Qt::DockTornOff))
+        return;
+    if ((place() == OutsideDock && !w))
+        return;
+
+    QPoint p(50, 50);
+    if (window())
+        p = window()->pos() + QPoint(20, 20);
+    if (dockArea) {
+        delete (Q3DockArea::DockWindowData*)dockWindowData;
+        dockWindowData = dockArea->dockWindowData(this);
+        dockArea->removeDockWindow(this, true, orientation() != Qt::Horizontal && qobject_cast<Q3ToolBar*>(this));
+    }
+    dockArea = 0;
+    if (lastPos != QPoint(-1, -1) && lastPos.x() > 0 && lastPos.y() > 0)
+        move(lastPos);
+    else
+        move(p);
+    if (lastSize != QSize(-1, -1))
+        resize(lastSize);
+    curPlace = OutsideDock;
+    updateGui();
+    emit orientationChanged(orientation());
+    QApplication::sendPostedEvents(this, QEvent::LayoutHint);
+    if (qobject_cast<Q3ToolBar*>(this))
+        adjustSize();
+    if (!w) {
+        if (!parentWidget() || parentWidget()->isVisible()) {
+            if (lastSize == QSize(-1, -1))
+                setAttribute(Qt::WA_Resized, false);// Ensures size is recalculated (opaque).
+            show();
+        }
+    } else {
+        setParent(w, 0);
+        move(-width() - 5, -height() - 5);
+        resize(1, 1);
+        show();
+    }
+    if (parentWidget() && isWindow())
+        parentWidget()->setActiveWindow();
+    emit placeChanged(place());
+}
+
+void Q3DockWindow::removeFromDock(bool fixNewLines)
+{
+    if (dockArea)
+        dockArea->removeDockWindow(this, false, false, fixNewLines);
+}
+
+/*!
+    Docks the dock window into the last dock area in which it was
+    docked.
+
+    If the dock window has no last dock area (e.g. it was created as a
+    floating window and has never been docked), or if the last dock
+    area it was docked in does not exist (e.g. the dock area has been
+    deleted), nothing happens.
+
+    The dock window will dock with the dock area regardless of the return value
+    of Q3DockArea::isDockWindowAccepted().
+
+    \sa undock() Q3DockArea::moveDockWindow(),
+    Q3DockArea::removeDockWindow(), Q3MainWindow::moveDockWindow(),
+    Q3MainWindow::removeDockWindow(), Q3DockArea::isDockWindowAccepted()
+
+*/
+
+void Q3DockWindow::dock()
+{
+    if (!(Q3DockArea::DockWindowData*)dockWindowData ||
+         !((Q3DockArea::DockWindowData*)dockWindowData)->area)
+        return;
+    curPlace = InDock;
+    lastPos = pos();
+    lastSize = size();
+    ((Q3DockArea::DockWindowData*)dockWindowData)->
+        area->dockWindow(this, (Q3DockArea::DockWindowData*)dockWindowData);
+    emit orientationChanged(orientation());
+    emit placeChanged(place());
+}
+
+/*! \reimp
+ */
+
+void Q3DockWindow::hideEvent(QHideEvent *e)
+{
+    Q3Frame::hideEvent(e);
+}
+
+/*! \reimp
+ */
+
+void Q3DockWindow::showEvent(QShowEvent *e)
+{
+    if (curPlace == OutsideDock && (parent() && parent()->objectName() == QLatin1String("qt_hide_dock"))) {
+        QRect sr = qApp->desktop()->availableGeometry(this);
+        if (!sr.contains(pos())) {
+            int nx = qMin(qMax(x(), sr.x()), sr.right()-width());
+            int ny = qMin(qMax(y(), sr.y()), sr.bottom()-height());
+            move(nx, ny);
+        }
+    }
+
+    Q3Frame::showEvent(e);
+}
+
+/*!
+    \property Q3DockWindow::opaqueMoving
+    \brief whether the dock window will be shown normally whilst it is
+    being moved.
+
+    If this property is false, (the default), the dock window will be
+    represented by an outline rectangle whilst it is being moved.
+
+    \warning Currently opaque moving has some problems and we do not
+    recommend using it at this time. We expect to fix these problems
+    in a future release.
+*/
+
+void Q3DockWindow::setOpaqueMoving(bool b)
+{
+    opaque = b;
+    horHandle->setOpaqueMoving(b);
+    verHandle->setOpaqueMoving(b);
+    titleBar->setOpaqueMoving(b);
+}
+
+bool Q3DockWindow::opaqueMoving() const
+{
+    return opaque;
+}
+
+void Q3DockWindow::updateSplitterVisibility(bool visible)
+{
+    if (area() && isResizeEnabled()) {
+        if (orientation() == Qt::Horizontal) {
+            if (visible)
+                vHandleRight->show();
+            else
+                vHandleRight->hide();
+            vHandleLeft->hide();
+        } else {
+            if (visible)
+                hHandleBottom->show();
+            else
+                hHandleBottom->hide();
+            hHandleTop->hide();
+        }
+    }
+}
+
+/*! \reimp */
+bool Q3DockWindow::eventFilter(QObject * o, QEvent *e)
+{
+    if (!o->isWidgetType())
+        return false;
+
+    if (e->type() == QEvent::KeyPress &&
+        (horHandle->mousePressed ||
+          verHandle->mousePressed ||
+          titleBar->mousePressed)) {
+        QKeyEvent *ke = (QKeyEvent*)e;
+        if (ke->key() == Qt::Key_Escape) {
+            horHandle->mousePressed =
+                verHandle->mousePressed =
+                    titleBar->mousePressed = false;
+            endRectDraw(!opaque);
+            qApp->removeEventFilter(this);
+            return true;
+        }
+    } else if (((QWidget*)o)->window() != this && place() == OutsideDock && isWindow()) {
+        if ((e->type() == QEvent::WindowDeactivate ||
+            e->type() == QEvent::WindowActivate))
+            event(e);
+    }
+    return false;
+}
+
+/*! \reimp */
+bool Q3DockWindow::event(QEvent *e)
+{
+    switch (e->type()) {
+    case QEvent::WindowDeactivate:
+        if (place() == OutsideDock && isWindow() && parentWidget()
+             && parentWidget()->isActiveWindow())
+            return true;
+        break;
+    case QEvent::HideToParent:
+        emit visibilityChanged(false);
+        break;
+    case QEvent::ShowToParent:
+        emit visibilityChanged(true);
+        break;
+    case QEvent::WindowTitleChange:
+    {
+        QString s = Q3Frame::windowTitle();
+        titleBar->setWindowTitle(s);
+#ifndef QT_NO_TOOLTIP
+        horHandle->setToolTip(s);
+        verHandle->setToolTip(s);
+#endif
+        break;
+    }
+    default:
+        break;
+    }
+    return Q3Frame::event(e);
+}
+
+/*!
+    Returns the dock window's title.
+*/
+QString Q3DockWindow::windowTitle() const
+{
+    return titleBar->windowTitle();
+}
+
+/*! \reimp */
+void Q3DockWindow::contextMenuEvent(QContextMenuEvent *e)
+{
+    QObject *o = this;
+    while (o) {
+        if (qobject_cast<Q3MainWindow*>(o))
+            break;
+        o = o->parent();
+    }
+    if (!o || ! ((Q3MainWindow*)o)->showDockMenu(e->globalPos()))
+        e->ignore();
+}
+
+QT_END_NAMESPACE
+
+#include "q3dockwindow.moc"
+
+#endif //QT_NO_MAINWINDOW