source: trunk/src/widgets/qdockwindow.cpp@ 108

Last change on this file since 108 was 105, checked in by dmik, 19 years ago

Widgets: Fixed [Qt bug]: QDockWindow's area covered by the dock window handler was not properly erased if moving was disabled.

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