--- /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