source: vendor/trolltech/current/src/widgets/qdockwindow.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

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