source: trunk/src/qt3support/widgets/q3dockwindow.cpp@ 345

Last change on this file since 345 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 64.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the Qt3Support module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "q3dockwindow.h"
43
44#ifndef QT_NO_MAINWINDOW
45#include "qapplication.h"
46#include "qcursor.h"
47#include "qdesktopwidget.h"
48#include "q3dockarea.h"
49#include "qevent.h"
50#include "qlayout.h"
51#include "q3mainwindow.h"
52#include "qpainter.h"
53#include "qpointer.h"
54#include "qstyle.h"
55#include "qstyleoption.h"
56#include "qtimer.h"
57#include "q3toolbar.h"
58#include "qtoolbutton.h"
59#include "qtooltip.h"
60#include <private/q3titlebar_p.h>
61#include <private/qwidgetresizehandler_p.h>
62#include <qrubberband.h>
63#include <qdebug.h>
64
65QT_BEGIN_NAMESPACE
66
67#ifdef Q_WS_MAC
68static bool default_opaque = true;
69#else
70static bool default_opaque = false;
71#endif
72
73class Q3DockWindowPrivate
74{
75};
76
77class Q3DockWindowResizeHandle : public QWidget
78{
79 Q_OBJECT
80
81public:
82 Q3DockWindowResizeHandle(Qt::Orientation o, QWidget *parent, Q3DockWindow *w, const char* /*name*/=0);
83 void setOrientation(Qt::Orientation o);
84 Qt::Orientation orientation() const { return orient; }
85
86 QSize sizeHint() const;
87
88protected:
89 void paintEvent(QPaintEvent *);
90 void mouseMoveEvent(QMouseEvent *);
91 void mousePressEvent(QMouseEvent *);
92 void mouseReleaseEvent(QMouseEvent *);
93 bool event(QEvent *event);
94
95private:
96 void startLineDraw();
97 void endLineDraw();
98 void drawLine(const QPoint &globalPos);
99
100private:
101 Qt::Orientation orient;
102 bool mousePressed;
103 QRubberBand *rubberBand;
104 QPoint lastPos, firstPos;
105 Q3DockWindow *dockWindow;
106 bool mouseOver;
107};
108
109Q3DockWindowResizeHandle::Q3DockWindowResizeHandle(Qt::Orientation o, QWidget *parent,
110 Q3DockWindow *w, const char *)
111 : QWidget(parent, "qt_dockwidget_internal"), mousePressed(false), rubberBand(0), dockWindow(w),
112 mouseOver(false)
113{
114 setOrientation(o);
115}
116
117QSize Q3DockWindowResizeHandle::sizeHint() const
118{
119 QStyleOptionQ3DockWindow opt;
120 opt.init(this);
121 if (!dockWindow->area() || dockWindow->area()->orientation() == Qt::Horizontal)
122 opt.state |= QStyle::State_Horizontal;
123
124 opt.rect = rect();
125 opt.docked = dockWindow->area();
126 opt.closeEnabled = dockWindow->isCloseEnabled();
127 int sw = 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, &opt, this) / 3;
128 return (style()->sizeFromContents(QStyle::CT_Q3DockWindow, &opt, QSize(sw, sw), this).expandedTo(QApplication::globalStrut()));
129}
130
131void Q3DockWindowResizeHandle::setOrientation(Qt::Orientation o)
132{
133 orient = o;
134 if (o == Qt::Horizontal) {
135#ifndef QT_NO_CURSOR
136 setCursor(Qt::splitVCursor);
137#endif
138 setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
139 } else {
140#ifndef QT_NO_CURSOR
141 setCursor(Qt::splitHCursor);
142#endif
143 setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding));
144 }
145}
146
147void Q3DockWindowResizeHandle::mousePressEvent(QMouseEvent *e)
148{
149 e->ignore();
150 if (e->button() != Qt::LeftButton)
151 return;
152 e->accept();
153 mousePressed = true;
154 if (!dockWindow->opaqueMoving())
155 startLineDraw();
156 lastPos = firstPos = e->globalPos();
157 if (!dockWindow->opaqueMoving())
158 drawLine(e->globalPos());
159}
160
161void Q3DockWindowResizeHandle::mouseMoveEvent(QMouseEvent *e)
162{
163 if (!mousePressed)
164 return;
165 if (!dockWindow->opaqueMoving()) {
166 if (orientation() != dockWindow->area()->orientation()) {
167 if (orientation() == Qt::Horizontal) {
168 int minpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).y();
169 int maxpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).y() + dockWindow->area()->height();
170 if (e->globalPos().y() < minpos || e->globalPos().y() > maxpos)
171 return;
172 } else {
173 int minpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).x();
174 int maxpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).x() + dockWindow->area()->width();
175 if (e->globalPos().x() < minpos || e->globalPos().x() > maxpos)
176 return;
177 }
178 } else {
179 QWidget *w = dockWindow->area()->window();
180 if (w) {
181 if (orientation() == Qt::Horizontal) {
182 int minpos = w->mapToGlobal(QPoint(0, 0)).y();
183 int maxpos = w->mapToGlobal(QPoint(0, 0)).y() + w->height();
184 if (e->globalPos().y() < minpos || e->globalPos().y() > maxpos)
185 return;
186 } else {
187 int minpos = w->mapToGlobal(QPoint(0, 0)).x();
188 int maxpos = w->mapToGlobal(QPoint(0, 0)).x() + w->width();
189 if (e->globalPos().x() < minpos || e->globalPos().x() > maxpos)
190 return;
191 }
192 }
193 }
194 }
195
196 if (!dockWindow->opaqueMoving())
197 drawLine(lastPos);
198 lastPos = e->globalPos();
199 if (dockWindow->opaqueMoving()) {
200 mouseReleaseEvent(e);
201 mousePressed = true;
202 firstPos = e->globalPos();
203 }
204 if (!dockWindow->opaqueMoving())
205 drawLine(e->globalPos());
206}
207
208void Q3DockWindowResizeHandle::mouseReleaseEvent(QMouseEvent *e)
209{
210 if (mousePressed) {
211 if (!dockWindow->opaqueMoving()) {
212 drawLine(lastPos);
213 endLineDraw();
214 }
215 if (orientation() != dockWindow->area()->orientation())
216 dockWindow->area()->invalidNextOffset(dockWindow);
217 if (orientation() == Qt::Horizontal) {
218 int dy;
219 if (dockWindow->area()->handlePosition() == Q3DockArea::Normal || orientation() != dockWindow->area()->orientation())
220 dy = e->globalPos().y() - firstPos.y();
221 else
222 dy = firstPos.y() - e->globalPos().y();
223 int d = dockWindow->height() + dy;
224 if (orientation() != dockWindow->area()->orientation()) {
225 dockWindow->setFixedExtentHeight(-1);
226 d = qMax(d, dockWindow->minimumHeight());
227 int ms = dockWindow->area()->maxSpace(d, dockWindow);
228 d = qMin(d, ms);
229 dockWindow->setFixedExtentHeight(d);
230 } else {
231 dockWindow->area()->setFixedExtent(d, dockWindow);
232 }
233 } else {
234 int dx;
235 if (dockWindow->area()->handlePosition() == Q3DockArea::Normal || orientation() != dockWindow->area()->orientation())
236 dx = e->globalPos().x() - firstPos.x();
237 else
238 dx = firstPos.x() - e->globalPos().x();
239 int d = dockWindow->width() + dx;
240 if (orientation() != dockWindow->area()->orientation()) {
241 dockWindow->setFixedExtentWidth(-1);
242 d = qMax(d, dockWindow->minimumWidth());
243 int ms = dockWindow->area()->maxSpace(d, dockWindow);
244 d = qMin(d, ms);
245 dockWindow->setFixedExtentWidth(d);
246 } else {
247 dockWindow->area()->setFixedExtent(d, dockWindow);
248 }
249 }
250 }
251
252 QApplication::postEvent(dockWindow->area(), new QEvent(QEvent::LayoutHint));
253 mousePressed = false;
254}
255
256bool Q3DockWindowResizeHandle::event(QEvent *event)
257{
258 switch (event->type()) {
259 case QEvent::HoverEnter:
260 if (!mouseOver) {
261 mouseOver = true;
262 update();
263 }
264 break;
265 case QEvent::HoverLeave:
266 if (mouseOver) {
267 mouseOver = false;
268 update();
269 }
270 break;
271 default:
272 break;
273 }
274 return QWidget::event(event);
275}
276
277void Q3DockWindowResizeHandle::paintEvent(QPaintEvent *)
278{
279 QPainter p(this);
280 QStyleOption opt(0);
281 opt.init(this);
282 if (orientation() == Qt::Horizontal)
283 opt.state |= QStyle::State_Horizontal;
284 style()->drawPrimitive(QStyle::PE_IndicatorDockWidgetResizeHandle, &opt, &p, this);
285}
286
287void Q3DockWindowResizeHandle::startLineDraw()
288{
289 if (rubberBand)
290 endLineDraw();
291 rubberBand = new QRubberBand(QRubberBand::Line);
292 rubberBand->setGeometry(-1, -1, 1, 1);
293 rubberBand->show();
294}
295
296void Q3DockWindowResizeHandle::endLineDraw()
297{
298 delete rubberBand;
299 rubberBand = 0;
300}
301
302void Q3DockWindowResizeHandle::drawLine(const QPoint &globalPos)
303{
304 QPoint start = mapToGlobal(QPoint(0, 0));
305 QPoint starta = dockWindow->area()->mapToGlobal(QPoint(0, 0));
306 QPoint end = globalPos;
307 if (orientation() == Qt::Horizontal) {
308 if (orientation() == dockWindow->orientation())
309 rubberBand->setGeometry(starta.x(), end.y(), dockWindow->area()->width(), height());
310 else
311 rubberBand->setGeometry(start.x(), end.y(), width(), height());
312 } else {
313 if (orientation() == dockWindow->orientation())
314 rubberBand->setGeometry(end.x(), starta.y(), width(), dockWindow->area()->height());
315 else
316 rubberBand->setGeometry(end.x(), start.y(), width(), height());
317 }
318}
319
320static QPoint realWidgetPos(Q3DockWindow *w)
321{
322 if (!w->parentWidget() || w->place() == Q3DockWindow::OutsideDock)
323 return w->pos();
324 return w->parentWidget()->mapToGlobal(w->geometry().topLeft());
325}
326
327class Q3DockWindowHandle : public QWidget
328{
329 Q_OBJECT
330 Q_PROPERTY(QString windowTitle READ windowTitle)
331 friend class Q3DockWindow;
332 friend class Q3DockWindowTitleBar;
333
334public:
335 Q3DockWindowHandle(Q3DockWindow *dw);
336 void updateGui();
337
338 QSize minimumSizeHint() const;
339 QSize minimumSize() const { return minimumSizeHint(); }
340 QSize sizeHint() const { return minimumSize(); }
341 void setOpaqueMoving(bool b) { opaque = b; }
342
343 QString windowTitle() const { return dockWindow->windowTitle(); }
344
345signals:
346 void doubleClicked();
347
348protected:
349 void paintEvent(QPaintEvent *e);
350 void resizeEvent(QResizeEvent *e);
351 void mousePressEvent(QMouseEvent *e);
352 void mouseMoveEvent(QMouseEvent *e);
353 void mouseReleaseEvent(QMouseEvent *e);
354 void mouseDoubleClickEvent(QMouseEvent *e);
355 void keyPressEvent(QKeyEvent *e);
356 void keyReleaseEvent(QKeyEvent *e);
357 void changeEvent(QEvent *);
358
359private slots:
360 void minimize();
361
362private:
363 Q3DockWindow *dockWindow;
364 QPoint offset;
365 QToolButton *closeButton;
366 QTimer *timer;
367 uint opaque : 1;
368 uint mousePressed : 1;
369 uint hadDblClick : 1;
370 uint ctrlDown : 1;
371 QPointer<QWidget> oldFocus;
372};
373
374class Q3DockWindowTitleBar : public Q3TitleBar
375{
376 Q_OBJECT
377 friend class Q3DockWindow;
378 friend class Q3DockWindowHandle;
379
380public:
381 Q3DockWindowTitleBar(Q3DockWindow *dw);
382 void updateGui();
383 void setOpaqueMoving(bool b) { opaque = b; }
384
385protected:
386 void resizeEvent(QResizeEvent *e);
387 void mousePressEvent(QMouseEvent *e);
388 void mouseMoveEvent(QMouseEvent *e);
389 void mouseReleaseEvent(QMouseEvent *e);
390 void mouseDoubleClickEvent(QMouseEvent *e);
391 void keyPressEvent(QKeyEvent *e);
392 void keyReleaseEvent(QKeyEvent *e);
393
394private:
395 Q3DockWindow *dockWindow;
396 QPoint offset;
397 uint mousePressed : 1;
398 uint hadDblClick : 1;
399 uint opaque : 1;
400 uint ctrlDown : 1;
401 QPointer<QWidget> oldFocus;
402
403};
404
405Q3DockWindowHandle::Q3DockWindowHandle(Q3DockWindow *dw)
406 : QWidget(dw, "qt_dockwidget_internal"), dockWindow(dw),
407 closeButton(0), opaque(default_opaque), mousePressed(false)
408{
409 ctrlDown = false;
410 timer = new QTimer(this);
411 connect(timer, SIGNAL(timeout()), this, SLOT(minimize()));
412#ifdef Q_WS_WIN
413 setCursor(Qt::SizeAllCursor);
414#endif
415}
416
417void Q3DockWindowHandle::paintEvent(QPaintEvent *e)
418{
419 if (!dockWindow->dockArea && !opaque)
420 return;
421 QPainter p(this);
422 QStyleOptionQ3DockWindow opt;
423 opt.init(this);
424 if (!dockWindow->area() || dockWindow->area()->orientation() == Qt::Horizontal)
425 opt.state |= QStyle::State_Horizontal;
426
427 opt.rect = rect();
428 opt.docked = dockWindow->area();
429 opt.closeEnabled = dockWindow->isCloseEnabled();
430 opt.rect = QStyle::visualRect(opt.direction, opt.rect,
431 style()->subElementRect(QStyle::SE_Q3DockWindowHandleRect, &opt, this));
432 style()->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p, this);
433 QWidget::paintEvent(e);
434}
435
436void Q3DockWindowHandle::keyPressEvent(QKeyEvent *e)
437{
438 if (!mousePressed)
439 return;
440 if (e->key() == Qt::Key_Control) {
441 ctrlDown = true;
442 dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
443 }
444}
445
446void Q3DockWindowHandle::keyReleaseEvent(QKeyEvent *e)
447{
448 if (!mousePressed)
449 return;
450 if (e->key() == Qt::Key_Control) {
451 ctrlDown = false;
452 dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
453 }
454}
455
456void Q3DockWindowHandle::mousePressEvent(QMouseEvent *e)
457{
458 if (!dockWindow->dockArea)
459 return;
460 ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
461 oldFocus = qApp->focusWidget();
462 setFocus();
463 e->ignore();
464 if (e->button() != Qt::LeftButton)
465 return;
466 e->accept();
467 hadDblClick = false;
468 mousePressed = true;
469 offset = e->pos();
470 dockWindow->startRectDraw(mapToGlobal(e->pos()), !opaque);
471 if (!opaque)
472 qApp->installEventFilter(dockWindow);
473}
474
475void Q3DockWindowHandle::mouseMoveEvent(QMouseEvent *e)
476{
477 if (!mousePressed || e->pos() == offset)
478 return;
479 ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
480 dockWindow->handleMove(e->pos() - offset, e->globalPos(), !opaque);
481 if (opaque)
482 dockWindow->updatePosition(e->globalPos());
483}
484
485void Q3DockWindowHandle::mouseReleaseEvent(QMouseEvent *e)
486{
487 ctrlDown = false;
488 qApp->removeEventFilter(dockWindow);
489 if (oldFocus)
490 oldFocus->setFocus();
491 if (!mousePressed)
492 return;
493 dockWindow->endRectDraw(!opaque);
494 mousePressed = false;
495#ifdef Q_WS_MAC
496 releaseMouse();
497#endif
498 if (!hadDblClick && offset == e->pos()) {
499 timer->start(QApplication::doubleClickInterval(), true);
500 } else if (!hadDblClick) {
501 dockWindow->updatePosition(e->globalPos());
502 }
503 if (opaque)
504 dockWindow->titleBar->mousePressed = false;
505 if (dockWindow->parentWidget())
506 QApplication::postEvent(dockWindow->parentWidget(), new QEvent(QEvent::LayoutHint));
507}
508
509void Q3DockWindowHandle::minimize()
510{
511 if (!dockWindow->area())
512 return;
513
514 Q3MainWindow *mw = qobject_cast<Q3MainWindow*>(dockWindow->area()->parentWidget());
515 if (mw && mw->isDockEnabled(dockWindow, Qt::DockMinimized))
516 mw->moveDockWindow(dockWindow, Qt::DockMinimized);
517}
518
519void Q3DockWindowHandle::resizeEvent(QResizeEvent *)
520{
521 updateGui();
522}
523
524void Q3DockWindowHandle::updateGui()
525{
526 updateGeometry();
527
528 if (!closeButton) {
529 closeButton = new QToolButton(this, "qt_close_button1");
530#ifndef QT_NO_CURSOR
531 closeButton->setCursor(Qt::ArrowCursor);
532#endif
533 QStyleOption opt(0);
534 opt.init(closeButton);
535 closeButton->setIcon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton, &opt,
536 closeButton));
537 closeButton->setFixedSize(12, 12);
538 connect(closeButton, SIGNAL(clicked()),
539 dockWindow, SLOT(hide()));
540 }
541
542 if (dockWindow->isCloseEnabled() && dockWindow->area())
543 closeButton->show();
544 else
545 closeButton->hide();
546
547 if (!dockWindow->area())
548 return;
549
550 if (dockWindow->area()->orientation() == Qt::Horizontal) {
551 int off = (width() - closeButton->width() - 1) / 2;
552 closeButton->move(off, 2);
553 } else {
554 int off = (height() - closeButton->height() - 1) / 2;
555 int x = QApplication::reverseLayout() ? 2 : width() - closeButton->width() - 2;
556 closeButton->move(x, off);
557 }
558}
559
560void Q3DockWindowHandle::changeEvent(QEvent *ev)
561{
562 if(ev->type() == QEvent::StyleChange) {
563 if (closeButton) {
564 QStyleOption opt(0);
565 opt.init(closeButton);
566 closeButton->setIcon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton,
567 &opt, closeButton));
568 }
569 }
570 QWidget::changeEvent(ev);
571}
572
573QSize Q3DockWindowHandle::minimumSizeHint() const
574{
575 if (!dockWindow->dockArea)
576 return QSize(0, 0);
577 int wh = dockWindow->isCloseEnabled() ? 17 : style()->pixelMetric(QStyle::PM_ToolBarHandleExtent, 0, this);
578 if (dockWindow->orientation() == Qt::Horizontal)
579 return QSize(wh, 0);
580 return QSize(0, wh);
581}
582
583void Q3DockWindowHandle::mouseDoubleClickEvent(QMouseEvent *e)
584{
585 e->ignore();
586 if (e->button() != Qt::LeftButton)
587 return;
588 e->accept();
589 timer->stop();
590 emit doubleClicked();
591 hadDblClick = true;
592 if (dockWindow->parentWidget())
593 QApplication::postEvent(dockWindow->parentWidget(), new QEvent(QEvent::LayoutHint));
594}
595
596Q3DockWindowTitleBar::Q3DockWindowTitleBar(Q3DockWindow *dw)
597 : Q3TitleBar(0, dw), dockWindow(dw),
598 mousePressed(false), hadDblClick(false), opaque(default_opaque)
599{
600 setObjectName(QLatin1String("qt_dockwidget_internal"));
601 ctrlDown = false;
602 setMouseTracking(true);
603 QStyleOptionTitleBar opt = getStyleOption();
604 setFixedHeight(style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, this));
605 connect(this, SIGNAL(doClose()), dockWindow, SLOT(hide()));
606}
607
608void Q3DockWindowTitleBar::keyPressEvent(QKeyEvent *e)
609{
610 if (!mousePressed)
611 return;
612 if (e->key() == Qt::Key_Control) {
613 ctrlDown = true;
614 dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
615 }
616}
617
618void Q3DockWindowTitleBar::keyReleaseEvent(QKeyEvent *e)
619{
620 if (!mousePressed)
621 return;
622 if (e->key() == Qt::Key_Control) {
623 ctrlDown = false;
624 dockWindow->handleMove(mapFromGlobal(QCursor::pos()) - offset, QCursor::pos(), !opaque);
625 }
626}
627
628void Q3DockWindowTitleBar::mousePressEvent(QMouseEvent *e)
629{
630 QStyleOptionTitleBar opt;
631 opt.init(this);
632 opt.subControls = QStyle::SC_All;
633 opt.activeSubControls = QStyle::SC_None;
634 opt.text = windowTitle();
635 //################
636 QIcon icon = windowIcon();
637 QSize s = icon.actualSize(QSize(64, 64));
638 opt.icon = icon.pixmap(s);
639 opt.titleBarState = window() ? window()->windowState() : static_cast<Qt::WindowStates>(Qt::WindowNoState);
640 opt.titleBarFlags = fakeWindowFlags();
641 QStyle::SubControl tbctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
642 e->pos(), this);
643
644 if (tbctrl < QStyle::SC_TitleBarLabel && tbctrl != QStyle::SC_None) {
645 Q3TitleBar::mousePressEvent(e);
646 return;
647 }
648
649 ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
650 oldFocus = qApp->focusWidget();
651// setFocus activates the window, which deactivates the main window
652// not what we want, and not required anyway on Windows
653#ifndef Q_WS_WIN
654 setFocus();
655#endif
656
657 e->ignore();
658 if (e->button() != Qt::LeftButton)
659 return;
660 if (e->y() < 3 && dockWindow->isResizeEnabled())
661 return;
662
663 e->accept();
664 bool oldPressed = mousePressed;
665 mousePressed = true;
666 hadDblClick = false;
667 offset = e->pos();
668 dockWindow->startRectDraw(mapToGlobal(e->pos()), !opaque);
669// grabMouse resets the Windows mouse press count, so we never receive a double click on Windows
670// not required on Windows, and did work on X11, too, but no problem there in the first place
671#ifndef Q_WS_WIN
672 if(!oldPressed && dockWindow->opaqueMoving())
673 grabMouse();
674#else
675 Q_UNUSED(oldPressed);
676#endif
677}
678
679void Q3DockWindowTitleBar::mouseMoveEvent(QMouseEvent *e)
680{
681 if (!mousePressed) {
682 Q3TitleBar::mouseMoveEvent(e);
683 return;
684 }
685
686 ctrlDown = (e->state() & Qt::ControlButton) == Qt::ControlButton;
687 e->accept();
688 dockWindow->handleMove(e->pos() - offset, e->globalPos(), !opaque);
689}
690
691void Q3DockWindowTitleBar::mouseReleaseEvent(QMouseEvent *e)
692{
693 if (!mousePressed) {
694 Q3TitleBar::mouseReleaseEvent(e);
695 return;
696 }
697
698 ctrlDown = false;
699 qApp->removeEventFilter(dockWindow);
700 if (oldFocus)
701 oldFocus->setFocus();
702
703 if (dockWindow->place() == Q3DockWindow::OutsideDock)
704 dockWindow->raise();
705
706 if(dockWindow->opaqueMoving())
707 releaseMouse();
708 if (!mousePressed)
709 return;
710 dockWindow->endRectDraw(!opaque);
711 mousePressed = false;
712 if (!hadDblClick)
713 dockWindow->updatePosition(e->globalPos());
714 if (opaque) {
715 dockWindow->horHandle->mousePressed = false;
716 dockWindow->verHandle->mousePressed = false;
717 }
718 if (dockWindow->parentWidget())
719 QApplication::postEvent(dockWindow->parentWidget(), new QEvent(QEvent::LayoutHint));
720}
721
722void Q3DockWindowTitleBar::resizeEvent(QResizeEvent *e)
723{
724 updateGui();
725 Q3TitleBar::resizeEvent(e);
726}
727
728void Q3DockWindowTitleBar::updateGui()
729{
730 if (dockWindow->isCloseEnabled()) {
731 setFakeWindowFlags(fakeWindowFlags() | Qt::WStyle_SysMenu);
732 } else {
733 setFakeWindowFlags(fakeWindowFlags() & ~Qt::WStyle_SysMenu);
734 }
735}
736
737void Q3DockWindowTitleBar::mouseDoubleClickEvent(QMouseEvent *)
738{
739 emit doubleClicked();
740 hadDblClick = true;
741 if (dockWindow->parentWidget())
742 QApplication::postEvent(dockWindow->parentWidget(), new QEvent(QEvent::LayoutHint));
743}
744
745/*!
746 \class Q3DockWindow
747 \brief The Q3DockWindow class provides a widget which can be docked
748 inside a Q3DockArea or floated as a top level window on the
749 desktop.
750
751 \compat
752
753 This class handles moving, resizing, docking and undocking dock
754 windows. Q3ToolBar is a subclass of Q3DockWindow so the
755 functionality provided for dock windows is available with the same
756 API for toolbars.
757
758 \img qmainwindow-qdockareas.png Q3DockWindows in a Q3DockArea
759 \caption Two Q3DockWindows (\l{Q3ToolBar}s) in a \l Q3DockArea
760
761 \img qdockwindow.png A Q3DockWindow
762 \caption A Floating Q3DockWindow
763
764 If the user drags the dock window into the dock area the dock
765 window will be docked. If the user drags the dock area outside any
766 dock areas the dock window will be undocked (floated) and will
767 become a top level window. Double clicking a floating dock
768 window's title bar will dock the dock window to the last dock area
769 it was docked in. Double clicking a docked dock window's handle
770 will undock (float) the dock window.
771 \omit
772 Single clicking a docked dock window's handle will minimize the
773 dock window (only its handle will appear, below the menu bar).
774 Single clicking the minimized handle will restore the dock window
775 to the last dock area that it was docked in.
776 \endomit
777 If the user clicks the close button (which appears on floating
778 dock windows by default) the dock window will disappear. You can
779 control whether or not a dock window has a close button with
780 setCloseMode().
781
782 Q3MainWindow provides four dock areas (top, left, right and bottom)
783 which can be used by dock windows. For many applications using the
784 dock areas provided by Q3MainWindow is sufficient. (See the \l
785 Q3DockArea documentation if you want to create your own dock
786 areas.) In Q3MainWindow a right-click popup menu (the dock window
787 menu) is available which lists dock windows and can be used to
788 show or hide them. (The popup menu only lists dock windows that
789 have a \link QWidget::setWindowTitle() caption\endlink.)
790
791 When you construct a dock window you \e must pass it a Q3DockArea
792 or a Q3MainWindow as its parent if you want it docked. Pass 0 for
793 the parent if you want it floated.
794
795 \snippet doc/src/snippets/code/src_qt3support_widgets_q3dockwindow.cpp 0
796
797 In the example above we create a new Q3ToolBar in the constructor
798 of a Q3MainWindow subclass (so that the \e this pointer points to
799 the Q3MainWindow). By default the toolbar will be added to the \c
800 Top dock area, but we've moved it to the \c Left dock area.
801
802 A dock window is often used to contain a single widget. In these
803 cases the widget can be set by calling setWidget(). If you're
804 constructing a dock window that contains multiple widgets, e.g. a
805 toolbar, arrange the widgets within a box layout inside the dock
806 window. To do this use the boxLayout() function to get a pointer
807 to the dock window's box layout, then add widgets to the layout
808 using the box layout's QBoxLayout::addWidget() function. The dock
809 window will dynamically set the orientation of the layout to be
810 vertical or horizontal as necessary, although you can control this
811 yourself with setOrientation().
812
813 Although a common use of dock windows is for toolbars, they can be
814 used with any widgets. When using larger
815 widgets it may make sense for the dock window to be resizable by
816 calling setResizeEnabled(). Resizable dock windows are given
817 splitter-like handles to allow the user to resize them within
818 their dock area. When resizable dock windows are undocked they
819 become top level windows and can be resized like any other top
820 level windows, e.g. by dragging a corner or edge.
821
822 Qt::Dock windows can be docked and undocked using dock() and undock().
823 A dock window's orientation can be set with setOrientation(). You
824 can also use Q3DockArea::moveDockWindow(). If you're using a
825 Q3MainWindow, Q3MainWindow::moveDockWindow() and
826 Q3MainWindow::removeDockWindow() are available.
827
828 A dock window can have some preferred settings, for example, you
829 can set a preferred offset from the left edge (or top edge for
830 vertical dock areas) of the dock area using setOffset(). If you'd
831 prefer a dock window to start on a new line when it is docked use
832 setNewLine(). The setFixedExtentWidth() and setFixedExtentHeight()
833 functions can be used to define the dock window's preferred size,
834 and the setHorizontallyStretchable() and setVerticallyStretchable()
835 functions set whether the dock window can be stretched or not.
836 Dock windows can be moved by default, but this can be changed with
837 setMovingEnabled(). When a dock window is moved it is shown as a
838 rectangular outline, but it can be shown normally using
839 setOpaqueMoving().
840
841 When a dock window's visibility changes, i.e. it is shown or
842 hidden, the visibilityChanged() signal is emitted. When a dock
843 window is docked, undocked or moved inside the dock area the
844 placeChanged() signal is emitted.
845*/
846
847/*!
848 \enum Q3DockWindow::Place
849
850 This enum specifies the possible locations for a Q3DockWindow:
851
852 \value InDock Inside a Q3DockArea.
853 \value OutsideDock Floating as a top level window on the desktop.
854*/
855
856/*!
857 \enum Q3DockWindow::CloseMode
858
859 This enum type specifies when (if ever) a dock window has a close
860 button.
861
862 \value Never The dock window never has a close button and cannot
863 be closed by the user.
864 \value Docked The dock window has a close button only when
865 docked.
866 \value Undocked The dock window has a close button only when
867 floating.
868 \value Always The dock window always has a close button.
869 \omit
870 Note that dock windows can always be minimized if the user clicks
871 their dock window handle when they are docked.
872 \endomit
873*/
874
875/*!
876 \fn void Q3DockWindow::setHorizontalStretchable(bool b)
877
878 If \a b is true the dock window is set to be horizontally
879 stretchable.
880*/
881/*!
882 \fn void Q3DockWindow::setVerticalStretchable(bool b)
883
884 If \a b is true the dock window is set to be vertically
885 stretchable.
886*/
887/*!
888 \fn bool Q3DockWindow::isHorizontalStretchable() const
889
890 Returns true if the dock window can be stretched horizontally;
891 otherwise returns false.
892*/
893/*!
894 \fn bool Q3DockWindow::isVerticalStretchable() const
895
896 Returns true if the dock window can be stretched vertically;
897 otherwise returns false.
898*/
899/*!
900 \fn void Q3DockWindow::orientationChanged(Qt::Orientation o)
901
902 This signal is emitted when the orientation of the dock window is
903 changed. The new orientation is \a o.
904*/
905
906/*!
907 \fn void Q3DockWindow::placeChanged(Q3DockWindow::Place p)
908
909 This signal is emitted when the dock window is docked (\a p is \c
910 InDock), undocked (\a p is \c OutsideDock) or moved inside the
911 the dock area.
912
913 \sa Q3DockArea::moveDockWindow(), Q3DockArea::removeDockWindow(),
914 Q3MainWindow::moveDockWindow(), Q3MainWindow::removeDockWindow()
915*/
916
917/*!
918 \fn void Q3DockWindow::visibilityChanged(bool visible)
919
920 This signal is emitted when the visibility of the dock window
921 relatively to its dock area is changed. If \a visible is true, the
922 Q3DockWindow is now visible to the dock area, otherwise it has been
923 hidden.
924
925 A dock window can be hidden if it has a close button which the
926 user has clicked. In the case of a Q3MainWindow a dock window can
927 have its visibility changed (hidden or shown) by clicking its name
928 in the dock window menu that lists the Q3MainWindow's dock windows.
929*/
930
931/*!
932 \fn Q3DockArea *Q3DockWindow::area() const
933
934 Returns the dock area in which this dock window is docked, or 0 if
935 the dock window is floating.
936*/
937
938/*!
939 \property Q3DockWindow::place
940 \brief the location where the dock window is placed
941
942 This is either \c InDock or \c OutsideDock.
943
944 \sa Q3DockArea::moveDockWindow(), Q3DockArea::removeDockWindow(),
945 Q3MainWindow::moveDockWindow(), Q3MainWindow::removeDockWindow()
946*/
947
948/*!
949 Constructs a Q3DockWindow with parent \a parent, called \a name and
950 with widget flags \a f.
951*/
952
953Q3DockWindow::Q3DockWindow(QWidget* parent, const char* name, Qt::WindowFlags f)
954 : Q3Frame(parent, name, f | Qt::WType_Dialog | Qt::WStyle_Customize | Qt::WStyle_NoBorder)
955{
956 curPlace = InDock;
957 isToolbar = false;
958 init();
959}
960
961/*!
962 Constructs a Q3DockWindow with parent \a parent, called \a name and
963 with widget flags \a f.
964
965 If \a p is \c InDock, the dock window is docked into a dock area
966 and \a parent \e must be a Q3DockArea or a Q3MainWindow. If the \a
967 parent is a Q3MainWindow the dock window will be docked in the main
968 window's \c Top dock area.
969
970 If \a p is \c OutsideDock, the dock window is created as a floating
971 window.
972
973 We recommend creating the dock area \c InDock with a Q3MainWindow
974 as parent then calling Q3MainWindow::moveDockWindow() to move the
975 dock window where you want it.
976*/
977
978Q3DockWindow::Q3DockWindow(Place p, QWidget *parent, const char *name, Qt::WindowFlags f)
979 : Q3Frame(parent, name, f | Qt::WType_Dialog | Qt::WStyle_Customize | Qt::WStyle_NoBorder)
980{
981 curPlace = p;
982 isToolbar = false;
983 init();
984}
985
986/*! \internal
987*/
988
989Q3DockWindow::Q3DockWindow(Place p, QWidget *parent, const char *name, Qt::WindowFlags f, bool toolbar)
990 : Q3Frame(parent, name, f | Qt::WType_Dialog | Qt::WStyle_Customize | Qt::WStyle_NoBorder)
991{
992 curPlace = p;
993 isToolbar = toolbar;
994 init();
995}
996
997class Q3DockWindowGridLayout : public QGridLayout
998{
999public:
1000 Q3DockWindowGridLayout(QWidget *parent, int nRows, int nCols)
1001 : QGridLayout(parent, nRows, nCols) {};
1002
1003 Qt::Orientations expandingDirections() const
1004 {
1005 return 0;
1006 }
1007};
1008
1009void Q3DockWindow::init()
1010{
1011 wid = 0;
1012 rubberBand = 0;
1013 dockArea = 0;
1014 tmpDockArea = 0;
1015 resizeEnabled = false;
1016 moveEnabled = true;
1017 nl = false;
1018 opaque = default_opaque;
1019 cMode = Never;
1020 offs = 0;
1021 fExtent = QSize(-1, -1);
1022 dockWindowData = 0;
1023 lastPos = QPoint(-1, -1);
1024 lastSize = QSize(-1, -1);
1025 stretchable[Qt::Horizontal] = false;
1026 stretchable[Qt::Vertical] = false;
1027
1028 widgetResizeHandler = new QWidgetResizeHandler(this);
1029 widgetResizeHandler->setMovingEnabled(false);
1030
1031 titleBar = new Q3DockWindowTitleBar(this);
1032 verHandle = new Q3DockWindowHandle(this);
1033 verHandle->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
1034 horHandle = new Q3DockWindowHandle(this);
1035 horHandle->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
1036
1037 vHandleLeft = new Q3DockWindowResizeHandle(Qt::Vertical, this, this, "vert. handle");
1038 vHandleRight = new Q3DockWindowResizeHandle(Qt::Vertical, this, this, "vert. handle");
1039 hHandleTop = new Q3DockWindowResizeHandle(Qt::Horizontal, this, this, "horz. handle");
1040 hHandleBottom = new Q3DockWindowResizeHandle(Qt::Horizontal, this, this, "horz. handle");
1041
1042 // Creating inner layout
1043 hbox = new QVBoxLayout();
1044 vbox = new QHBoxLayout();
1045 childBox = new QBoxLayout(QBoxLayout::LeftToRight);
1046 vbox->addSpacing(2);
1047 vbox->addWidget(verHandle);
1048 vbox->addStretch(0);
1049 vbox->addLayout(childBox, 1);
1050 vbox->addStretch(0);
1051
1052 hbox->setResizeMode(QLayout::FreeResize);
1053 hbox->setMargin(isResizeEnabled() || curPlace == OutsideDock ? 2 : 0);
1054 hbox->setSpacing(1);
1055 hbox->addWidget(titleBar);
1056 hbox->addWidget(horHandle);
1057 hbox->addLayout(vbox);
1058
1059 // Set up the initial handle layout for Qt::Vertical
1060 // Handle layout will change on calls to setOrienation()
1061 QGridLayout *glayout = new Q3DockWindowGridLayout(this, 3, 3);
1062 glayout->setResizeMode(QLayout::Minimum);
1063 glayout->addMultiCellWidget(hHandleTop, 0, 0, 1, 1);
1064 glayout->addMultiCellWidget(hHandleBottom, 2, 2, 1, 1);
1065 glayout->addMultiCellWidget(vHandleLeft, 0, 2, 0, 0);
1066 glayout->addMultiCellWidget(vHandleRight, 0, 2, 2, 2);
1067 glayout->addLayout(hbox, 1, 1);
1068 glayout->setRowStretch(1, 1);
1069 glayout->setColStretch(1, 1);
1070
1071 hHandleBottom->hide();
1072 vHandleRight->hide();
1073 hHandleTop->hide();
1074 vHandleLeft->hide();
1075 setFrameStyle(Q3Frame::StyledPanel | Q3Frame::Raised);
1076 setLineWidth(2);
1077
1078 if (parentWidget())
1079 parentWidget()->installEventFilter(this);
1080 QWidget *mw = parentWidget();
1081 Q3DockArea *da = qobject_cast<Q3DockArea*>(parentWidget());
1082 if (da) {
1083 if (curPlace == InDock)
1084 da->moveDockWindow(this);
1085 mw = da->parentWidget();
1086 }
1087 if (qobject_cast<Q3MainWindow*>(mw)) {
1088 if (place() == InDock) {
1089 Qt::Dock myDock = Qt::DockTop;
1090 // make sure we put the window in the correct dock.
1091 if (dockArea) {
1092 Q3MainWindow *mainw = (Q3MainWindow*)mw;
1093 // I'm not checking if it matches the top because I've
1094 // done the assignment to it above.
1095 if (dockArea == mainw->leftDock())
1096 myDock = Qt::DockLeft;
1097 else if (dockArea == mainw->rightDock())
1098 myDock = Qt::DockRight;
1099 else if (dockArea == mainw->bottomDock())
1100 myDock = Qt::DockBottom;
1101 }
1102 ((Q3MainWindow*)mw)->addDockWindow(this, myDock);
1103 }
1104 moveEnabled = ((Q3MainWindow*)mw)->dockWindowsMovable();
1105 opaque = ((Q3MainWindow*)mw)->opaqueMoving();
1106 }
1107
1108 updateGui();
1109
1110 connect(titleBar, SIGNAL(doubleClicked()), this, SLOT(dock()));
1111 connect(verHandle, SIGNAL(doubleClicked()), this, SLOT(undock()));
1112 connect(horHandle, SIGNAL(doubleClicked()), this, SLOT(undock()));
1113 connect(this, SIGNAL(orientationChanged(Qt::Orientation)),
1114 this, SLOT(setOrientation(Qt::Orientation)));
1115}
1116
1117/*!
1118 Sets the orientation of the dock window to \a o. The orientation
1119 is propagated to the layout boxLayout().
1120
1121 \warning All undocked Q3ToolBars will always have a horizontal orientation.
1122*/
1123
1124void Q3DockWindow::setOrientation(Qt::Orientation o)
1125{
1126 QGridLayout *glayout = (QGridLayout*)layout();
1127 glayout->removeWidget(hHandleTop);
1128 glayout->removeWidget(hHandleBottom);
1129 glayout->removeWidget(vHandleLeft);
1130 glayout->removeWidget(vHandleRight);
1131
1132 if (o == Qt::Horizontal) {
1133 // Set up the new layout as
1134 // 3 3 3 1 = vHandleLeft 4 = hHandleBottom
1135 // 1 X 2 2 = vHandleRight X = Inner Layout
1136 // 4 4 4 3 = hHandleTop
1137 glayout->addMultiCellWidget(hHandleTop, 0, 0, 0, 2);
1138 glayout->addMultiCellWidget(hHandleBottom, 2, 2, 0, 2);
1139 glayout->addMultiCellWidget(vHandleLeft, 1, 1, 0, 0);
1140 glayout->addMultiCellWidget(vHandleRight, 1, 1, 2, 2);
1141 } else {
1142 // Set up the new layout as
1143 // 1 3 2 1 = vHandleLeft 4 = hHandleBottom
1144 // 1 X 2 2 = vHandleRight X = Inner Layout
1145 // 1 4 2 3 = hHandleTop
1146 glayout->addMultiCellWidget(hHandleTop, 0, 0, 1, 1);
1147 glayout->addMultiCellWidget(hHandleBottom, 2, 2, 1, 1);
1148 glayout->addMultiCellWidget(vHandleLeft, 0, 2, 0, 0);
1149 glayout->addMultiCellWidget(vHandleRight, 0, 2, 2, 2);
1150 }
1151 boxLayout()->setDirection(o == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom);
1152 QApplication::sendPostedEvents(this, QEvent::LayoutHint);
1153 QEvent *e = new QEvent(QEvent::LayoutHint);
1154 QApplication::postEvent(this, e);
1155}
1156
1157/*!
1158 Destroys the dock window and its child widgets.
1159*/
1160
1161Q3DockWindow::~Q3DockWindow()
1162{
1163 qApp->removeEventFilter(this);
1164 if (area())
1165 area()->removeDockWindow(this, false, false);
1166 Q3DockArea *a = area();
1167 if (!a && dockWindowData)
1168 a = ((Q3DockArea::DockWindowData*)dockWindowData)->area;
1169 Q3MainWindow *mw = a ? qobject_cast<Q3MainWindow*>(a->parentWidget()) : 0;
1170 if (mw)
1171 mw->removeDockWindow(this);
1172
1173 delete (Q3DockArea::DockWindowData*)dockWindowData;
1174}
1175
1176/*! \reimp
1177*/
1178
1179void Q3DockWindow::resizeEvent(QResizeEvent *e)
1180{
1181 Q3Frame::resizeEvent(e);
1182 updateGui();
1183}
1184
1185
1186void Q3DockWindow::swapRect(QRect &r, Qt::Orientation o, const QPoint &offset, Q3DockArea *)
1187{
1188 r.setSize(QSize(r.height(), r.width()));
1189 bool reverse = QApplication::reverseLayout();
1190 if (o == Qt::Horizontal)
1191 r.moveBy(-r.width()/2, 0);
1192 else
1193 r.moveBy(reverse ? - r.width() : 0, -r.height() / 2 );
1194 r.moveBy(offset.x(), offset.y());
1195}
1196
1197QWidget *Q3DockWindow::areaAt(const QPoint &gp)
1198{
1199 QWidget *w = qApp->widgetAt(gp);
1200
1201 if (w && (w == this || w == titleBar) && parentWidget())
1202 w = parentWidget()->childAt(parentWidget()->mapFromGlobal(gp));
1203
1204 while (w) {
1205 if (qobject_cast<Q3DockArea*>(w)) {
1206 Q3DockArea *a = (Q3DockArea*)w;
1207 if (a->isDockWindowAccepted(this))
1208 return w;
1209 }
1210 if (qobject_cast<Q3MainWindow*>(w)) {
1211 Q3MainWindow *mw = (Q3MainWindow*)w;
1212 Q3DockArea *a = mw->dockingArea(mw->mapFromGlobal(gp));
1213 if (a && a->isDockWindowAccepted(this))
1214 return a;
1215 }
1216 w = w->isWindow() ? 0 : (QWidget *)w->parent();
1217 }
1218 return 0;
1219}
1220
1221void Q3DockWindow::handleMove(const QPoint &pos, const QPoint &gp, bool drawRect)
1222{
1223 if (!rubberBand)
1224 return;
1225
1226 currRect = QRect(realWidgetPos(this), size());
1227 QWidget *w = areaAt(gp);
1228 if (titleBar->ctrlDown || horHandle->ctrlDown || verHandle->ctrlDown)
1229 w = 0;
1230 currRect.moveBy(pos.x(), pos.y());
1231 if (!qobject_cast<Q3DockArea*>(w)) {
1232 if (startOrientation != Qt::Horizontal && qobject_cast<Q3ToolBar*>(this))
1233 swapRect(currRect, Qt::Horizontal, startOffset, (Q3DockArea*)w);
1234 if (drawRect) {
1235 rubberBand->setGeometry(currRect);
1236 } else {
1237 QPoint mp(mapToGlobal(pos));
1238 if(place() == InDock) {
1239 undock();
1240 if(titleBar) {
1241 mp = QPoint(titleBar->width() / 2, titleBar->height() / 2);
1242 QMouseEvent me(QEvent::MouseButtonPress, mp, Qt::LeftButton, 0);
1243 QApplication::sendEvent(titleBar, &me);
1244 mp = titleBar->mapToGlobal(mp);
1245 }
1246 }
1247 move(mp);
1248 }
1249 state = OutsideDock;
1250 return;
1251 }
1252
1253 Q3DockArea *area = (Q3DockArea*)w;
1254 if(area->isVisible()) {
1255 state = InDock;
1256 Qt::Orientation o = (area ? area->orientation() :
1257 (boxLayout()->direction() == QBoxLayout::LeftToRight ||
1258 boxLayout()->direction() == QBoxLayout::RightToLeft ?
1259 Qt::Horizontal : Qt::Vertical));
1260 if (startOrientation != o)
1261 swapRect(currRect, o, startOffset, area);
1262 if (drawRect) {
1263 rubberBand->setGeometry(currRect);
1264 }
1265 tmpDockArea = area;
1266 }
1267}
1268
1269void Q3DockWindow::updateGui()
1270{
1271 if (curPlace == OutsideDock) {
1272 hbox->setMargin(2);
1273 horHandle->hide();
1274 verHandle->hide();
1275 if (moveEnabled)
1276 titleBar->show();
1277 else
1278 titleBar->hide();
1279 titleBar->updateGui();
1280 hHandleTop->hide();
1281 vHandleLeft->hide();
1282 hHandleBottom->hide();
1283 vHandleRight->hide();
1284 setLineWidth(2);
1285 widgetResizeHandler->setActive(isResizeEnabled());
1286 } else {
1287 hbox->setMargin(0);
1288 titleBar->hide();
1289 if (orientation() == Qt::Horizontal) {
1290 horHandle->hide();
1291 if (moveEnabled)
1292 verHandle->show();
1293 else
1294 verHandle->hide();
1295#ifdef Q_WS_MAC
1296 if(horHandle->mousePressed) {
1297 horHandle->mousePressed = false;
1298 verHandle->mousePressed = true;
1299 verHandle->grabMouse();
1300 }
1301#endif
1302 verHandle->updateGui();
1303 } else {
1304 if (moveEnabled)
1305 horHandle->show();
1306 else
1307 horHandle->hide();
1308 horHandle->updateGui();
1309#ifdef Q_WS_MAC
1310 if(verHandle->mousePressed) {
1311 verHandle->mousePressed = false;
1312 horHandle->mousePressed = true;
1313 horHandle->grabMouse();
1314 }
1315#endif
1316 verHandle->hide();
1317 }
1318 if (isResizeEnabled()) {
1319 if (orientation() == Qt::Horizontal) {
1320 hHandleBottom->raise();
1321 hHandleTop->raise();
1322 } else {
1323 vHandleRight->raise();
1324 vHandleLeft->raise();
1325 }
1326
1327 if (area()) {
1328 if (orientation() == Qt::Horizontal) {
1329 if (area()->handlePosition() == Q3DockArea::Normal) {
1330 hHandleBottom->show();
1331 hHandleTop->hide();
1332 } else {
1333 hHandleTop->show();
1334 hHandleBottom->hide();
1335 }
1336 if (!area()->isLastDockWindow(this))
1337 vHandleRight->show();
1338 else
1339 vHandleRight->hide();
1340 vHandleLeft->hide();
1341 } else {
1342 if ((area()->handlePosition() == Q3DockArea::Normal) != QApplication::reverseLayout()) {
1343 vHandleRight->show();
1344 vHandleLeft->hide();
1345 } else {
1346 vHandleLeft->show();
1347 vHandleRight->hide();
1348 }
1349 if (!area()->isLastDockWindow(this))
1350 hHandleBottom->show();
1351 else
1352 hHandleBottom->hide();
1353 hHandleTop->hide();
1354 }
1355 }
1356 }
1357#ifndef Q_OS_WINCE
1358 if (moveEnabled)
1359 setLineWidth(1);
1360 else
1361 setLineWidth(0);
1362#endif
1363 widgetResizeHandler->setActive(false);
1364 }
1365}
1366
1367void Q3DockWindow::updatePosition(const QPoint &globalPos)
1368{
1369 if (curPlace == OutsideDock && state == InDock)
1370 lastSize = size();
1371
1372 bool doAdjustSize = curPlace != state && state == OutsideDock;
1373 bool doUpdate = true;
1374 bool doOrientationChange = true;
1375 if (state != curPlace && state == InDock) {
1376 doUpdate = false;
1377 curPlace = state;
1378 updateGui();
1379 QApplication::sendPostedEvents();
1380 }
1381 Qt::Orientation oo = orientation();
1382
1383 if (state == InDock) {
1384 if (tmpDockArea) {
1385 bool differentDocks = false;
1386 if (dockArea && dockArea != tmpDockArea) {
1387 differentDocks = true;
1388 delete (Q3DockArea::DockWindowData*)dockWindowData;
1389 dockWindowData = dockArea->dockWindowData(this);
1390 dockArea->removeDockWindow(this, false, false);
1391 }
1392 dockArea = tmpDockArea;
1393 if (differentDocks) {
1394 if (doUpdate) {
1395 doUpdate = false;
1396 curPlace = state;
1397 updateGui();
1398 }
1399 emit orientationChanged(tmpDockArea->orientation());
1400 doOrientationChange = false;
1401 } else {
1402 updateGui();
1403 }
1404 dockArea->moveDockWindow(this, globalPos, currRect, startOrientation != oo);
1405 }
1406 } else {
1407 if (dockArea) {
1408 Q3MainWindow *mw = (Q3MainWindow*)dockArea->parentWidget();
1409 if (qobject_cast<Q3MainWindow*>(mw) &&
1410 (!mw->isDockEnabled(Qt::DockTornOff) ||
1411 !mw->isDockEnabled(this, Qt::DockTornOff)))
1412 return;
1413 delete (Q3DockArea::DockWindowData*)dockWindowData;
1414 dockWindowData = dockArea->dockWindowData(this);
1415 dockArea->removeDockWindow(this, true,
1416 startOrientation != Qt::Horizontal && qobject_cast<Q3ToolBar*>(this));
1417 }
1418 dockArea = 0;
1419 QPoint topLeft = currRect.topLeft();
1420 QRect screen = qApp->desktop()->availableGeometry(topLeft);
1421 if (!screen.contains(topLeft)) {
1422 topLeft.setY(qMax(topLeft.y(), screen.top()));
1423 topLeft.setY(qMin(topLeft.y(), screen.bottom()-height()));
1424 topLeft.setX(qMax(topLeft.x(), screen.left()));
1425 topLeft.setX(qMin(topLeft.x(), screen.right()-width()));
1426 }
1427 move(topLeft);
1428 }
1429
1430 if (curPlace == InDock && state == OutsideDock && !qobject_cast<Q3ToolBar*>(this)) {
1431 if (lastSize != QSize(-1, -1))
1432 resize(lastSize);
1433 }
1434
1435 if (doUpdate) {
1436 curPlace = state;
1437 updateGui();
1438 }
1439 if (doOrientationChange)
1440 emit orientationChanged(orientation());
1441 tmpDockArea = 0;
1442 if (doAdjustSize) {
1443 QApplication::sendPostedEvents(this, QEvent::LayoutHint);
1444 if (qobject_cast<Q3ToolBar*>(this))
1445 adjustSize();
1446 if (lastSize == QSize(-1, -1))
1447 setAttribute(Qt::WA_Resized, false); // Ensures size is recalculated (non-opaque).
1448 show();
1449 if (parentWidget() && isWindow())
1450 parentWidget()->setActiveWindow();
1451
1452 }
1453
1454 emit placeChanged(curPlace);
1455}
1456
1457/*!
1458 Sets the dock window's main widget to \a w.
1459
1460 \sa boxLayout()
1461*/
1462
1463void Q3DockWindow::setWidget(QWidget *w)
1464{
1465 wid = w;
1466 boxLayout()->addWidget(w);
1467 updateGui();
1468}
1469
1470/*!
1471 Returns the dock window's main widget.
1472
1473 \sa setWidget()
1474*/
1475
1476QWidget *Q3DockWindow::widget() const
1477{
1478 return wid;
1479}
1480
1481void Q3DockWindow::startRectDraw(const QPoint &so, bool drawRect)
1482{
1483 state = place();
1484 if (rubberBand)
1485 endRectDraw(!opaque);
1486 rubberBand = new QRubberBand(QRubberBand::Rectangle);
1487 currRect = QRect(realWidgetPos(this), size());
1488 if (drawRect) {
1489 rubberBand->setGeometry(currRect);
1490 }
1491 startOrientation = orientation();
1492 startOffset = mapFromGlobal(so);
1493 rubberBand->show();
1494}
1495
1496void Q3DockWindow::endRectDraw(bool)
1497{
1498 delete rubberBand;
1499 rubberBand = 0;
1500}
1501
1502/*!
1503 \reimp
1504*/
1505void Q3DockWindow::drawFrame(QPainter *p)
1506{
1507 if (place() == InDock) {
1508 Q3Frame::drawFrame(p);
1509 return;
1510 }
1511
1512 QStyleOptionFrame opt;
1513 opt.rect = rect();
1514 opt.palette = palette();
1515 opt.state = QStyle::State_None;
1516 if (titleBar->isActive())
1517 opt.state |= QStyle::State_Active;
1518 opt.lineWidth = lineWidth();
1519 opt.midLineWidth = midLineWidth();
1520
1521 style()->drawPrimitive(QStyle::PE_FrameWindow, &opt, p, this);
1522}
1523
1524/*!
1525 \reimp
1526*/
1527void Q3DockWindow::drawContents(QPainter *p)
1528{
1529 // This is only used by the PocketPC style. We probably need to revist later.
1530 QStyleOption opt(0, QStyleOption::SO_Default);
1531 opt.init(this);
1532 if (titleBar->isActive())
1533 opt.state |= QStyle::State_Active;
1534 style()->drawControl(QStyle::CE_Q3DockWindowEmptyArea, &opt, p, this);
1535}
1536
1537/*!
1538 \property Q3DockWindow::resizeEnabled
1539 \brief whether the dock window is resizeable
1540
1541 A resizeable dock window can be resized using splitter-like
1542 handles inside a dock area and like every other top level window
1543 when floating.
1544
1545 A dock window is both horizontally and vertically stretchable if
1546 you call setResizeEnabled(true).
1547
1548 This property is false by default.
1549
1550 \sa setVerticallyStretchable() setHorizontallyStretchable()
1551*/
1552
1553void Q3DockWindow::setResizeEnabled(bool b)
1554{
1555 resizeEnabled = b;
1556 updateGui();
1557}
1558
1559/*!
1560 \property Q3DockWindow::movingEnabled
1561 \brief whether the user can move the dock window within the dock
1562 area, move the dock window to another dock area, or float the dock
1563 window.
1564
1565 This property is true by default.
1566*/
1567
1568void Q3DockWindow::setMovingEnabled(bool b)
1569{
1570 moveEnabled = b;
1571 updateGui();
1572}
1573
1574bool Q3DockWindow::isResizeEnabled() const
1575{
1576 return resizeEnabled;
1577}
1578
1579bool Q3DockWindow::isMovingEnabled() const
1580{
1581 return moveEnabled;
1582}
1583
1584/*!
1585 \property Q3DockWindow::closeMode
1586 \brief the close mode of a dock window
1587
1588 Defines when (if ever) the dock window has a close button. The
1589 choices are \c Never, \c Docked (i.e. only when docked), \c
1590 Undocked (only when undocked, i.e. floated) or \c Always.
1591
1592 The default is \c Never.
1593*/
1594
1595void Q3DockWindow::setCloseMode(int m)
1596{
1597 cMode = m;
1598 if (place() == InDock) {
1599 horHandle->updateGui();
1600 verHandle->updateGui();
1601 } else {
1602 titleBar->updateGui();
1603 }
1604}
1605
1606/*!
1607 Returns true if the dock window has a close button; otherwise
1608 returns false. The result depends on the dock window's \l Place
1609 and its \l CloseMode.
1610
1611 \sa setCloseMode()
1612*/
1613
1614bool Q3DockWindow::isCloseEnabled() const
1615{
1616 return (((cMode & Docked) == Docked && place() == InDock) ||
1617 ((cMode & Undocked) == Undocked && place() == OutsideDock));
1618}
1619
1620int Q3DockWindow::closeMode() const
1621{
1622 return cMode;
1623}
1624
1625/*!
1626 \property Q3DockWindow::horizontallyStretchable
1627 \brief whether the dock window is horizontally stretchable.
1628
1629 A dock window is horizontally stretchable if you call
1630 setHorizontallyStretchable(true) or setResizeEnabled(true).
1631
1632 \warning Stretchability is broken. You must call
1633 setResizeEnabled(true) to get proper behavior and even then
1634 Q3DockWindow does not limit stretchablilty.
1635
1636 \sa setResizeEnabled()
1637*/
1638
1639void Q3DockWindow::setHorizontallyStretchable(bool b)
1640{
1641 stretchable[Qt::Horizontal] = b;
1642}
1643
1644/*!
1645 \property Q3DockWindow::verticallyStretchable
1646 \brief whether the dock window is vertically stretchable.
1647
1648 A dock window is vertically stretchable if you call
1649 setVerticallyStretchable(true) or setResizeEnabled(true).
1650
1651 \sa setResizeEnabled()
1652
1653 \warning Stretchability is broken. You must call
1654 setResizeEnabled(true) to get proper behavior and even then
1655 Q3DockWindow does not limit stretchablilty.
1656*/
1657
1658void Q3DockWindow::setVerticallyStretchable(bool b)
1659{
1660 stretchable[Qt::Vertical] = b;
1661}
1662
1663bool Q3DockWindow::isHorizontallyStretchable() const
1664{
1665 return isResizeEnabled() || stretchable[Qt::Horizontal];
1666}
1667
1668bool Q3DockWindow::isVerticallyStretchable() const
1669{
1670 return isResizeEnabled() || stretchable[Qt::Vertical];
1671}
1672
1673/*!
1674 \property Q3DockWindow::stretchable
1675 \brief whether the dock window is stretchable in the current
1676 orientation()
1677
1678 This property can be set using setHorizontallyStretchable() and
1679 setVerticallyStretchable(), or with setResizeEnabled().
1680
1681 \warning Stretchability is broken. You must call
1682 setResizeEnabled(true) to get proper behavior and even then
1683 Q3DockWindow does not limit stretchablilty.
1684
1685 \sa setResizeEnabled()
1686*/
1687
1688bool Q3DockWindow::isStretchable() const
1689{
1690 if (orientation() == Qt::Horizontal)
1691 return isHorizontallyStretchable();
1692 return isVerticallyStretchable();
1693}
1694
1695/*!
1696 Returns the orientation of the dock window.
1697
1698 \sa orientationChanged()
1699*/
1700
1701Qt::Orientation Q3DockWindow::orientation() const
1702{
1703 if (dockArea)
1704 return dockArea->orientation();
1705 if (qobject_cast<const Q3ToolBar*>(this))
1706 return Qt::Horizontal;
1707 return (((Q3DockWindow*)this)->boxLayout()->direction() == QBoxLayout::LeftToRight ||
1708 ((Q3DockWindow*)this)->boxLayout()->direction() == QBoxLayout::RightToLeft ?
1709 Qt::Horizontal : Qt::Vertical);
1710}
1711
1712int Q3DockWindow::offset() const
1713{
1714 return offs;
1715}
1716
1717/*!
1718 \property Q3DockWindow::offset
1719 \brief the dock window's preferred offset from the dock area's
1720 left edge (top edge for vertical dock areas)
1721
1722 The default is 0.
1723*/
1724
1725void Q3DockWindow::setOffset(int o)
1726{
1727 offs = o;
1728}
1729
1730/*!
1731 Returns the dock window's preferred size (fixed extent).
1732
1733 \sa setFixedExtentWidth() setFixedExtentHeight()
1734*/
1735
1736QSize Q3DockWindow::fixedExtent() const
1737{
1738 return fExtent;
1739}
1740
1741/*!
1742 Sets the dock window's preferred width for its fixed extent (size)
1743 to \a w.
1744
1745 \sa setFixedExtentHeight()
1746*/
1747
1748void Q3DockWindow::setFixedExtentWidth(int w)
1749{
1750 fExtent.setWidth(w);
1751}
1752
1753/*!
1754 Sets the dock window's preferred height for its fixed extent
1755 (size) to \a h.
1756
1757 \sa setFixedExtentWidth()
1758*/
1759
1760void Q3DockWindow::setFixedExtentHeight(int h)
1761{
1762 fExtent.setHeight(h);
1763}
1764
1765/*!
1766 \property Q3DockWindow::newLine
1767 \brief whether the dock window prefers to start a new line in the
1768 dock area.
1769
1770 The default is false, i.e. the dock window doesn't require a new
1771 line in the dock area.
1772*/
1773
1774void Q3DockWindow::setNewLine(bool b)
1775{
1776 nl = b;
1777}
1778
1779bool Q3DockWindow::newLine() const
1780{
1781 return nl;
1782}
1783
1784/*!
1785 Returns the layout which is used for adding widgets to the dock
1786 window. The layout's orientation is set automatically to match the
1787 orientation of the dock window. You can add widgets to the layout
1788 using the box layout's QBoxLayout::addWidget() function.
1789
1790 If the dock window only needs to contain a single widget use
1791 setWidget() instead.
1792
1793 \sa setWidget() setOrientation()
1794*/
1795
1796QBoxLayout *Q3DockWindow::boxLayout()
1797{
1798 return childBox;
1799}
1800
1801/*! \reimp
1802 */
1803
1804QSize Q3DockWindow::sizeHint() const
1805{
1806 QSize sh(Q3Frame::sizeHint());
1807 if (place() == InDock)
1808 sh = sh.expandedTo(fixedExtent());
1809 sh = sh.expandedTo(QSize(16, 16));
1810 if (area()) {
1811 if (area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible())
1812 sh.setWidth(sh.width() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1813 else if (area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible())
1814 sh.setHeight(sh.height() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1815 }
1816 return sh;
1817}
1818
1819/*! \internal
1820 */
1821
1822QSize Q3DockWindow::minimumSize() const
1823{
1824 QSize ms(Q3Frame::minimumSize());
1825 if (place() == InDock)
1826 ms = ms.expandedTo(fixedExtent());
1827 ms = ms.expandedTo(QSize(16, 16));
1828 if (area()) {
1829 if (area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible())
1830 ms.setWidth(ms.width() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1831 else if (area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible())
1832 ms.setHeight(ms.height() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1833 }
1834 return ms;
1835}
1836
1837/*! \reimp
1838 */
1839
1840QSize Q3DockWindow::minimumSizeHint() const
1841{
1842 QSize msh(Q3Frame::minimumSize());
1843 if (place() == InDock)
1844 msh = msh.expandedTo(fixedExtent());
1845 msh = msh.expandedTo(QSize(16, 16));
1846 if (area()) {
1847 if (area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible())
1848 msh.setWidth(msh.width() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1849 else if (area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible())
1850 msh.setHeight(msh.height() + 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this) / 3);
1851 }
1852 return msh;
1853}
1854
1855/*!
1856 \fn void Q3DockWindow::undock()
1857
1858 Undocks the Q3DockWindow from its current dock area if it is
1859 docked; otherwise does nothing.
1860
1861 \sa dock() Q3DockArea::moveDockWindow(),
1862 Q3DockArea::removeDockWindow(), Q3MainWindow::moveDockWindow(),
1863 Q3MainWindow::removeDockWindow()
1864*/
1865
1866/*!
1867 \fn void Q3DockWindow::undock(QWidget *widget)
1868
1869 Undocks the specified \a widget from its current dock area if it is
1870 docked; otherwise does nothing.
1871
1872 \sa dock() Q3DockArea::moveDockWindow(),
1873 Q3DockArea::removeDockWindow(), Q3MainWindow::moveDockWindow(),
1874 Q3MainWindow::removeDockWindow()
1875*/
1876void Q3DockWindow::undock(QWidget *w)
1877{
1878 Q3MainWindow *mw = 0;
1879 if (area())
1880 mw = qobject_cast<Q3MainWindow*>(area()->parentWidget());
1881 if (mw && !mw->isDockEnabled(this, Qt::DockTornOff))
1882 return;
1883 if ((place() == OutsideDock && !w))
1884 return;
1885
1886 QPoint p(50, 50);
1887 if (window())
1888 p = window()->pos() + QPoint(20, 20);
1889 if (dockArea) {
1890 delete (Q3DockArea::DockWindowData*)dockWindowData;
1891 dockWindowData = dockArea->dockWindowData(this);
1892 dockArea->removeDockWindow(this, true, orientation() != Qt::Horizontal && qobject_cast<Q3ToolBar*>(this));
1893 }
1894 dockArea = 0;
1895 if (lastPos != QPoint(-1, -1) && lastPos.x() > 0 && lastPos.y() > 0)
1896 move(lastPos);
1897 else
1898 move(p);
1899 if (lastSize != QSize(-1, -1))
1900 resize(lastSize);
1901 curPlace = OutsideDock;
1902 updateGui();
1903 emit orientationChanged(orientation());
1904 QApplication::sendPostedEvents(this, QEvent::LayoutHint);
1905 if (qobject_cast<Q3ToolBar*>(this))
1906 adjustSize();
1907 if (!w) {
1908 if (!parentWidget() || parentWidget()->isVisible()) {
1909 if (lastSize == QSize(-1, -1))
1910 setAttribute(Qt::WA_Resized, false);// Ensures size is recalculated (opaque).
1911 show();
1912 }
1913 } else {
1914 setParent(w, 0);
1915 move(-width() - 5, -height() - 5);
1916 resize(1, 1);
1917 show();
1918 }
1919 if (parentWidget() && isWindow())
1920 parentWidget()->setActiveWindow();
1921 emit placeChanged(place());
1922}
1923
1924void Q3DockWindow::removeFromDock(bool fixNewLines)
1925{
1926 if (dockArea)
1927 dockArea->removeDockWindow(this, false, false, fixNewLines);
1928}
1929
1930/*!
1931 Docks the dock window into the last dock area in which it was
1932 docked.
1933
1934 If the dock window has no last dock area (e.g. it was created as a
1935 floating window and has never been docked), or if the last dock
1936 area it was docked in does not exist (e.g. the dock area has been
1937 deleted), nothing happens.
1938
1939 The dock window will dock with the dock area regardless of the return value
1940 of Q3DockArea::isDockWindowAccepted().
1941
1942 \sa undock() Q3DockArea::moveDockWindow(),
1943 Q3DockArea::removeDockWindow(), Q3MainWindow::moveDockWindow(),
1944 Q3MainWindow::removeDockWindow(), Q3DockArea::isDockWindowAccepted()
1945
1946*/
1947
1948void Q3DockWindow::dock()
1949{
1950 if (!(Q3DockArea::DockWindowData*)dockWindowData ||
1951 !((Q3DockArea::DockWindowData*)dockWindowData)->area)
1952 return;
1953 curPlace = InDock;
1954 lastPos = pos();
1955 lastSize = size();
1956 ((Q3DockArea::DockWindowData*)dockWindowData)->
1957 area->dockWindow(this, (Q3DockArea::DockWindowData*)dockWindowData);
1958 emit orientationChanged(orientation());
1959 emit placeChanged(place());
1960}
1961
1962/*! \reimp
1963 */
1964
1965void Q3DockWindow::hideEvent(QHideEvent *e)
1966{
1967 Q3Frame::hideEvent(e);
1968}
1969
1970/*! \reimp
1971 */
1972
1973void Q3DockWindow::showEvent(QShowEvent *e)
1974{
1975 if (curPlace == OutsideDock && (parent() && parent()->objectName() == QLatin1String("qt_hide_dock"))) {
1976 QRect sr = qApp->desktop()->availableGeometry(this);
1977 if (!sr.contains(pos())) {
1978 int nx = qMin(qMax(x(), sr.x()), sr.right()-width());
1979 int ny = qMin(qMax(y(), sr.y()), sr.bottom()-height());
1980 move(nx, ny);
1981 }
1982 }
1983
1984 Q3Frame::showEvent(e);
1985}
1986
1987/*!
1988 \property Q3DockWindow::opaqueMoving
1989 \brief whether the dock window will be shown normally whilst it is
1990 being moved.
1991
1992 If this property is false, (the default), the dock window will be
1993 represented by an outline rectangle whilst it is being moved.
1994
1995 \warning Currently opaque moving has some problems and we do not
1996 recommend using it at this time. We expect to fix these problems
1997 in a future release.
1998*/
1999
2000void Q3DockWindow::setOpaqueMoving(bool b)
2001{
2002 opaque = b;
2003 horHandle->setOpaqueMoving(b);
2004 verHandle->setOpaqueMoving(b);
2005 titleBar->setOpaqueMoving(b);
2006}
2007
2008bool Q3DockWindow::opaqueMoving() const
2009{
2010 return opaque;
2011}
2012
2013void Q3DockWindow::updateSplitterVisibility(bool visible)
2014{
2015 if (area() && isResizeEnabled()) {
2016 if (orientation() == Qt::Horizontal) {
2017 if (visible)
2018 vHandleRight->show();
2019 else
2020 vHandleRight->hide();
2021 vHandleLeft->hide();
2022 } else {
2023 if (visible)
2024 hHandleBottom->show();
2025 else
2026 hHandleBottom->hide();
2027 hHandleTop->hide();
2028 }
2029 }
2030}
2031
2032/*! \reimp */
2033bool Q3DockWindow::eventFilter(QObject * o, QEvent *e)
2034{
2035 if (!o->isWidgetType())
2036 return false;
2037
2038 if (e->type() == QEvent::KeyPress &&
2039 (horHandle->mousePressed ||
2040 verHandle->mousePressed ||
2041 titleBar->mousePressed)) {
2042 QKeyEvent *ke = (QKeyEvent*)e;
2043 if (ke->key() == Qt::Key_Escape) {
2044 horHandle->mousePressed =
2045 verHandle->mousePressed =
2046 titleBar->mousePressed = false;
2047 endRectDraw(!opaque);
2048 qApp->removeEventFilter(this);
2049 return true;
2050 }
2051 } else if (((QWidget*)o)->window() != this && place() == OutsideDock && isWindow()) {
2052 if ((e->type() == QEvent::WindowDeactivate ||
2053 e->type() == QEvent::WindowActivate))
2054 event(e);
2055 }
2056 return false;
2057}
2058
2059/*! \reimp */
2060bool Q3DockWindow::event(QEvent *e)
2061{
2062 switch (e->type()) {
2063 case QEvent::WindowDeactivate:
2064 if (place() == OutsideDock && isWindow() && parentWidget()
2065 && parentWidget()->isActiveWindow())
2066 return true;
2067 break;
2068 case QEvent::HideToParent:
2069 emit visibilityChanged(false);
2070 break;
2071 case QEvent::ShowToParent:
2072 emit visibilityChanged(true);
2073 break;
2074 case QEvent::WindowTitleChange:
2075 {
2076 QString s = Q3Frame::windowTitle();
2077 titleBar->setWindowTitle(s);
2078#ifndef QT_NO_TOOLTIP
2079 horHandle->setToolTip(s);
2080 verHandle->setToolTip(s);
2081#endif
2082 break;
2083 }
2084 default:
2085 break;
2086 }
2087 return Q3Frame::event(e);
2088}
2089
2090/*!
2091 Returns the dock window's title.
2092*/
2093QString Q3DockWindow::windowTitle() const
2094{
2095 return titleBar->windowTitle();
2096}
2097
2098/*! \reimp */
2099void Q3DockWindow::contextMenuEvent(QContextMenuEvent *e)
2100{
2101 QObject *o = this;
2102 while (o) {
2103 if (qobject_cast<Q3MainWindow*>(o))
2104 break;
2105 o = o->parent();
2106 }
2107 if (!o || ! ((Q3MainWindow*)o)->showDockMenu(e->globalPos()))
2108 e->ignore();
2109}
2110
2111QT_END_NAMESPACE
2112
2113#include "q3dockwindow.moc"
2114
2115#endif //QT_NO_MAINWINDOW
Note: See TracBrowser for help on using the repository browser.