1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the Qt 3 compatibility classes of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "q3dockwindow.h"
31
#ifndef QT_NO_MAINWINDOW
32
#include "qapplication.h"
34
#include "qdesktopwidget.h"
35
#include "q3dockarea.h"
38
#include "q3mainwindow.h"
42
#include "qstyleoption.h"
44
#include "q3toolbar.h"
45
#include "qtoolbutton.h"
47
#include <private/q3titlebar_p.h>
48
#include <private/qwidgetresizehandler_p.h>
49
#include <qrubberband.h>
52
static bool default_opaque = true;
54
static bool default_opaque = false;
57
class Q3DockWindowPrivate
61
class Q3DockWindowResizeHandle : public QWidget
66
Q3DockWindowResizeHandle(Qt::Orientation o, QWidget *parent, Q3DockWindow *w, const char* /*name*/=0);
67
void setOrientation(Qt::Orientation o);
68
Qt::Orientation orientation() const { return orient; }
70
QSize sizeHint() const;
73
void paintEvent(QPaintEvent *);
74
void mouseMoveEvent(QMouseEvent *);
75
void mousePressEvent(QMouseEvent *);
76
void mouseReleaseEvent(QMouseEvent *);
81
void drawLine(const QPoint &globalPos);
84
Qt::Orientation orient;
86
QRubberBand *rubberBand;
87
QPoint lastPos, firstPos;
88
Q3DockWindow *dockWindow;
92
Q3DockWindowResizeHandle::Q3DockWindowResizeHandle(Qt::Orientation o, QWidget *parent,
93
Q3DockWindow *w, const char *)
94
: QWidget(parent, "qt_dockwidget_internal"), mousePressed(false), rubberBand(0), dockWindow(w)
99
QSize Q3DockWindowResizeHandle::sizeHint() const
101
QStyleOptionQ3DockWindow opt;
103
if (!dockWindow->area() || dockWindow->area()->orientation() == Qt::Horizontal)
104
opt.state |= QStyle::State_Horizontal;
107
opt.docked = dockWindow->area();
108
opt.closeEnabled = dockWindow->isCloseEnabled();
109
int sw = 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, &opt, this) / 3;
110
return (style()->sizeFromContents(QStyle::CT_Q3DockWindow, &opt, QSize(sw, sw), this).expandedTo(QApplication::globalStrut()));
113
void Q3DockWindowResizeHandle::setOrientation(Qt::Orientation o)
116
if (o == Qt::Horizontal) {
118
setCursor(Qt::splitVCursor);
120
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
123
setCursor(Qt::splitHCursor);
125
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding));
129
void Q3DockWindowResizeHandle::mousePressEvent(QMouseEvent *e)
132
if (e->button() != Qt::LeftButton)
136
if (!dockWindow->opaqueMoving())
138
lastPos = firstPos = e->globalPos();
139
if (!dockWindow->opaqueMoving())
140
drawLine(e->globalPos());
143
void Q3DockWindowResizeHandle::mouseMoveEvent(QMouseEvent *e)
147
if (!dockWindow->opaqueMoving()) {
148
if (orientation() != dockWindow->area()->orientation()) {
149
if (orientation() == Qt::Horizontal) {
150
int minpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).y();
151
int maxpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).y() + dockWindow->area()->height();
152
if (e->globalPos().y() < minpos || e->globalPos().y() > maxpos)
155
int minpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).x();
156
int maxpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).x() + dockWindow->area()->width();
157
if (e->globalPos().x() < minpos || e->globalPos().x() > maxpos)
161
QWidget *w = dockWindow->area()->window();
163
if (orientation() == Qt::Horizontal) {
164
int minpos = w->mapToGlobal(QPoint(0, 0)).y();
165
int maxpos = w->mapToGlobal(QPoint(0, 0)).y() + w->height();
166
if (e->globalPos().y() < minpos || e->globalPos().y() > maxpos)
169
int minpos = w->mapToGlobal(QPoint(0, 0)).x();
170
int maxpos = w->mapToGlobal(QPoint(0, 0)).x() + w->width();
171
if (e->globalPos().x() < minpos || e->globalPos().x() > maxpos)
178
if (!dockWindow->opaqueMoving())
180
lastPos = e->globalPos();
181
if (dockWindow->opaqueMoving()) {
182
mouseReleaseEvent(e);
184
firstPos = e->globalPos();
186
if (!dockWindow->opaqueMoving())
187
drawLine(e->globalPos());
190
void Q3DockWindowResizeHandle::mouseReleaseEvent(QMouseEvent *e)
193
if (!dockWindow->opaqueMoving()) {
197
if (orientation() != dockWindow->area()->orientation())
198
dockWindow->area()->invalidNextOffset(dockWindow);
199
if (orientation() == Qt::Horizontal) {
201
if (dockWindow->area()->handlePosition() == Q3DockArea::Normal || orientation() != dockWindow->area()->orientation())
202
dy = e->globalPos().y() - firstPos.y();
204
dy = firstPos.y() - e->globalPos().y();
205
int d = dockWindow->height() + dy;
206
if (orientation() != dockWindow->area()->orientation()) {
207
dockWindow->setFixedExtentHeight(-1);
208
d = qMax(d, dockWindow->minimumHeight());
209
int ms = dockWindow->area()->maxSpace(d, dockWindow);
211
dockWindow->setFixedExtentHeight(d);
213
dockWindow->area()->setFixedExtent(d, dockWindow);
217
if (dockWindow->area()->handlePosition() == Q3DockArea::Normal || orientation() != dockWindow->area()->orientation())
218
dx = e->globalPos().x() - firstPos.x();
220
dx = firstPos.x() - e->globalPos().x();
221
int d = dockWindow->width() + dx;
222
if (orientation() != dockWindow->area()->orientation()) {
223
dockWindow->setFixedExtentWidth(-1);
224
d = qMax(d, dockWindow->minimumWidth());
225
int ms = dockWindow->area()->maxSpace(d, dockWindow);
227
dockWindow->setFixedExtentWidth(d);
229
dockWindow->area()->setFixedExtent(d, dockWindow);
234
QApplication::postEvent(dockWindow->area(), new QEvent(QEvent::LayoutHint));
235
mousePressed = false;
238
void Q3DockWindowResizeHandle::paintEvent(QPaintEvent *)
241
QStyleOption opt(0, QStyleOption::SO_Default);
243
opt.palette = palette();
244
opt.state = QStyle::State_None;
246
opt.state |= QStyle::State_Enabled;
247
if (orientation() == Qt::Horizontal)
248
opt.state |= QStyle::State_Horizontal;
249
style()->drawPrimitive(QStyle::PE_IndicatorDockWidgetResizeHandle, &opt, &p, this);
252
void Q3DockWindowResizeHandle::startLineDraw()
256
rubberBand = new QRubberBand(QRubberBand::Line);
260
void Q3DockWindowResizeHandle::endLineDraw()
266
void Q3DockWindowResizeHandle::drawLine(const QPoint &globalPos)
268
QPoint start = mapToGlobal(QPoint(0, 0));
269
QPoint starta = dockWindow->area()->mapToGlobal(QPoint(0, 0));
270
QPoint end = globalPos;
271
if (orientation() == Qt::Horizontal) {
272
if (orientation() == dockWindow->orientation())
273
rubberBand->setGeometry(starta.x(), end.y(), dockWindow->area()->width(), height());
275
rubberBand->setGeometry(start.x(), end.y(), width(), height());
277
if (orientation() == dockWindow->orientation())
278
rubberBand->setGeometry(end.x(), starta.y(), width(), dockWindow->area()->height());
280
rubberBand->setGeometry(end.x(), start.y(), width(), height());
284
static QPoint realWidgetPos(Q3DockWindow *w)
286
if (!w->parentWidget() || w->place() == Q3DockWindow::OutsideDock)
288
return w->parentWidget()->mapToGlobal(w->geometry().topLeft());
291
class Q3DockWindowHandle : public QWidget
294
Q_PROPERTY(QString windowTitle READ windowTitle)
295
friend class Q3DockWindow;
296
friend class Q3DockWindowTitleBar;
299
Q3DockWindowHandle(Q3DockWindow *dw);
302
QSize minimumSizeHint() const;
303
QSize minimumSize() const { return minimumSizeHint(); }
304
QSize sizeHint() const { return minimumSize(); }
305
QSizePolicy sizePolicy() const;
306
void setOpaqueMoving(bool b) { opaque = b; }
308
QString windowTitle() const { return dockWindow->windowTitle(); }
311
void doubleClicked();
314
void paintEvent(QPaintEvent *e);
315
void resizeEvent(QResizeEvent *e);
316
void mousePressEvent(QMouseEvent *e);
317
void mouseMoveEvent(QMouseEvent *e);
318
void mouseReleaseEvent(QMouseEvent *e);
319
void mouseDoubleClickEvent(QMouseEvent *e);
320
void keyPressEvent(QKeyEvent *e);
321
void keyReleaseEvent(QKeyEvent *e);
322
void changeEvent(QEvent *);
328
Q3DockWindow *dockWindow;
330
QToolButton *closeButton;
333
uint mousePressed : 1;
334
uint hadDblClick : 1;
336
QPointer<QWidget> oldFocus;
339
class Q3DockWindowTitleBar : public Q3TitleBar
342
friend class Q3DockWindow;
343
friend class Q3DockWindowHandle;
346
Q3DockWindowTitleBar(Q3DockWindow *dw);
348
void setOpaqueMoving(bool b) { opaque = b; }
351
void resizeEvent(QResizeEvent *e);
352
void mousePressEvent(QMouseEvent *e);
353
void mouseMoveEvent(QMouseEvent *e);
354
void mouseReleaseEvent(QMouseEvent *e);
355
void mouseDoubleClickEvent(QMouseEvent *e);
356
void keyPressEvent(QKeyEvent *e);
357
void keyReleaseEvent(QKeyEvent *e);
360
Q3DockWindow *dockWindow;
362
uint mousePressed : 1;
363
uint hadDblClick : 1;
366
QPointer<QWidget> oldFocus;
370
Q3DockWindowHandle::Q3DockWindowHandle(Q3DockWindow *dw)
371
: QWidget(dw, "qt_dockwidget_internal"), dockWindow(dw),
372
closeButton(0), opaque(default_opaque), mousePressed(false)
375
timer = new QTimer(this);
376
connect(timer, SIGNAL(timeout()), this, SLOT(minimize()));
378
setCursor(Qt::SizeAllCursor);
382
void Q3DockWindowHandle::paintEvent(QPaintEvent *e)
384
if ((!dockWindow->dockArea || mousePressed) && !opaque)
387
QStyleOptionQ3DockWindow opt;
389
if (!dockWindow->area() || dockWindow->area()->orientation() == Qt::Horizontal)
390
opt.state |= QStyle::State_Horizontal;
393
opt.docked = dockWindow->area();
394
opt.closeEnabled = dockWindow->isCloseEnabled();
395
opt.rect = QStyle::visualRect(opt.direction, opt.rect,
396
style()->subElementRect(QStyle::SE_Q3DockWindowHandleRect, &opt, this));
397
style()->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p, this);
398
QWidget::paintEvent(e);
401
void Q3DockWindowHandle::keyPressEvent(QKeyEvent *e)
405
if (e->key() == Qt::Key_Control) {
407
dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
411
void Q3DockWindowHandle::keyReleaseEvent(QKeyEvent *e)
415
if (e->key() == Qt::Key_Control) {
417
dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
421
void Q3DockWindowHandle::mousePressEvent(QMouseEvent *e)
423
if (!dockWindow->dockArea)
425
ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
426
oldFocus = qApp->focusWidget();
429
if (e->button() != Qt::LeftButton)
435
dockWindow->startRectDraw(mapToGlobal(e->pos()), !opaque);
437
qApp->installEventFilter(dockWindow);
440
void Q3DockWindowHandle::mouseMoveEvent(QMouseEvent *e)
442
if (!mousePressed || e->pos() == offset)
444
ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
445
dockWindow->handleMove(e->pos() - offset, e->globalPos(), !opaque);
447
dockWindow->updatePosition(e->globalPos());
450
void Q3DockWindowHandle::mouseReleaseEvent(QMouseEvent *e)
453
qApp->removeEventFilter(dockWindow);
455
oldFocus->setFocus();
458
dockWindow->endRectDraw(!opaque);
459
mousePressed = false;
463
if (!hadDblClick && offset == e->pos()) {
464
timer->start(QApplication::doubleClickInterval(), true);
465
} else if (!hadDblClick) {
466
dockWindow->updatePosition(e->globalPos());
469
dockWindow->titleBar->mousePressed = false;
472
void Q3DockWindowHandle::minimize()
474
if (!dockWindow->area())
477
Q3MainWindow *mw = qobject_cast<Q3MainWindow*>(dockWindow->area()->parentWidget());
478
if (mw && mw->isDockEnabled(dockWindow, Qt::DockMinimized))
479
mw->moveDockWindow(dockWindow, Qt::DockMinimized);
482
void Q3DockWindowHandle::resizeEvent(QResizeEvent *)
487
void Q3DockWindowHandle::updateGui()
490
closeButton = new QToolButton(this, "qt_close_button1");
492
closeButton->setCursor(Qt::ArrowCursor);
495
opt.init(closeButton);
496
closeButton->setIcon(style()->standardPixmap(QStyle::SP_DockWidgetCloseButton, &opt,
498
closeButton->setFixedSize(12, 12);
499
connect(closeButton, SIGNAL(clicked()),
500
dockWindow, SLOT(hide()));
503
if (dockWindow->isCloseEnabled() && dockWindow->area())
508
if (!dockWindow->area())
511
if (dockWindow->area()->orientation() == Qt::Horizontal) {
512
int off = (width() - closeButton->width() - 1) / 2;
513
closeButton->move(off, 2);
515
int off = (height() - closeButton->height() - 1) / 2;
516
int x = QApplication::reverseLayout() ? 2 : width() - closeButton->width() - 2;
517
closeButton->move(x, off);
521
void Q3DockWindowHandle::changeEvent(QEvent *ev)
523
if(ev->type() == QEvent::StyleChange) {
526
opt.init(closeButton);
527
closeButton->setIcon(style()->standardPixmap(QStyle::SP_DockWidgetCloseButton,
531
QWidget::changeEvent(ev);
534
QSize Q3DockWindowHandle::minimumSizeHint() const
536
if (!dockWindow->dockArea)
538
int wh = dockWindow->isCloseEnabled() ? 17 : style()->pixelMetric(QStyle::PM_DockWidgetHandleExtent, 0, this);
539
if (dockWindow->orientation() == Qt::Horizontal)
544
QSizePolicy Q3DockWindowHandle::sizePolicy() const
546
if (dockWindow->orientation() != Qt::Horizontal)
547
return QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
548
return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
551
void Q3DockWindowHandle::mouseDoubleClickEvent(QMouseEvent *e)
554
if (e->button() != Qt::LeftButton)
558
emit doubleClicked();
562
Q3DockWindowTitleBar::Q3DockWindowTitleBar(Q3DockWindow *dw)
563
: Q3TitleBar(0, dw), dockWindow(dw),
564
mousePressed(false), hadDblClick(false), opaque(default_opaque)
566
setObjectName("qt_dockwidget_internal");
568
setMouseTracking(true);
569
QStyleOptionTitleBar opt = getStyleOption();
570
setFixedHeight(style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, this));
571
connect(this, SIGNAL(doClose()), dockWindow, SLOT(hide()));
574
void Q3DockWindowTitleBar::keyPressEvent(QKeyEvent *e)
578
if (e->key() == Qt::Key_Control) {
580
dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
584
void Q3DockWindowTitleBar::keyReleaseEvent(QKeyEvent *e)
588
if (e->key() == Qt::Key_Control) {
590
dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
594
void Q3DockWindowTitleBar::mousePressEvent(QMouseEvent *e)
596
QStyleOptionTitleBar opt;
598
opt.subControls = QStyle::SC_All;
599
opt.activeSubControls = QStyle::SC_None;
600
opt.text = windowTitle();
602
QIcon icon = windowIcon();
603
QSize s = icon.actualSize(QSize(64, 64));
604
opt.icon = icon.pixmap(s);
605
opt.titleBarState = window() ? window()->windowState() : static_cast<Qt::WindowStates>(Qt::WindowNoState);
606
opt.titleBarFlags = windowFlags();
607
QStyle::SubControl tbctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
609
if (tbctrl > QStyle::SC_TitleBarLabel) {
610
Q3TitleBar::mousePressEvent(e);
614
ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
615
oldFocus = qApp->focusWidget();
616
// setFocus activates the window, which deactivates the main window
617
// not what we want, and not required anyway on Windows
623
if (e->button() != Qt::LeftButton)
625
if (e->y() < 3 && dockWindow->isResizeEnabled())
629
bool oldPressed = mousePressed;
633
dockWindow->startRectDraw(mapToGlobal(e->pos()), !opaque);
634
// grabMouse resets the Windows mouse press count, so we never receive a double click on Windows
635
// not required on Windows, and did work on X11, too, but no problem there in the first place
637
if(!oldPressed && dockWindow->opaqueMoving())
640
Q_UNUSED(oldPressed);
644
void Q3DockWindowTitleBar::mouseMoveEvent(QMouseEvent *e)
647
Q3TitleBar::mouseMoveEvent(e);
651
ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
653
dockWindow->handleMove(e->pos() - offset, e->globalPos(), !opaque);
656
void Q3DockWindowTitleBar::mouseReleaseEvent(QMouseEvent *e)
659
Q3TitleBar::mouseReleaseEvent(e);
664
qApp->removeEventFilter(dockWindow);
666
oldFocus->setFocus();
668
if (dockWindow->place() == Q3DockWindow::OutsideDock)
671
if(dockWindow->opaqueMoving())
675
dockWindow->endRectDraw(!opaque);
676
mousePressed = false;
678
dockWindow->updatePosition(e->globalPos());
680
dockWindow->horHandle->mousePressed = false;
681
dockWindow->verHandle->mousePressed = false;
685
void Q3DockWindowTitleBar::resizeEvent(QResizeEvent *e)
688
Q3TitleBar::resizeEvent(e);
691
void Q3DockWindowTitleBar::updateGui()
693
if (dockWindow->isCloseEnabled()) {
694
setWindowFlags(windowFlags() | Qt::WStyle_SysMenu);
696
setWindowFlags(windowFlags() & ~Qt::WStyle_SysMenu);
700
void Q3DockWindowTitleBar::mouseDoubleClickEvent(QMouseEvent *)
702
emit doubleClicked();
707
\class Q3DockWindow q3dockwindow.h
708
\brief The Q3DockWindow class provides a widget which can be docked
709
inside a Q3DockArea or floated as a top level window on the
714
This class handles moving, resizing, docking and undocking dock
715
windows. Q3ToolBar is a subclass of Q3DockWindow so the
716
functionality provided for dock windows is available with the same
719
\img qmainwindow-qdockareas.png Q3DockWindows in a Q3DockArea
720
\caption Two Q3DockWindows (\l{Q3ToolBar}s) in a \l Q3DockArea
722
\img qdockwindow.png A Q3DockWindow
723
\caption A Floating Q3DockWindow
725
If the user drags the dock window into the dock area the dock
726
window will be docked. If the user drags the dock area outside any
727
dock areas the dock window will be undocked (floated) and will
728
become a top level window. Double clicking a floating dock
729
window's title bar will dock the dock window to the last dock area
730
it was docked in. Double clicking a docked dock window's handle
731
will undock (float) the dock window.
733
Single clicking a docked dock window's handle will minimize the
734
dock window (only its handle will appear, below the menu bar).
735
Single clicking the minimized handle will restore the dock window
736
to the last dock area that it was docked in.
738
If the user clicks the close button (which appears on floating
739
dock windows by default) the dock window will disappear. You can
740
control whether or not a dock window has a close button with
743
Q3MainWindow provides four dock areas (top, left, right and bottom)
744
which can be used by dock windows. For many applications using the
745
dock areas provided by Q3MainWindow is sufficient. (See the \l
746
Q3DockArea documentation if you want to create your own dock
747
areas.) In Q3MainWindow a right-click popup menu (the dock window
748
menu) is available which lists dock windows and can be used to
749
show or hide them. (The popup menu only lists dock windows that
750
have a \link QWidget::setWindowTitle() caption\endlink.)
752
When you construct a dock window you \e must pass it a Q3DockArea
753
or a Q3MainWindow as its parent if you want it docked. Pass 0 for
754
the parent if you want it floated.
757
Q3ToolBar *fileTools = new Q3ToolBar(this, "File Actions");
758
moveDockWindow(fileTools, Left);
761
In the example above we create a new Q3ToolBar in the constructor
762
of a Q3MainWindow subclass (so that the \e this pointer points to
763
the Q3MainWindow). By default the toolbar will be added to the \c
764
Top dock area, but we've moved it to the \c Left dock area.
766
A dock window is often used to contain a single widget. In these
767
cases the widget can be set by calling setWidget(). If you're
768
constructing a dock window that contains multiple widgets, e.g. a
769
toolbar, arrange the widgets within a box layout inside the dock
770
window. To do this use the boxLayout() function to get a pointer
771
to the dock window's box layout, then add widgets to the layout
772
using the box layout's QBoxLayout::addWidget() function. The dock
773
window will dynamically set the orientation of the layout to be
774
vertical or horizontal as necessary, although you can control this
775
yourself with setOrientation().
777
Although a common use of dock windows is for toolbars, they can be
778
used with any widgets. When using larger
779
widgets it may make sense for the dock window to be resizable by
780
calling setResizeEnabled(). Resizable dock windows are given
781
splitter-like handles to allow the user to resize them within
782
their dock area. When resizable dock windows are undocked they
783
become top level windows and can be resized like any other top
784
level windows, e.g. by dragging a corner or edge.
786
Qt::Dock windows can be docked and undocked using dock() and undock().
787
A dock window's orientation can be set with setOrientation(). You
788
can also use Q3DockArea::moveDockWindow(). If you're using a
789
Q3MainWindow, Q3MainWindow::moveDockWindow() and
790
Q3MainWindow::removeDockWindow() are available.
792
A dock window can have some preferred settings, for example, you
793
can set a preferred offset from the left edge (or top edge for
794
vertical dock areas) of the dock area using setOffset(). If you'd
795
prefer a dock window to start on a new line when it is docked use
796
setNewLine(). The setFixedExtentWidth() and setFixedExtentHeight()
797
functions can be used to define the dock window's preferred size,
798
and the setHorizontallyStretchable() and setVerticallyStretchable()
799
functions set whether the dock window can be stretched or not.
800
Dock windows can be moved by default, but this can be changed with
801
setMovingEnabled(). When a dock window is moved it is shown as a
802
rectangular outline, but it can be shown normally using
805
When a dock window's visibility changes, i.e. it is shown or
806
hidden, the visibilityChanged() signal is emitted. When a dock
807
window is docked, undocked or moved inside the dock area the
808
placeChanged() signal is emitted.
812
\enum Q3DockWindow::Place
814
This enum specifies the possible locations for a Q3DockWindow:
816
\value InDock Inside a Q3DockArea.
817
\value OutsideDock Floating as a top level window on the desktop.
821
\enum Q3DockWindow::CloseMode
823
This enum type specifies when (if ever) a dock window has a close
826
\value Never The dock window never has a close button and cannot
827
be closed by the user.
828
\value Docked The dock window has a close button only when
830
\value Undocked The dock window has a close button only when
832
\value Always The dock window always has a close button.
834
Note that dock windows can always be minimized if the user clicks
835
their dock window handle when they are docked.
840
\fn void Q3DockWindow::setHorizontalStretchable(bool b)
842
If \a b is true the dock window is set to be horizontally
846
\fn void Q3DockWindow::setVerticalStretchable(bool b)
848
If \a b is true the dock window is set to be vertically
852
\fn bool Q3DockWindow::isHorizontalStretchable() const
855
\fn bool Q3DockWindow::isVerticalStretchable() const
858
\fn void Q3DockWindow::orientationChanged(Qt::Orientation o)
860
This signal is emitted when the orientation of the dock window is
861
changed. The new orientation is \a o.
865
\fn void Q3DockWindow::placeChanged(Q3DockWindow::Place p)
867
This signal is emitted when the dock window is docked (\a p is \c
868
InDock), undocked (\a p is \c OutsideDock) or moved inside the
871
\sa Q3DockArea::moveDockWindow(), Q3DockArea::removeDockWindow(),
872
Q3MainWindow::moveDockWindow(), Q3MainWindow::removeDockWindow()
876
\fn void Q3DockWindow::visibilityChanged(bool visible)
878
This signal is emitted when the visibility of the dock window
879
relatively to its dock area is changed. If \a visible is true, the
880
Q3DockWindow is now visible to the dock area, otherwise it has been
883
A dock window can be hidden if it has a close button which the
884
user has clicked. In the case of a Q3MainWindow a dock window can
885
have its visibility changed (hidden or shown) by clicking its name
886
in the dock window menu that lists the Q3MainWindow's dock windows.
890
\fn Q3DockArea *Q3DockWindow::area() const
892
Returns the dock area in which this dock window is docked, or 0 if
893
the dock window is floating.
897
\property Q3DockWindow::place
898
\brief the location where the dock window is placed
900
This is either \c InDock or \c OutsideDock.
902
\sa Q3DockArea::moveDockWindow(), Q3DockArea::removeDockWindow(),
903
Q3MainWindow::moveDockWindow(), Q3MainWindow::removeDockWindow()
907
Constructs a Q3DockWindow with parent \a parent, called \a name and
908
with widget flags \a f.
911
Q3DockWindow::Q3DockWindow(QWidget* parent, const char* name, Qt::WFlags f)
912
: Q3Frame(parent, name, f | Qt::WType_Dialog | Qt::WStyle_Customize | Qt::WStyle_NoBorder)
920
Constructs a Q3DockWindow with parent \a parent, called \a name and
921
with widget flags \a f.
923
If \a p is \c InDock, the dock window is docked into a dock area
924
and \a parent \e must be a Q3DockArea or a Q3MainWindow. If the \a
925
parent is a Q3MainWindow the dock window will be docked in the main
926
window's \c Top dock area.
928
If \a p is \c OutsideDock, the dock window is created as a floating
931
We recommend creating the dock area \c InDock with a Q3MainWindow
932
as parent then calling Q3MainWindow::moveDockWindow() to move the
933
dock window where you want it.
936
Q3DockWindow::Q3DockWindow(Place p, QWidget *parent, const char *name, Qt::WFlags f)
937
: Q3Frame(parent, name, f | Qt::WType_Dialog | Qt::WStyle_Customize | Qt::WStyle_NoBorder)
947
Q3DockWindow::Q3DockWindow(Place p, QWidget *parent, const char *name, Qt::WFlags f, bool toolbar)
948
: Q3Frame(parent, name, f | Qt::WType_Dialog | Qt::WStyle_Customize | Qt::WStyle_NoBorder)
955
class Q3DockWindowGridLayout : public QGridLayout
958
Q3DockWindowGridLayout(QWidget *parent, int nRows, int nCols)
959
: QGridLayout(parent, nRows, nCols) {};
961
Qt::Orientations expandingDirections() const
967
void Q3DockWindow::init()
973
resizeEnabled = false;
976
opaque = default_opaque;
979
fExtent = QSize(-1, -1);
981
lastPos = QPoint(-1, -1);
982
lastSize = QSize(-1, -1);
984
widgetResizeHandler = new QWidgetResizeHandler(this);
985
widgetResizeHandler->setMovingEnabled(false);
987
titleBar = new Q3DockWindowTitleBar(this);
988
verHandle = new Q3DockWindowHandle(this);
989
horHandle = new Q3DockWindowHandle(this);
991
vHandleLeft = new Q3DockWindowResizeHandle(Qt::Vertical, this, this, "vert. handle");
992
vHandleRight = new Q3DockWindowResizeHandle(Qt::Vertical, this, this, "vert. handle");
993
hHandleTop = new Q3DockWindowResizeHandle(Qt::Horizontal, this, this, "horz. handle");
994
hHandleBottom = new Q3DockWindowResizeHandle(Qt::Horizontal, this, this, "horz. handle");
996
// Creating inner layout
997
hbox = new QVBoxLayout();
998
vbox = new QHBoxLayout();
999
childBox = new QBoxLayout(QBoxLayout::LeftToRight);
1000
vbox->addWidget(verHandle);
1001
vbox->addLayout(childBox);
1003
hbox->setResizeMode(QLayout::FreeResize);
1004
hbox->setMargin(isResizeEnabled() || curPlace == OutsideDock ? 2 : 0);
1005
hbox->setSpacing(1);
1006
hbox->addWidget(titleBar);
1007
hbox->addWidget(horHandle);
1008
hbox->addLayout(vbox);
1010
// Set up the initial handle layout for Qt::Vertical
1011
// Handle layout will change on calls to setOrienation()
1012
QGridLayout *glayout = new Q3DockWindowGridLayout(this, 3, 3);
1013
glayout->setResizeMode(QLayout::Minimum);
1014
glayout->addMultiCellWidget(hHandleTop, 0, 0, 1, 1);
1015
glayout->addMultiCellWidget(hHandleBottom, 2, 2, 1, 1);
1016
glayout->addMultiCellWidget(vHandleLeft, 0, 2, 0, 0);
1017
glayout->addMultiCellWidget(vHandleRight, 0, 2, 2, 2);
1018
glayout->addLayout(hbox, 1, 1);
1019
glayout->setRowStretch(1, 1);
1020
glayout->setColStretch(1, 1);
1022
hHandleBottom->hide();
1023
vHandleRight->hide();
1025
vHandleLeft->hide();
1026
setFrameStyle(Q3Frame::StyledPanel | Q3Frame::Raised);
1030
parentWidget()->installEventFilter(this);
1031
QWidget *mw = parentWidget();
1032
Q3DockArea *da = qobject_cast<Q3DockArea*>(parentWidget());
1034
if (curPlace == InDock)
1035
da->moveDockWindow(this);
1036
mw = da->parentWidget();
1038
if (qobject_cast<Q3MainWindow*>(mw)) {
1039
if (place() == InDock) {
1040
Qt::Dock myDock = Qt::DockTop;
1041
// make sure we put the window in the correct dock.
1043
Q3MainWindow *mainw = (Q3MainWindow*)mw;
1044
// I'm not checking if it matches the top because I've
1045
// done the assignment to it above.
1046
if (dockArea == mainw->leftDock())
1047
myDock = Qt::DockLeft;
1048
else if (dockArea == mainw->rightDock())
1049
myDock = Qt::DockRight;
1050
else if (dockArea == mainw->bottomDock())
1051
myDock = Qt::DockBottom;
1053
((Q3MainWindow*)mw)->addDockWindow(this, myDock);
1055
moveEnabled = ((Q3MainWindow*)mw)->dockWindowsMovable();
1056
opaque = ((Q3MainWindow*)mw)->opaqueMoving();
1060
stretchable[Qt::Horizontal] = false;
1061
stretchable[Qt::Vertical] = false;
1063
connect(titleBar, SIGNAL(doubleClicked()), this, SLOT(dock()));
1064
connect(verHandle, SIGNAL(doubleClicked()), this, SLOT(undock()));
1065
connect(horHandle, SIGNAL(doubleClicked()), this, SLOT(undock()));
1066
connect(this, SIGNAL(orientationChanged(Qt::Orientation)),
1067
this, SLOT(setOrientation(Qt::Orientation)));
1071
Sets the orientation of the dock window to \a o. The orientation
1072
is propagated to the layout boxLayout().
1074
\warning All undocked Q3ToolBars will always have a horizontal orientation.
1077
void Q3DockWindow::setOrientation(Qt::Orientation o)
1079
QGridLayout *glayout = (QGridLayout*)layout();
1080
glayout->removeWidget(hHandleTop);
1081
glayout->removeWidget(hHandleBottom);
1082
glayout->removeWidget(vHandleLeft);
1083
glayout->removeWidget(vHandleRight);
1085
if (o == Qt::Horizontal) {
1086
// Set up the new layout as
1087
// 3 3 3 1 = vHandleLeft 4 = hHandleBottom
1088
// 1 X 2 2 = vHandleRight X = Inner Layout
1089
// 4 4 4 3 = hHandleTop
1090
glayout->addMultiCellWidget(hHandleTop, 0, 0, 0, 2);
1091
glayout->addMultiCellWidget(hHandleBottom, 2, 2, 0, 2);
1092
glayout->addMultiCellWidget(vHandleLeft, 1, 1, 0, 0);
1093
glayout->addMultiCellWidget(vHandleRight, 1, 1, 2, 2);
1095
// Set up the new layout as
1096
// 1 3 2 1 = vHandleLeft 4 = hHandleBottom
1097
// 1 X 2 2 = vHandleRight X = Inner Layout
1098
// 1 4 2 3 = hHandleTop
1099
glayout->addMultiCellWidget(hHandleTop, 0, 0, 1, 1);
1100
glayout->addMultiCellWidget(hHandleBottom, 2, 2, 1, 1);
1101
glayout->addMultiCellWidget(vHandleLeft, 0, 2, 0, 0);
1102
glayout->addMultiCellWidget(vHandleRight, 0, 2, 2, 2);
1104
boxLayout()->setDirection(o == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom);
1105
QApplication::sendPostedEvents(this, QEvent::LayoutHint);
1106
QEvent *e = new QEvent(QEvent::LayoutHint);
1107
QApplication::postEvent(this, e);
1111
Destroys the dock window and its child widgets.
1114
Q3DockWindow::~Q3DockWindow()
1116
qApp->removeEventFilter(this);
1118
area()->removeDockWindow(this, false, false);
1119
Q3DockArea *a = area();
1120
if (!a && dockWindowData)
1121
a = ((Q3DockArea::DockWindowData*)dockWindowData)->area;
1122
Q3MainWindow *mw = a ? qobject_cast<Q3MainWindow*>(a->parentWidget()) : 0;
1124
mw->removeDockWindow(this);
1126
delete (Q3DockArea::DockWindowData*)dockWindowData;
1132
void Q3DockWindow::resizeEvent(QResizeEvent *e)
1134
Q3Frame::resizeEvent(e);
1139
void Q3DockWindow::swapRect(QRect &r, Qt::Orientation o, const QPoint &offset, Q3DockArea *)
1141
r.setSize(QSize(r.height(), r.width()));
1142
bool reverse = QApplication::reverseLayout();
1143
if (o == Qt::Horizontal)
1144
r.moveBy(-r.width()/2, 0);
1146
r.moveBy(reverse ? - r.width() : 0, -r.height() / 2 );
1147
r.moveBy(offset.x(), offset.y());
1150
QWidget *Q3DockWindow::areaAt(const QPoint &gp)
1152
QWidget *w = qApp->widgetAt(gp);
1154
if (w && (w == this || w == titleBar) && parentWidget())
1155
w = parentWidget()->childAt(parentWidget()->mapFromGlobal(gp));
1158
if (qobject_cast<Q3DockArea*>(w)) {
1159
Q3DockArea *a = (Q3DockArea*)w;
1160
if (a->isDockWindowAccepted(this))
1163
if (qobject_cast<Q3MainWindow*>(w)) {
1164
Q3MainWindow *mw = (Q3MainWindow*)w;
1165
Q3DockArea *a = mw->dockingArea(mw->mapFromGlobal(gp));
1166
if (a && a->isDockWindowAccepted(this))
1169
w = w->isWindow() ? 0 : (QWidget *)w->parent();
1174
void Q3DockWindow::handleMove(const QPoint &pos, const QPoint &gp, bool drawRect)
1179
currRect = QRect(realWidgetPos(this), size());
1180
QWidget *w = areaAt(gp);
1181
if (titleBar->ctrlDown || horHandle->ctrlDown || verHandle->ctrlDown)
1183
currRect.moveBy(pos.x(), pos.y());
1184
if (!qobject_cast<Q3DockArea*>(w)) {
1185
if (startOrientation != Qt::Horizontal && qobject_cast<Q3ToolBar*>(this))
1186
swapRect(currRect, Qt::Horizontal, startOffset, (Q3DockArea*)w);
1188
rubberBand->setGeometry(currRect);
1190
QPoint mp(mapToGlobal(pos));
1191
if(place() == InDock) {
1194
mp = QPoint(titleBar->width() / 2, titleBar->height() / 2);
1195
QMouseEvent me(QEvent::MouseButtonPress, mp, Qt::LeftButton, 0);
1196
QApplication::sendEvent(titleBar, &me);
1197
mp = titleBar->mapToGlobal(mp);
1202
state = OutsideDock;
1206
Q3DockArea *area = (Q3DockArea*)w;
1207
if(area->isVisible()) {
1209
Qt::Orientation o = (area ? area->orientation() :
1210
(boxLayout()->direction() == QBoxLayout::LeftToRight ||
1211
boxLayout()->direction() == QBoxLayout::RightToLeft ?
1212
Qt::Horizontal : Qt::Vertical));
1213
if (startOrientation != o)
1214
swapRect(currRect, o, startOffset, area);
1216
rubberBand->setGeometry(currRect);
1222
void Q3DockWindow::updateGui()
1224
if (curPlace == OutsideDock) {
1232
titleBar->updateGui();
1234
vHandleLeft->hide();
1235
hHandleBottom->hide();
1236
vHandleRight->hide();
1238
widgetResizeHandler->setActive(isResizeEnabled());
1240
hbox->setMargin(isResizeEnabled() ? 0 : 2);
1242
if (orientation() == Qt::Horizontal) {
1249
if(horHandle->mousePressed) {
1250
horHandle->mousePressed = false;
1251
verHandle->mousePressed = true;
1252
verHandle->grabMouse();
1255
verHandle->updateGui();
1261
horHandle->updateGui();
1263
if(verHandle->mousePressed) {
1264
verHandle->mousePressed = false;
1265
horHandle->mousePressed = true;
1266
horHandle->grabMouse();
1271
if (isResizeEnabled()) {
1272
if (orientation() == Qt::Horizontal) {
1273
hHandleBottom->raise();
1274
hHandleTop->raise();
1276
vHandleRight->raise();
1277
vHandleLeft->raise();
1281
if (orientation() == Qt::Horizontal) {
1282
if (area()->handlePosition() == Q3DockArea::Normal) {
1283
hHandleBottom->show();
1287
hHandleBottom->hide();
1289
if (!area()->isLastDockWindow(this))
1290
vHandleRight->show();
1292
vHandleRight->hide();
1293
vHandleLeft->hide();
1295
if ((area()->handlePosition() == Q3DockArea::Normal) != QApplication::reverseLayout()) {
1296
vHandleRight->show();
1297
vHandleLeft->hide();
1299
vHandleLeft->show();
1300
vHandleRight->hide();
1302
if (!area()->isLastDockWindow(this))
1303
hHandleBottom->show();
1305
hHandleBottom->hide();
1315
hbox->setMargin(lineWidth());
1319
widgetResizeHandler->setActive(false);
1323
void Q3DockWindow::updatePosition(const QPoint &globalPos)
1325
if (curPlace == OutsideDock && state == InDock)
1328
bool doAdjustSize = curPlace != state && state == OutsideDock;
1329
bool doUpdate = true;
1330
bool doOrientationChange = true;
1331
if (state != curPlace && state == InDock) {
1335
QApplication::sendPostedEvents();
1337
Qt::Orientation oo = orientation();
1339
if (state == InDock) {
1341
bool differentDocks = false;
1342
if (dockArea && dockArea != tmpDockArea) {
1343
differentDocks = true;
1344
delete (Q3DockArea::DockWindowData*)dockWindowData;
1345
dockWindowData = dockArea->dockWindowData(this);
1346
dockArea->removeDockWindow(this, false, false);
1348
dockArea = tmpDockArea;
1349
if (differentDocks) {
1355
emit orientationChanged(tmpDockArea->orientation());
1356
doOrientationChange = false;
1360
dockArea->moveDockWindow(this, globalPos, currRect, startOrientation != oo);
1364
Q3MainWindow *mw = (Q3MainWindow*)dockArea->parentWidget();
1365
if (qobject_cast<Q3MainWindow*>(mw) &&
1366
(!mw->isDockEnabled(Qt::DockTornOff) ||
1367
!mw->isDockEnabled(this, Qt::DockTornOff)))
1369
delete (Q3DockArea::DockWindowData*)dockWindowData;
1370
dockWindowData = dockArea->dockWindowData(this);
1371
dockArea->removeDockWindow(this, true,
1372
startOrientation != Qt::Horizontal && qobject_cast<Q3ToolBar*>(this));
1375
QPoint topLeft = currRect.topLeft();
1376
QRect screen = qApp->desktop()->availableGeometry(topLeft);
1377
if (!screen.contains(topLeft)) {
1378
topLeft.setY(qMax(topLeft.y(), screen.top()));
1379
topLeft.setY(qMin(topLeft.y(), screen.bottom()-height()));
1380
topLeft.setX(qMax(topLeft.x(), screen.left()));
1381
topLeft.setX(qMin(topLeft.x(), screen.right()-width()));
1386
if (curPlace == InDock && state == OutsideDock && !qobject_cast<Q3ToolBar*>(this)) {
1387
if (lastSize != QSize(-1, -1))
1395
if (doOrientationChange)
1396
emit orientationChanged(orientation());
1399
QApplication::sendPostedEvents(this, QEvent::LayoutHint);
1400
if (qobject_cast<Q3ToolBar*>(this))
1402
setAttribute(Qt::WA_Resized, false); // Ensures size is recalculated (non-opaque).
1404
if (parentWidget() && isWindow())
1405
parentWidget()->setActiveWindow();
1409
emit placeChanged(curPlace);
1413
Sets the dock window's main widget to \a w.
1418
void Q3DockWindow::setWidget(QWidget *w)
1421
boxLayout()->addWidget(w);
1426
Returns the dock window's main widget.
1431
QWidget *Q3DockWindow::widget() const
1436
void Q3DockWindow::startRectDraw(const QPoint &so, bool drawRect)
1440
endRectDraw(!opaque);
1441
rubberBand = new QRubberBand(QRubberBand::Rectangle);
1442
currRect = QRect(realWidgetPos(this), size());
1444
rubberBand->setGeometry(currRect);
1446
startOrientation = orientation();
1447
startOffset = mapFromGlobal(so);
1451
void Q3DockWindow::endRectDraw(bool)
1460
void Q3DockWindow::drawFrame(QPainter *p)
1462
if (place() == InDock) {
1463
Q3Frame::drawFrame(p);
1467
QStyleOptionFrame opt;
1469
opt.palette = palette();
1470
opt.state = QStyle::State_None;
1471
if (titleBar->isActive())
1472
opt.state |= QStyle::State_Active;
1473
opt.lineWidth = lineWidth();
1474
opt.midLineWidth = midLineWidth();
1476
style()->drawPrimitive(QStyle::PE_FrameWindow, &opt, p, this);
1482
void Q3DockWindow::drawContents(QPainter *p)
1484
// This is only used by the PocketPC style. We probably need to revist later.
1485
QStyleOption opt(0, QStyleOption::SO_Default);
1487
if (titleBar->isActive())
1488
opt.state |= QStyle::State_Active;
1489
style()->drawControl(QStyle::CE_Q3DockWindowEmptyArea, &opt, p, this);
1493
\property Q3DockWindow::resizeEnabled
1494
\brief whether the dock window is resizeable
1496
A resizeable dock window can be resized using splitter-like
1497
handles inside a dock area and like every other top level window
1500
A dock window is both horizontally and vertically stretchable if
1501
you call setResizeEnabled(true).
1503
This property is false by default.
1505
\sa setVerticallyStretchable() setHorizontallyStretchable()
1508
void Q3DockWindow::setResizeEnabled(bool b)
1511
hbox->setMargin(b ? 0 : 2);
1516
\property Q3DockWindow::movingEnabled
1517
\brief whether the user can move the dock window within the dock
1518
area, move the dock window to another dock area, or float the dock
1521
This property is true by default.
1524
void Q3DockWindow::setMovingEnabled(bool b)
1530
bool Q3DockWindow::isResizeEnabled() const
1532
return resizeEnabled;
1535
bool Q3DockWindow::isMovingEnabled() const
1541
\property Q3DockWindow::closeMode
1542
\brief the close mode of a dock window
1544
Defines when (if ever) the dock window has a close button. The
1545
choices are \c Never, \c Docked (i.e. only when docked), \c
1546
Undocked (only when undocked, i.e. floated) or \c Always.
1548
The default is \c Never.
1551
void Q3DockWindow::setCloseMode(int m)
1554
if (place() == InDock) {
1555
horHandle->updateGui();
1556
verHandle->updateGui();
1558
titleBar->updateGui();
1563
Returns true if the dock window has a close button; otherwise
1564
returns false. The result depends on the dock window's \l Place
1565
and its \l CloseMode.
1570
bool Q3DockWindow::isCloseEnabled() const
1572
return ((cMode & Docked) == Docked && place() == InDock ||
1573
(cMode & Undocked) == Undocked && place() == OutsideDock);
1576
int Q3DockWindow::closeMode() const
1582
\property Q3DockWindow::horizontallyStretchable
1583
\brief whether the dock window is horizontally stretchable.
1585
A dock window is horizontally stretchable if you call
1586
setHorizontallyStretchable(true) or setResizeEnabled(true).
1588
\warning Stretchability is broken. You must call
1589
setResizeEnabled(true) to get proper behavior and even then
1590
Q3DockWindow does not limit stretchablilty.
1592
\sa setResizeEnabled()
1595
void Q3DockWindow::setHorizontallyStretchable(bool b)
1597
stretchable[Qt::Horizontal] = b;
1601
\property Q3DockWindow::verticallyStretchable
1602
\brief whether the dock window is vertically stretchable.
1604
A dock window is vertically stretchable if you call
1605
setVerticallyStretchable(true) or setResizeEnabled(true).
1607
\sa setResizeEnabled()
1609
\warning Stretchability is broken. You must call
1610
setResizeEnabled(true) to get proper behavior and even then
1611
Q3DockWindow does not limit stretchablilty.
1614
void Q3DockWindow::setVerticallyStretchable(bool b)
1616
stretchable[Qt::Vertical] = b;
1619
bool Q3DockWindow::isHorizontallyStretchable() const
1621
return isResizeEnabled() || stretchable[Qt::Horizontal];
1624
bool Q3DockWindow::isVerticallyStretchable() const
1626
return isResizeEnabled() || stretchable[Qt::Vertical];
1630
\property Q3DockWindow::stretchable
1631
\brief whether the dock window is stretchable in the current
1634
This property can be set using setHorizontallyStretchable() and
1635
setVerticallyStretchable(), or with setResizeEnabled().
1637
\warning Stretchability is broken. You must call
1638
setResizeEnabled(true) to get proper behavior and even then
1639
Q3DockWindow does not limit stretchablilty.
1641
\sa setResizeEnabled()
1644
bool Q3DockWindow::isStretchable() const
1646
if (orientation() == Qt::Horizontal)
1647
return isHorizontallyStretchable();
1648
return isVerticallyStretchable();
1652
Returns the orientation of the dock window.
1654
\sa orientationChanged()
1657
Qt::Orientation Q3DockWindow::orientation() const
1660
return dockArea->orientation();
1661
if (qobject_cast<const Q3ToolBar*>(this))
1662
return Qt::Horizontal;
1663
return (((Q3DockWindow*)this)->boxLayout()->direction() == QBoxLayout::LeftToRight ||
1664
((Q3DockWindow*)this)->boxLayout()->direction() == QBoxLayout::RightToLeft ?
1665
Qt::Horizontal : Qt::Vertical);
1668
int Q3DockWindow::offset() const
1674
\property Q3DockWindow::offset
1675
\brief the dock window's preferred offset from the dock area's
1676
left edge (top edge for vertical dock areas)
1681
void Q3DockWindow::setOffset(int o)
1687
Returns the dock window's preferred size (fixed extent).
1689
\sa setFixedExtentWidth() setFixedExtentHeight()
1692
QSize Q3DockWindow::fixedExtent() const
1698
Sets the dock window's preferred width for its fixed extent (size)
1701
\sa setFixedExtentHeight()
1704
void Q3DockWindow::setFixedExtentWidth(int w)
1706
fExtent.setWidth(w);
1710
Sets the dock window's preferred height for its fixed extent
1713
\sa setFixedExtentWidth()
1716
void Q3DockWindow::setFixedExtentHeight(int h)
1718
fExtent.setHeight(h);
1722
\property Q3DockWindow::newLine
1723
\brief whether the dock window prefers to start a new line in the
1726
The default is false, i.e. the dock window doesn't require a new
1727
line in the dock area.
1730
void Q3DockWindow::setNewLine(bool b)
1735
bool Q3DockWindow::newLine() const
1741
Returns the layout which is used for adding widgets to the dock
1742
window. The layout's orientation is set automatically to match the
1743
orientation of the dock window. You can add widgets to the layout
1744
using the box layout's QBoxLayout::addWidget() function.
1746
If the dock window only needs to contain a single widget use
1747
setWidget() instead.
1749
\sa setWidget() setOrientation()
1752
QBoxLayout *Q3DockWindow::boxLayout()
1760
QSize Q3DockWindow::sizeHint() const
1762
QSize sh(Q3Frame::sizeHint());
1763
if (place() == InDock)
1764
sh = sh.expandedTo(fixedExtent());
1765
sh = sh.expandedTo(QSize(16, 16));
1767
if (area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible())
1768
sh.setWidth(sh.width() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1769
else if (area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible())
1770
sh.setHeight(sh.height() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1778
QSize Q3DockWindow::minimumSize() const
1780
QSize ms(Q3Frame::minimumSize());
1781
if (place() == InDock)
1782
ms = ms.expandedTo(fixedExtent());
1783
ms = ms.expandedTo(QSize(16, 16));
1785
if (area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible())
1786
ms.setWidth(ms.width() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1787
else if (area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible())
1788
ms.setHeight(ms.height() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1796
QSize Q3DockWindow::minimumSizeHint() const
1798
QSize msh(Q3Frame::minimumSize());
1799
if (place() == InDock)
1800
msh = msh.expandedTo(fixedExtent());
1801
msh = msh.expandedTo(QSize(16, 16));
1803
if (area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible())
1804
msh.setWidth(msh.width() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1805
else if (area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible())
1806
msh.setHeight(msh.height() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1812
void Q3DockWindow::undock(QWidget *w)
1814
Q3MainWindow *mw = 0;
1816
mw = qobject_cast<Q3MainWindow*>(area()->parentWidget());
1817
if (mw && !mw->isDockEnabled(this, Qt::DockTornOff))
1819
if ((place() == OutsideDock && !w))
1824
p = window()->pos() + QPoint(20, 20);
1826
delete (Q3DockArea::DockWindowData*)dockWindowData;
1827
dockWindowData = dockArea->dockWindowData(this);
1828
dockArea->removeDockWindow(this, true, orientation() != Qt::Horizontal && qobject_cast<Q3ToolBar*>(this));
1831
if (lastPos != QPoint(-1, -1) && lastPos.x() > 0 && lastPos.y() > 0)
1835
if (lastSize != QSize(-1, -1))
1837
curPlace = OutsideDock;
1839
emit orientationChanged(orientation());
1840
QApplication::sendPostedEvents(this, QEvent::LayoutHint);
1841
if (qobject_cast<Q3ToolBar*>(this))
1844
if (!parentWidget() || parentWidget()->isVisible()) {
1845
setAttribute(Qt::WA_Resized, false);// Ensures size is recalculated (opaque).
1850
move(-width() - 5, -height() - 5);
1854
if (parentWidget() && isWindow())
1855
parentWidget()->setActiveWindow();
1856
emit placeChanged(place());
1860
\fn void Q3DockWindow::undock()
1862
Undocks the Q3DockWindow from its current dock area if it is
1863
docked; otherwise does nothing.
1865
\sa dock() Q3DockArea::moveDockWindow(),
1866
Q3DockArea::removeDockWindow(), Q3MainWindow::moveDockWindow(),
1867
Q3MainWindow::removeDockWindow()
1870
void Q3DockWindow::removeFromDock(bool fixNewLines)
1873
dockArea->removeDockWindow(this, false, false, fixNewLines);
1877
Docks the dock window into the last dock area in which it was
1880
If the dock window has no last dock area (e.g. it was created as a
1881
floating window and has never been docked), or if the last dock
1882
area it was docked in does not exist (e.g. the dock area has been
1883
deleted), nothing happens.
1885
The dock window will dock with the dock area regardless of the return value
1886
of Q3DockArea::isDockWindowAccepted().
1888
\sa undock() Q3DockArea::moveDockWindow(),
1889
Q3DockArea::removeDockWindow(), Q3MainWindow::moveDockWindow(),
1890
Q3MainWindow::removeDockWindow(), Q3DockArea::isDockWindowAccepted()
1894
void Q3DockWindow::dock()
1896
if (!(Q3DockArea::DockWindowData*)dockWindowData ||
1897
!((Q3DockArea::DockWindowData*)dockWindowData)->area)
1902
((Q3DockArea::DockWindowData*)dockWindowData)->
1903
area->dockWindow(this, (Q3DockArea::DockWindowData*)dockWindowData);
1904
emit orientationChanged(orientation());
1905
emit placeChanged(place());
1911
void Q3DockWindow::hideEvent(QHideEvent *e)
1913
Q3Frame::hideEvent(e);
1919
void Q3DockWindow::showEvent(QShowEvent *e)
1921
if (curPlace == OutsideDock && (parent() && parent()->objectName() == QLatin1String("qt_hide_dock"))) {
1922
QRect sr = qApp->desktop()->availableGeometry(this);
1923
if (!sr.contains(pos())) {
1924
int nx = qMin(qMax(x(), sr.x()), sr.right()-width());
1925
int ny = qMin(qMax(y(), sr.y()), sr.bottom()-height());
1930
Q3Frame::showEvent(e);
1934
\property Q3DockWindow::opaqueMoving
1935
\brief whether the dock window will be shown normally whilst it is
1938
If this property is false, (the default), the dock window will be
1939
represented by an outline rectangle whilst it is being moved.
1941
\warning Currently opaque moving has some problems and we do not
1942
recommend using it at this time. We expect to fix these problems
1943
in a future release.
1946
void Q3DockWindow::setOpaqueMoving(bool b)
1949
horHandle->setOpaqueMoving(b);
1950
verHandle->setOpaqueMoving(b);
1951
titleBar->setOpaqueMoving(b);
1954
bool Q3DockWindow::opaqueMoving() const
1959
void Q3DockWindow::updateSplitterVisibility(bool visible)
1961
if (area() && isResizeEnabled()) {
1962
if (orientation() == Qt::Horizontal) {
1964
vHandleRight->show();
1966
vHandleRight->hide();
1967
vHandleLeft->hide();
1970
hHandleBottom->show();
1972
hHandleBottom->hide();
1979
bool Q3DockWindow::eventFilter(QObject * o, QEvent *e)
1981
if (!o->isWidgetType())
1984
if (e->type() == QEvent::KeyPress &&
1985
(horHandle->mousePressed ||
1986
verHandle->mousePressed ||
1987
titleBar->mousePressed)) {
1988
QKeyEvent *ke = (QKeyEvent*)e;
1989
if (ke->key() == Qt::Key_Escape) {
1990
horHandle->mousePressed =
1991
verHandle->mousePressed =
1992
titleBar->mousePressed = false;
1993
endRectDraw(!opaque);
1994
qApp->removeEventFilter(this);
1997
} else if (((QWidget*)o)->window() != this && place() == OutsideDock && isWindow()) {
1998
if ((e->type() == QEvent::WindowDeactivate ||
1999
e->type() == QEvent::WindowActivate))
2006
bool Q3DockWindow::event(QEvent *e)
2008
switch (e->type()) {
2009
case QEvent::WindowDeactivate:
2010
if (place() == OutsideDock && isWindow() && parentWidget()
2011
&& parentWidget()->isActiveWindow())
2014
case QEvent::HideToParent:
2015
emit visibilityChanged(false);
2017
case QEvent::ShowToParent:
2018
emit visibilityChanged(true);
2020
case QEvent::WindowTitleChange:
2022
QString s = Q3Frame::windowTitle();
2023
titleBar->setWindowTitle(s);
2024
horHandle->setToolTip(s);
2025
verHandle->setToolTip(s);
2031
return Q3Frame::event(e);
2035
Returns the dock window's title.
2037
QString Q3DockWindow::windowTitle() const
2039
return titleBar->windowTitle();
2043
void Q3DockWindow::contextMenuEvent(QContextMenuEvent *e)
2047
if (qobject_cast<Q3MainWindow*>(o))
2051
if (!o || ! ((Q3MainWindow*)o)->showDockMenu(e->globalPos()))
2055
#include "q3dockwindow.moc"
2057
#endif //QT_NO_MAINWINDOW