Salome HOME
NRI : Merge from V1_2.
[modules/kernel.git] / src / PatchQt / qworkspaceP.cxx
1 //  SALOME PatchQt : patch for Qt
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : qworkspaceP.cxx
8 //  Author : Vadim SANDLER
9 //  Module : SALOME
10 //  $Header$
11
12 using namespace std;
13 #include "qworkspaceP.h"
14
15 #include <qapplication.h>
16 #include <qobjectlist.h>
17 #include <qlayout.h>
18 #include <qtoolbutton.h>
19 #include <qlabel.h>
20 #include <qvbox.h>
21 #include <qaccel.h>
22 #include <qcursor.h>
23 #include <qpopupmenu.h>
24 #include <qmenubar.h>
25 #include <qguardedptr.h>
26 #include <qiconset.h>
27 #include <qfocusdata.h>
28 #include <qdatetime.h>
29 #include <qtooltip.h>
30 #include <qwmatrix.h>
31 #include <qimage.h>
32 #include <qscrollbar.h>
33 #include <qstyle.h>
34 #include <qframe.h>
35 #if defined(Q_WS_WIN)
36 #include <qt_windows.h>
37 #endif
38 #include <qplatformdefs.h>
39 #include <qtimer.h>
40 #include <qpainter.h>
41
42 #include <private/qapplication_p.h>
43 #include <private/qinternal_p.h>
44
45 #define BUTTON_WIDTH    16
46 #define BUTTON_HEIGHT   14
47
48
49 /*!
50     \class QWorkspaceP qworkspace.h
51     \brief The QWorkspaceP widget provides a workspace window that can
52     contain decorated windows, e.g. for MDI.
53
54     \module workspace
55
56     \ingroup application
57     \ingroup organizers
58     \mainclass
59
60     An MDI (multiple document interface) application has one main
61     window with a menu bar. The central widget of this window is a
62     workspace. The workspace itself contains zero, one or more
63     document windows, each of which displays a document.
64
65     The workspace itself is an ordinary Qt widget. It has a standard
66     constructor that takes a parent widget and an object name. The
67     parent window is usually a QMainWindow, but it need not be.
68
69     Document windows (i.e. MDI windows) are also ordinary Qt widgets
70     which have the workspace as parent widget. When you call show(),
71     hide(), showMaximized(), setCaption(), etc. on a document window,
72     it is shown, hidden, etc. with a frame, caption, icon and icon
73     text, just as you'd expect. You can provide widget flags which
74     will be used for the layout of the decoration or the behaviour of
75     the widget itself.
76
77     To change the geometry of the MDI windows it is necessary to make
78     the function calls to the parentWidget() of the widget, as this
79     will move or resize the decorated window.
80
81     A document window becomes active when it gets the keyboard focus.
82     You can activate it using setFocus(), and the user can activate it
83     by moving focus in the normal ways. The workspace emits a signal
84     windowActivated() when it detects the activation change, and the
85     function activeWindow() always returns a pointer to the active
86     document window.
87
88     The convenience function windowList() returns a list of all
89     document windows. This is useful to create a popup menu
90     "<u>W</u>indows" on the fly, for example.
91
92     QWorkspaceP provides two built-in layout strategies for child
93     windows: cascade() and tile(). Both are slots so you can easily
94     connect menu entries to them.
95
96     If you want your users to be able to work with document windows
97     larger than the actual workspace, set the scrollBarsEnabled
98     property to TRUE.
99
100     If the top-level window contains a menu bar and a document window
101     is maximised, QWorkspaceP moves the document window's minimize,
102     restore and close buttons from the document window's frame to the
103     workspace window's menu bar. It then inserts a window operations
104     menu at the far left of the menu bar.
105 */
106
107 static bool inCaptionChange = FALSE;
108
109 class QWorkspacePPrivate {
110 public:
111     QWorkspacePChild* active;
112     QPtrList<QWorkspacePChild> windows;
113     QPtrList<QWorkspacePChild> focus;
114     QPtrList<QWidget> icons;
115     QWorkspacePChild* maxWindow;
116     QRect maxRestore;
117     QGuardedPtr<QFrame> maxcontrols;
118     QGuardedPtr<QMenuBar> maxmenubar;
119
120     int px;
121     int py;
122     QWidget *becomeActive;
123     QGuardedPtr<QLabel> maxtools;
124     QPopupMenu* popup;
125     QPopupMenu* toolPopup;
126     int menuId;
127     int controlId;
128     QString topCaption;
129     bool autoFocusChange;
130
131     QScrollBar *vbar, *hbar;
132     QWidget *corner;
133     int yoffset, xoffset;
134 };
135
136 /*!
137   Constructs a workspace with a \a parent and a \a name.
138  */
139 QWorkspaceP::QWorkspaceP( QWidget *parent, const char *name )
140     : QWidget( parent, name, WNoMousePropagation )
141 {
142     d = new QWorkspacePPrivate;
143     d->maxcontrols = 0;
144     d->active = 0;
145     d->maxWindow = 0;
146     d->maxtools = 0;
147     d->px = 0;
148     d->py = 0;
149     d->becomeActive = 0;
150     d->autoFocusChange = FALSE;
151 #if defined(Q_WS_WIN)
152     d->popup = new QPopupMenu( this, "qt_internal_mdi_popup" );
153     d->toolPopup = new QPopupMenu( this, "qt_internal_mdi_popup" );
154 #else
155     d->popup = new QPopupMenu( parentWidget(), "qt_internal_mdi_popup" );
156     d->toolPopup = new QPopupMenu( parentWidget(), "qt_internal_mdi_popup" );
157 #endif
158
159     d->menuId = -1;
160     d->controlId = -1;
161     connect( d->popup, SIGNAL( aboutToShow() ), this, SLOT(operationMenuAboutToShow() ));
162     connect( d->popup, SIGNAL( activated(int) ), this, SLOT( operationMenuActivated(int) ) );
163     d->popup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarNormalButton)), tr("&Restore"), 1);
164     d->popup->insertItem(tr("&Move"), 2);
165     d->popup->insertItem(tr("&Size"), 3);
166     d->popup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarMinButton)), tr("Mi&nimize"), 4);
167     d->popup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarMaxButton)), tr("Ma&ximize"), 5);
168     d->popup->insertSeparator();
169     d->popup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarCloseButton)),
170                                   tr("&Close")
171 #ifndef QT_NO_ACCEL
172                                         +"\t"+QAccel::keyToString(CTRL+Key_F4)
173 #endif
174                     , this, SLOT( closeActiveWindow() ) );
175
176     connect( d->toolPopup, SIGNAL( aboutToShow() ), this, SLOT(toolMenuAboutToShow() ));
177     connect( d->toolPopup, SIGNAL( activated(int) ), this, SLOT( operationMenuActivated(int) ) );
178     d->toolPopup->insertItem(tr("&Move"), 2);
179     d->toolPopup->insertItem(tr("&Size"), 3);
180     d->toolPopup->insertItem(tr("Stay on &Top"), 7);
181     d->toolPopup->setItemChecked( 7, TRUE );
182     d->toolPopup->setCheckable( TRUE );
183     d->toolPopup->insertSeparator();
184     d->toolPopup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarShadeButton)), tr("Sh&ade"), 6);
185     d->toolPopup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarCloseButton)),
186                                       tr("&Close")
187 #ifndef QT_NO_ACCEL
188                                         +"\t"+QAccel::keyToString( CTRL+Key_F4)
189 #endif
190                 , this, SLOT( closeActiveWindow() ) );
191
192 #ifndef QT_NO_ACCEL
193     QAccel* a = new QAccel( this );
194     a->connectItem( a->insertItem( ALT + Key_Minus),
195                     this, SLOT( showOperationMenu() ) );
196
197     a->connectItem( a->insertItem( CTRL + Key_F6),
198                     this, SLOT( activateNextWindow() ) );
199     a->connectItem( a->insertItem( CTRL + Key_Tab),
200                     this, SLOT( activateNextWindow() ) );
201
202     a->connectItem( a->insertItem( CTRL + SHIFT + Key_F6),
203                     this, SLOT( activatePreviousWindow() ) );
204     a->connectItem( a->insertItem( CTRL + SHIFT + Key_Tab),
205                     this, SLOT( activatePreviousWindow() ) );
206
207     a->connectItem( a->insertItem( CTRL + Key_F4 ),
208                     this, SLOT( closeActiveWindow() ) );
209 #endif
210
211     setBackgroundMode( PaletteDark );
212     setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
213
214 #ifndef QT_NO_WIDGET_TOPEXTRA
215     d->topCaption = topLevelWidget()->caption();
216 #endif
217
218     d->hbar = d->vbar = 0;
219     d->corner = 0;
220     d->xoffset = d->yoffset = 0;
221
222     updateWorkspace();
223
224     topLevelWidget()->installEventFilter( this );
225 }
226
227 /*!  Destroys the workspace and frees any allocated resources. */
228
229 QWorkspaceP::~QWorkspaceP()
230 {
231     delete d;
232     d = 0;
233 }
234
235 /*!\reimp */
236 QSize QWorkspaceP::sizeHint() const
237 {
238     QSize s( QApplication::desktop()->size() );
239     return QSize( s.width()*2/3, s.height()*2/3);
240 }
241
242 /*! \reimp */
243 void QWorkspaceP::setPaletteBackgroundColor( const QColor & c )
244 {
245     setEraseColor( c );
246 }
247
248
249 /*! \reimp */
250 void QWorkspaceP::setPaletteBackgroundPixmap( const QPixmap & pm )
251 {
252     setErasePixmap( pm );
253 }
254
255 /*! \reimp */
256 void QWorkspaceP::childEvent( QChildEvent * e)
257 {
258     if (e->inserted() && e->child()->isWidgetType()) {
259         QWidget* w = (QWidget*) e->child();
260         if ( !w || !w->testWFlags( WStyle_Title | WStyle_NormalBorder | WStyle_DialogBorder )
261              || d->icons.contains( w ) || w == d->vbar || w == d->hbar || w == d->corner )
262             return;         // nothing to do
263
264         bool hasBeenHidden = w->isHidden();
265         bool hasSize = w->testWState( WState_Resized );
266         int x = w->x();
267         int y = w->y();
268         bool hasPos = x != 0 || y != 0;
269         QSize s = w->size().expandedTo( w->minimumSizeHint() );
270         if ( !hasSize && w->sizeHint().isValid() )
271             w->adjustSize();
272
273         QWorkspacePChild* child = new QWorkspacePChild( w, this, "qt_workspacechild" );
274         child->installEventFilter( this );
275
276         connect( child, SIGNAL( popupOperationMenu( const QPoint& ) ),
277                  this, SLOT( popupOperationMenu( const QPoint& ) ) );
278         connect( child, SIGNAL( showOperationMenu() ),
279                  this, SLOT( showOperationMenu() ) );
280         d->windows.append( child );
281         if ( child->isVisibleTo( this ) )
282             d->focus.append( child );
283         child->internalRaise();
284
285         if ( hasBeenHidden )
286             w->hide();
287         else if ( !isVisible() )  // that's a case were we don't receive a showEvent in time. Tricky.
288             child->show();
289
290         if ( !hasPos )
291             place( child );
292         if ( hasSize )
293             child->resize( s + child->baseSize() );
294         else
295             child->adjustSize();
296         if ( hasPos )
297             child->move( x, y );
298
299         activateWindow( w );
300         updateWorkspace();
301     } else if (e->removed() ) {
302         if ( d->windows.contains( (QWorkspacePChild*)e->child() ) ) {
303             d->windows.removeRef( (QWorkspacePChild*)e->child() );
304             d->focus.removeRef( (QWorkspacePChild*)e->child() );
305             if (d->windows.count() <= 0) { // VSR+ 26/03/03 -->
306               activateWindow( 0 );         
307               d->maxWindow = 0;            
308               hideMaximizeControls();      
309             }                              // <-- VSR+ 26/03/03
310             updateWorkspace();
311         }
312     }
313 }
314
315 /*! \reimp
316 */
317 #ifndef QT_NO_WHEELEVENT
318 void QWorkspaceP::wheelEvent( QWheelEvent *e )
319 {
320     if ( !scrollBarsEnabled() )
321         return;
322     if ( d->vbar && d->vbar->isVisible() && !( e->state() & AltButton ) )
323         QApplication::sendEvent( d->vbar, e );
324     else if ( d->hbar && d->hbar->isVisible() )
325         QApplication::sendEvent( d->hbar, e );
326 }
327 #endif
328
329 void QWorkspaceP::activateWindow( QWidget* w, bool change_focus )
330 {
331     if ( !w ) {
332         d->active = 0;
333         emit windowActivated( 0 );
334         return;
335     }
336     if ( !isVisibleTo( 0 ) ) {
337         d->becomeActive = w;
338         return;
339     }
340     if ( d->active && d->active->windowWidget() == w )
341         return;
342     QPtrListIterator<QWorkspacePChild> it( d->windows );
343     while ( it.current () ) {
344         QWorkspacePChild* c = it.current();
345         ++it;
346         c->setActive( c->windowWidget() == w );
347         if (c->windowWidget() == w)
348             d->active = c;
349     }
350
351     if (!d->active)
352         return;
353
354     if ( d->maxWindow && d->maxWindow != d->active && d->active->windowWidget() &&
355          d->active->windowWidget()->testWFlags( WStyle_MinMax ) &&
356          !d->active->windowWidget()->testWFlags( WStyle_Tool ) ) {
357         maximizeWindow( d->active->windowWidget() );
358         if ( d->maxtools ) {
359 #ifndef QT_NO_WIDGET_TOPEXTRA
360             if ( w->icon() ) {
361                 QPixmap pm(*w->icon());
362                 if(pm.width() != 14 || pm.height() != 14) {
363                     QImage im;
364                     im = pm;
365                     pm = im.smoothScale( 14, 14 );
366                 }
367                 d->maxtools->setPixmap( pm );
368             } else
369 #endif
370             {
371                 QPixmap pm(14,14);
372                 pm.fill( white );
373                 d->maxtools->setPixmap( pm );
374             }
375         }
376     }
377
378     d->active->internalRaise();
379
380     if ( change_focus ) {
381         if ( d->focus.find( d->active ) >=0 ) {
382             d->focus.removeRef( d->active );
383 //          d->focus.append( d->active ); //VSR-
384         }
385         d->focus.append( d->active ); //VSR+
386     }
387
388     updateWorkspace();
389     emit windowActivated( w );
390 }
391
392
393 /*!
394   Returns the active window, or 0 if no window is active.
395  */
396 QWidget* QWorkspaceP::activeWindow() const
397 {
398     return d->active?d->active->windowWidget():0;
399 }
400
401
402 void QWorkspaceP::place( QWidget* w)
403 {
404     int overlap, minOverlap = 0;
405     int possible;
406
407     QRect r1(0, 0, 0, 0);
408     QRect r2(0, 0, 0, 0);
409     QRect maxRect = rect();
410     int x = maxRect.left(), y = maxRect.top();
411     QPoint wpos(maxRect.left(), maxRect.top());
412
413     bool firstPass = TRUE;
414
415     do {
416         if ( y + w->height() > maxRect.bottom() ) {
417             overlap = -1;
418         } else if( x + w->width() > maxRect.right() ) {
419             overlap = -2;
420         } else {
421             overlap = 0;
422
423             r1.setRect(x, y, w->width(), w->height());
424
425             QWidget *l;
426             QPtrListIterator<QWorkspacePChild> it( d->windows );
427             while ( it.current () ) {
428                 l = it.current();
429                 ++it;
430                 if (! d->icons.contains(l) && ! l->isHidden() && l != w ) {
431                     if ( d->maxWindow == l )
432                         r2 = d->maxRestore;
433                     else
434                         r2.setRect(l->x(), l->y(), l->width(), l->height());
435
436                     if (r2.intersects(r1)) {
437                         r2.setCoords(QMAX(r1.left(), r2.left()),
438                                      QMAX(r1.top(), r2.top()),
439                                      QMIN(r1.right(), r2.right()),
440                                      QMIN(r1.bottom(), r2.bottom())
441                                      );
442
443                         overlap += (r2.right() - r2.left()) *
444                                    (r2.bottom() - r2.top());
445                     }
446                 }
447             }
448         }
449
450         if (overlap == 0) {
451             wpos = QPoint(x, y);
452             break;
453         }
454
455         if (firstPass) {
456             firstPass = FALSE;
457             minOverlap = overlap;
458         } else if ( overlap >= 0 && overlap < minOverlap) {
459             minOverlap = overlap;
460             wpos = QPoint(x, y);
461         }
462
463         if ( overlap > 0 ) {
464             possible = maxRect.right();
465             if ( possible - w->width() > x) possible -= w->width();
466
467             QWidget *l;
468             QPtrListIterator<QWorkspacePChild> it( d->windows );
469             while ( it.current () ) {
470                 l = it.current();
471                 ++it;
472                 if (! d->icons.contains(l) && ! l->isHidden() && l != w ) {
473                     if ( d->maxWindow == l )
474                         r2 = d->maxRestore;
475                     else
476                         r2.setRect(l->x(), l->y(), l->width(), l->height());
477
478                     if( ( y < r2.bottom() ) && ( r2.top() < w->height() + y ) ) {
479                         if( r2.right() > x )
480                             possible = possible < r2.right() ?
481                                        possible : r2.right();
482
483                         if( r2.left() - w->width() > x )
484                             possible = possible < r2.left() - w->width() ?
485                                        possible : r2.left() - w->width();
486                     }
487                 }
488             }
489
490             x = possible;
491         } else if ( overlap == -2 ) {
492             x = maxRect.left();
493             possible = maxRect.bottom();
494
495             if ( possible - w->height() > y ) possible -= w->height();
496
497             QWidget *l;
498             QPtrListIterator<QWorkspacePChild> it( d->windows );
499             while ( it.current () ) {
500                 l = it.current();
501                 ++it;
502                 if (l != w && ! d->icons.contains(w)) {
503                     if ( d->maxWindow == l )
504                         r2 = d->maxRestore;
505                     else
506                         r2.setRect(l->x(), l->y(), l->width(), l->height());
507
508                     if( r2.bottom() > y)
509                         possible = possible < r2.bottom() ?
510                                    possible : r2.bottom();
511
512                     if( r2.top() - w->height() > y )
513                         possible = possible < r2.top() - w->height() ?
514                                    possible : r2.top() - w->height();
515                 }
516             }
517
518             y = possible;
519         }
520     }
521     while( overlap != 0 && overlap != -1 );
522
523     w->move(wpos);
524     updateWorkspace();
525 }
526
527
528 void QWorkspaceP::insertIcon( QWidget* w )
529 {
530     if ( !w || d->icons.contains( w ) )
531         return;
532     d->icons.append( w );
533     if (w->parentWidget() != this )
534         w->reparent( this, 0, QPoint(0,0), FALSE);
535
536
537     QRect cr = updateWorkspace();
538     int x = 0;
539     int y = cr.height() - w->height();
540
541     QPtrListIterator<QWidget> it( d->icons );
542     while ( it.current () ) {
543         QWidget* i = it.current();
544         ++it;
545         if ( x > 0 && x + i->width() > cr.width() ){
546             x = 0;
547             y -= i->height();
548         }
549
550         if ( i != w &&
551             i->geometry().intersects( QRect( x, y, w->width(), w->height() ) ) )
552             x += i->width();
553     }
554     w->move( x, y );
555
556     if ( isVisibleTo( parentWidget() ) ) {
557         w->show();
558         w->lower();
559     }
560     updateWorkspace();
561 }
562
563
564 void QWorkspaceP::removeIcon( QWidget* w)
565 {
566     if ( !d->icons.contains( w ) )
567         return;
568     d->icons.remove( w );
569     w->hide();
570 }
571
572
573 /*! \reimp  */
574 void QWorkspaceP::resizeEvent( QResizeEvent * )
575 {
576     if ( d->maxWindow ) {
577         d->maxWindow->adjustToFullscreen();
578         ((QWorkspaceP*)d->maxWindow->windowWidget())->setWState( WState_Maximized );
579     }
580
581     QRect cr = updateWorkspace();
582
583     QPtrListIterator<QWorkspacePChild> it( d->windows );
584     while ( it.current () ) {
585         QWorkspacePChild* c = it.current();
586         ++it;
587         if ( c->windowWidget() && !c->windowWidget()->testWFlags( WStyle_Tool ) )
588             continue;
589
590         int x = c->x();
591         int y = c->y();
592         if ( c->snappedDown )
593             y =  cr.height() - c->height();
594         if ( c->snappedRight )
595             x =  cr.width() - c->width();
596
597         if ( x != c->x() || y != c->y() )
598             c->move( x, y );
599     }
600
601 }
602
603 /*! \reimp */
604 void QWorkspaceP::showEvent( QShowEvent *e )
605 {
606     if ( d->maxWindow && !style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this))
607         showMaximizeControls();
608     QWidget::showEvent( e );
609     if ( d->becomeActive ) {
610         activateWindow( d->becomeActive );
611         d->becomeActive = 0;
612     }
613     else if ( d->windows.count() > 0 && !d->active )
614         activateWindow( d->windows.first()->windowWidget() );
615
616     updateWorkspace();
617 }
618
619 /*! \reimp */
620 void QWorkspaceP::hideEvent( QHideEvent * )
621 {
622
623     if ( !isVisibleTo(0) && !style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this))
624         hideMaximizeControls();
625 }
626
627 void QWorkspaceP::minimizeWindow( QWidget* w)
628 {
629     QWorkspacePChild* c = findChild( w );
630     QWorkspacePChild* oldActive = d->active;    //VSR+
631
632     if ( !w || w && (!w->testWFlags( WStyle_Minimize ) || w->testWFlags( WStyle_Tool) ) )
633         return;
634
635     if ( c ) {
636         QWorkspaceP *fake = (QWorkspaceP*)w;
637
638         setUpdatesEnabled( FALSE );
639         bool wasMax = FALSE;
640         if ( c == d->maxWindow ) {
641             wasMax = TRUE;
642             d->maxWindow = 0;
643             inCaptionChange = TRUE;
644 #ifndef QT_NO_WIDGET_TOPEXTRA
645             if ( !!d->topCaption )
646                 topLevelWidget()->setCaption( d->topCaption );
647 #endif
648             inCaptionChange = FALSE;
649             if ( !style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this) )
650                 hideMaximizeControls();
651             for (QPtrListIterator<QWorkspacePChild> it( d->windows ); it.current(); ++it ) {
652                 QWorkspacePChild* c = it.current();
653                 if ( c->titlebar )
654                     c->titlebar->setMovable( TRUE );
655                 c->widgetResizeHandler->setActive( TRUE );
656             }
657         }
658         insertIcon( c->iconWidget() );
659         bool wasFocused = c->titlebar->isActive();
660         blockSignals( TRUE );//VSR+
661         c->hide();
662         blockSignals( FALSE );//VSR+
663         if ( wasFocused && ( !d->active || d->active && d->active->testWState( WState_Minimized ) ) ) { //VSR+
664 //      if ( wasFocused && d->active && d->active->testWState( WState_Minimized ) ) {                   //VSR-
665 //VSR-      blockSignals( TRUE ); 
666             activateWindow( w, FALSE );
667 //VSR-      blockSignals( FALSE );
668         }
669         else if ( oldActive != d->active ) { //VSR+
670            emit ( windowActivated( d->active ? d->active->windowWidget() : 0 ) ); //VSR+
671         } //VSR+
672         if ( wasMax )
673             c->setGeometry( d->maxRestore );
674         if ( d->focus.find( c ) < 0 ) // VSR+
675             d->focus.append( c );
676
677         setUpdatesEnabled( TRUE );
678         updateWorkspace();
679
680         fake->clearWState( WState_Maximized );
681         fake->setWState( WState_Minimized );
682         c->clearWState( WState_Maximized );
683         c->setWState( WState_Minimized );
684     }
685 }
686
687 void QWorkspaceP::normalizeWindow( QWidget* w)
688 {
689     QWorkspacePChild* c = findChild( w );
690     if ( !w )
691         return;
692     if ( c ) {
693         QWorkspaceP *fake = (QWorkspaceP*)w;
694         fake->clearWState( WState_Minimized | WState_Maximized );
695         if ( !style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this) && d->maxWindow ) {
696             hideMaximizeControls();
697         } else {
698             c->widgetResizeHandler->setActive( TRUE );
699             if ( c->titlebar )
700                 c->titlebar->setMovable(TRUE);
701         }
702         fake->clearWState( WState_Minimized | WState_Maximized );
703         c->clearWState( WState_Minimized | WState_Maximized );
704
705         if ( c == d->maxWindow ) {
706             c->setGeometry( d->maxRestore );
707             d->maxWindow = 0;
708 #ifndef QT_NO_WIDGET_TOPEXTRA
709             inCaptionChange = TRUE;
710             if ( !!d->topCaption )
711                 topLevelWidget()->setCaption( d->topCaption );
712             inCaptionChange = FALSE;
713 #endif
714         } else {
715             if ( c->iconw )
716                 removeIcon( c->iconw->parentWidget() );
717             c->show();
718         }
719
720         if ( !style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this))
721             hideMaximizeControls();
722         for (QPtrListIterator<QWorkspacePChild> it( d->windows ); it.current(); ++it ) {
723             QWorkspacePChild* c = it.current();
724             if ( c->titlebar )
725                 c->titlebar->setMovable( TRUE );
726             c->widgetResizeHandler->setActive( TRUE );
727         }
728         activateWindow( w, TRUE );
729
730         updateWorkspace();
731     }
732 }
733
734 void QWorkspaceP::maximizeWindow( QWidget* w)
735 {
736     QWorkspacePChild* c = findChild( w );
737
738     if ( !w || w && (!w->testWFlags( WStyle_Maximize ) || w->testWFlags( WStyle_Tool) ) )
739         return;
740     if ( w->maximumSize().isValid() && ( w->maximumWidth() < width() || w->maximumHeight() < height() ) ) {
741         w->resize( w->maximumSize() );
742         return;
743     }
744
745     if ( c ) {
746         setUpdatesEnabled( FALSE );
747         if (c->iconw && d->icons.contains( c->iconw->parentWidget() ) )
748             normalizeWindow( w );
749         QWorkspaceP *fake = (QWorkspaceP*)w;
750
751         QRect r( c->geometry() );
752         c->adjustToFullscreen();
753         c->show();
754         c->internalRaise();
755         qApp->sendPostedEvents( c, QEvent::Resize );
756         qApp->sendPostedEvents( c, QEvent::Move );
757         qApp->sendPostedEvents( c, QEvent::ShowWindowRequest );
758         if ( d->maxWindow != c ) {
759             if ( d->maxWindow )
760                 d->maxWindow->setGeometry( d->maxRestore );
761             d->maxWindow = c;
762             d->maxRestore = r;
763         }
764
765         activateWindow( w );
766         if(!style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this)) {
767             showMaximizeControls();
768         } else {
769             c->widgetResizeHandler->setActive( FALSE );
770             if ( c->titlebar )
771                 c->titlebar->setMovable( FALSE );
772         }
773 #ifndef QT_NO_WIDGET_TOPEXTRA
774         inCaptionChange = TRUE;
775         if ( !!d->topCaption )
776             topLevelWidget()->setCaption( tr("%1 - [%2]")
777                 .arg(d->topCaption).arg(c->caption()) );
778         inCaptionChange = FALSE;
779 #endif
780         setUpdatesEnabled( TRUE );
781
782         updateWorkspace();
783
784         fake->clearWState( WState_Minimized );
785         fake->setWState( WState_Maximized );
786         c->clearWState( WState_Minimized );
787         c->setWState( WState_Maximized );
788     }
789 }
790
791 void QWorkspaceP::showWindow( QWidget* w)
792 {
793     if ( d->maxWindow && w->testWFlags( WStyle_Maximize ) && !w->testWFlags( WStyle_Tool) )
794         maximizeWindow( w );
795     else if ( !w->testWFlags( WStyle_Tool ) )
796         normalizeWindow( w );
797     else
798         w->parentWidget()->show();
799     if ( d->maxWindow )
800         d->maxWindow->raise();
801     updateWorkspace();
802 }
803
804
805 QWorkspacePChild* QWorkspaceP::findChild( QWidget* w)
806 {
807     QPtrListIterator<QWorkspacePChild> it( d->windows );
808     while ( it.current () ) {
809         QWorkspacePChild* c = it.current();
810         ++it;
811         if (c->windowWidget() == w)
812             return c;
813     }
814     return 0;
815 }
816
817 /*!
818   Returns a list of all windows.
819  */
820 QWidgetList QWorkspaceP::windowList() const
821 {
822     QWidgetList windows;
823     QPtrListIterator<QWorkspacePChild> it( d->windows );
824     while ( it.current () ) {
825         QWorkspacePChild* c = it.current();
826         ++it;
827         if ( c->windowWidget() )
828             windows.append( c->windowWidget() );
829     }
830     return windows;
831 }
832
833 /*!\reimp*/
834 bool QWorkspaceP::eventFilter( QObject *o, QEvent * e)
835 {
836     static QTime* t = 0;
837     static QWorkspaceP* tc = 0;
838 #ifndef QT_NO_MENUBAR
839     if ( o == d->maxtools && d->menuId != -1 ) {
840         switch ( e->type() ) {
841         case QEvent::MouseButtonPress:
842             {
843                 QMenuBar* b = (QMenuBar*)o->parent();
844                 if ( !t )
845                     t = new QTime;
846                 if ( tc != this || t->elapsed() > QApplication::doubleClickInterval() ) {
847                     if ( QApplication::reverseLayout() ) {
848                         QPoint p = b->mapToGlobal( QPoint( b->x() + b->width(), b->y() + b->height() ) );
849                         p.rx() -= d->popup->sizeHint().width();
850                         popupOperationMenu( p );
851                     } else {
852                         popupOperationMenu( b->mapToGlobal( QPoint( b->x(), b->y() + b->height() ) ) );
853                     }
854                     t->start();
855                     tc = this;
856                 } else {
857                     tc = 0;
858                     closeActiveWindow();
859                 }
860                 return TRUE;
861             }
862         default:
863             break;
864         }
865         return QWidget::eventFilter( o, e );
866     }
867 #endif
868     switch ( e->type() ) {
869     case QEvent::Hide:
870     case QEvent::HideToParent:
871         if ( !o->isA( "QWorkspacePChild" ) || !isVisible() )
872             break;
873         d->focus.removeRef( (QWorkspacePChild*)o );
874         if ( d->active != o )
875             break;
876         if ( d->focus.isEmpty() ) {
877             activateWindow( 0 );
878         } else {
879             d->autoFocusChange = TRUE;
880             activatePreviousWindow();
881             QWorkspacePChild* c = d->active;
882             while ( d->active &&
883                     d->active->windowWidget() &&
884                     d->active->windowWidget()->testWFlags( WStyle_Tool ) ) {
885                 activatePreviousWindow();
886                 if ( d->active == c )
887                     break;
888             }
889             d->autoFocusChange = FALSE;
890         }
891         if ( d->maxWindow == o && d->maxWindow->isHidden() ) {
892             d->maxWindow->setGeometry( d->maxRestore );
893             d->maxWindow = 0;
894             if ( d->active )
895                 maximizeWindow( d->active );
896
897             if ( !d->maxWindow ) {
898
899                 if ( style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this)) {
900                     QWorkspacePChild *wc = (QWorkspacePChild *)o;
901                     wc->widgetResizeHandler->setActive( TRUE );
902                     if ( wc->titlebar )
903                         wc->titlebar->setMovable( TRUE );
904                 } else {
905                     hideMaximizeControls();
906                 }
907 #ifndef QT_NO_WIDGET_TOPEXTRA
908                 inCaptionChange = TRUE;
909                 if ( !!d->topCaption )
910                     topLevelWidget()->setCaption( d->topCaption );
911                 inCaptionChange = FALSE;
912 #endif
913             }
914         }
915         break;
916     case QEvent::Show:
917         if ( o->isA("QWorkspacePChild") && !d->focus.containsRef( (QWorkspacePChild*)o ) )
918             d->focus.append( (QWorkspacePChild*)o );
919         updateWorkspace();
920         break;
921     case QEvent::CaptionChange:
922         if ( inCaptionChange )
923             break;
924
925 #ifndef QT_NO_WIDGET_TOPEXTRA
926         inCaptionChange = TRUE;
927         if ( o == topLevelWidget() )
928             d->topCaption = ((QWidget*)o)->caption();
929
930         if ( d->maxWindow && !!d->topCaption )
931             topLevelWidget()->setCaption( tr("%1 - [%2]")
932                 .arg(d->topCaption).arg(d->maxWindow->caption()));
933         inCaptionChange = FALSE;
934 #endif
935
936         break;
937     case QEvent::Close:
938         if ( o == topLevelWidget() )
939         {
940             QPtrListIterator<QWorkspacePChild> it( d->windows );
941             while ( it.current () ) {
942                 QWorkspacePChild* c = it.current();
943                 ++it;
944                 if ( c->shademode )
945                     c->showShaded();
946             }
947         } else if ( o->inherits("QWorkspacePChild") ) {
948             d->popup->hide();
949         }
950         if ( d->windows.count() > 1 || d->windows.first() && d->active != d->windows.first() )
951           activatePreviousWindow();
952         updateWorkspace();
953         break;
954     default:
955         break;
956     }
957     return QWidget::eventFilter( o, e);
958 }
959
960 void QWorkspaceP::showMaximizeControls()
961 {
962 #ifndef QT_NO_MENUBAR
963     Q_ASSERT(d->maxWindow);
964     QMenuBar* b = 0;
965     
966     // Do a breadth-first search first on every parent, 
967     QWidget* w = parentWidget();
968     QObjectList * l = 0;
969     while ( !l && w ) {
970         l = w->queryList( "QMenuBar", 0, FALSE, FALSE );
971         w = w->parentWidget();  
972         if ( l && !l->count() ) {
973             delete l;
974             l = 0;
975         }
976     } 
977     
978     // and query recursively if nothing is found.
979     if ( !l || !l->count() ) {
980         if ( l )
981             delete l;
982         l = topLevelWidget()->queryList( "QMenuBar", 0, 0, TRUE );
983     }
984     if ( l && l->count() )
985         b = (QMenuBar *)l->first();
986     delete l;
987
988     if ( !b )
989         return;
990
991     if ( !d->maxcontrols ) {
992         d->maxmenubar = b;
993         d->maxcontrols = new QFrame( topLevelWidget(), "qt_maxcontrols" );
994         QHBoxLayout* l = new QHBoxLayout( d->maxcontrols,
995                                           d->maxcontrols->frameWidth(), 0 );
996         if ( d->maxWindow->windowWidget()->testWFlags(WStyle_Minimize) ) {
997             QToolButton* iconB = new QToolButton( d->maxcontrols, "iconify" );
998 #ifndef QT_NO_TOOLTIP
999             QToolTip::add( iconB, tr( "Minimize" ) );
1000 #endif
1001             l->addWidget( iconB );
1002             iconB->setFocusPolicy( NoFocus );
1003             iconB->setIconSet(style().stylePixmap(QStyle::SP_TitleBarMinButton));
1004             iconB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
1005             connect( iconB, SIGNAL( clicked() ),
1006                      this, SLOT( minimizeActiveWindow() ) );
1007         }
1008
1009         QToolButton* restoreB = new QToolButton( d->maxcontrols, "restore" );
1010 #ifndef QT_NO_TOOLTIP
1011         QToolTip::add( restoreB, tr( "Restore Down" ) );
1012 #endif
1013         l->addWidget( restoreB );
1014         restoreB->setFocusPolicy( NoFocus );
1015         restoreB->setIconSet( style().stylePixmap(QStyle::SP_TitleBarNormalButton));
1016         restoreB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
1017         connect( restoreB, SIGNAL( clicked() ),
1018                  this, SLOT( normalizeActiveWindow() ) );
1019
1020         l->addSpacing( 2 );
1021         QToolButton* closeB = new QToolButton( d->maxcontrols, "close" );
1022 #ifndef QT_NO_TOOLTIP
1023         QToolTip::add( closeB, tr( "Close" ) );
1024 #endif
1025         l->addWidget( closeB );
1026         closeB->setFocusPolicy( NoFocus );
1027         closeB->setIconSet( style().stylePixmap(QStyle::SP_TitleBarCloseButton) );
1028         closeB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
1029         connect( closeB, SIGNAL( clicked() ),
1030                  this, SLOT( closeActiveWindow() ) );
1031
1032         d->maxcontrols->setFixedSize( d->maxcontrols->minimumSizeHint() );
1033     }
1034
1035     if ( d->controlId == -1 || b->indexOf( d->controlId ) == -1 ) {
1036         QFrame* dmaxcontrols = d->maxcontrols;
1037         d->controlId = b->insertItem( dmaxcontrols, -1, b->count() );
1038     }
1039     if ( d->active && ( d->menuId == -1 || b->indexOf( d->menuId ) == -1 ) ) {
1040         if ( !d->maxtools ) {
1041             d->maxtools = new QLabel( topLevelWidget(), "qt_maxtools" );
1042             d->maxtools->installEventFilter( this );
1043         }
1044 #ifndef QT_NO_WIDGET_TOPEXTRA
1045         if ( d->active->windowWidget() && d->active->windowWidget()->icon() ) {
1046             QPixmap pm(*d->active->windowWidget()->icon());
1047             if(pm.width() != 14 || pm.height() != 14) {
1048                 QImage im;
1049                 im = pm;
1050                 pm = im.smoothScale( 14, 14 );
1051             }
1052             d->maxtools->setPixmap( pm );
1053         } else
1054 #endif
1055         {
1056             QPixmap pm(14,14);
1057             pm.fill( white );
1058             d->maxtools->setPixmap( pm );
1059         }
1060         d->menuId = b->insertItem( d->maxtools, -1, 0 );
1061     }
1062 #endif
1063 }
1064
1065
1066 void QWorkspaceP::hideMaximizeControls()
1067 {
1068 #ifndef QT_NO_MENUBAR
1069     if ( d->maxmenubar ) {
1070         int mi = d->menuId;
1071         if ( mi != -1 ) {
1072             if ( d->maxmenubar->indexOf( mi ) != -1 )
1073                 d->maxmenubar->removeItem( mi );
1074             d->maxtools = 0;
1075         }
1076         int ci = d->controlId;
1077         if ( ci != -1 && d->maxmenubar->indexOf( ci ) != -1 )
1078             d->maxmenubar->removeItem( ci );
1079     }
1080     d->maxcontrols = 0;
1081     d->menuId = -1;
1082     d->controlId = -1;
1083 #endif
1084 }
1085
1086 void QWorkspaceP::closeActiveWindow()
1087 {
1088     setUpdatesEnabled( FALSE );
1089     if ( d->maxWindow && d->maxWindow->windowWidget() )
1090         d->maxWindow->windowWidget()->close();
1091     else if ( d->active && d->active->windowWidget() )
1092         d->active->windowWidget()->close();
1093     setUpdatesEnabled( TRUE );
1094     updateWorkspace();
1095 }
1096
1097 void QWorkspaceP::closeAllWindows()
1098 {
1099     QPtrListIterator<QWorkspacePChild> it( d->windows );
1100     QWorkspacePChild *c = 0;
1101     while ( ( c = it.current() ) != 0 ) {
1102         ++it;
1103         if ( c->windowWidget() )
1104             c->windowWidget()->close();
1105     }
1106 }
1107
1108 void QWorkspaceP::normalizeActiveWindow()
1109 {
1110     if  ( d->maxWindow )
1111         d->maxWindow->showNormal();
1112     else if ( d->active )
1113         d->active->showNormal();
1114 }
1115
1116 void QWorkspaceP::minimizeActiveWindow()
1117 {
1118     if ( d->maxWindow )
1119         d->maxWindow->showMinimized();
1120     else if ( d->active )
1121         d->active->showMinimized();
1122 }
1123
1124 void QWorkspaceP::showOperationMenu()
1125 {
1126     if  ( !d->active || !d->active->windowWidget() )
1127         return;
1128     Q_ASSERT( d->active->windowWidget()->testWFlags( WStyle_SysMenu ) );
1129     QPoint p;
1130     QPopupMenu *popup = d->active->windowWidget()->testWFlags( WStyle_Tool ) ? d->toolPopup : d->popup;
1131     if ( QApplication::reverseLayout() ) {
1132         p = QPoint( d->active->windowWidget()->mapToGlobal( QPoint(d->active->windowWidget()->width(),0) ) );
1133         p.rx() -= popup->sizeHint().width();
1134     } else {
1135         p = QPoint( d->active->windowWidget()->mapToGlobal( QPoint(0,0) ) );
1136     }
1137     if ( !d->active->isVisible() ) {
1138         p = d->active->iconWidget()->mapToGlobal( QPoint(0,0) );
1139         p.ry() -= popup->sizeHint().height();
1140     }
1141     popupOperationMenu( p );
1142 }
1143
1144 void QWorkspaceP::popupOperationMenu( const QPoint&  p)
1145 {
1146     if ( !d->active || !d->active->windowWidget() || !d->active->windowWidget()->testWFlags( WStyle_SysMenu ) )
1147         return;
1148     if ( d->active->windowWidget()->testWFlags( WStyle_Tool ))
1149         d->toolPopup->popup( p );
1150     else
1151         d->popup->popup( p );
1152 }
1153
1154 void QWorkspaceP::operationMenuAboutToShow()
1155 {
1156     for ( int i = 1; i < 6; i++ ) {
1157         bool enable = d->active != 0;
1158         d->popup->setItemEnabled( i, enable );
1159     }
1160
1161     if ( !d->active || !d->active->windowWidget() )
1162         return;
1163
1164     d->popup->setItemEnabled( 4, d->active->windowWidget()->testWFlags( WStyle_Minimize ) );
1165     d->popup->setItemEnabled( 5, d->active->windowWidget()->testWFlags( WStyle_Maximize ) );
1166
1167     if ( d->active == d->maxWindow ) {
1168         d->popup->setItemEnabled( 2, FALSE );
1169         d->popup->setItemEnabled( 3, FALSE );
1170         d->popup->setItemEnabled( 5, FALSE );
1171     } else if ( d->active->isVisible() ){
1172         d->popup->setItemEnabled( 1, FALSE );
1173     } else {
1174         d->popup->setItemEnabled( 2, FALSE );
1175         d->popup->setItemEnabled( 3, FALSE );
1176         d->popup->setItemEnabled( 4, FALSE );
1177     }
1178 }
1179
1180 void QWorkspaceP::toolMenuAboutToShow()
1181 {
1182     if ( !d->active || !d->active->windowWidget() )
1183         return;
1184
1185     d->toolPopup->setItemEnabled( 3, !d->active->shademode );
1186     if ( d->active->shademode )
1187         d->toolPopup->changeItem( 6,
1188                                   QIconSet(style().stylePixmap(QStyle::SP_TitleBarUnshadeButton)), tr("&Unshade") );
1189     else
1190         d->toolPopup->changeItem( 6, QIconSet(style().stylePixmap(QStyle::SP_TitleBarShadeButton)), tr("Sh&ade") );
1191     d->toolPopup->setItemEnabled( 6, d->active->windowWidget()->testWFlags( WStyle_MinMax ) );
1192     d->toolPopup->setItemChecked( 7, d->active->windowWidget()->testWFlags( WStyle_StaysOnTop ) );
1193 }
1194
1195 void QWorkspaceP::operationMenuActivated( int a )
1196 {
1197     if ( !d->active )
1198         return;
1199     switch ( a ) {
1200     case 1:
1201         d->active->showNormal();
1202         break;
1203     case 2:
1204         d->active->doMove();
1205         break;
1206     case 3:
1207         if ( d->active->shademode )
1208             d->active->showShaded();
1209         d->active->doResize();
1210         break;
1211     case 4:
1212         d->active->showMinimized();
1213         break;
1214     case 5:
1215         d->active->showMaximized();
1216         break;
1217     case 6:
1218         d->active->showShaded();
1219         break;
1220     case 7:
1221         {
1222             QWorkspaceP* w = (QWorkspaceP*)d->active->windowWidget();
1223             if ( !w )
1224                 break;
1225             if ( w->testWFlags( WStyle_StaysOnTop ) ) {
1226                 w->clearWFlags( WStyle_StaysOnTop );
1227             } else {
1228                 w->setWFlags( WStyle_StaysOnTop );
1229                 w->parentWidget()->raise();
1230             }
1231         }
1232         break;
1233     default:
1234         break;
1235     }
1236 }
1237
1238 void QWorkspaceP::activateNextWindow()
1239 {
1240     if ( d->focus.isEmpty() )
1241         return;
1242     if ( !d->active ) {
1243         if ( d->focus.first() )
1244             activateWindow( d->focus.first()->windowWidget(), FALSE );
1245         return;
1246     }
1247
1248     int a = d->focus.find( d->active ) + 1;
1249
1250     a = a % d->focus.count();
1251
1252     if ( d->focus.at( a ) )
1253         activateWindow( d->focus.at( a )->windowWidget(), FALSE );
1254     else
1255         d->active = 0;
1256 }
1257
1258 void QWorkspaceP::activatePreviousWindow()
1259 {
1260     if ( d->focus.isEmpty() ) {
1261         if ( d->windows.count() > 0 ) { //VSR+
1262             activateWindow( d->windows.last()->windowWidget() ); //VSR+
1263         } //VSR+
1264         return;
1265     }
1266     if ( !d->active ) {
1267         if ( d->focus.last() )
1268             activateWindow( d->focus.first()->windowWidget(), FALSE );
1269         else
1270             activateWindow( 0 );
1271
1272         return;
1273     }
1274
1275     int a = d->focus.find( d->active ) - 1;
1276
1277     if ( a < 0 )
1278         a = d->focus.count()-1;
1279
1280     if ( d->autoFocusChange ) {
1281         QWidget *widget = 0;
1282         while ( a >= 0 && d->focus.at( a ) && ( widget = d->focus.at( a )->windowWidget() ) && !widget->isVisible() )
1283             a--;
1284         if ( a < 0 )
1285             a = d->focus.count() - 1;
1286     }
1287
1288     if ( d->focus.at( a ) )
1289         activateWindow( d->focus.at( a )->windowWidget(), FALSE );
1290     else
1291         activateWindow( 0 );
1292 }
1293
1294
1295 /*!
1296   \fn void QWorkspaceP::windowActivated( QWidget* w )
1297
1298   This signal is emitted when the window widget \a w becomes active.
1299   Note that \a w can be null, and that more than one signal may be
1300   fired for one activation event.
1301
1302   \sa activeWindow(), windowList()
1303 */
1304
1305
1306
1307 /*!
1308   Arranges all child windows in a cascade pattern.
1309
1310   \sa tile()
1311  */
1312 void QWorkspaceP::cascade()
1313 {
1314     if  ( d->maxWindow )
1315         d->maxWindow->showNormal();
1316
1317     if ( d->vbar ) {
1318         d->vbar->blockSignals( TRUE );
1319         d->vbar->setValue( 0 );
1320         d->vbar->blockSignals( FALSE );
1321         d->hbar->blockSignals( TRUE );
1322         d->hbar->setValue( 0 );
1323         d->hbar->blockSignals( FALSE );
1324         scrollBarChanged();
1325     }
1326
1327     const int xoffset = 13;
1328     const int yoffset = 20;
1329
1330     // make a list of all relevant mdi clients
1331     QPtrList<QWorkspacePChild> widgets;
1332     QWorkspacePChild* wc = 0;
1333     for ( wc = d->windows.first(); wc; wc = d->windows.next() )
1334         if ( wc->iconw )
1335             normalizeWindow( wc->windowWidget() );
1336     for ( wc = d->focus.first(); wc; wc = d->focus.next() )
1337         if ( wc->windowWidget()->isVisibleTo( this ) && !wc->windowWidget()->testWFlags( WStyle_Tool ) )
1338             widgets.append( wc );
1339
1340     int x = 0;
1341     int y = 0;
1342
1343     setUpdatesEnabled( FALSE );
1344     QPtrListIterator<QWorkspacePChild> it( widgets );
1345     int children = d->windows.count() - 1;
1346     while ( it.current () ) {
1347         QWorkspacePChild *child = it.current();
1348         ++it;
1349         child->setUpdatesEnabled( FALSE );
1350         bool hasSizeHint = FALSE;
1351         QSize prefSize = child->windowWidget()->sizeHint().expandedTo( child->windowWidget()->minimumSizeHint() );
1352
1353         if ( !prefSize.isValid() )
1354             prefSize = QSize( width() - children * xoffset, height() - children * yoffset );
1355         else
1356             hasSizeHint = TRUE;
1357         prefSize = prefSize.expandedTo( child->windowWidget()->minimumSize() ).boundedTo( child->windowWidget()->maximumSize() );
1358         if ( hasSizeHint )
1359             prefSize += QSize( child->baseSize().width(), child->baseSize().height() );
1360
1361         int w = prefSize.width();
1362         int h = prefSize.height();
1363
1364         child->showNormal();
1365         qApp->sendPostedEvents( 0, QEvent::ShowNormal );
1366         if ( y + h > height() )
1367             y = 0;
1368         if ( x + w > width() )
1369             x = 0;
1370         child->setGeometry( x, y, w, h );
1371         x += xoffset;
1372         y += yoffset;
1373         child->internalRaise();
1374         child->setUpdatesEnabled( TRUE );
1375     }
1376     setUpdatesEnabled( TRUE );
1377     updateWorkspace();
1378 }
1379
1380 /*!
1381   Arranges all child windows in a tile pattern.
1382
1383   \sa cascade()
1384  */
1385 void QWorkspaceP::tile()
1386 {
1387     if  ( d->maxWindow )
1388         d->maxWindow->showNormal();
1389
1390     if ( d->vbar ) {
1391         d->vbar->blockSignals( TRUE );
1392         d->vbar->setValue( 0 );
1393         d->vbar->blockSignals( FALSE );
1394         d->hbar->blockSignals( TRUE );
1395         d->hbar->setValue( 0 );
1396         d->hbar->blockSignals( FALSE );
1397         scrollBarChanged();
1398     }
1399
1400     int rows = 1;
1401     int cols = 1;
1402     int n = 0;
1403     QWorkspacePChild* c;
1404
1405     QPtrListIterator<QWorkspacePChild> it( d->windows );
1406     while ( it.current () ) {
1407         c = it.current();
1408         ++it;
1409         if ( !c->windowWidget()->isHidden() &&
1410              !c->windowWidget()->testWFlags( WStyle_StaysOnTop ) &&
1411              !c->windowWidget()->testWFlags( WStyle_Tool ) )
1412             n++;
1413     }
1414
1415     while ( rows * cols < n ) {
1416         if ( cols <= rows )
1417             cols++;
1418         else
1419             rows++;
1420     }
1421     int add = cols * rows - n;
1422     bool* used = new bool[ cols*rows ];
1423     for ( int i = 0; i < rows*cols; i++ )
1424         used[i] = FALSE;
1425
1426     int row = 0;
1427     int col = 0;
1428     int w = width() / cols;
1429     int h = height() / rows;
1430
1431     it.toFirst();
1432     while ( it.current () ) {
1433         c = it.current();
1434         ++it;
1435         if ( c->windowWidget()->isHidden() || c->windowWidget()->testWFlags( WStyle_Tool ) )
1436             continue;
1437         if ( c->windowWidget()->testWFlags( WStyle_StaysOnTop ) ) {
1438             QPoint p = c->pos();
1439             if ( p.x()+c->width() < 0 )
1440                 p.setX( 0 );
1441             if ( p.x() > width() )
1442                 p.setX( width() - c->width() );
1443             if ( p.y() + 10 < 0 )
1444                 p.setY( 0 );
1445             if ( p.y() > height() )
1446                 p.setY( height() - c->height() );
1447
1448
1449             if ( p != c->pos() )
1450                 c->QFrame::move( p );
1451         } else {
1452             c->showNormal();
1453             qApp->sendPostedEvents( 0, QEvent::ShowNormal );
1454             used[row*cols+col] = TRUE;
1455             if ( add ) {
1456                 c->setGeometry( col*w, row*h, QMIN( w, c->windowWidget()->maximumWidth()+c->baseSize().width() ),
1457                                               QMIN( 2*h, c->windowWidget()->maximumHeight()+c->baseSize().height() ) );
1458                 used[(row+1)*cols+col] = TRUE;
1459                 add--;
1460             } else {
1461                 c->setGeometry( col*w, row*h, QMIN( w, c->windowWidget()->maximumWidth()+c->baseSize().width() ),
1462                                               QMIN( h, c->windowWidget()->maximumHeight()+c->baseSize().height() ) );
1463             }
1464             while( row < rows && col < cols && used[row*cols+col] ) {
1465                 col++;
1466                 if ( col == cols ) {
1467                     col = 0;
1468                     row++;
1469                 }
1470             }
1471         }
1472     }
1473     delete [] used;
1474     updateWorkspace();
1475 }
1476
1477 QWorkspacePChild::QWorkspacePChild( QWidget* window, QWorkspaceP *parent,
1478                                   const char *name )
1479     : QFrame( parent, name,
1480               WStyle_Customize | WStyle_NoBorder  | WDestructiveClose | WNoMousePropagation | WSubWindow )
1481 {
1482     setMouseTracking( TRUE );
1483     act = FALSE;
1484     iconw = 0;
1485     lastfocusw = 0;
1486     shademode = FALSE;
1487     titlebar = 0;
1488     snappedRight = FALSE;
1489     snappedDown = FALSE;
1490
1491     if (window) {
1492         switch (window->focusPolicy()) {
1493         case QWidget::NoFocus:
1494             window->setFocusPolicy(QWidget::ClickFocus);
1495             break;
1496         case QWidget::TabFocus:
1497             window->setFocusPolicy(QWidget::StrongFocus);
1498             break;
1499         default:
1500             break;
1501         }
1502     }
1503
1504     if ( window && window->testWFlags( WStyle_Title ) ) {
1505         titlebar = new QTitleBarP( window, this, "qt_ws_titlebar" );
1506         connect( titlebar, SIGNAL( doActivate() ),
1507                  this, SLOT( activate() ) );
1508         connect( titlebar, SIGNAL( doClose() ),
1509                  window, SLOT( close() ) );
1510         connect( titlebar, SIGNAL( doMinimize() ),
1511                  this, SLOT( showMinimized() ) );
1512         connect( titlebar, SIGNAL( doNormal() ),
1513                  this, SLOT( showNormal() ) );
1514         connect( titlebar, SIGNAL( doMaximize() ),
1515                  this, SLOT( showMaximized() ) );
1516         connect( titlebar, SIGNAL( popupOperationMenu( const QPoint& ) ),
1517                  this, SIGNAL( popupOperationMenu( const QPoint& ) ) );
1518         connect( titlebar, SIGNAL( showOperationMenu() ),
1519                  this, SIGNAL( showOperationMenu() ) );
1520         connect( titlebar, SIGNAL( doShade() ),
1521                  this, SLOT( showShaded() ) );
1522         connect( titlebar, SIGNAL( doubleClicked() ),
1523                  this, SLOT( titleBarDoubleClicked() ) );
1524     }
1525
1526     if ( window && window->testWFlags( WStyle_Tool ) ) {
1527         setFrameStyle( QFrame::StyledPanel | QFrame::Raised );
1528         setLineWidth( 2 );
1529         setMinimumSize( 128, 0 );
1530     } else {
1531         setFrameStyle( QFrame::StyledPanel | QFrame::Raised );
1532         setLineWidth( 2 );
1533         setMinimumSize( 128, 0 );
1534     }
1535
1536     childWidget = window;
1537     if (!childWidget)
1538         return;
1539
1540 #ifndef QT_NO_WIDGET_TOPEXTRA
1541     setCaption( childWidget->caption() );
1542 #endif
1543
1544     QPoint p;
1545     QSize s;
1546     QSize cs;
1547
1548     bool hasBeenResized = childWidget->testWState( WState_Resized );
1549
1550     if ( !hasBeenResized )
1551         cs = childWidget->sizeHint().expandedTo( childWidget->minimumSizeHint() );
1552     else
1553         cs = childWidget->size();
1554
1555     int th = titlebar ? titlebar->sizeHint().height() : 0;
1556     if ( titlebar ) {
1557 #ifndef QT_NO_WIDGET_TOPEXTRA
1558         if( childWidget->icon() ) {
1559             QPixmap pm(*childWidget->icon());
1560             if(pm.width() != 14 || pm.height() != 14) {
1561                 QImage im;
1562                 im = pm;
1563                 pm = im.smoothScale( 14, 14 );
1564             }
1565             titlebar->setIcon( pm );
1566         }
1567 #endif
1568         p = QPoint( contentsRect().x(),
1569                     th + contentsRect().y() );
1570         s = QSize( cs.width() + 2*frameWidth(),
1571                    cs.height() + 2*frameWidth() + th + 2 );
1572     } else {
1573         p = QPoint( contentsRect().x(), contentsRect().y() );
1574         s = QSize( cs.width() + 2*frameWidth(),
1575                    cs.height() + 2*frameWidth() );
1576     }
1577
1578     childWidget->reparent( this, p);
1579     resize( s );
1580
1581     childWidget->installEventFilter( this );
1582
1583     widgetResizeHandler = new QWidgetResizeHandlerP( this, window );
1584     widgetResizeHandler->setMovingEnabled( FALSE );
1585     widgetResizeHandler->setSizeProtection( !parent->scrollBarsEnabled() );
1586     connect( widgetResizeHandler, SIGNAL( activate() ),
1587              this, SLOT( activate() ) );
1588     widgetResizeHandler->setExtraHeight( th + 2 );
1589
1590     setBaseSize( baseSize() );
1591 }
1592
1593 QWorkspacePChild::~QWorkspacePChild()
1594 {
1595     if ( iconw )
1596         delete iconw->parentWidget();
1597 }
1598
1599 void QWorkspacePChild::moveEvent( QMoveEvent * )
1600 {
1601     ((QWorkspaceP*) parentWidget() )->updateWorkspace();
1602 }
1603
1604 void QWorkspacePChild::resizeEvent( QResizeEvent * )
1605 {
1606     QRect r = contentsRect();
1607     QRect cr;
1608
1609     if ( titlebar ) {
1610         int th = titlebar->sizeHint().height();
1611         QRect tbrect( 0, 0, width(), th );
1612         if ( !style().styleHint( QStyle::SH_TitleBar_NoBorder ) )
1613             tbrect = QRect( r.x(), r.y(), r.width(), th );
1614         titlebar->setGeometry( tbrect );
1615         cr = QRect( r.x(), r.y() + titlebar->height() + (shademode ? 5 : 1),
1616             r.width(), r.height() - titlebar->height() - 2 );
1617     } else {
1618         cr = r;
1619     }
1620
1621     if (!childWidget)
1622         return;
1623
1624     windowSize = cr.size();
1625     childWidget->setGeometry( cr );
1626     ((QWorkspaceP*) parentWidget() )->updateWorkspace();
1627 }
1628
1629 QSize QWorkspacePChild::baseSize() const
1630 {
1631     int th = titlebar ? titlebar->sizeHint().height() : 0;
1632     return QSize( 2*frameWidth(), 2*frameWidth() + th + 2 );
1633 }
1634
1635 QSize QWorkspacePChild::sizeHint() const
1636 {
1637     if ( !childWidget )
1638         return QFrame::sizeHint() + baseSize();
1639     return childWidget->sizeHint().expandedTo( childWidget->minimumSizeHint() ) + baseSize();
1640 }
1641
1642 QSize QWorkspacePChild::minimumSizeHint() const
1643 {
1644     if ( !childWidget )
1645         return QFrame::minimumSizeHint() + baseSize();
1646     QSize s = childWidget->minimumSize();
1647     if ( s.isEmpty() )
1648         s = childWidget->minimumSizeHint();
1649     return s + baseSize();
1650 }
1651
1652 void QWorkspacePChild::activate()
1653 {
1654     ((QWorkspaceP*)parentWidget())->activateWindow( windowWidget() );
1655 }
1656
1657 bool QWorkspacePChild::eventFilter( QObject * o, QEvent * e)
1658 {
1659     if ( !isActive() && ( e->type() == QEvent::MouseButtonPress ||
1660         e->type() == QEvent::FocusIn ) ) {
1661         if ( iconw ) {
1662             ((QWorkspaceP*)parentWidget())->normalizeWindow( windowWidget() );
1663             if ( iconw ) {
1664                 ((QWorkspaceP*)parentWidget())->removeIcon( iconw->parentWidget() );
1665                 delete iconw->parentWidget();
1666                 iconw = 0;
1667             }
1668         }
1669         activate();
1670     }
1671
1672     // for all widgets except the window, we that's the only thing we
1673     // process, and if we have no childWidget we skip totally
1674     if ( o != childWidget || childWidget == 0 )
1675         return FALSE;
1676
1677     switch ( e->type() ) {
1678     case QEvent::Show:
1679         if ( ((QWorkspaceP*)parentWidget())->d->focus.find( this ) < 0 )
1680             ((QWorkspaceP*)parentWidget())->d->focus.append( this );
1681         if ( isVisibleTo( parentWidget() ) )
1682             break;
1683         if (( (QShowEvent*)e)->spontaneous() )
1684             break;
1685         // fall through
1686     case QEvent::ShowToParent:
1687         if ( windowWidget() && windowWidget()->testWFlags( WStyle_StaysOnTop ) ) {
1688             internalRaise();
1689             show();
1690         }
1691         ((QWorkspaceP*)parentWidget())->showWindow( windowWidget() );
1692         break;
1693     case QEvent::ShowMaximized:
1694         if ( windowWidget()->maximumSize().isValid() &&
1695              ( windowWidget()->maximumWidth() < parentWidget()->width() ||
1696                windowWidget()->maximumHeight() < parentWidget()->height() ) ) {
1697             windowWidget()->resize( windowWidget()->maximumSize() );
1698             break;
1699         }
1700         if ( windowWidget()->testWFlags( WStyle_Maximize ) && !windowWidget()->testWFlags( WStyle_Tool ) )
1701             ((QWorkspaceP*)parentWidget())->maximizeWindow( windowWidget() );
1702         else
1703             ((QWorkspaceP*)parentWidget())->normalizeWindow( windowWidget() );
1704         break;
1705     case QEvent::ShowMinimized:
1706         ((QWorkspaceP*)parentWidget())->minimizeWindow( windowWidget() );
1707         break;
1708     case QEvent::ShowNormal:
1709         ((QWorkspaceP*)parentWidget())->normalizeWindow( windowWidget() );
1710         if (iconw) {
1711             ((QWorkspaceP*)parentWidget())->removeIcon( iconw->parentWidget() );
1712             delete iconw->parentWidget();
1713         }
1714         break;
1715     case QEvent::Hide:
1716     case QEvent::HideToParent:
1717         if ( !childWidget->isVisibleTo( this ) ) {
1718             QWidget * w = iconw;
1719             if ( w && ( w = w->parentWidget() ) ) {
1720                 ((QWorkspaceP*)parentWidget())->removeIcon( w );
1721                 delete w;
1722             }
1723             hide();
1724         }
1725         break;
1726     case QEvent::CaptionChange:
1727 #ifndef QT_NO_WIDGET_TOPEXTRA
1728         setCaption( childWidget->caption() );
1729         if ( iconw )
1730             iconw->setCaption( childWidget->caption() );
1731 #endif
1732         break;
1733     case QEvent::IconChange:
1734         {
1735             QWorkspaceP* ws = (QWorkspaceP*)parentWidget();
1736             if ( !titlebar )
1737                 break;
1738 #ifndef QT_NO_WIDGET_TOPEXTRA
1739             if ( childWidget->icon() ) {
1740                 titlebar->setIcon( *childWidget->icon() );
1741             } else
1742 #endif
1743             {
1744                 QPixmap pm;
1745                 titlebar->setIcon( pm );
1746             }
1747
1748             if ( ws->d->maxWindow != this )
1749                 break;
1750
1751             if ( ws->d->maxtools ) {
1752 #ifndef QT_NO_WIDGET_TOPEXTRA
1753                 if ( childWidget->icon() ) {
1754                     QPixmap pm(*childWidget->icon());
1755                     if(pm.width() != 14 || pm.height() != 14) {
1756                         QImage im;
1757                         im = pm;
1758                         pm = im.smoothScale( 14, 14 );
1759                     }
1760                     ws->d->maxtools->setPixmap( pm );
1761                 } else
1762 #endif
1763                 {
1764                     QPixmap pm(14,14);
1765                     pm.fill( white );
1766                     ws->d->maxtools->setPixmap( pm );
1767                 }
1768             }
1769         }
1770         break;
1771     case QEvent::Resize:
1772         {
1773             QResizeEvent* re = (QResizeEvent*)e;
1774             if ( re->size() != windowSize && !shademode )
1775                 resize( re->size() + baseSize() );
1776         }
1777         break;
1778
1779     case QEvent::WindowDeactivate:
1780         if ( titlebar )
1781             titlebar->setActive( FALSE );
1782         break;
1783
1784     case QEvent::WindowActivate:
1785         if ( titlebar )
1786             titlebar->setActive( act );
1787         break;
1788
1789     default:
1790         break;
1791     }
1792
1793     return QFrame::eventFilter(o, e);
1794 }
1795
1796 bool QWorkspacePChild::focusNextPrevChild( bool next )
1797 {
1798     QFocusData *f = focusData();
1799
1800     QWidget *startingPoint = f->home();
1801     QWidget *candidate = 0;
1802     QWidget *w = next ? f->next() : f->prev();
1803     while( !candidate && w != startingPoint ) {
1804         if ( w != startingPoint &&
1805              (w->focusPolicy() & TabFocus) == TabFocus
1806              && w->isEnabled() &&!w->focusProxy() && w->isVisible() )
1807             candidate = w;
1808         w = next ? f->next() : f->prev();
1809     }
1810
1811     if ( candidate ) {
1812         QObjectList *ol = queryList();
1813         bool ischild = ol->findRef( candidate ) != -1;
1814         delete ol;
1815         if ( !ischild ) {
1816             startingPoint = f->home();
1817             QWidget *nw = next ? f->prev() : f->next();
1818             QObjectList *ol2 = queryList();
1819             QWidget *lastValid = 0;
1820             candidate = startingPoint;
1821             while ( nw != startingPoint ) {
1822                 if ( ( candidate->focusPolicy() & TabFocus ) == TabFocus
1823                     && candidate->isEnabled() &&!candidate->focusProxy() && candidate->isVisible() )
1824                     lastValid = candidate;
1825                 if ( ol2->findRef( nw ) == -1 ) {
1826                     candidate = lastValid;
1827                     break;
1828                 }
1829                 candidate = nw;
1830                 nw = next ? f->prev() : f->next();
1831             }
1832             delete ol2;
1833         }
1834     }
1835
1836     if ( !candidate )
1837         return FALSE;
1838
1839     candidate->setFocus();
1840     return TRUE;
1841 }
1842
1843 void QWorkspacePChild::childEvent( QChildEvent*  e)
1844 {
1845     if ( e->type() == QEvent::ChildRemoved && e->child() == childWidget ) {
1846         childWidget = 0;
1847         if ( iconw ) {
1848             ((QWorkspaceP*)parentWidget())->removeIcon( iconw->parentWidget() );
1849             delete iconw->parentWidget();
1850         }
1851         close();
1852     }
1853 }
1854
1855
1856 void QWorkspacePChild::doResize()
1857 {
1858     widgetResizeHandler->doResize();
1859 }
1860
1861 void QWorkspacePChild::doMove()
1862 {
1863     widgetResizeHandler->doMove();
1864 }
1865
1866 void QWorkspacePChild::enterEvent( QEvent * )
1867 {
1868 }
1869
1870 void QWorkspacePChild::leaveEvent( QEvent * )
1871 {
1872 #ifndef QT_NO_CURSOR
1873     if ( !widgetResizeHandler->isButtonDown() )
1874         setCursor( arrowCursor );
1875 #endif
1876 }
1877
1878 void QWorkspacePChild::drawFrame( QPainter *p )
1879 {
1880     QStyle::SFlags flags = QStyle::Style_Default;
1881     QStyleOption opt(lineWidth(),midLineWidth());
1882
1883     if ( act )
1884         flags |= QStyle::Style_Active;
1885
1886     style().drawPrimitive( QStyle::PE_WindowFrame, p, rect(), colorGroup(), flags, opt );
1887 }
1888
1889 void QWorkspacePChild::styleChange( QStyle & )
1890 {
1891     resizeEvent( 0 );
1892     if ( iconw ) {
1893         QVBox *vbox = (QVBox*)iconw->parentWidget()->qt_cast( "QVBox" );
1894         Q_ASSERT(vbox);
1895         if ( !style().styleHint( QStyle::SH_TitleBar_NoBorder ) ) {
1896             vbox->setFrameStyle( QFrame::WinPanel | QFrame::Raised );
1897             vbox->resize( 196+2*vbox->frameWidth(), 20 + 2*vbox->frameWidth() );
1898         } else {
1899             vbox->resize( 196, 20 );
1900         }
1901     }
1902 }
1903
1904 static bool isChildOf( QWidget * child, QWidget * parent )
1905 {
1906     if ( !parent || !child )
1907         return FALSE;
1908     QWidget * w = child;
1909     while( w && w != parent )
1910         w = w->parentWidget();
1911     return w != 0;
1912 }
1913
1914
1915 void QWorkspacePChild::setActive( bool b )
1916 {
1917     if ( !childWidget )
1918         return;
1919
1920     if ( act == b )
1921         return;
1922
1923     act = b;
1924     repaint( FALSE );
1925
1926     if ( titlebar )
1927         titlebar->setActive( act );
1928     if ( iconw )
1929         iconw->setActive( act );
1930
1931     QObjectList* ol = childWidget->queryList( "QWidget" );
1932     if ( act ) {
1933         QObject *o;
1934         for ( o = ol->first(); o; o = ol->next() )
1935             o->removeEventFilter( this );
1936         bool hasFocus = isChildOf( focusWidget(), childWidget );
1937         if ( !hasFocus ) {
1938             if ( lastfocusw && ol->contains( lastfocusw ) &&
1939                  lastfocusw->focusPolicy() != NoFocus ) {
1940                 // this is a bug if lastfocusw has been deleted, a new
1941                 // widget has been created, and the new one is a child
1942                 // of the same window as the old one. but even though
1943                 // it's a bug the behaviour is reasonable
1944                 lastfocusw->setFocus();
1945             } else if ( childWidget->focusPolicy() != NoFocus ) {
1946                 childWidget->setFocus();
1947             } else {
1948                 // find something, anything, that accepts focus, and use that.
1949                 o = ol->first();
1950                 while( o && ((QWidget*)o)->focusPolicy() == NoFocus )
1951                     o = ol->next();
1952                 if ( o )
1953                     ((QWidget*)o)->setFocus();
1954             }
1955         }
1956     } else {
1957         lastfocusw = 0;
1958         if ( isChildOf( focusWidget(), childWidget ) )
1959             lastfocusw = focusWidget();
1960         QObject * o;
1961         for ( o = ol->first(); o; o = ol->next() ) {
1962             o->removeEventFilter( this );
1963             o->installEventFilter( this );
1964         }
1965     }
1966     delete ol;
1967 }
1968
1969 bool QWorkspacePChild::isActive() const
1970 {
1971     return act;
1972 }
1973
1974 QWidget* QWorkspacePChild::windowWidget() const
1975 {
1976     return childWidget;
1977 }
1978
1979
1980 QWidget* QWorkspacePChild::iconWidget() const
1981 {
1982     if ( !iconw ) {
1983         QWorkspacePChild* that = (QWorkspacePChild*) this;
1984         QVBox* vbox = new QVBox(0, "qt_vbox" );
1985         if ( !style().styleHint( QStyle::SH_TitleBar_NoBorder ) ) {
1986             vbox->setFrameStyle( QFrame::WinPanel | QFrame::Raised );
1987             vbox->resize( 196+2*vbox->frameWidth(), 20 + 2*vbox->frameWidth() );
1988         } else {
1989             vbox->resize( 196, 20 );
1990         }
1991         QTitleBarP *tb = new QTitleBarP( windowWidget(), vbox, "_workspacechild_icon_");
1992         ((QWorkspacePChild*)tb)->setWState( WState_Minimized );
1993         that->iconw = tb;
1994         iconw->setActive( isActive() );
1995         connect( iconw, SIGNAL( doActivate() ),
1996                  this, SLOT( activate() ) );
1997         connect( iconw, SIGNAL( doClose() ),
1998                  windowWidget(), SLOT( close() ) );
1999         connect( iconw, SIGNAL( doNormal() ),
2000                  this, SLOT( showNormal() ) );
2001         connect( iconw, SIGNAL( doMaximize() ),
2002                  this, SLOT( showMaximized() ) );
2003         connect( iconw, SIGNAL( popupOperationMenu( const QPoint& ) ),
2004                  this, SIGNAL( popupOperationMenu( const QPoint& ) ) );
2005         connect( iconw, SIGNAL( showOperationMenu() ),
2006                  this, SIGNAL( showOperationMenu() ) );
2007         connect( iconw, SIGNAL( doubleClicked() ),
2008                  this, SLOT( titleBarDoubleClicked() ) );
2009     }
2010 #ifndef QT_NO_WIDGET_TOPEXTRA
2011     if ( windowWidget() ) {
2012         iconw->setCaption( windowWidget()->caption() );
2013         if ( windowWidget()->icon() )
2014             iconw->setIcon( *windowWidget()->icon() );
2015     }
2016 #endif
2017     return iconw->parentWidget();
2018 }
2019
2020 void QWorkspacePChild::showMinimized()
2021 {
2022     QApplication::postEvent( windowWidget(), new QEvent( QEvent::ShowMinimized ) );
2023 }
2024
2025 void QWorkspacePChild::showMaximized()
2026 {
2027     QApplication::postEvent( windowWidget(), new QEvent( QEvent::ShowMaximized ) );
2028 }
2029
2030 void QWorkspacePChild::showNormal()
2031 {
2032     QApplication::postEvent( windowWidget(), new QEvent( QEvent::ShowNormal ) );
2033 }
2034
2035 void QWorkspacePChild::showShaded()
2036 {
2037     if ( !titlebar)
2038         return;
2039     Q_ASSERT( windowWidget()->testWFlags( WStyle_MinMax ) && windowWidget()->testWFlags( WStyle_Tool ) );
2040     ((QWorkspaceP*)parentWidget())->activateWindow( windowWidget() );
2041     if ( shademode ) {
2042         QWorkspacePChild* fake = (QWorkspacePChild*)windowWidget();
2043         fake->clearWState( WState_Minimized );
2044         clearWState( WState_Minimized );
2045
2046         shademode = FALSE;
2047         resize( shadeRestore );
2048         setMinimumSize( shadeRestoreMin );
2049     } else {
2050         shadeRestore = size();
2051         shadeRestoreMin = minimumSize();
2052         setMinimumHeight(0);
2053         shademode = TRUE;
2054         QWorkspacePChild* fake = (QWorkspacePChild*)windowWidget();
2055         fake->setWState( WState_Minimized );
2056         setWState( WState_Minimized );
2057
2058         resize( width(), titlebar->height() + 2*lineWidth() + 1 );
2059     }
2060     titlebar->update();
2061 }
2062
2063 void QWorkspacePChild::titleBarDoubleClicked()
2064 {
2065     if ( !windowWidget() )
2066         return;
2067     if ( windowWidget()->testWFlags( WStyle_MinMax ) ) {
2068         if ( windowWidget()->testWFlags( WStyle_Tool ) )
2069             showShaded();
2070         else if ( iconw )
2071             showNormal();
2072         else if ( windowWidget()->testWFlags( WStyle_Maximize ) )
2073             showMaximized();
2074     }
2075 }
2076
2077 void QWorkspacePChild::adjustToFullscreen()
2078 {
2079     qApp->sendPostedEvents( this, QEvent::Resize );
2080     qApp->sendPostedEvents( childWidget, QEvent::Resize );
2081     qApp->sendPostedEvents( childWidget, QEvent::Move );
2082     if(style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this)) {
2083         setGeometry( 0, 0, parentWidget()->width(), parentWidget()->height());
2084     } else {
2085         setGeometry( -childWidget->x(), -childWidget->y(),
2086                      parentWidget()->width() + width() - childWidget->width(),
2087                      parentWidget()->height() + height() - childWidget->height() );
2088     }
2089     setWState( WState_Maximized );
2090     ((QWorkspacePChild*)childWidget)->setWState( WState_Maximized );
2091 }
2092
2093 void QWorkspacePChild::adjustSize()
2094 {
2095     if ( !testWState(WState_Polished) )
2096         polish();
2097
2098     QSize prefSize = windowWidget()->sizeHint().expandedTo( windowWidget()->minimumSizeHint() );
2099     prefSize = prefSize.expandedTo( windowWidget()->minimumSize() ).boundedTo( windowWidget()->maximumSize() );
2100     prefSize += baseSize();
2101
2102     resize( prefSize );
2103 }
2104
2105 void QWorkspacePChild::setCaption( const QString& cap )
2106 {
2107     if ( titlebar )
2108         titlebar->setCaption( cap );
2109 #ifndef QT_NO_WIDGET_TOPEXTRA
2110     QWidget::setCaption( cap );
2111 #endif
2112 }
2113
2114 void QWorkspacePChild::internalRaise()
2115 {
2116     setUpdatesEnabled( FALSE );
2117     if ( iconw )
2118         iconw->parentWidget()->raise();
2119     raise();
2120
2121     if ( !windowWidget() || windowWidget()->testWFlags( WStyle_StaysOnTop ) ) {
2122         setUpdatesEnabled( TRUE );
2123         return;
2124     }
2125
2126     QPtrListIterator<QWorkspacePChild> it( ((QWorkspaceP*)parent())->d->windows );
2127     while ( it.current () ) {
2128         QWorkspacePChild* c = it.current();
2129         ++it;
2130         if ( c->windowWidget() &&
2131             !c->windowWidget()->isHidden() &&
2132              c->windowWidget()->testWFlags( WStyle_StaysOnTop ) )
2133              c->raise();
2134     }
2135
2136     setUpdatesEnabled( TRUE );
2137 }
2138
2139 void QWorkspacePChild::move( int x, int y )
2140 {
2141     int nx = x;
2142     int ny = y;
2143
2144     if ( windowWidget() && windowWidget()->testWFlags( WStyle_Tool ) ) {
2145         int dx = 10;
2146         int dy = 10;
2147
2148         if ( QABS( x ) < dx )
2149             nx = 0;
2150         if ( QABS( y ) < dy )
2151             ny = 0;
2152         if ( QABS( x + width() - parentWidget()->width() ) < dx ) {
2153             nx = parentWidget()->width() - width();
2154             snappedRight = TRUE;
2155         } else
2156             snappedRight = FALSE;
2157
2158         if ( QABS( y + height() - parentWidget()->height() ) < dy ) {
2159             ny = parentWidget()->height() - height();
2160             snappedDown = TRUE;
2161         } else
2162             snappedDown = FALSE;
2163     }
2164     QFrame::move( nx, ny );
2165 }
2166
2167 bool QWorkspaceP::scrollBarsEnabled() const
2168 {
2169     return d->vbar != 0;
2170 }
2171
2172 /*! \property QWorkspaceP::scrollBarsEnabled
2173     \brief whether the workspace provides scrollbars
2174
2175     If this property is set to TRUE, it is possible to resize child
2176     windows over the right or the bottom edge out of the visible area
2177     of the workspace. The workspace shows scrollbars to make it
2178     possible for the user to access those windows. If this property is
2179     set to FALSE (the default), resizing windows out of the visible
2180     area of the workspace is not permitted.
2181 */
2182 void QWorkspaceP::setScrollBarsEnabled( bool enable )
2183 {
2184     if ( (d->vbar != 0) == enable )
2185         return;
2186
2187     d->xoffset = d->yoffset = 0;
2188     if ( enable ) {
2189         d->vbar = new QScrollBar( Vertical, this, "vertical scrollbar" );
2190         connect( d->vbar, SIGNAL( valueChanged(int) ), this, SLOT( scrollBarChanged() ) );
2191         d->hbar = new QScrollBar( Horizontal, this, "horizontal scrollbar" );
2192         connect( d->hbar, SIGNAL( valueChanged(int) ), this, SLOT( scrollBarChanged() ) );
2193         d->corner = new QWidget( this, "qt_corner" );
2194         updateWorkspace();
2195     } else {
2196         delete d->vbar;
2197         delete d->hbar;
2198         delete d->corner;
2199         d->vbar = d->hbar = 0;
2200         d->corner = 0;
2201     }
2202
2203     QPtrListIterator<QWorkspacePChild> it( d->windows );
2204     while ( it.current () ) {
2205         QWorkspacePChild *child = it.current();
2206         ++it;
2207         child->widgetResizeHandler->setSizeProtection( !enable );
2208     }
2209 }
2210
2211 QRect QWorkspaceP::updateWorkspace()
2212 {
2213     if ( !isUpdatesEnabled() )
2214         return rect();
2215
2216     QRect cr( rect() );
2217
2218     if ( scrollBarsEnabled() && !d->maxWindow ) {
2219         d->corner->raise();
2220         d->vbar->raise();
2221         d->hbar->raise();
2222         if ( d->maxWindow )
2223             d->maxWindow->raise();
2224
2225         QRect r( 0, 0, 0, 0 );
2226         QPtrListIterator<QWorkspacePChild> it( d->windows );
2227         while ( it.current () ) {
2228             QWorkspacePChild *child = it.current();
2229             ++it;
2230             if ( !child->isHidden() )
2231                 r = r.unite( child->geometry() );
2232         }
2233         d->vbar->blockSignals( TRUE );
2234         d->hbar->blockSignals( TRUE );
2235
2236         int hsbExt = d->hbar->sizeHint().height();
2237         int vsbExt = d->vbar->sizeHint().width();
2238
2239
2240         bool showv = d->yoffset || d->yoffset + r.bottom() - height() + 1 > 0 || d->yoffset + r.top() < 0;
2241         bool showh = d->xoffset || d->xoffset + r.right() - width() + 1 > 0 || d->xoffset + r.left() < 0;
2242
2243         if ( showh && !showv)
2244             showv = d->yoffset + r.bottom() - height() + hsbExt + 1 > 0;
2245         if ( showv && !showh )
2246             showh = d->xoffset + r.right() - width() + vsbExt  + 1 > 0;
2247
2248         if ( !showh )
2249             hsbExt = 0;
2250         if ( !showv )
2251             vsbExt = 0;
2252
2253         if ( showv ) {
2254             d->vbar->setSteps( QMAX( height() / 12, 30 ), height()  - hsbExt );
2255             d->vbar->setRange( QMIN( 0, d->yoffset + QMIN( 0, r.top() ) ), QMAX( 0, d->yoffset + QMAX( 0, r.bottom() - height() + hsbExt + 1) ) );
2256             d->vbar->setGeometry( width() - vsbExt, 0, vsbExt, height() - hsbExt );
2257             d->vbar->setValue( d->yoffset );
2258             d->vbar->show();
2259         } else {
2260             d->vbar->hide();
2261         }
2262
2263         if ( showh ) {
2264             d->hbar->setSteps( QMAX( width() / 12, 30 ), width() - vsbExt );
2265             d->hbar->setRange( QMIN( 0, d->xoffset + QMIN( 0, r.left() ) ), QMAX( 0, d->xoffset + QMAX( 0, r.right() - width() + vsbExt  + 1) ) );
2266             d->hbar->setGeometry( 0, height() - hsbExt, width() - vsbExt, hsbExt );
2267             d->hbar->setValue( d->xoffset );
2268             d->hbar->show();
2269         } else {
2270             d->hbar->hide();
2271         }
2272
2273         if ( showh && showv ) {
2274             d->corner->setGeometry( width() - vsbExt, height() - hsbExt, vsbExt, hsbExt );
2275             d->corner->show();
2276         } else {
2277             d->corner->hide();
2278         }
2279
2280         d->vbar->blockSignals( FALSE );
2281         d->hbar->blockSignals( FALSE );
2282
2283         cr.setRect( 0, 0, width() - vsbExt, height() - hsbExt );
2284     }
2285
2286     QPtrListIterator<QWidget> ii( d->icons );
2287     while ( ii.current() ) {
2288         QWorkspacePChild* w = (QWorkspacePChild*)ii.current();
2289         ++ii;
2290         int x = w->x();
2291         int y = w->y();
2292         bool m = FALSE;
2293         if ( x+w->width() > cr.width() ) {
2294             m = TRUE;
2295             x =  cr.width() - w->width();
2296         }
2297         if ( y+w->height() >  cr.height() ) {
2298             y =  cr.height() - w->height();
2299             m = TRUE;
2300         }
2301         if ( m )
2302             w->move( x, y );
2303     }
2304
2305     return cr;
2306
2307 }
2308
2309 void QWorkspaceP::scrollBarChanged()
2310 {
2311     int ver = d->yoffset - d->vbar->value();
2312     int hor = d->xoffset - d->hbar->value();
2313     d->yoffset = d->vbar->value();
2314     d->xoffset = d->hbar->value();
2315
2316     QPtrListIterator<QWorkspacePChild> it( d->windows );
2317     while ( it.current () ) {
2318         QWorkspacePChild *child = it.current();
2319         ++it;
2320         // we do not use move() due to the reimplementation in QWorkspacePChild
2321         child->setGeometry( child->x() + hor, child->y() + ver, child->width(), child->height() );
2322     }
2323     updateWorkspace();
2324 }
2325
2326 #ifndef QT_NO_STYLE
2327 /*!\reimp */
2328 void QWorkspaceP::styleChange( QStyle &olds )
2329 {
2330     int fs = style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this);
2331     if ( isVisibleTo(0) && d->maxWindow &&
2332          fs != olds.styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this)) {
2333         if( fs )
2334             hideMaximizeControls();
2335         else
2336             showMaximizeControls();
2337     }
2338     QWidget::styleChange(olds);
2339 }
2340 #endif
2341
2342 #define RANGE 4
2343
2344 static bool resizeHorizontalDirectionFixed = FALSE;
2345 static bool resizeVerticalDirectionFixed = FALSE;
2346
2347 QWidgetResizeHandlerP::QWidgetResizeHandlerP( QWidget *parent, QWidget *cw, const char *name )
2348     : QObject( parent, name ), widget( parent ), childWidget( cw ? cw : parent ),
2349       extrahei( 0 ), buttonDown( FALSE ), moveResizeMode( FALSE ), sizeprotect( TRUE ), moving( TRUE )
2350 {
2351     mode = Nowhere;
2352     widget->setMouseTracking( TRUE );
2353     range = widget->inherits( "QFrame" ) ? ((QFrame*)widget)->frameWidth() : RANGE;
2354     range = QMAX( RANGE, range );
2355     active = TRUE;
2356     qApp->installEventFilter( this );
2357 }
2358
2359 static QWidget *childOf( QWidget *w, QWidget *child )
2360 {
2361     while ( child ) {
2362         if ( child == w )
2363             return child;
2364         child = child->parentWidget();
2365     }
2366     return 0;
2367 }
2368
2369 bool QWidgetResizeHandlerP::eventFilter( QObject *o, QEvent *ee )
2370 {
2371     if ( !active || !o->isWidgetType() )
2372         return FALSE;
2373
2374     QWidget *w = childOf( widget, (QWidget*)o );
2375     if ( !w || o->inherits( "QSizeGrip" ) )
2376         return FALSE;
2377
2378     QMouseEvent *e = (QMouseEvent*)ee;
2379     switch ( e->type() ) {
2380     case QEvent::MouseButtonPress: {
2381         if ( w->isMaximized() )
2382             break;
2383         if ( !widget->rect().contains( widget->mapFromGlobal( e->globalPos() ) ) )
2384             return FALSE;
2385         if ( e->button() == LeftButton ) {
2386             emit activate();
2387             bool me = isMovingEnabled();
2388             setMovingEnabled( me && o == widget );
2389             mouseMoveEvent( e );
2390             setMovingEnabled( me );
2391             buttonDown = TRUE;
2392             moveOffset = widget->mapFromGlobal( e->globalPos() );
2393             invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
2394         }
2395     } break;
2396     case QEvent::MouseButtonRelease:
2397         if ( w->isMaximized() )
2398             break;
2399         if ( e->button() == LeftButton ) {
2400             moveResizeMode = FALSE;
2401             buttonDown = FALSE;
2402             widget->releaseMouse();
2403             widget->releaseKeyboard();
2404         }
2405         break;
2406     case QEvent::MouseMove: {
2407         if ( w->isMaximized() )
2408             break;
2409         bool me = isMovingEnabled();
2410         setMovingEnabled( me && o == widget );
2411         mouseMoveEvent( e );
2412         setMovingEnabled( me );
2413         if ( buttonDown && mode != Center )
2414             return TRUE;
2415     } break;
2416     case QEvent::KeyPress:
2417         keyPressEvent( (QKeyEvent*)e );
2418         break;
2419     case QEvent::AccelOverride:
2420         if ( buttonDown ) {
2421             ((QKeyEvent*)ee)->accept();
2422             return TRUE;
2423         }
2424         break;
2425     default:
2426         break;
2427     }
2428     return FALSE;
2429 }
2430
2431 void QWidgetResizeHandlerP::mouseMoveEvent( QMouseEvent *e )
2432 {
2433     QPoint pos = widget->mapFromGlobal( e->globalPos() );
2434     if ( !moveResizeMode && ( !buttonDown || ( e->state() & LeftButton ) == 0 ) ) {
2435         if ( pos.y() <= range && pos.x() <= range)
2436             mode = TopLeft;
2437         else if ( pos.y() >= widget->height()-range && pos.x() >= widget->width()-range)
2438             mode = BottomRight;
2439         else if ( pos.y() >= widget->height()-range && pos.x() <= range)
2440             mode = BottomLeft;
2441         else if ( pos.y() <= range && pos.x() >= widget->width()-range)
2442             mode = TopRight;
2443         else if ( pos.y() <= range )
2444             mode = Top;
2445         else if ( pos.y() >= widget->height()-range )
2446             mode = Bottom;
2447         else if ( pos.x() <= range )
2448             mode = Left;
2449         else if (  pos.x() >= widget->width()-range )
2450             mode = Right;
2451         else
2452             mode = Center;
2453
2454         if ( widget->isMinimized() )
2455             mode = Center;
2456 #ifndef QT_NO_CURSOR
2457         setMouseCursor( mode );
2458 #endif
2459         return;
2460     }
2461
2462     if ( buttonDown && !isMovingEnabled() && mode == Center && !moveResizeMode )
2463         return;
2464
2465     if ( widget->testWState( WState_ConfigPending ) )
2466         return;
2467
2468     QPoint globalPos = widget->parentWidget( TRUE ) ?
2469                        widget->parentWidget( TRUE )->mapFromGlobal( e->globalPos() ) : e->globalPos();
2470     if ( widget->parentWidget( TRUE ) && !widget->parentWidget( TRUE )->rect().contains( globalPos ) ) {
2471         if ( globalPos.x() < 0 )
2472             globalPos.rx() = 0;
2473         if ( globalPos.y() < 0 )
2474             globalPos.ry() = 0;
2475         if ( sizeprotect && globalPos.x() > widget->parentWidget()->width() )
2476             globalPos.rx() = widget->parentWidget()->width();
2477         if ( sizeprotect && globalPos.y() > widget->parentWidget()->height() )
2478             globalPos.ry() = widget->parentWidget()->height();
2479     }
2480
2481     QPoint p = globalPos + invertedMoveOffset;
2482     QPoint pp = globalPos - moveOffset;
2483
2484     int fw = 0;
2485     int mw = QMAX( childWidget->minimumSizeHint().width(),
2486                    childWidget->minimumWidth() );
2487     int mh = QMAX( childWidget->minimumSizeHint().height(),
2488                    childWidget->minimumHeight() );
2489     if ( childWidget != widget ) {
2490         if ( widget->inherits( "QFrame" ) )
2491             fw = ( (QFrame *) widget )->frameWidth();
2492         mw += 2 * fw;
2493         mh += 2 * fw + extrahei;
2494     }
2495
2496     QSize mpsize( widget->geometry().right() - pp.x() + 1,
2497                   widget->geometry().bottom() - pp.y() + 1 );
2498     mpsize = mpsize.expandedTo( widget->minimumSize() ).expandedTo( QSize(mw, mh) );
2499     QPoint mp( widget->geometry().right() - mpsize.width() + 1,
2500                widget->geometry().bottom() - mpsize.height() + 1 );
2501
2502     QRect geom = widget->geometry();
2503
2504     switch ( mode ) {
2505     case TopLeft:
2506         geom = QRect( mp, widget->geometry().bottomRight() ) ;
2507         break;
2508     case BottomRight:
2509         geom = QRect( widget->geometry().topLeft(), p ) ;
2510         break;
2511     case BottomLeft:
2512         geom = QRect( QPoint(mp.x(), widget->geometry().y() ), QPoint( widget->geometry().right(), p.y()) ) ;
2513         break;
2514     case TopRight:
2515         geom = QRect( QPoint( widget->geometry().x(), mp.y() ), QPoint( p.x(), widget->geometry().bottom()) ) ;
2516         break;
2517     case Top:
2518         geom = QRect( QPoint( widget->geometry().left(), mp.y() ), widget->geometry().bottomRight() ) ;
2519         break;
2520     case Bottom:
2521         geom = QRect( widget->geometry().topLeft(), QPoint( widget->geometry().right(), p.y() ) ) ;
2522         break;
2523     case Left:
2524         geom = QRect( QPoint( mp.x(), widget->geometry().top() ), widget->geometry().bottomRight() ) ;
2525         break;
2526     case Right:
2527         geom = QRect( widget->geometry().topLeft(), QPoint( p.x(), widget->geometry().bottom() ) ) ;
2528         break;
2529     case Center:
2530         if ( isMovingEnabled() || moveResizeMode )
2531             geom.moveTopLeft( pp );
2532         break;
2533     default:
2534         break;
2535     }
2536
2537     QSize maxsize( childWidget->maximumSize() );
2538     if ( childWidget != widget )
2539         maxsize += QSize( 2 * fw, 2 * fw + extrahei );
2540
2541     geom = QRect( geom.topLeft(),
2542                   geom.size().expandedTo( widget->minimumSize() )
2543                              .expandedTo( QSize(mw, mh) )
2544                              .boundedTo( maxsize ) );
2545
2546     if ( geom != widget->geometry() &&
2547         ( widget->isTopLevel() || widget->parentWidget()->rect().intersects( geom ) ) ) {
2548         if ( widget->isMinimized() )
2549             widget->move( geom.topLeft() );
2550         else
2551             widget->setGeometry( geom );
2552     }
2553
2554 #if defined(Q_WS_WIN)
2555     MSG msg;
2556 #if defined(UNICODE)
2557 #  ifndef Q_OS_TEMP
2558     if ( qWinVersion() & WV_NT_based ) {
2559 #  endif
2560         while(PeekMessageW( &msg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE ))
2561             ;
2562 #  ifndef Q_OS_TEMP
2563     } else
2564 #  endif
2565 #endif
2566 #ifndef Q_OS_TEMP
2567     {
2568         while(PeekMessageA( &msg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE ))
2569             ;
2570     }
2571 #endif
2572 #endif
2573
2574     QApplication::syncX();
2575 }
2576
2577 void QWidgetResizeHandlerP::setMouseCursor( MousePosition m )
2578 {
2579 #ifndef QT_NO_CURSOR
2580     switch ( m ) {
2581     case TopLeft:
2582     case BottomRight:
2583         widget->setCursor( sizeFDiagCursor );
2584         break;
2585     case BottomLeft:
2586     case TopRight:
2587         widget->setCursor( sizeBDiagCursor );
2588         break;
2589     case Top:
2590     case Bottom:
2591         widget->setCursor( sizeVerCursor );
2592         break;
2593     case Left:
2594     case Right:
2595         widget->setCursor( sizeHorCursor );
2596         break;
2597     default:
2598         widget->setCursor( arrowCursor );
2599         break;
2600     }
2601 #endif
2602 }
2603
2604 void QWidgetResizeHandlerP::keyPressEvent( QKeyEvent * e )
2605 {
2606     if ( !isMove() && !isResize() )
2607         return;
2608     bool is_control = e->state() & ControlButton;
2609     int delta = is_control?1:8;
2610     QPoint pos = QCursor::pos();
2611     switch ( e->key() ) {
2612     case Key_Left:
2613         pos.rx() -= delta;
2614         if ( pos.x() <= QApplication::desktop()->geometry().left() ) {
2615             if ( mode == TopLeft || mode == BottomLeft ) {
2616                 moveOffset.rx() += delta;
2617                 invertedMoveOffset.rx() += delta;
2618             } else {
2619                 moveOffset.rx() -= delta;
2620                 invertedMoveOffset.rx() -= delta;
2621             }
2622         }
2623         if ( isResize() && !resizeHorizontalDirectionFixed ) {
2624             resizeHorizontalDirectionFixed = TRUE;
2625             if ( mode == BottomRight )
2626                 mode = BottomLeft;
2627             else if ( mode == TopRight )
2628                 mode = TopLeft;
2629 #ifndef QT_NO_CURSOR
2630             setMouseCursor( mode );
2631             widget->grabMouse( widget->cursor() );
2632 #else
2633             widget->grabMouse();
2634 #endif
2635         }
2636         break;
2637     case Key_Right:
2638         pos.rx() += delta;
2639         if ( pos.x() >= QApplication::desktop()->geometry().right() ) {
2640             if ( mode == TopRight || mode == BottomRight ) {
2641                 moveOffset.rx() += delta;
2642                 invertedMoveOffset.rx() += delta;
2643             } else {
2644                 moveOffset.rx() -= delta;
2645                 invertedMoveOffset.rx() -= delta;
2646             }
2647         }
2648         if ( isResize() && !resizeHorizontalDirectionFixed ) {
2649             resizeHorizontalDirectionFixed = TRUE;
2650             if ( mode == BottomLeft )
2651                 mode = BottomRight;
2652             else if ( mode == TopLeft )
2653                 mode = TopRight;
2654 #ifndef QT_NO_CURSOR
2655             setMouseCursor( mode );
2656             widget->grabMouse( widget->cursor() );
2657 #else
2658             widget->grabMouse();
2659 #endif
2660         }
2661         break;
2662     case Key_Up:
2663         pos.ry() -= delta;
2664         if ( pos.y() <= QApplication::desktop()->geometry().top() ) {
2665             if ( mode == TopLeft || mode == TopRight ) {
2666                 moveOffset.ry() += delta;
2667                 invertedMoveOffset.ry() += delta;
2668             } else {
2669                 moveOffset.ry() -= delta;
2670                 invertedMoveOffset.ry() -= delta;
2671             }
2672         }
2673         if ( isResize() && !resizeVerticalDirectionFixed ) {
2674             resizeVerticalDirectionFixed = TRUE;
2675             if ( mode == BottomLeft )
2676                 mode = TopLeft;
2677             else if ( mode == BottomRight )
2678                 mode = TopRight;
2679 #ifndef QT_NO_CURSOR
2680             setMouseCursor( mode );
2681             widget->grabMouse( widget->cursor() );
2682 #else
2683             widget->grabMouse();
2684 #endif
2685         }
2686         break;
2687     case Key_Down:
2688         pos.ry() += delta;
2689         if ( pos.y() >= QApplication::desktop()->geometry().bottom() ) {
2690             if ( mode == BottomLeft || mode == BottomRight ) {
2691                 moveOffset.ry() += delta;
2692                 invertedMoveOffset.ry() += delta;
2693             } else {
2694                 moveOffset.ry() -= delta;
2695                 invertedMoveOffset.ry() -= delta;
2696             }
2697         }
2698         if ( isResize() && !resizeVerticalDirectionFixed ) {
2699             resizeVerticalDirectionFixed = TRUE;
2700             if ( mode == TopLeft )
2701                 mode = BottomLeft;
2702             else if ( mode == TopRight )
2703                 mode = BottomRight;
2704 #ifndef QT_NO_CURSOR
2705             setMouseCursor( mode );
2706             widget->grabMouse( widget->cursor() );
2707 #else
2708             widget->grabMouse();
2709 #endif
2710         }
2711         break;
2712     case Key_Space:
2713     case Key_Return:
2714     case Key_Enter:
2715     case Key_Escape:
2716         moveResizeMode = FALSE;
2717         widget->releaseMouse();
2718         widget->releaseKeyboard();
2719         buttonDown = FALSE;
2720         break;
2721     default:
2722         return;
2723     }
2724     QCursor::setPos( pos );
2725 }
2726
2727
2728 void QWidgetResizeHandlerP::doResize()
2729 {
2730     if ( !active )
2731         return;
2732
2733     moveResizeMode = TRUE;
2734     buttonDown = TRUE;
2735     moveOffset = widget->mapFromGlobal( QCursor::pos() );
2736     if ( moveOffset.x() < widget->width()/2) {
2737         if ( moveOffset.y() < widget->height()/2)
2738             mode = TopLeft;
2739         else
2740             mode = BottomLeft;
2741     } else {
2742         if ( moveOffset.y() < widget->height()/2)
2743             mode = TopRight;
2744         else
2745             mode = BottomRight;
2746     }
2747     invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
2748 #ifndef QT_NO_CURSOR
2749     setMouseCursor( mode );
2750     widget->grabMouse( widget->cursor()  );
2751 #else
2752     widget->grabMouse();
2753 #endif
2754     widget->grabKeyboard();
2755     resizeHorizontalDirectionFixed = FALSE;
2756     resizeVerticalDirectionFixed = FALSE;
2757 }
2758
2759 void QWidgetResizeHandlerP::doMove()
2760 {
2761     if ( !active )
2762         return;
2763
2764     mode = Center;
2765     moveResizeMode = TRUE;
2766     buttonDown = TRUE;
2767     moveOffset = widget->mapFromGlobal( QCursor::pos() );
2768     invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
2769 #ifndef QT_NO_CURSOR
2770     widget->grabMouse( SizeAllCursor );
2771 #else
2772     widget->grabMouse();
2773 #endif
2774     widget->grabKeyboard();
2775 }
2776
2777 #ifndef QT_NO_TOOLTIP
2778 class QTitleBarPTip : public QToolTip
2779 {
2780 public:
2781     QTitleBarPTip( QWidget * parent ) : QToolTip( parent ) { }
2782
2783     void maybeTip( const QPoint &pos )
2784     {
2785         if ( !parentWidget()->inherits( "QTitleBarP" ) )
2786             return;
2787         QTitleBarP *t = (QTitleBarP *)parentWidget();
2788
2789         QString tipstring;
2790         QStyle::SubControl ctrl = t->style().querySubControl(QStyle::CC_TitleBar, t, pos);
2791         QSize controlSize = t->style().querySubControlMetrics(QStyle::CC_TitleBar, t, ctrl).size();
2792
2793         QWidget *window = t->window();
2794         if ( window ) {
2795             switch(ctrl) {
2796             case QStyle::SC_TitleBarSysMenu:
2797                 if ( t->testWFlags( WStyle_SysMenu ) )
2798                     tipstring = QTitleBarP::tr( "System Menu" );
2799                 break;
2800
2801             case QStyle::SC_TitleBarShadeButton:
2802                 if ( t->testWFlags( WStyle_Tool ) && t->testWFlags( WStyle_MinMax ) )
2803                     tipstring = QTitleBarP::tr( "Shade" );
2804                 break;
2805
2806             case QStyle::SC_TitleBarUnshadeButton:
2807                 if ( t->testWFlags( WStyle_Tool ) && t->testWFlags( WStyle_MinMax ) )
2808                     tipstring = QTitleBarP::tr( "Unshade" );
2809                 break;
2810
2811             case QStyle::SC_TitleBarNormalButton:
2812             case QStyle::SC_TitleBarMinButton:
2813                 if ( !t->testWFlags( WStyle_Tool ) && t->testWFlags( WStyle_Minimize ) ) {
2814                     if( window->isMinimized() )
2815                         tipstring = QTitleBarP::tr( "Normalize" );
2816                     else
2817                         tipstring = QTitleBarP::tr( "Minimize" );
2818                 }
2819                 break;
2820
2821             case QStyle::SC_TitleBarMaxButton:
2822                 if ( !t->testWFlags( WStyle_Tool ) && t->testWFlags( WStyle_Maximize ) )
2823                     tipstring = QTitleBarP::tr( "Maximize" );
2824                 break;
2825
2826             case QStyle::SC_TitleBarCloseButton:
2827                 if ( t->testWFlags( WStyle_SysMenu ) )
2828                     tipstring = QTitleBarP::tr( "Close" );
2829                 break;
2830
2831             default:
2832                 break;
2833             }
2834         }
2835 #ifndef QT_NO_WIDGET_TOPEXTRA
2836         if ( tipstring.isEmpty() ) {
2837             if ( t->visibleText() != t->caption() )
2838                 tipstring = t->caption();
2839         }
2840 #endif
2841         if(!tipstring.isEmpty())
2842             tip( QRect(pos, controlSize), tipstring );
2843     }
2844 };
2845 #endif
2846
2847 class QTitleBarPPrivate
2848 {
2849 public:
2850     QTitleBarPPrivate()
2851         : toolTip( 0 ), act( 0 ), window( 0 ), movable( 1 ), pressed( 0 ), autoraise(0)
2852     {
2853     }
2854
2855     QStyle::SCFlags buttonDown;
2856     QPoint moveOffset;
2857     QToolTip *toolTip;
2858     bool act                :1;
2859     QWidget* window;
2860     bool movable            :1;
2861     bool pressed            :1;
2862     bool autoraise          :1;
2863     QString cuttext;
2864 };
2865
2866 QTitleBarP::QTitleBarP(QWidget* w, QWidget* parent, const char* name)
2867     : QWidget( parent, name, WStyle_Customize | WStyle_NoBorder | WResizeNoErase | WRepaintNoErase )
2868 {
2869     d = new QTitleBarPPrivate();
2870
2871 #ifndef QT_NO_TOOLTIP
2872     d->toolTip = new QTitleBarPTip( this );
2873 #endif
2874     d->window = w;
2875     d->buttonDown = QStyle::SC_None;
2876     d->act = 0;
2877     if ( w ) {
2878         setWFlags( ((QTitleBarP*)w)->getWFlags() | WResizeNoErase | WRepaintNoErase );
2879 #ifndef QT_NO_WIDGET_TOPEXTRA
2880         setCaption( w->caption() );
2881 #endif
2882     } else {
2883         setWFlags( WStyle_Customize | WResizeNoErase | WRepaintNoErase );
2884     }
2885
2886     readColors();
2887     setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
2888     setMouseTracking(TRUE);
2889 }
2890
2891 QTitleBarP::~QTitleBarP()
2892 {
2893 #ifndef QT_NO_TOOLTIP
2894     delete d->toolTip;
2895 #endif
2896
2897     delete d;
2898     d = 0;
2899 }
2900
2901 #ifdef Q_WS_WIN
2902 extern QRgb qt_colorref2qrgb(COLORREF col);
2903 #endif
2904
2905 void QTitleBarP::readColors()
2906 {
2907     QPalette pal = palette();
2908
2909 #ifdef Q_WS_WIN // ask system properties on windows
2910 #ifndef SPI_GETGRADIENTCAPTIONS
2911 #define SPI_GETGRADIENTCAPTIONS 0x1008
2912 #endif
2913 #ifndef COLOR_GRADIENTACTIVECAPTION
2914 #define COLOR_GRADIENTACTIVECAPTION 27
2915 #endif
2916 #ifndef COLOR_GRADIENTINACTIVECAPTION
2917 #define COLOR_GRADIENTINACTIVECAPTION 28
2918 #endif
2919     if ( QApplication::desktopSettingsAware() ) {
2920         pal.setColor( QPalette::Active, QColorGroup::Highlight, qt_colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION)) );
2921         pal.setColor( QPalette::Inactive, QColorGroup::Highlight, qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)) );
2922         pal.setColor( QPalette::Active, QColorGroup::HighlightedText, qt_colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)) );
2923         pal.setColor( QPalette::Inactive, QColorGroup::HighlightedText, qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)) );
2924         if ( qt_winver != Qt::WV_95 && qt_winver != WV_NT ) {
2925             BOOL gradient;
2926 #ifdef Q_OS_TEMP
2927             SystemParametersInfo( SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0 );
2928 #else
2929 #if defined(UNICODE)
2930             if ( qt_winver & Qt::WV_NT_based )
2931                 SystemParametersInfo( SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0 );
2932             else
2933 #endif
2934                 SystemParametersInfoA( SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0 );
2935 #endif
2936             if ( gradient ) {
2937                 pal.setColor( QPalette::Active, QColorGroup::Base, qt_colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)) );
2938                 pal.setColor( QPalette::Inactive, QColorGroup::Base, qt_colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)) );
2939             } else {
2940                 pal.setColor( QPalette::Active, QColorGroup::Base, palette().active().highlight() );
2941                 pal.setColor( QPalette::Inactive, QColorGroup::Base, palette().inactive().highlight() );
2942             }
2943         }
2944     } else
2945 #endif // Q_WS_WIN
2946     {
2947         pal.setColor( QPalette::Active, QColorGroup::Highlight, palette().active().highlight() );
2948         pal.setColor( QPalette::Active, QColorGroup::Base, palette().active().highlight() );
2949         pal.setColor( QPalette::Inactive, QColorGroup::Highlight, palette().inactive().dark() );
2950         pal.setColor( QPalette::Inactive, QColorGroup::Base, palette().inactive().dark() );
2951         pal.setColor( QPalette::Inactive, QColorGroup::HighlightedText, palette().inactive().background() );
2952     }
2953
2954     setPalette( pal );
2955     setActive( d->act );
2956 }
2957
2958 void QTitleBarP::mousePressEvent( QMouseEvent * e)
2959 {
2960     emit doActivate();
2961     if ( e->button() == LeftButton ) {
2962         d->pressed = TRUE;
2963         QStyle::SCFlags ctrl = style().querySubControl(QStyle::CC_TitleBar, this, e->pos());
2964         switch (ctrl) {
2965         case QStyle::SC_TitleBarSysMenu:
2966             if ( testWFlags( WStyle_SysMenu ) && !testWFlags( WStyle_Tool ) ) {
2967                 d->buttonDown = QStyle::SC_None;
2968                 static QTime* t = 0;
2969                 static QTitleBarP* tc = 0;
2970                 if ( !t )
2971                     t = new QTime;
2972                 if ( tc != this || t->elapsed() > QApplication::doubleClickInterval() ) {
2973                     emit showOperationMenu();
2974                     t->start();
2975                     tc = this;
2976                 } else {
2977                     tc = 0;
2978                     emit doClose();
2979                     return;
2980                 }
2981             }
2982             break;
2983
2984         case QStyle::SC_TitleBarShadeButton:
2985         case QStyle::SC_TitleBarUnshadeButton:
2986             if ( testWFlags( WStyle_MinMax ) && testWFlags( WStyle_Tool ) )
2987                 d->buttonDown = ctrl;
2988             break;
2989
2990         case QStyle::SC_TitleBarNormalButton:
2991             if( testWFlags( WStyle_Minimize ) && !testWFlags( WStyle_Tool ) )
2992                 d->buttonDown = ctrl;
2993             break;
2994
2995         case QStyle::SC_TitleBarMinButton:
2996             if( testWFlags( WStyle_Minimize ) && !testWFlags( WStyle_Tool ) )
2997                 d->buttonDown = ctrl;
2998             break;
2999
3000         case QStyle::SC_TitleBarMaxButton:
3001             if ( testWFlags( WStyle_Maximize ) && !testWFlags( WStyle_Tool ) )
3002                 d->buttonDown = ctrl;
3003             break;
3004
3005         case QStyle::SC_TitleBarCloseButton:
3006             if ( testWFlags( WStyle_SysMenu ) )
3007                 d->buttonDown = ctrl;
3008             break;
3009
3010         case QStyle::SC_TitleBarLabel:
3011             d->buttonDown = ctrl;
3012             d->moveOffset = mapToParent( e->pos() );
3013             break;
3014         
3015         default:
3016             break;
3017         }
3018         repaint( FALSE );
3019     } else {
3020         d->pressed = FALSE;
3021     }
3022 }
3023
3024 void QTitleBarP::contextMenuEvent( QContextMenuEvent *e )
3025 {
3026     QStyle::SCFlags ctrl = style().querySubControl(QStyle::CC_TitleBar, this, e->pos());
3027     if( ctrl == QStyle::SC_TitleBarLabel || ctrl == QStyle::SC_TitleBarSysMenu ) {
3028         emit popupOperationMenu(e->globalPos());
3029         e->accept();
3030     }
3031 }
3032
3033 void QTitleBarP::mouseReleaseEvent( QMouseEvent * e)
3034 {
3035     if ( e->button() == LeftButton && d->pressed) {
3036         QStyle::SCFlags ctrl = style().querySubControl(QStyle::CC_TitleBar, this, e->pos());
3037
3038         if (ctrl == d->buttonDown) {
3039             switch(ctrl) {
3040             case QStyle::SC_TitleBarShadeButton:
3041             case QStyle::SC_TitleBarUnshadeButton:
3042                 if( testWFlags( WStyle_MinMax ) && testWFlags( WStyle_Tool ) )
3043                     emit doShade();
3044                 break;
3045         
3046             case QStyle::SC_TitleBarNormalButton:
3047                 if( testWFlags( WStyle_MinMax ) && !testWFlags( WStyle_Tool ) )
3048                     emit doNormal();
3049                 break;
3050
3051             case QStyle::SC_TitleBarMinButton:
3052                 if( testWFlags( WStyle_Minimize ) && !testWFlags( WStyle_Tool ) )
3053                     emit doMinimize();
3054                 break;
3055
3056             case QStyle::SC_TitleBarMaxButton:
3057                 if( d->window && testWFlags( WStyle_Maximize ) && !testWFlags( WStyle_Tool ) ) {
3058                     if(d->window->isMaximized())
3059                         emit doNormal();
3060                     else
3061                         emit doMaximize();
3062                 }
3063                 break;
3064
3065             case QStyle::SC_TitleBarCloseButton:
3066                 if( testWFlags( WStyle_SysMenu ) ) {
3067                     d->buttonDown = QStyle::SC_None;
3068                     repaint(FALSE);
3069                     emit doClose();             
3070                     return;
3071                 }
3072                 break;
3073
3074             default:
3075                 break;
3076             }
3077         }
3078         d->buttonDown = QStyle::SC_None;
3079         repaint(FALSE);
3080         d->pressed = FALSE;
3081     }
3082 }
3083
3084 void QTitleBarP::mouseMoveEvent( QMouseEvent * e)
3085 {
3086     switch (d->buttonDown) {
3087     case QStyle::SC_None:
3088         if(autoRaise())
3089             repaint( FALSE );
3090         break;
3091     case QStyle::SC_TitleBarSysMenu:
3092         break;
3093     case QStyle::SC_TitleBarShadeButton:
3094     case QStyle::SC_TitleBarUnshadeButton:
3095     case QStyle::SC_TitleBarNormalButton:
3096     case QStyle::SC_TitleBarMinButton:
3097     case QStyle::SC_TitleBarMaxButton:
3098     case QStyle::SC_TitleBarCloseButton:
3099         {
3100             QStyle::SCFlags last_ctrl = d->buttonDown;
3101             d->buttonDown = style().querySubControl(QStyle::CC_TitleBar, this, e->pos());
3102             if( d->buttonDown != last_ctrl)
3103                 d->buttonDown = QStyle::SC_None;
3104             repaint(FALSE);
3105             d->buttonDown = last_ctrl;
3106         }
3107         break;
3108
3109     case QStyle::SC_TitleBarLabel:
3110         if ( d->buttonDown == QStyle::SC_TitleBarLabel && d->movable && d->pressed ) {
3111             if ( (d->moveOffset - mapToParent( e->pos() ) ).manhattanLength() >= 4 ) {
3112                 QPoint p = mapFromGlobal(e->globalPos());
3113 #ifndef QT_NO_WORKSPACE
3114                 if(d->window && d->window->parentWidget()->inherits("QWorkspacePChild")) {
3115                     QWidget *w = d->window->parentWidget()->parentWidget();
3116                     if(w && w->inherits("QWorkspaceP")) {
3117                         QWorkspaceP *workspace = (QWorkspaceP*)w;
3118                         p = workspace->mapFromGlobal( e->globalPos() );
3119                         if ( !workspace->rect().contains(p) ) {
3120                             if ( p.x() < 0 )
3121                                 p.rx() = 0;
3122                             if ( p.y() < 0 )
3123                                 p.ry() = 0;
3124                             if ( p.x() > workspace->width() )
3125                                 p.rx() = workspace->width();
3126                             if ( p.y() > workspace->height() )
3127                                 p.ry() = workspace->height();
3128                         }
3129                     }
3130                 }
3131 #endif
3132                 QPoint pp = p - d->moveOffset;
3133                 parentWidget()->move( pp );
3134             }
3135         } else {
3136             QStyle::SCFlags last_ctrl = d->buttonDown;
3137             d->buttonDown = QStyle::SC_None;
3138             if( d->buttonDown != last_ctrl)
3139                 repaint(FALSE);
3140         }
3141         break;
3142     }
3143 }
3144
3145 void QTitleBarP::resizeEvent( QResizeEvent *r)
3146 {
3147     QWidget::resizeEvent(r);
3148     cutText();
3149 }
3150
3151 void QTitleBarP::paintEvent(QPaintEvent *)
3152 {
3153     QStyle::SCFlags ctrls = QStyle::SC_TitleBarLabel;
3154     if ( testWFlags( WStyle_SysMenu) ) {
3155         if ( testWFlags( WStyle_Tool ) ) {
3156             ctrls |= QStyle::SC_TitleBarCloseButton;
3157             if ( d->window && testWFlags( WStyle_MinMax ) ) {
3158                 if ( d->window->isMinimized() )
3159                     ctrls |= QStyle::SC_TitleBarUnshadeButton;
3160                 else
3161                     ctrls |= QStyle::SC_TitleBarShadeButton;
3162             }
3163         } else {
3164             ctrls |= QStyle::SC_TitleBarSysMenu | QStyle::SC_TitleBarCloseButton;
3165             if ( d->window && testWFlags( WStyle_Minimize ) ) {
3166                 if( d->window && d->window->isMinimized() )
3167                     ctrls |= QStyle::SC_TitleBarNormalButton;
3168                 else
3169                     ctrls |= QStyle::SC_TitleBarMinButton;
3170             }
3171             if ( d->window && testWFlags( WStyle_Maximize ) && !d->window->isMaximized() )
3172                 ctrls |= QStyle::SC_TitleBarMaxButton;
3173         }
3174     }
3175
3176     QStyle::SCFlags under_mouse = QStyle::SC_None;
3177     if( autoRaise() && hasMouse() ) {
3178         QPoint p(mapFromGlobal(QCursor::pos()));
3179         under_mouse = style().querySubControl(QStyle::CC_TitleBar, this, p);
3180         ctrls ^= under_mouse;
3181     }
3182
3183     // QSharedDoubleBuffer buffer( (bool)FALSE, (bool)FALSE );
3184     // buffer.begin( this, rect() );
3185     QSharedDoubleBuffer buffer( this, rect() );
3186     style().drawComplexControl(QStyle::CC_TitleBar, buffer.painter(), this, rect(),
3187                                colorGroup(),
3188                                isEnabled() ? QStyle::Style_Enabled :
3189                                QStyle::Style_Default, ctrls, d->buttonDown);
3190     if(under_mouse != QStyle::SC_None)
3191         style().drawComplexControl(QStyle::CC_TitleBar, buffer.painter(), this, rect(),
3192                                    colorGroup(),
3193                                    QStyle::Style_MouseOver |
3194                                    (isEnabled() ? QStyle::Style_Enabled : 0),
3195                                    under_mouse, d->buttonDown);
3196 }
3197
3198 void QTitleBarP::mouseDoubleClickEvent( QMouseEvent *e )
3199 {
3200     if ( e->button() != LeftButton )
3201         return;
3202
3203     switch(style().querySubControl(QStyle::CC_TitleBar, this, e->pos())) {
3204     case QStyle::SC_TitleBarLabel:
3205         emit doubleClicked();
3206         break;
3207
3208     case QStyle::SC_TitleBarSysMenu:
3209         if ( testWFlags( WStyle_SysMenu ) )
3210             emit doClose();
3211         break;
3212
3213     default:
3214         break;
3215     }
3216 }
3217
3218 void QTitleBarP::cutText()
3219 {
3220 #ifndef QT_NO_WIDGET_TOPEXTRA
3221     QFontMetrics fm( font() );
3222
3223     int maxw = style().querySubControlMetrics(QStyle::CC_TitleBar, this,
3224                                               QStyle::SC_TitleBarLabel).width();
3225     if ( !d->window )
3226         maxw = width() - 20;
3227     const QString txt = caption();
3228     d->cuttext = txt;
3229     if ( fm.width( txt + "m" ) > maxw ) {
3230         int i = txt.length();
3231         int dotlength = fm.width( "..." );
3232         while ( i>0 && fm.width(txt.left( i )) + dotlength > maxw )
3233             i--;
3234         if(i != (int)txt.length())
3235             d->cuttext = txt.left( i ) + "...";
3236     }
3237 #endif
3238 }
3239
3240 void QTitleBarP::setCaption( const QString& title )
3241 {
3242 #ifndef QT_NO_WIDGET_TOPEXTRA
3243     if( caption() == title)
3244         return;
3245     QWidget::setCaption( title );
3246     cutText();
3247
3248     update();
3249 #endif
3250 }
3251
3252
3253 void QTitleBarP::setIcon( const QPixmap& icon )
3254 {
3255 #ifndef QT_NO_WIDGET_TOPEXTRA
3256 #ifndef QT_NO_IMAGE_SMOOTHSCALE
3257     QRect menur = style().querySubControlMetrics(QStyle::CC_TitleBar, this,
3258                                                   QStyle::SC_TitleBarSysMenu);
3259
3260     QPixmap theIcon;
3261     if (icon.width() > menur.width()) {
3262         // try to keep something close to the same aspect
3263         int aspect = (icon.height() * 100) / icon.width();
3264         int newh = (aspect * menur.width()) / 100;
3265         theIcon.convertFromImage( icon.convertToImage().smoothScale(menur.width(),
3266                                                                    newh) );
3267     } else if (icon.height() > menur.height()) {
3268         // try to keep something close to the same aspect
3269         int aspect = (icon.width() * 100) / icon.height();
3270         int neww = (aspect * menur.height()) / 100;
3271         theIcon.convertFromImage( icon.convertToImage().smoothScale(neww,
3272                                                                    menur.height()) );
3273     } else
3274         theIcon = icon;
3275
3276     QWidget::setIcon( theIcon );
3277 #else
3278     QWidget::setIcon( icon );
3279 #endif
3280
3281     update();
3282 #endif
3283 }
3284
3285 void QTitleBarP::leaveEvent( QEvent * )
3286 {
3287     if(autoRaise() && !d->pressed)
3288         repaint( FALSE );
3289 }
3290
3291 void QTitleBarP::enterEvent( QEvent * )
3292 {
3293     if(autoRaise() && !d->pressed)
3294         repaint( FALSE );
3295     QEvent e( QEvent::Leave );
3296     QApplication::sendEvent( parentWidget(), &e );
3297 }
3298
3299 void QTitleBarP::setActive( bool active )
3300 {
3301     if ( d->act == active )
3302         return ;
3303
3304     d->act = active;
3305     update();
3306 }
3307
3308 bool QTitleBarP::isActive() const
3309 {
3310     return d->act;
3311 }
3312
3313 bool QTitleBarP::usesActiveColor() const
3314 {
3315     return ( isActive() && isActiveWindow() ) ||
3316            ( !window() && topLevelWidget()->isActiveWindow() );
3317 }
3318
3319 QString QTitleBarP::visibleText() const
3320 {
3321     return d->cuttext;
3322 }
3323
3324 QWidget *QTitleBarP::window() const
3325 {
3326     return d->window;
3327 }
3328
3329 bool QTitleBarP::event( QEvent* e )
3330 {
3331     if ( e->type() == QEvent::ApplicationPaletteChange ) {
3332         readColors();
3333         return TRUE;
3334     } else if ( e->type() == QEvent::WindowActivate ) {
3335         setActive( d->act );
3336     } else if ( e->type() == QEvent::WindowDeactivate ) {
3337         bool wasActive = d->act;
3338         setActive( FALSE );
3339         d->act = wasActive;
3340     }
3341
3342     return QWidget::event( e );
3343 }
3344
3345 void QTitleBarP::setMovable(bool b)
3346 {
3347     d->movable = b;
3348 }
3349
3350 bool QTitleBarP::isMovable() const
3351 {
3352     return d->movable;
3353 }
3354
3355 void QTitleBarP::setAutoRaise(bool b)
3356 {
3357     d->autoraise = b;
3358 }
3359
3360 bool QTitleBarP::autoRaise() const
3361 {
3362     return d->autoraise;
3363 }
3364
3365 QSize QTitleBarP::sizeHint() const
3366 {
3367     constPolish();
3368     QRect menur = style().querySubControlMetrics(QStyle::CC_TitleBar, this,
3369                                                  QStyle::SC_TitleBarSysMenu);
3370     return QSize( menur.width(), style().pixelMetric( QStyle::PM_TitleBarHeight, this ) );
3371 }
3372