summaryrefslogtreecommitdiffstats
path: root/src/workspace/qworkspace.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
commitbd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch)
tree7a520322212d48ebcb9fbe1087e7fca28b76185c /src/workspace/qworkspace.cpp
downloadqt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz
qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip
Add Qt3 development HEAD version
Diffstat (limited to 'src/workspace/qworkspace.cpp')
-rw-r--r--src/workspace/qworkspace.cpp3026
1 files changed, 3026 insertions, 0 deletions
diff --git a/src/workspace/qworkspace.cpp b/src/workspace/qworkspace.cpp
new file mode 100644
index 0000000..b6699e8
--- /dev/null
+++ b/src/workspace/qworkspace.cpp
@@ -0,0 +1,3026 @@
+/****************************************************************************
+**
+** Implementation of the QWorkspace class
+**
+** Created : 931107
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the workspace module of the Qt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "qworkspace.h"
+#ifndef QT_NO_WORKSPACE
+#include "qapplication.h"
+#include "../widgets/qtitlebar_p.h"
+#include "qobjectlist.h"
+#include "qlayout.h"
+#include "qtoolbutton.h"
+#include "qlabel.h"
+#include "qvbox.h"
+#include "qaccel.h"
+#include "qcursor.h"
+#include "qpopupmenu.h"
+#include "qmenubar.h"
+#include "qguardedptr.h"
+#include "qiconset.h"
+#include "../widgets/qwidgetresizehandler_p.h"
+#include "qfocusdata.h"
+#include "qdatetime.h"
+#include "qtooltip.h"
+#include "qwmatrix.h"
+#include "qimage.h"
+#include "qscrollbar.h"
+#include "qstyle.h"
+#include "qbitmap.h"
+
+// magic non-mdi things
+#include "qtimer.h"
+#include "qdockarea.h"
+#include "qstatusbar.h"
+#include "qmainwindow.h"
+#include "qdockwindow.h"
+#include "qtoolbar.h"
+
+#define BUTTON_WIDTH 16
+#define BUTTON_HEIGHT 14
+
+/*!
+ \class QWorkspace qworkspace.h
+ \brief The QWorkspace widget provides a workspace window that can
+ contain decorated windows, e.g. for MDI.
+
+ \module workspace
+
+ \ingroup application
+ \ingroup organizers
+ \mainclass
+
+ MDI (multiple document interface) applications typically have one
+ main window with a menu bar and toolbar, and a central widget that
+ is a QWorkspace. The workspace itself contains zero, one or more
+ document windows, each of which is a widget.
+
+ The workspace itself is an ordinary Qt widget. It has a standard
+ constructor that takes a parent widget and an object name. The
+ parent window is usually a QMainWindow, but it need not be.
+
+ Document windows (i.e. MDI windows) are also ordinary Qt widgets
+ which have the workspace as their parent widget. When you call
+ show(), hide(), showMaximized(), setCaption(), etc. on a document
+ window, it is shown, hidden, etc. with a frame, caption, icon and
+ icon text, just as you'd expect. You can provide widget flags
+ which will be used for the layout of the decoration or the
+ behaviour of the widget itself.
+
+ To change or retrieve the geometry of MDI windows you must operate
+ on the MDI widget's parentWidget(). (The parentWidget() provides
+ access to the decorated window in which the MDI window's widget is
+ shown.)
+
+ A document window becomes active when it gets the keyboard focus.
+ You can also activate a window in code using setFocus(). The user
+ can activate a window by moving focus in the usual ways, for
+ example by clicking a window or by pressing Tab. The workspace
+ emits a signal windowActivated() when it detects the activation
+ change, and the function activeWindow() always returns a pointer
+ to the active document window.
+
+ The convenience function windowList() returns a list of all
+ document windows. This is useful to create a popup menu
+ "<u>W</u>indows" on the fly, for example.
+
+ QWorkspace provides two built-in layout strategies for child
+ windows: cascade() and tile(). Both are slots so you can easily
+ connect menu entries to them.
+
+ If you want your users to be able to work with document windows
+ larger than the actual workspace, set the scrollBarsEnabled
+ property to TRUE.
+
+ If the top-level window contains a menu bar and a document window
+ is maximised, QWorkspace moves the document window's minimize,
+ restore and close buttons from the document window's frame to the
+ workspace window's menu bar. It then inserts a window operations
+ menu at the far left of the menu bar.
+*/
+
+static bool inCaptionChange = FALSE;
+
+class QWorkspaceChild : public QFrame
+{
+ Q_OBJECT
+
+ friend class QWorkspace;
+ friend class QTitleBar;
+
+public:
+ QWorkspaceChild( QWidget* window,
+ QWorkspace* parent=0, const char* name=0 );
+ ~QWorkspaceChild();
+
+ void setActive( bool );
+ bool isActive() const;
+
+ void adjustToFullscreen();
+
+ void setStatusBar(QStatusBar *);
+ QWidget* windowWidget() const;
+ QWidget* iconWidget() const;
+
+ void doResize();
+ void doMove();
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ QSize baseSize() const;
+
+signals:
+ void showOperationMenu();
+ void popupOperationMenu( const QPoint& );
+
+public slots:
+ void activate();
+ void showMinimized();
+ void showMaximized();
+ void showNormal();
+ void showShaded();
+ void setCaption( const QString& );
+ void internalRaise();
+ void titleBarDoubleClicked();
+
+ void move( int x, int y );
+
+protected:
+ bool event(QEvent * );
+ void enterEvent( QEvent * );
+ void leaveEvent( QEvent * );
+ void childEvent( QChildEvent* );
+ void resizeEvent( QResizeEvent * );
+ void moveEvent( QMoveEvent * );
+ bool eventFilter( QObject *, QEvent * );
+
+ bool focusNextPrevChild( bool );
+
+ void drawFrame( QPainter * );
+ void styleChange( QStyle & );
+
+private:
+ QWidget* childWidget;
+ QGuardedPtr<QWidget> lastfocusw;
+ QWidgetResizeHandler *widgetResizeHandler;
+ QTitleBar* titlebar;
+ QGuardedPtr<QStatusBar> statusbar;
+ QGuardedPtr<QTitleBar> iconw;
+ QSize windowSize;
+ QSize shadeRestore;
+ QSize shadeRestoreMin;
+ bool act :1;
+ bool shademode :1;
+ bool snappedRight :1;
+ bool snappedDown :1;
+#if defined(Q_DISABLE_COPY) // Disabled copy constructor and operator=
+ QWorkspaceChild( const QWorkspaceChild & );
+ QWorkspaceChild &operator=( const QWorkspaceChild & );
+#endif
+};
+
+class QMainWindow;
+
+class QWorkspacePrivate {
+public:
+ QWorkspaceChild* active;
+ QPtrList<QWorkspaceChild> windows;
+ QPtrList<QWorkspaceChild> focus;
+ QPtrList<QWidget> icons;
+ QWorkspaceChild* maxWindow;
+ QRect maxRestore;
+ QGuardedPtr<QFrame> maxcontrols;
+ QGuardedPtr<QMenuBar> maxmenubar;
+
+ int px;
+ int py;
+ QWidget *becomeActive;
+ QGuardedPtr<QLabel> maxtools;
+ QPopupMenu* popup;
+ QPopupMenu* toolPopup;
+ int menuId;
+ int controlId;
+ QString topCaption;
+
+ QScrollBar *vbar, *hbar;
+ QWidget *corner;
+ int yoffset, xoffset;
+
+ // toplevel mdi fu
+ QWorkspace::WindowMode wmode;
+ QGuardedPtr<QMainWindow> mainwindow;
+ QPtrList<QDockWindow> dockwindows, newdocks;
+};
+
+static bool isChildOf( QWidget * child, QWidget * parent )
+{
+ if ( !parent || !child )
+ return FALSE;
+ QWidget * w = child;
+ while( w && w != parent )
+ w = w->parentWidget();
+ return w != 0;
+}
+
+/*!
+ Constructs a workspace with a \a parent and a \a name.
+*/
+QWorkspace::QWorkspace( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ init();
+}
+
+#ifdef QT_WORKSPACE_WINDOWMODE
+/*!
+ Constructs a workspace with a \a parent and a \a name. This
+ constructor will also set the WindowMode to \a mode.
+
+ \sa windowMode()
+*/
+QWorkspace::QWorkspace( QWorkspace::WindowMode mode, QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ init();
+ d->wmode = mode;
+}
+#endif
+
+
+/*!
+ \internal
+*/
+void
+QWorkspace::init()
+{
+ d = new QWorkspacePrivate;
+ d->maxcontrols = 0;
+ d->active = 0;
+ d->maxWindow = 0;
+ d->maxtools = 0;
+ d->px = 0;
+ d->py = 0;
+ d->becomeActive = 0;
+#if defined( QT_WORKSPACE_WINDOWMODE ) && defined( Q_WS_MAC )
+ d->wmode = AutoDetect;
+#else
+ d->wmode = MDI;
+#endif
+ d->mainwindow = 0;
+#if defined(Q_WS_WIN)
+ d->popup = new QPopupMenu( this, "qt_internal_mdi_popup" );
+ d->toolPopup = new QPopupMenu( this, "qt_internal_mdi_popup" );
+#else
+ d->popup = new QPopupMenu( parentWidget(), "qt_internal_mdi_popup" );
+ d->toolPopup = new QPopupMenu( parentWidget(), "qt_internal_mdi_popup" );
+#endif
+
+ d->menuId = -1;
+ d->controlId = -1;
+ connect( d->popup, SIGNAL( aboutToShow() ), this, SLOT(operationMenuAboutToShow() ));
+ connect( d->popup, SIGNAL( activated(int) ), this, SLOT( operationMenuActivated(int) ) );
+ d->popup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarNormalButton)), tr("&Restore"), 1);
+ d->popup->insertItem(tr("&Move"), 2);
+ d->popup->insertItem(tr("&Size"), 3);
+ d->popup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarMinButton)), tr("Mi&nimize"), 4);
+ d->popup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarMaxButton)), tr("Ma&ximize"), 5);
+ d->popup->insertSeparator();
+ d->popup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarCloseButton)),
+ tr("&Close")
+#ifndef QT_NO_ACCEL
+ +"\t"+QAccel::keyToString(CTRL+Key_F4)
+#endif
+ , this, SLOT( closeActiveWindow() ) );
+
+ connect( d->toolPopup, SIGNAL( aboutToShow() ), this, SLOT(toolMenuAboutToShow() ));
+ connect( d->toolPopup, SIGNAL( activated(int) ), this, SLOT( operationMenuActivated(int) ) );
+ d->toolPopup->insertItem(tr("&Move"), 2);
+ d->toolPopup->insertItem(tr("&Size"), 3);
+ d->toolPopup->insertItem(tr("Stay on &Top"), 7);
+ d->toolPopup->setItemChecked( 7, TRUE );
+ d->toolPopup->setCheckable( TRUE );
+ d->toolPopup->insertSeparator();
+ d->toolPopup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarShadeButton)), tr("Sh&ade"), 6);
+ d->toolPopup->insertItem(QIconSet(style().stylePixmap(QStyle::SP_TitleBarCloseButton)),
+ tr("&Close")
+#ifndef QT_NO_ACCEL
+ +"\t"+QAccel::keyToString( CTRL+Key_F4)
+#endif
+ , this, SLOT( closeActiveWindow() ) );
+
+#ifndef QT_NO_ACCEL
+ QAccel* a = new QAccel( this );
+ a->connectItem( a->insertItem( ALT + Key_Minus),
+ this, SLOT( showOperationMenu() ) );
+
+ a->connectItem( a->insertItem( CTRL + Key_F6),
+ this, SLOT( activateNextWindow() ) );
+ a->connectItem( a->insertItem( CTRL + Key_Tab),
+ this, SLOT( activateNextWindow() ) );
+ a->connectItem( a->insertItem( Key_Forward ),
+ this, SLOT( activateNextWindow() ) );
+
+ a->connectItem( a->insertItem( CTRL + SHIFT + Key_F6),
+ this, SLOT( activatePreviousWindow() ) );
+ a->connectItem( a->insertItem( CTRL + SHIFT + Key_Tab),
+ this, SLOT( activatePreviousWindow() ) );
+ a->connectItem( a->insertItem( Key_Back ),
+ this, SLOT( activatePreviousWindow() ) );
+
+ a->connectItem( a->insertItem( CTRL + Key_F4 ),
+ this, SLOT( closeActiveWindow() ) );
+#endif
+
+ setBackgroundMode( PaletteDark );
+ setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
+
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ d->topCaption = topLevelWidget()->caption();
+#endif
+
+ d->hbar = d->vbar = 0;
+ d->corner = 0;
+ d->xoffset = d->yoffset = 0;
+
+ updateWorkspace();
+
+ topLevelWidget()->installEventFilter( this );
+}
+
+/*! Destroys the workspace and frees any allocated resources. */
+
+QWorkspace::~QWorkspace()
+{
+ delete d;
+ d = 0;
+}
+
+/*!\reimp */
+QSize QWorkspace::sizeHint() const
+{
+ QSize s( QApplication::desktop()->size() );
+ return QSize( s.width()*2/3, s.height()*2/3);
+}
+
+/*! \reimp */
+void QWorkspace::setPaletteBackgroundColor( const QColor & c )
+{
+ setEraseColor( c );
+}
+
+
+/*! \reimp */
+void QWorkspace::setPaletteBackgroundPixmap( const QPixmap & pm )
+{
+ setErasePixmap( pm );
+}
+
+/*! \reimp */
+void QWorkspace::childEvent( QChildEvent * e)
+{
+ if (e->inserted() && e->child()->isWidgetType()) {
+ QWidget* w = (QWidget*) e->child();
+ if ( !w || !w->testWFlags( WStyle_Title | WStyle_NormalBorder | WStyle_DialogBorder) || w->testWFlags(WType_Dialog)
+ || d->icons.contains( w ) || w == d->vbar || w == d->hbar || w == d->corner )
+ return; // nothing to do
+
+ bool wasMaximized = w->isMaximized();
+ bool wasMinimized = w->isMinimized();
+ bool hasBeenHidden = w->isHidden();
+ bool hasSize = w->testWState( WState_Resized );
+ int x = w->x();
+ int y = w->y();
+ bool hasPos = x != 0 || y != 0;
+ QSize s = w->size().expandedTo( w->minimumSizeHint() );
+ if ( !hasSize && w->sizeHint().isValid() )
+ w->adjustSize();
+
+ QWorkspaceChild* child = new QWorkspaceChild( w, this, "qt_workspacechild" );
+ child->installEventFilter( this );
+
+ connect( child, SIGNAL( popupOperationMenu(const QPoint&) ),
+ this, SLOT( popupOperationMenu(const QPoint&) ) );
+ connect( child, SIGNAL( showOperationMenu() ),
+ this, SLOT( showOperationMenu() ) );
+ d->windows.append( child );
+ if ( child->isVisibleTo( this ) )
+ d->focus.append( child );
+ child->internalRaise();
+
+ if ( !hasPos )
+ place( child );
+ if ( hasSize )
+ child->resize( s + child->baseSize() );
+ else
+ child->adjustSize();
+ if ( hasPos )
+ child->move( x, y );
+
+ if ( hasBeenHidden )
+ w->hide();
+ else if ( !isVisible() ) // that's a case were we don't receive a showEvent in time. Tricky.
+ child->show();
+
+ if ( wasMaximized )
+ w->showMaximized();
+ else if ( wasMinimized )
+ w->showMinimized();
+ else if (!hasBeenHidden)
+ activateWindow( w );
+
+ updateWorkspace();
+ } else if (e->removed() ) {
+ if ( d->windows.contains( (QWorkspaceChild*)e->child() ) ) {
+ d->windows.removeRef( (QWorkspaceChild*)e->child() );
+ d->focus.removeRef( (QWorkspaceChild*)e->child() );
+ if (d->maxWindow == e->child())
+ d->maxWindow = 0;
+ updateWorkspace();
+ }
+ }
+}
+
+/*! \reimp
+*/
+#ifndef QT_NO_WHEELEVENT
+void QWorkspace::wheelEvent( QWheelEvent *e )
+{
+ if ( !scrollBarsEnabled() )
+ return;
+ if ( d->vbar && d->vbar->isVisible() && !( e->state() & AltButton ) )
+ QApplication::sendEvent( d->vbar, e );
+ else if ( d->hbar && d->hbar->isVisible() )
+ QApplication::sendEvent( d->hbar, e );
+}
+#endif
+
+void QWorkspace::activateWindow( QWidget* w, bool change_focus )
+{
+ if ( !w ) {
+ d->active = 0;
+ emit windowActivated( 0 );
+ return;
+ }
+ if ( d->wmode == MDI && !isVisibleTo( 0 ) ) {
+ d->becomeActive = w;
+ return;
+ }
+
+ if ( d->active && d->active->windowWidget() == w ) {
+ if ( !isChildOf( focusWidget(), w ) ) // child window does not have focus
+ d->active->setActive( TRUE );
+ return;
+ }
+
+ d->active = 0;
+ // First deactivate all other workspace clients
+ QPtrListIterator<QWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ QWorkspaceChild* c = it.current();
+ ++it;
+ if(windowMode() == QWorkspace::TopLevel && c->isTopLevel() &&
+ c->windowWidget() == w && !c->isActive())
+ c->setActiveWindow();
+ if (c->windowWidget() == w)
+ d->active = c;
+ else
+ c->setActive( FALSE );
+ }
+
+ if (!d->active)
+ return;
+
+ // Then activate the new one, so the focus is stored correctly
+ d->active->setActive( TRUE );
+
+ if (!d->active)
+ return;
+
+ if ( d->maxWindow && d->maxWindow != d->active && d->active->windowWidget() &&
+ d->active->windowWidget()->testWFlags( WStyle_MinMax ) &&
+ !d->active->windowWidget()->testWFlags( WStyle_Tool ) ) {
+ d->active->showMaximized();
+ if ( d->maxtools ) {
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ if ( w->icon() ) {
+ QPixmap pm(*w->icon());
+ int iconSize = d->maxtools->size().height();
+ if(pm.width() > iconSize || pm.height() > iconSize) {
+ QImage im;
+ im = pm;
+ pm = im.smoothScale( QMIN(iconSize, pm.width()), QMIN(iconSize, pm.height()) );
+ }
+ d->maxtools->setPixmap( pm );
+ } else
+#endif
+ {
+ QPixmap pm(14,14);
+ pm.fill( color1 );
+ pm.setMask(pm.createHeuristicMask());
+ d->maxtools->setPixmap( pm );
+ }
+ }
+ } else { // done implicitly in maximizeWindow otherwise
+ d->active->internalRaise();
+ }
+
+ if ( change_focus ) {
+ if ( d->focus.find( d->active ) >=0 ) {
+ d->focus.removeRef( d->active );
+ d->focus.append( d->active );
+ }
+ }
+
+ updateWorkspace();
+ emit windowActivated( w );
+}
+
+
+/*!
+ Returns the active window, or 0 if no window is active.
+*/
+QWidget* QWorkspace::activeWindow() const
+{
+ return d->active?d->active->windowWidget():0;
+}
+
+
+void QWorkspace::place( QWidget* w)
+{
+ QPtrList<QWidget> widgets;
+ for(QPtrListIterator<QWorkspaceChild> it( d->windows ); it.current(); ++it)
+ if ((*it) != w)
+ widgets.append((*it));
+
+ if(d->wmode == TopLevel) {
+ for(QPtrListIterator<QDockWindow> it( d->dockwindows ); it.current(); ++it)
+ if ((*it) != w)
+ widgets.append((*it));
+ }
+
+ int overlap, minOverlap = 0;
+ int possible;
+
+ QRect r1(0, 0, 0, 0);
+ QRect r2(0, 0, 0, 0);
+ QRect maxRect = rect();
+ if(d->wmode == TopLevel) {
+ const QDesktopWidget *dw = qApp->desktop();
+ maxRect = dw->availableGeometry(dw->screenNumber(topLevelWidget()));
+ }
+ int x = maxRect.left(), y = maxRect.top();
+ QPoint wpos(maxRect.left(), maxRect.top());
+
+ bool firstPass = TRUE;
+
+ do {
+ if ( y + w->height() > maxRect.bottom() ) {
+ overlap = -1;
+ } else if( x + w->width() > maxRect.right() ) {
+ overlap = -2;
+ } else {
+ overlap = 0;
+
+ r1.setRect(x, y, w->width(), w->height());
+
+ QWidget *l;
+ QPtrListIterator<QWidget> it( widgets );
+ while ( it.current () ) {
+ l = it.current();
+ ++it;
+
+ if ( d->maxWindow == l )
+ r2 = d->maxRestore;
+ else
+ r2.setRect(l->x(), l->y(), l->width(), l->height());
+
+ if (r2.intersects(r1)) {
+ r2.setCoords(QMAX(r1.left(), r2.left()),
+ QMAX(r1.top(), r2.top()),
+ QMIN(r1.right(), r2.right()),
+ QMIN(r1.bottom(), r2.bottom())
+ );
+
+ overlap += (r2.right() - r2.left()) *
+ (r2.bottom() - r2.top());
+ }
+ }
+ }
+
+ if (overlap == 0) {
+ wpos = QPoint(x, y);
+ break;
+ }
+
+ if (firstPass) {
+ firstPass = FALSE;
+ minOverlap = overlap;
+ } else if ( overlap >= 0 && overlap < minOverlap) {
+ minOverlap = overlap;
+ wpos = QPoint(x, y);
+ }
+
+ if ( overlap > 0 ) {
+ possible = maxRect.right();
+ if ( possible - w->width() > x) possible -= w->width();
+
+ QWidget *l;
+ QPtrListIterator<QWidget> it( widgets );
+ while ( it.current () ) {
+ l = it.current();
+ ++it;
+ if ( d->maxWindow == l )
+ r2 = d->maxRestore;
+ else
+ r2.setRect(l->x(), l->y(), l->width(), l->height());
+
+ if( ( y < r2.bottom() ) && ( r2.top() < w->height() + y ) ) {
+ if( r2.right() > x )
+ possible = possible < r2.right() ?
+ possible : r2.right();
+
+ if( r2.left() - w->width() > x )
+ possible = possible < r2.left() - w->width() ?
+ possible : r2.left() - w->width();
+ }
+ }
+
+ x = possible;
+ } else if ( overlap == -2 ) {
+ x = maxRect.left();
+ possible = maxRect.bottom();
+
+ if ( possible - w->height() > y ) possible -= w->height();
+
+ QWidget *l;
+ QPtrListIterator<QWidget> it( widgets );
+ while ( it.current () ) {
+ l = it.current();
+ ++it;
+ if ( d->maxWindow == l )
+ r2 = d->maxRestore;
+ else
+ r2.setRect(l->x(), l->y(), l->width(), l->height());
+
+ if( r2.bottom() > y)
+ possible = possible < r2.bottom() ?
+ possible : r2.bottom();
+
+ if( r2.top() - w->height() > y )
+ possible = possible < r2.top() - w->height() ?
+ possible : r2.top() - w->height();
+ }
+
+ y = possible;
+ }
+ }
+ while( overlap != 0 && overlap != -1 );
+
+#if 0
+ if(windowMode() == QWorkspace::TopLevel && wpos.y()) {
+ QPoint fr = w->topLevelWidget()->frameGeometry().topLeft(),
+ r = w->topLevelWidget()->geometry().topLeft();
+ wpos += QPoint(r.x() - fr.x(), r.y() - fr.y());
+ }
+#endif
+ w->move(wpos);
+ updateWorkspace();
+}
+
+
+void QWorkspace::insertIcon( QWidget* w )
+{
+ if ( !w || d->icons.contains( w ) )
+ return;
+ d->icons.append( w );
+ if (w->parentWidget() != this )
+ w->reparent( this, 0, QPoint(0,0), FALSE);
+ QRect cr = updateWorkspace();
+ int x = 0;
+ int y = cr.height() - w->height();
+
+ QPtrListIterator<QWidget> it( d->icons );
+ while ( it.current () ) {
+ QWidget* i = it.current();
+ ++it;
+ if ( x > 0 && x + i->width() > cr.width() ){
+ x = 0;
+ y -= i->height();
+ }
+
+ if ( i != w &&
+ i->geometry().intersects( QRect( x, y, w->width(), w->height() ) ) )
+ x += i->width();
+ }
+ w->move( x, y );
+
+ if ( isVisibleTo( parentWidget() ) ) {
+ w->show();
+ w->lower();
+ }
+ updateWorkspace();
+}
+
+
+void QWorkspace::removeIcon( QWidget* w)
+{
+ if ( !d->icons.contains( w ) )
+ return;
+ d->icons.remove( w );
+ w->hide();
+}
+
+
+/*! \reimp */
+void QWorkspace::resizeEvent( QResizeEvent * )
+{
+ if ( d->maxWindow ) {
+ d->maxWindow->adjustToFullscreen();
+ if (d->maxWindow->windowWidget())
+ ((QWorkspace*)d->maxWindow->windowWidget())->setWState( WState_Maximized );
+ }
+
+ QRect cr = updateWorkspace();
+
+ QPtrListIterator<QWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ QWorkspaceChild* c = it.current();
+ ++it;
+ if ( c->windowWidget() && !c->windowWidget()->testWFlags( WStyle_Tool ) )
+ continue;
+
+ int x = c->x();
+ int y = c->y();
+ if ( c->snappedDown )
+ y = cr.height() - c->height();
+ if ( c->snappedRight )
+ x = cr.width() - c->width();
+
+ if ( x != c->x() || y != c->y() )
+ c->move( x, y );
+ }
+
+}
+
+void QWorkspace::handleUndock(QDockWindow *w)
+{
+ const QDesktopWidget *dw = qApp->desktop();
+ QRect maxRect = dw->availableGeometry(dw->screenNumber(d->mainwindow));
+ QPoint wpos(maxRect.left(), maxRect.top());
+ int possible = 0;
+ if(!::qt_cast<QToolBar*>(w)) {
+ struct place_score { int o, x, y; } score = {0, 0, 0};
+ int left = 1, x = wpos.x(), y = wpos.y();
+ QPtrListIterator<QDockWindow> it( d->dockwindows );
+ while(1) {
+ if(y + w->height() > maxRect.bottom()) {
+ if(left) {
+ x = maxRect.right() - w->width();
+ y = maxRect.top();
+ left = 0;
+ } else {
+ break;
+ }
+ }
+
+ QDockWindow *l, *nearest = NULL, *furthest;
+ for ( it.toFirst(); it.current(); ++it ) {
+ l = it.current();
+ if ( l != w && y == l->y() ) {
+ if(!nearest) {
+ nearest = l;
+ } else if(l->x() == x) {
+ nearest = l;
+ break;
+ } else if(left && (l->x() - x) < (nearest->x() - x)) {
+ nearest = l;
+ } else if(!left && (x - l->x()) < (x - nearest->x())) {
+ nearest = l;
+ }
+ }
+ }
+ QRect r2(x, y, w->width(), w->height());
+ if(!nearest || !nearest->geometry().intersects(r2)) {
+ wpos = QPoint(x, y); //best possible outcome
+ possible = 2;
+ break;
+ }
+
+ QDockWindow *o = NULL;
+ int overlap = 0;
+ for( it.toFirst(); it.current(); ++it ) {
+ l = it.current();
+ if ( l != w && l->geometry().intersects(QRect(QPoint(x, y), w->size()))) {
+ overlap++;
+ o = l;
+ }
+ }
+ if(o && overlap == 1 && w->isVisible() && !o->isVisible()) {
+ wpos = QPoint(x, y);
+ possible = 2;
+ while(d->dockwindows.remove(o));
+ d->newdocks.append(o);
+ if(d->newdocks.count() == 1)
+ QTimer::singleShot(0, this, SLOT(dockWindowsShow()));
+ break;
+ }
+
+ for ( furthest = nearest, it.toFirst(); it.current(); ++it ) {
+ l = it.current();
+ if ( l != w && l->y() == nearest->y() &&
+ ((left && (l->x() == nearest->x() + nearest->width())) ||
+ (!left && (l->x() + l->width() == nearest->x()) )))
+ furthest = l;
+ }
+ if(left)
+ x = furthest->x() + furthest->width();
+ else
+ x = furthest->x() - w->width();
+
+ QPoint sc_pt(x, y);
+ place_score sc;
+ if(left)
+ sc.x = (x + w->width()) * 2;
+ else
+ sc.x = ((maxRect.width() - x) * 2) + 1;
+ sc.y = sc_pt.y();
+ for( sc.o = 0, it.toFirst(); it.current(); ++it ) {
+ l = it.current();
+ if ( l != w && l->geometry().intersects(QRect(sc_pt, w->size())))
+ sc.o++;
+ }
+ if(maxRect.contains(QRect(sc_pt, w->size())) &&
+ (!possible || (sc.o < score.o) ||
+ ((score.o || sc.o == score.o) && score.x < sc.x))) {
+ wpos = sc_pt;
+ score = sc;
+ possible = 1;
+ }
+ y += nearest->height();
+ if(left)
+ x = maxRect.x();
+ else
+ x = maxRect.right() - w->width();
+ }
+ if(!possible || (possible == 1 && score.o)) { //fallback to less knowledgeable function
+ place(w);
+ wpos = w->pos();
+ }
+ }
+
+ bool ishidden = w->isHidden();
+ QSize olds(w->size());
+ if(w->place() == QDockWindow::InDock)
+ w->undock();
+ w->move(wpos);
+ w->resize(olds);
+ if(!ishidden)
+ w->show();
+ else
+ w->hide();
+}
+
+void QWorkspace::dockWindowsShow()
+{
+ QPtrList<QDockWindow> lst = d->newdocks;
+ d->newdocks.clear();
+ for(QPtrListIterator<QDockWindow> dw_it(lst); (*dw_it); ++dw_it) {
+ if(d->dockwindows.find((*dw_it)) != -1)
+ continue;
+ handleUndock((*dw_it));
+ d->dockwindows.append((*dw_it));
+ }
+}
+
+/*! \reimp */
+void QWorkspace::showEvent( QShowEvent *e )
+{
+ /* This is all magic, be carefull when playing with this code - this tries to allow people to
+ use QWorkspace as a high level abstraction for window management, but removes enforcement that
+ QWorkspace be used as an MDI. */
+ if(d->wmode == AutoDetect) {
+ d->wmode = MDI;
+ QWidget *o = topLevelWidget();
+ if(::qt_cast<QMainWindow*>(o)) {
+ d->wmode = TopLevel;
+ const QObjectList *c = o->children();
+ for(QObjectListIt it(*c); it; ++it) {
+ if((*it)->isWidgetType() && !((QWidget *)(*it))->isTopLevel() &&
+ !::qt_cast<QHBox*>(*it) && !::qt_cast<QVBox*>(*it) &&
+ !::qt_cast<QWorkspaceChild*>(*it) && !(*it)->inherits("QHideDock") &&
+ !::qt_cast<QDockArea*>(*it) && !::qt_cast<QWorkspace*>(*it) &&
+ !::qt_cast<QMenuBar*>(*it) && !::qt_cast<QStatusBar*>(*it)) {
+ d->wmode = MDI;
+ break;
+ }
+ }
+ }
+ }
+ if(d->wmode == TopLevel) {
+ QWidget *o = topLevelWidget();
+ d->mainwindow = ::qt_cast<QMainWindow*>(o);
+ const QObjectList children = *o->children();
+ for(QObjectListIt it(children); it; ++it) {
+ if(!(*it)->isWidgetType())
+ continue;
+ QWidget *w = (QWidget *)(*it);
+ if(w->isTopLevel())
+ continue;
+ if(::qt_cast<QDockArea*>(w)) {
+ const QObjectList *dock_c = w->children();
+ if(dock_c) {
+ QPtrList<QToolBar> tb_list;
+ for(QObjectListIt dock_it(*dock_c); dock_it; ++dock_it) {
+ if(!(*dock_it)->isWidgetType())
+ continue;
+ if(::qt_cast<QToolBar*>(*dock_it)) {
+ tb_list.append((QToolBar *)(*dock_it));
+ } else if (::qt_cast<QDockWindow*>(*dock_it)) {
+ QDockWindow *dw = (QDockWindow*)(*dock_it);
+ dw->move(dw->mapToGlobal(QPoint(0, 0)));
+ d->newdocks.append(dw);
+ } else {
+ qDebug("not sure what to do with %s %s", (*dock_it)->className(),
+ (*dock_it)->name());
+ }
+ }
+ if(tb_list.count() == 1) {
+ QToolBar *tb = tb_list.first();
+ tb->move(0, 0);
+ d->newdocks.prepend(tb);
+ } else if(tb_list.count()) {
+ QDockWindow *dw = new QDockWindow(QDockWindow::OutsideDock,
+ w->parentWidget(),
+ QString("QMagicDock_") + w->name());
+ dw->installEventFilter(this);
+ dw->setResizeEnabled(TRUE);
+ dw->setCloseMode( QDockWindow::Always );
+ dw->setResizeEnabled(FALSE);
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ dw->setCaption(o->caption());
+#endif
+ QSize os(w->size());
+ if(w->layout() && w->layout()->hasHeightForWidth()) {
+ w->layout()->invalidate();
+ os.setHeight(w->layout()->heightForWidth(os.width()));
+ }
+ if(!w->isHidden())
+ dw->show();
+ w->reparent(dw, QPoint(0, 0));
+ dw->setWidget(w);
+ dw->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
+ dw->setGeometry(0, 0, os.width(), os.height() + dw->sizeHint().height());
+ d->newdocks.prepend(dw);
+ ((QDockArea*)w)->setAcceptDockWindow(dw, FALSE);
+ w->show();
+ }
+ }
+ w->installEventFilter(this);
+ } else if(::qt_cast<QStatusBar*>(w)) {
+ if(activeWindow()) {
+ QWorkspaceChild *c;
+ if ( ( c = findChild(activeWindow()) ) )
+ c->setStatusBar((QStatusBar*)w);
+ }
+ } else if(::qt_cast<QWorkspaceChild*>(w)) {
+ w->reparent(this, w->testWFlags(~(0)) | WType_TopLevel, w->pos());
+ }
+ }
+ dockWindowsShow(); //now place and undock windows discovered
+
+ QWidget *w = new QWidget(NULL, "QDoesNotExist",
+ WType_Dialog | WStyle_Customize | WStyle_NoBorder);
+// if(qApp->mainWidget() == o)
+// QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()));
+ QDesktopWidget *dw = QApplication::desktop();
+ w->setGeometry(dw->availableGeometry(dw->screenNumber(o)));
+ o->reparent(w, QPoint(0, 0), TRUE);
+ {
+ QMenuBar *mb = 0;
+ if(::qt_cast<QMainWindow*>(o))
+ mb = ((QMainWindow *)o)->menuBar();
+ if(!mb)
+ mb = (QMenuBar*)o->child(NULL, "QMenuBar");
+ if(mb)
+ mb->reparent(w, QPoint(0, 0));
+ }
+ reparent(w, QPoint(0,0));
+ setGeometry(0, 0, w->width(), w->height());
+#if 0
+ /* Hide really isn't acceptable because I need to make the rest of Qt
+ think it is visible, so instead I set it to an empty mask. I'm not
+ sure what problems this is going to create, hopefully everything will
+ be happy (or not even notice since this is mostly intended for Qt/Mac) */
+// w->setMask(QRegion());
+// w->show();
+#else
+ w->hide();
+#endif
+ }
+
+ //done with that nastiness, on with your regularly schedueled programming..
+ if ( d->maxWindow && !style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this))
+ showMaximizeControls();
+ QWidget::showEvent( e );
+ if ( d->becomeActive ) {
+ activateWindow( d->becomeActive );
+ d->becomeActive = 0;
+ } else if ( d->windows.count() > 0 && !d->active ) {
+ activateWindow( d->windows.first()->windowWidget() );
+ }
+
+ // force a frame repaint - this is a workaround for what seems to be a bug
+ // introduced when changing the QWidget::show() implementation. Might be
+ // a windows bug as well though.
+ for (QPtrListIterator<QWorkspaceChild> it( d->windows ); it.current(); ++it ) {
+ QWorkspaceChild* c = it.current();
+ QApplication::postEvent(c, new QPaintEvent(c->rect(), TRUE));
+ }
+
+ updateWorkspace();
+}
+
+/*! \reimp */
+void QWorkspace::hideEvent( QHideEvent * )
+{
+ if ( !isVisibleTo(0) && !style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this))
+ hideMaximizeControls();
+}
+
+void QWorkspace::minimizeWindow( QWidget* w)
+{
+ QWorkspaceChild* c = findChild( w );
+
+ if ( !w || w && (!w->testWFlags( WStyle_Minimize ) || w->testWFlags( WStyle_Tool) ) )
+ return;
+
+ if ( c ) {
+ QWorkspace *fake = (QWorkspace*)w;
+
+ setUpdatesEnabled( FALSE );
+ bool wasMax = FALSE;
+ if ( c == d->maxWindow ) {
+ wasMax = TRUE;
+ d->maxWindow = 0;
+ inCaptionChange = TRUE;
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ if ( !!d->topCaption )
+ topLevelWidget()->setCaption( d->topCaption );
+#endif
+ inCaptionChange = FALSE;
+ if ( !style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this) )
+ hideMaximizeControls();
+ for (QPtrListIterator<QWorkspaceChild> it( d->windows ); it.current(); ++it ) {
+ QWorkspaceChild* c = it.current();
+ if ( c->titlebar )
+ c->titlebar->setMovable( TRUE );
+ c->widgetResizeHandler->setActive( TRUE );
+ }
+ }
+
+ insertIcon( c->iconWidget() );
+ c->hide();
+ if ( wasMax )
+ c->setGeometry( d->maxRestore );
+ d->focus.append( c );
+
+ activateWindow(w);
+
+ setUpdatesEnabled( TRUE );
+ updateWorkspace();
+
+ fake->clearWState( WState_Maximized );
+ fake->setWState( WState_Minimized );
+ c->clearWState( WState_Maximized );
+ c->setWState( WState_Minimized );
+ }
+}
+
+void QWorkspace::normalizeWindow( QWidget* w)
+{
+ QWorkspaceChild* c = findChild( w );
+ if ( !w )
+ return;
+ if ( c ) {
+ QWorkspace *fake = (QWorkspace*)w;
+ fake->clearWState( WState_Minimized | WState_Maximized );
+ if ( !style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this) && d->maxWindow ) {
+ hideMaximizeControls();
+ } else {
+ if ( w->minimumSize() != w->maximumSize() )
+ c->widgetResizeHandler->setActive( TRUE );
+ if ( c->titlebar )
+ c->titlebar->setMovable(TRUE);
+ }
+ fake->clearWState( WState_Minimized | WState_Maximized );
+ c->clearWState( WState_Minimized | WState_Maximized );
+
+ if ( c == d->maxWindow ) {
+ c->setGeometry( d->maxRestore );
+ d->maxWindow = 0;
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ inCaptionChange = TRUE;
+ if ( !!d->topCaption )
+ topLevelWidget()->setCaption( d->topCaption );
+ inCaptionChange = FALSE;
+#endif
+ } else {
+ if ( c->iconw )
+ removeIcon( c->iconw->parentWidget() );
+ c->show();
+ }
+
+ if ( !style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this))
+ hideMaximizeControls();
+ for (QPtrListIterator<QWorkspaceChild> it( d->windows ); it.current(); ++it ) {
+ QWorkspaceChild* c = it.current();
+ if ( c->titlebar )
+ c->titlebar->setMovable( TRUE );
+ if ( c->childWidget && c->childWidget->minimumSize() != c->childWidget->maximumSize() )
+ c->widgetResizeHandler->setActive( TRUE );
+ }
+ activateWindow( w, TRUE );
+ updateWorkspace();
+ }
+}
+
+void QWorkspace::maximizeWindow( QWidget* w)
+{
+ QWorkspaceChild* c = findChild( w );
+
+ if ( !w || w && (!w->testWFlags( WStyle_Maximize ) || w->testWFlags( WStyle_Tool) ) )
+ return;
+
+ if ( c ) {
+ setUpdatesEnabled( FALSE );
+ if (c->iconw && d->icons.contains( c->iconw->parentWidget() ) )
+ normalizeWindow( w );
+ QWorkspace *fake = (QWorkspace*)w;
+
+ QRect r( c->geometry() );
+ c->adjustToFullscreen();
+ c->show();
+ c->internalRaise();
+ qApp->sendPostedEvents( c, QEvent::Resize );
+ qApp->sendPostedEvents( c, QEvent::Move );
+ qApp->sendPostedEvents( c, QEvent::ShowWindowRequest );
+ if ( d->maxWindow != c ) {
+ if ( d->maxWindow )
+ d->maxWindow->setGeometry( d->maxRestore );
+ d->maxWindow = c;
+ d->maxRestore = r;
+ }
+
+ activateWindow( w );
+ if(!style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this)) {
+ showMaximizeControls();
+ } else {
+ c->widgetResizeHandler->setActive( FALSE );
+ if ( c->titlebar )
+ c->titlebar->setMovable( FALSE );
+ }
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ inCaptionChange = TRUE;
+ if ( !!d->topCaption )
+ topLevelWidget()->setCaption( tr("%1 - [%2]")
+ .arg(d->topCaption).arg(c->caption()) );
+ inCaptionChange = FALSE;
+#endif
+ setUpdatesEnabled( TRUE );
+
+ updateWorkspace();
+
+ fake->clearWState( WState_Minimized );
+ fake->setWState( WState_Maximized );
+ c->clearWState( WState_Minimized );
+ c->setWState( WState_Maximized );
+ }
+}
+
+void QWorkspace::showWindow( QWidget* w)
+{
+ if ( d->maxWindow && w->testWFlags( WStyle_Maximize ) && !w->testWFlags( WStyle_Tool) )
+ maximizeWindow(w);
+ else if (w->isMinimized() && !w->testWFlags(WStyle_Tool))
+ minimizeWindow(w);
+ else if ( !w->testWFlags( WStyle_Tool ) )
+ normalizeWindow(w);
+ else
+ w->parentWidget()->show();
+ if ( d->maxWindow )
+ d->maxWindow->internalRaise();
+ updateWorkspace();
+}
+
+
+QWorkspaceChild* QWorkspace::findChild( QWidget* w)
+{
+ QPtrListIterator<QWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ QWorkspaceChild* c = it.current();
+ ++it;
+ if (c->windowWidget() == w)
+ return c;
+ }
+ return 0;
+}
+
+/*!
+ \obsolete
+ \overload
+ */
+QWidgetList QWorkspace::windowList() const
+{
+ return windowList( CreationOrder );
+}
+
+/*!
+ Returns a list of all windows. If \a order is CreationOrder
+ (the default) the windows are listed in the order in which they
+ had been inserted into the workspace. If \a order is StackingOrder
+ the windows are listed in their stacking order, with the topmost window
+ being the last window in the list.
+
+ QWidgetList is the same as QPtrList<QWidget>.
+
+ \sa QPtrList
+*/
+QWidgetList QWorkspace::windowList( WindowOrder order ) const
+{
+ QWidgetList windows;
+ if ( order == StackingOrder ) {
+ const QObjectList *cl = children();
+ if ( cl ) {
+ QObjectListIt it( *cl );
+ while (it.current()) {
+ QObject *o = it.current();
+ ++it;
+ QWorkspaceChild *c = ::qt_cast<QWorkspaceChild*>(o);
+ if (c && c->windowWidget())
+ windows.append(c->windowWidget());
+ }
+ }
+ } else {
+ QPtrListIterator<QWorkspaceChild> it( d->windows );
+ while (it.current()) {
+ QWorkspaceChild* c = it.current();
+ ++it;
+ if ( c->windowWidget() )
+ windows.append( c->windowWidget() );
+ }
+ }
+ return windows;
+}
+
+/*!\reimp*/
+bool QWorkspace::eventFilter( QObject *o, QEvent * e)
+{
+ if(d->wmode == TopLevel && d->mainwindow && o->parent() == d->mainwindow) {
+ if((e->type() == QEvent::ChildInserted || e->type() == QEvent::Reparent) &&
+ ::qt_cast<QDockArea*>(o) && !((QWidget*)o)->isVisible()) {
+ QChildEvent *ce = (QChildEvent*)e;
+ if(!::qt_cast<QDockWindow*>(ce->child())) {
+ qDebug("No idea what to do..");
+ return FALSE;
+ }
+ QDockWindow *w = (QDockWindow*)ce->child();
+ if(d->newdocks.find(w) == -1 && d->dockwindows.find(w) == -1) {
+ if(::qt_cast<QToolBar*>(w))
+ d->newdocks.prepend(w);
+ else
+ d->newdocks.append(w);
+ if(d->newdocks.count() == 1)
+ QTimer::singleShot(0, this, SLOT(dockWindowsShow()));
+ }
+ } else if(e->type() == QEvent::Hide && !e->spontaneous() && !qstrncmp(o->name(), "QMagicDock_", 11)) {
+// d->mainwindow->close();
+ }
+ return QWidget::eventFilter(o, e);
+ }
+
+ static QTime* t = 0;
+ static QWorkspace* tc = 0;
+#ifndef QT_NO_MENUBAR
+ if ( o == d->maxtools && d->menuId != -1 ) {
+ switch ( e->type() ) {
+ case QEvent::MouseButtonPress:
+ {
+ QMenuBar* b = (QMenuBar*)o->parent();
+ if ( !t )
+ t = new QTime;
+ if ( tc != this || t->elapsed() > QApplication::doubleClickInterval() ) {
+ if ( QApplication::reverseLayout() ) {
+ QPoint p = b->mapToGlobal( QPoint( b->x() + b->width(), b->y() + b->height() ) );
+ p.rx() -= d->popup->sizeHint().width();
+ popupOperationMenu( p );
+ } else {
+ popupOperationMenu( b->mapToGlobal( QPoint( b->x(), b->y() + b->height() ) ) );
+ }
+ t->start();
+ tc = this;
+ } else {
+ tc = 0;
+ closeActiveWindow();
+ }
+ return TRUE;
+ }
+ default:
+ break;
+ }
+ return QWidget::eventFilter( o, e );
+ }
+#endif
+ switch ( e->type() ) {
+ case QEvent::Hide:
+ case QEvent::HideToParent:
+ if ( !o->isA( "QWorkspaceChild" ) || !isVisible() || e->spontaneous() )
+ break;
+ if ( d->active == o ) {
+ int a = d->focus.find( d->active );
+ for ( ;; ) {
+ if ( --a < 0 )
+ a = d->focus.count()-1;
+ QWorkspaceChild* c = d->focus.at( a );
+ if ( !c || c == o ) {
+ if ( c && c->iconw && d->icons.contains( c->iconw->parentWidget() ) )
+ break;
+ activateWindow( 0 );
+ break;
+ }
+ if ( c->isShown() ) {
+ activateWindow( c->windowWidget(), FALSE );
+ break;
+ }
+ }
+ }
+ d->focus.removeRef( (QWorkspaceChild*)o );
+ if ( d->maxWindow == o && d->maxWindow->isHidden() ) {
+ d->maxWindow->setGeometry( d->maxRestore );
+ d->maxWindow = 0;
+ if ( d->active )
+ maximizeWindow( d->active );
+
+ if ( !d->maxWindow ) {
+
+ if ( style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this)) {
+ QWorkspaceChild *wc = (QWorkspaceChild *)o;
+ wc->widgetResizeHandler->setActive( TRUE );
+ if ( wc->titlebar )
+ wc->titlebar->setMovable( TRUE );
+ } else {
+ hideMaximizeControls();
+ }
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ inCaptionChange = TRUE;
+ if ( !!d->topCaption )
+ topLevelWidget()->setCaption( d->topCaption );
+ inCaptionChange = FALSE;
+#endif
+ }
+ }
+ updateWorkspace();
+ break;
+ case QEvent::Show:
+ if ( o->isA("QWorkspaceChild") && !d->focus.containsRef( (QWorkspaceChild*)o ) )
+ d->focus.append( (QWorkspaceChild*)o );
+ updateWorkspace();
+ break;
+ case QEvent::CaptionChange:
+ if ( inCaptionChange )
+ break;
+
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ inCaptionChange = TRUE;
+ if ( o == topLevelWidget() ) {
+ QWidget *tlw = (QWidget*)o;
+ if ( !d->maxWindow
+ || tlw->caption() != tr("%1 - [%2]").arg(d->topCaption).arg(d->maxWindow->caption()) )
+ d->topCaption = tlw->caption();
+ }
+
+ if ( d->maxWindow && !!d->topCaption )
+ topLevelWidget()->setCaption( tr("%1 - [%2]")
+ .arg(d->topCaption).arg(d->maxWindow->caption()));
+ inCaptionChange = FALSE;
+#endif
+
+ break;
+ case QEvent::Close:
+ if ( o == topLevelWidget() )
+ {
+ QPtrListIterator<QWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ QWorkspaceChild* c = it.current();
+ ++it;
+ if ( c->shademode )
+ c->showShaded();
+ }
+ } else if ( ::qt_cast<QWorkspaceChild*>(o) ) {
+ d->popup->hide();
+ }
+ updateWorkspace();
+ break;
+ default:
+ break;
+ }
+ return QWidget::eventFilter( o, e);
+}
+
+void QWorkspace::showMaximizeControls()
+{
+#ifndef QT_NO_MENUBAR
+ Q_ASSERT(d->maxWindow);
+ QMenuBar* b = 0;
+
+ // Do a breadth-first search first on every parent,
+ QWidget* w = parentWidget();
+ QObjectList * l = 0;
+ while ( !l && w ) {
+ l = w->queryList( "QMenuBar", 0, FALSE, FALSE );
+ w = w->parentWidget();
+ if ( l && !l->count() ) {
+ delete l;
+ l = 0;
+ }
+ }
+
+ // and query recursively if nothing is found.
+ if ( !l || !l->count() ) {
+ if ( l )
+ delete l;
+ l = topLevelWidget()->queryList( "QMenuBar", 0, 0, TRUE );
+ }
+ if ( l && l->count() )
+ b = (QMenuBar *)l->first();
+ delete l;
+
+ if ( !b )
+ return;
+
+ if ( !d->maxcontrols ) {
+ d->maxmenubar = b;
+ d->maxcontrols = new QFrame( topLevelWidget(), "qt_maxcontrols" );
+ QHBoxLayout* l = new QHBoxLayout( d->maxcontrols,
+ d->maxcontrols->frameWidth(), 0 );
+ if ( d->maxWindow->windowWidget() &&
+ d->maxWindow->windowWidget()->testWFlags(WStyle_Minimize) ) {
+ QToolButton* iconB = new QToolButton( d->maxcontrols, "iconify" );
+#ifndef QT_NO_TOOLTIP
+ QToolTip::add( iconB, tr( "Minimize" ) );
+#endif
+ l->addWidget( iconB );
+ iconB->setFocusPolicy( NoFocus );
+ iconB->setIconSet(style().stylePixmap(QStyle::SP_TitleBarMinButton));
+ iconB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
+ connect( iconB, SIGNAL( clicked() ),
+ this, SLOT( minimizeActiveWindow() ) );
+ }
+
+ QToolButton* restoreB = new QToolButton( d->maxcontrols, "restore" );
+#ifndef QT_NO_TOOLTIP
+ QToolTip::add( restoreB, tr( "Restore Down" ) );
+#endif
+ l->addWidget( restoreB );
+ restoreB->setFocusPolicy( NoFocus );
+ restoreB->setIconSet( style().stylePixmap(QStyle::SP_TitleBarNormalButton));
+ restoreB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
+ connect( restoreB, SIGNAL( clicked() ),
+ this, SLOT( normalizeActiveWindow() ) );
+
+ l->addSpacing( 2 );
+ QToolButton* closeB = new QToolButton( d->maxcontrols, "close" );
+#ifndef QT_NO_TOOLTIP
+ QToolTip::add( closeB, tr( "Close" ) );
+#endif
+ l->addWidget( closeB );
+ closeB->setFocusPolicy( NoFocus );
+ closeB->setIconSet( style().stylePixmap(QStyle::SP_TitleBarCloseButton) );
+ closeB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
+ connect( closeB, SIGNAL( clicked() ),
+ this, SLOT( closeActiveWindow() ) );
+
+ d->maxcontrols->setFixedSize( d->maxcontrols->minimumSizeHint() );
+ }
+
+ if ( d->controlId == -1 || b->indexOf( d->controlId ) == -1 ) {
+ QFrame* dmaxcontrols = d->maxcontrols;
+ d->controlId = b->insertItem( dmaxcontrols, -1, b->count() );
+ }
+ if ( !d->active && d->becomeActive ) {
+ d->active = (QWorkspaceChild*)d->becomeActive->parentWidget();
+ d->active->setActive( TRUE );
+ d->becomeActive = 0;
+ emit windowActivated( d->active->windowWidget() );
+ }
+ if ( d->active && ( d->menuId == -1 || b->indexOf( d->menuId ) == -1 ) ) {
+ if ( !d->maxtools ) {
+ d->maxtools = new QLabel( topLevelWidget(), "qt_maxtools" );
+ d->maxtools->installEventFilter( this );
+ }
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ if ( d->active->windowWidget() && d->active->windowWidget()->icon() ) {
+ QPixmap pm(*d->active->windowWidget()->icon());
+ int iconSize = d->maxcontrols->size().height();
+ if(pm.width() > iconSize || pm.height() > iconSize) {
+ QImage im;
+ im = pm;
+ pm = im.smoothScale( QMIN(iconSize, pm.width()), QMIN(iconSize, pm.height()) );
+ }
+ d->maxtools->setPixmap( pm );
+ } else
+#endif
+ {
+ QPixmap pm(14,14);
+ pm.fill( color1 );
+ pm.setMask(pm.createHeuristicMask());
+ d->maxtools->setPixmap( pm );
+ }
+ d->menuId = b->insertItem( d->maxtools, -1, 0 );
+ }
+#endif
+}
+
+
+void QWorkspace::hideMaximizeControls()
+{
+#ifndef QT_NO_MENUBAR
+ if ( d->maxmenubar ) {
+ int mi = d->menuId;
+ if ( mi != -1 ) {
+ if ( d->maxmenubar->indexOf( mi ) != -1 )
+ d->maxmenubar->removeItem( mi );
+ d->maxtools = 0;
+ }
+ int ci = d->controlId;
+ if ( ci != -1 && d->maxmenubar->indexOf( ci ) != -1 )
+ d->maxmenubar->removeItem( ci );
+ }
+ d->maxcontrols = 0;
+ d->menuId = -1;
+ d->controlId = -1;
+#endif
+}
+
+/*!
+ Closes the child window that is currently active.
+
+ \sa closeAllWindows()
+*/
+void QWorkspace::closeActiveWindow()
+{
+ setUpdatesEnabled( FALSE );
+ if ( d->maxWindow && d->maxWindow->windowWidget() )
+ d->maxWindow->windowWidget()->close();
+ else if ( d->active && d->active->windowWidget() )
+ d->active->windowWidget()->close();
+ setUpdatesEnabled( TRUE );
+ updateWorkspace();
+}
+
+/*!
+ Closes all child windows.
+
+ The windows are closed in random order. The operation stops if a
+ window does not accept the close event.
+
+ \sa closeActiveWindow()
+*/
+void QWorkspace::closeAllWindows()
+{
+ bool did_close = TRUE;
+ QPtrListIterator<QWorkspaceChild> it( d->windows );
+ QWorkspaceChild *c = 0;
+ while ( ( c = it.current() ) && did_close ) {
+ ++it;
+ if ( c->windowWidget() )
+ did_close = c->windowWidget()->close();
+ }
+}
+
+void QWorkspace::normalizeActiveWindow()
+{
+ if ( d->maxWindow )
+ d->maxWindow->showNormal();
+ else if ( d->active )
+ d->active->showNormal();
+}
+
+void QWorkspace::minimizeActiveWindow()
+{
+ if ( d->maxWindow )
+ d->maxWindow->showMinimized();
+ else if ( d->active )
+ d->active->showMinimized();
+}
+
+void QWorkspace::showOperationMenu()
+{
+ if ( !d->active || !d->active->windowWidget() )
+ return;
+ Q_ASSERT( d->active->windowWidget()->testWFlags( WStyle_SysMenu ) );
+ QPoint p;
+ QPopupMenu *popup = d->active->windowWidget()->testWFlags( WStyle_Tool ) ? d->toolPopup : d->popup;
+ if ( QApplication::reverseLayout() ) {
+ p = QPoint( d->active->windowWidget()->mapToGlobal( QPoint(d->active->windowWidget()->width(),0) ) );
+ p.rx() -= popup->sizeHint().width();
+ } else {
+ p = QPoint( d->active->windowWidget()->mapToGlobal( QPoint(0,0) ) );
+ }
+ if ( !d->active->isVisible() ) {
+ p = d->active->iconWidget()->mapToGlobal( QPoint(0,0) );
+ p.ry() -= popup->sizeHint().height();
+ }
+ popupOperationMenu( p );
+}
+
+void QWorkspace::popupOperationMenu( const QPoint& p)
+{
+ if ( !d->active || !d->active->windowWidget() || !d->active->windowWidget()->testWFlags( WStyle_SysMenu ) )
+ return;
+ if ( d->active->windowWidget()->testWFlags( WStyle_Tool ))
+ d->toolPopup->popup( p );
+ else
+ d->popup->popup( p );
+}
+
+void QWorkspace::operationMenuAboutToShow()
+{
+ for ( int i = 1; i < 6; i++ ) {
+ bool enable = d->active != 0;
+ d->popup->setItemEnabled( i, enable );
+ }
+
+ if ( !d->active || !d->active->windowWidget() )
+ return;
+
+ QWidget *windowWidget = d->active->windowWidget();
+ bool canResize = windowWidget->maximumSize() != windowWidget->minimumSize();
+ d->popup->setItemEnabled( 3, canResize );
+ d->popup->setItemEnabled( 4, windowWidget->testWFlags( WStyle_Minimize ) );
+ d->popup->setItemEnabled( 5, windowWidget->testWFlags( WStyle_Maximize ) && canResize );
+
+ if ( d->active == d->maxWindow ) {
+ d->popup->setItemEnabled( 2, FALSE );
+ d->popup->setItemEnabled( 3, FALSE );
+ d->popup->setItemEnabled( 5, FALSE );
+ } else if ( d->active->isVisible() ){
+ d->popup->setItemEnabled( 1, FALSE );
+ } else {
+ d->popup->setItemEnabled( 2, FALSE );
+ d->popup->setItemEnabled( 3, FALSE );
+ d->popup->setItemEnabled( 4, FALSE );
+ }
+}
+
+void QWorkspace::toolMenuAboutToShow()
+{
+ if ( !d->active || !d->active->windowWidget() )
+ return;
+
+ QWidget *windowWidget = d->active->windowWidget();
+ bool canResize = windowWidget->maximumSize() != windowWidget->minimumSize();
+
+ d->toolPopup->setItemEnabled( 3, !d->active->shademode && canResize );
+ if ( d->active->shademode )
+ d->toolPopup->changeItem( 6,
+ QIconSet(style().stylePixmap(QStyle::SP_TitleBarUnshadeButton)), tr("&Unshade") );
+ else
+ d->toolPopup->changeItem( 6, QIconSet(style().stylePixmap(QStyle::SP_TitleBarShadeButton)), tr("Sh&ade") );
+ d->toolPopup->setItemEnabled( 6, d->active->windowWidget()->testWFlags( WStyle_MinMax ) );
+ d->toolPopup->setItemChecked( 7, d->active->windowWidget()->testWFlags( WStyle_StaysOnTop ) );
+}
+
+void QWorkspace::operationMenuActivated( int a )
+{
+ if ( !d->active )
+ return;
+ switch ( a ) {
+ case 1:
+ d->active->showNormal();
+ break;
+ case 2:
+ d->active->doMove();
+ break;
+ case 3:
+ if ( d->active->shademode )
+ d->active->showShaded();
+ d->active->doResize();
+ break;
+ case 4:
+ d->active->showMinimized();
+ break;
+ case 5:
+ d->active->showMaximized();
+ break;
+ case 6:
+ d->active->showShaded();
+ break;
+ case 7:
+ {
+ QWorkspace* w = (QWorkspace*)d->active->windowWidget();
+ if ( !w )
+ break;
+ if ( w->testWFlags( WStyle_StaysOnTop ) ) {
+ w->clearWFlags( WStyle_StaysOnTop );
+ } else {
+ w->setWFlags( WStyle_StaysOnTop );
+ w->parentWidget()->raise();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ Activates the next window in the child window chain.
+
+ \sa activatePrevWindow()
+*/
+void QWorkspace::activateNextWindow()
+{
+ if ( d->focus.isEmpty() )
+ return;
+ if ( !d->active ) {
+ if ( d->focus.first() )
+ activateWindow( d->focus.first()->windowWidget(), FALSE );
+ return;
+ }
+
+ int a = d->focus.find( d->active ) + 1;
+
+ a = a % d->focus.count();
+
+ if ( d->focus.at( a ) )
+ activateWindow( d->focus.at( a )->windowWidget(), FALSE );
+ else
+ activateWindow(0);
+}
+
+void QWorkspace::activatePreviousWindow()
+{
+ activatePrevWindow();
+}
+
+/*!
+ Activates the previous window in the child window chain.
+
+ \sa activateNextWindow()
+*/
+void QWorkspace::activatePrevWindow()
+{
+ if ( d->focus.isEmpty() )
+ return;
+ if ( !d->active ) {
+ if ( d->focus.last() )
+ activateWindow( d->focus.first()->windowWidget(), FALSE );
+ else
+ activateWindow( 0 );
+
+ return;
+ }
+
+ int a = d->focus.find( d->active ) - 1;
+ if ( a < 0 )
+ a = d->focus.count()-1;
+
+ if ( d->focus.at( a ) )
+ activateWindow( d->focus.at( a )->windowWidget(), FALSE );
+ else
+ activateWindow( 0 );
+}
+
+
+/*!
+ \fn void QWorkspace::windowActivated( QWidget* w )
+
+ This signal is emitted when the window widget \a w becomes active.
+ Note that \a w can be null, and that more than one signal may be
+ emitted for a single activation event.
+
+ \sa activeWindow(), windowList()
+*/
+
+
+
+/*!
+ Arranges all the child windows in a cascade pattern.
+
+ \sa tile()
+*/
+void QWorkspace::cascade()
+{
+ blockSignals(TRUE);
+ if ( d->maxWindow )
+ d->maxWindow->showNormal();
+
+ if ( d->vbar ) {
+ d->vbar->blockSignals( TRUE );
+ d->vbar->setValue( 0 );
+ d->vbar->blockSignals( FALSE );
+ d->hbar->blockSignals( TRUE );
+ d->hbar->setValue( 0 );
+ d->hbar->blockSignals( FALSE );
+ scrollBarChanged();
+ }
+
+ const int xoffset = 13;
+ const int yoffset = 20;
+
+ // make a list of all relevant mdi clients
+ QPtrList<QWorkspaceChild> widgets;
+ QWorkspaceChild* wc = 0;
+ for ( wc = d->focus.first(); wc; wc = d->focus.next() )
+ if ( wc->windowWidget()->isVisibleTo( this ) && !wc->windowWidget()->testWFlags( WStyle_Tool ) && !wc->iconw )
+ widgets.append( wc );
+
+ int x = 0;
+ int y = 0;
+
+ setUpdatesEnabled( FALSE );
+ QPtrListIterator<QWorkspaceChild> it( widgets );
+ while ( it.current () ) {
+ QWorkspaceChild *child = it.current();
+ ++it;
+ child->setUpdatesEnabled( FALSE );
+ QSize prefSize = child->windowWidget()->sizeHint().expandedTo( child->windowWidget()->minimumSizeHint() );
+
+ if ( !prefSize.isValid() )
+ prefSize = child->windowWidget()->size();
+ prefSize = prefSize.expandedTo( child->windowWidget()->minimumSize() ).boundedTo( child->windowWidget()->maximumSize() );
+ if (prefSize.isValid())
+ prefSize += QSize( child->baseSize().width(), child->baseSize().height() );
+
+ int w = prefSize.width();
+ int h = prefSize.height();
+
+ child->showNormal();
+ qApp->sendPostedEvents( 0, QEvent::ShowNormal );
+ if ( y + h > height() )
+ y = 0;
+ if ( x + w > width() )
+ x = 0;
+ child->setGeometry( x, y, w, h );
+ x += xoffset;
+ y += yoffset;
+ child->internalRaise();
+ child->setUpdatesEnabled( TRUE );
+ }
+ setUpdatesEnabled( TRUE );
+ updateWorkspace();
+ blockSignals(FALSE);
+}
+
+/*!
+ Arranges all child windows in a tile pattern.
+
+ \sa cascade()
+*/
+void QWorkspace::tile()
+{
+ blockSignals(TRUE);
+ QWidget *oldActive = d->active ? d->active->windowWidget() : 0;
+ if ( d->maxWindow )
+ d->maxWindow->showNormal();
+
+ if ( d->vbar ) {
+ d->vbar->blockSignals( TRUE );
+ d->vbar->setValue( 0 );
+ d->vbar->blockSignals( FALSE );
+ d->hbar->blockSignals( TRUE );
+ d->hbar->setValue( 0 );
+ d->hbar->blockSignals( FALSE );
+ scrollBarChanged();
+ }
+
+ int rows = 1;
+ int cols = 1;
+ int n = 0;
+ QWorkspaceChild* c;
+
+ QPtrListIterator<QWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ c = it.current();
+ ++it;
+ if ( !c->windowWidget()->isHidden() &&
+ !c->windowWidget()->testWFlags( WStyle_StaysOnTop ) &&
+ !c->windowWidget()->testWFlags( WStyle_Tool ) &&
+ !c->iconw )
+ n++;
+ }
+
+ while ( rows * cols < n ) {
+ if ( cols <= rows )
+ cols++;
+ else
+ rows++;
+ }
+ int add = cols * rows - n;
+ bool* used = new bool[ cols*rows ];
+ for ( int i = 0; i < rows*cols; i++ )
+ used[i] = FALSE;
+
+ int row = 0;
+ int col = 0;
+ int w = width() / cols;
+ int h = height() / rows;
+
+ it.toFirst();
+ while ( it.current () ) {
+ c = it.current();
+ ++it;
+ if ( c->iconw || c->windowWidget()->isHidden() || c->windowWidget()->testWFlags( WStyle_Tool ) )
+ continue;
+ if (!row && !col) {
+ w -= c->baseSize().width();
+ h -= c->baseSize().height();
+ }
+ if ( c->windowWidget()->testWFlags( WStyle_StaysOnTop ) ) {
+ QPoint p = c->pos();
+ if ( p.x()+c->width() < 0 )
+ p.setX( 0 );
+ if ( p.x() > width() )
+ p.setX( width() - c->width() );
+ if ( p.y() + 10 < 0 )
+ p.setY( 0 );
+ if ( p.y() > height() )
+ p.setY( height() - c->height() );
+
+ if ( p != c->pos() )
+ c->QFrame::move( p );
+ } else {
+ c->showNormal();
+ qApp->sendPostedEvents( 0, QEvent::ShowNormal );
+ used[row*cols+col] = TRUE;
+ QSize sz(w, h);
+ QSize bsize(c->baseSize());
+ sz = sz.expandedTo(c->windowWidget()->minimumSize()).boundedTo(c->windowWidget()->maximumSize());
+ sz += bsize;
+
+ if ( add ) {
+ if (sz.height() == h + bsize.height()) // no relevant constrains
+ sz.rheight() *= 2;
+ c->setGeometry(col*w + col*bsize.width(), row*h + row*bsize.height(), sz.width(), sz.height());
+ used[(row+1)*cols+col] = TRUE;
+ add--;
+ } else {
+ c->setGeometry(col*w + col*bsize.width(), row*h + row*bsize.height(), sz.width(), sz.height());
+ }
+ while( row < rows && col < cols && used[row*cols+col] ) {
+ col++;
+ if ( col == cols ) {
+ col = 0;
+ row++;
+ }
+ }
+ }
+ }
+ delete [] used;
+
+ activateWindow( oldActive );
+ updateWorkspace();
+ blockSignals(FALSE);
+}
+
+QWorkspaceChild::QWorkspaceChild( QWidget* window, QWorkspace *parent,
+ const char *name )
+ : QFrame( parent, name,
+ (parent->windowMode() == QWorkspace::TopLevel ? (WStyle_MinMax | WStyle_SysMenu | WType_TopLevel) :
+ WStyle_NoBorder ) | WStyle_Customize | WDestructiveClose | WNoMousePropagation | WSubWindow )
+{
+ statusbar = 0;
+ setMouseTracking( TRUE );
+ act = FALSE;
+ iconw = 0;
+ lastfocusw = 0;
+ shademode = FALSE;
+ titlebar = 0;
+ snappedRight = FALSE;
+ snappedDown = FALSE;
+
+ if (window) {
+ switch (window->focusPolicy()) {
+ case QWidget::NoFocus:
+ window->setFocusPolicy(QWidget::ClickFocus);
+ break;
+ case QWidget::TabFocus:
+ window->setFocusPolicy(QWidget::StrongFocus);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ( window && window->testWFlags( WStyle_Title ) && parent->windowMode() != QWorkspace::TopLevel ) {
+ titlebar = new QTitleBar( window, this, "qt_ws_titlebar" );
+ connect( titlebar, SIGNAL( doActivate() ),
+ this, SLOT( activate() ) );
+ connect( titlebar, SIGNAL( doClose() ),
+ window, SLOT( close() ) );
+ connect( titlebar, SIGNAL( doMinimize() ),
+ this, SLOT( showMinimized() ) );
+ connect( titlebar, SIGNAL( doNormal() ),
+ this, SLOT( showNormal() ) );
+ connect( titlebar, SIGNAL( doMaximize() ),
+ this, SLOT( showMaximized() ) );
+ connect( titlebar, SIGNAL( popupOperationMenu(const QPoint&) ),
+ this, SIGNAL( popupOperationMenu(const QPoint&) ) );
+ connect( titlebar, SIGNAL( showOperationMenu() ),
+ this, SIGNAL( showOperationMenu() ) );
+ connect( titlebar, SIGNAL( doShade() ),
+ this, SLOT( showShaded() ) );
+ connect( titlebar, SIGNAL( doubleClicked() ),
+ this, SLOT( titleBarDoubleClicked() ) );
+ }
+
+ setFrameStyle( QFrame::StyledPanel | QFrame::Raised );
+ setLineWidth( style().pixelMetric(QStyle::PM_MDIFrameWidth, this) );
+ setMinimumSize( 128, 0 );
+
+ childWidget = window;
+ if (!childWidget)
+ return;
+
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ setCaption( childWidget->caption() );
+#endif
+
+ QPoint p;
+ QSize s;
+ QSize cs;
+
+ bool hasBeenResized = childWidget->testWState( WState_Resized );
+
+ if ( !hasBeenResized )
+ cs = childWidget->sizeHint().expandedTo( childWidget->minimumSizeHint() );
+ else
+ cs = childWidget->size();
+
+ int th = titlebar ? titlebar->sizeHint().height() : 0;
+ if ( titlebar ) {
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ int iconSize = th;
+ if( childWidget->icon() ) {
+ QPixmap pm(*childWidget->icon());
+ if(pm.width() > iconSize || pm.height() > iconSize) {
+ QImage im;
+ im = pm;
+ pm = im.smoothScale( QMIN(iconSize, pm.width()), QMIN(iconSize, pm.height()) );
+ }
+ titlebar->setIcon( pm );
+ }
+#endif
+ if ( !style().styleHint( QStyle::SH_TitleBar_NoBorder, titlebar ) )
+ th += frameWidth();
+ else
+ th -= contentsRect().y();
+
+ p = QPoint( contentsRect().x(),
+ th + contentsRect().y() );
+ s = QSize( cs.width() + 2*frameWidth(),
+ cs.height() + 2*frameWidth() + th );
+ } else {
+ p = QPoint( contentsRect().x(), contentsRect().y() );
+ s = QSize( cs.width() + 2*frameWidth(),
+ cs.height() + 2*frameWidth() );
+ }
+
+ childWidget->reparent( this, p);
+ resize( s );
+
+ childWidget->installEventFilter( this );
+
+ widgetResizeHandler = new QWidgetResizeHandler( this, window );
+ widgetResizeHandler->setSizeProtection( !parent->scrollBarsEnabled() );
+ connect( widgetResizeHandler, SIGNAL( activate() ),
+ this, SLOT( activate() ) );
+ if ( !style().styleHint( QStyle::SH_TitleBar_NoBorder, titlebar ) )
+ widgetResizeHandler->setExtraHeight( th + contentsRect().y() - 2*frameWidth() );
+ else
+ widgetResizeHandler->setExtraHeight( th + contentsRect().y() - frameWidth() );
+ if(parent->windowMode() == QWorkspace::TopLevel && isTopLevel()) {
+ move(0, 0);
+ widgetResizeHandler->setActive( FALSE );
+ }
+ if ( childWidget->minimumSize() == childWidget->maximumSize() )
+ widgetResizeHandler->setActive( QWidgetResizeHandler::Resize, FALSE );
+ setBaseSize( baseSize() );
+}
+
+QWorkspaceChild::~QWorkspaceChild()
+{
+ if ( iconw )
+ delete iconw->parentWidget();
+ QWorkspace *workspace = ::qt_cast<QWorkspace*>(parentWidget());
+ if ( workspace ) {
+ workspace->d->focus.removeRef(this);
+ if ( workspace->d->active == this ) {
+ workspace->activatePrevWindow();
+ if (workspace->d->active == this) {
+ workspace->activateWindow(0);
+ }
+ }
+ if ( workspace->d->maxWindow == this ) {
+ workspace->hideMaximizeControls();
+ workspace->d->maxWindow = 0;
+ }
+ }
+}
+
+bool QWorkspaceChild::event( QEvent *e )
+{
+ if(((QWorkspace*)parentWidget())->windowMode() == QWorkspace::TopLevel) {
+ switch(e->type()) {
+ case QEvent::Close:
+ if(windowWidget()) {
+ if(!windowWidget()->close()) {
+ if(((QWorkspace*) parentWidget() )->d->active == this)
+ ((QWorkspace*) parentWidget() )->activatePrevWindow();
+ return TRUE;
+ }
+ }
+ break;
+#if 0
+ case QEvent::WindowDeactivate:
+ if(statusbar) {
+ QSize newsize(width(), height() - statusbar->height());
+ if(statusbar->parentWidget() == this)
+ statusbar->hide();
+ statusbar = 0;
+ resize(newsize);
+ }
+ break;
+#endif
+ case QEvent::WindowActivate:
+ if(((QWorkspace*)parentWidget())->activeWindow() == windowWidget())
+ activate();
+ if(statusbar)
+ statusbar->show();
+ else if(((QWorkspace*) parentWidget() )->d->mainwindow)
+ setStatusBar(((QWorkspace*) parentWidget() )->d->mainwindow->statusBar());
+ break;
+ default:
+ break;
+ }
+ }
+ return QWidget::event(e);
+}
+
+void QWorkspaceChild::setStatusBar( QStatusBar *sb )
+{
+ if(((QWorkspace*) parentWidget() )->windowMode() == QWorkspace::TopLevel) {
+ QSize newsize;
+ if(sb) {
+ sb->show();
+ if(sb != statusbar) {
+ sb->reparent(this, QPoint(0, height()), TRUE);
+ newsize = QSize(width(), height() + sb->height());
+ }
+ }
+ statusbar = sb;
+ if(!newsize.isNull())
+ resize(newsize);
+ }
+}
+
+void QWorkspaceChild::moveEvent( QMoveEvent *e )
+{
+ if(((QWorkspace*) parentWidget() )->windowMode() == QWorkspace::TopLevel && !e->spontaneous()) {
+ QPoint p = parentWidget()->topLevelWidget()->pos();
+ if(x() < p.x() || y() < p.y())
+ move(QMAX(x(), p.x()), QMAX(y(), p.y()));
+ }
+ ((QWorkspace*) parentWidget() )->updateWorkspace();
+}
+
+void QWorkspaceChild::resizeEvent( QResizeEvent * )
+{
+ QRect r = contentsRect();
+ QRect cr;
+
+ if ( titlebar ) {
+ int th = titlebar->sizeHint().height();
+ QRect tbrect( 0, 0, width(), th );
+ if ( !style().styleHint( QStyle::SH_TitleBar_NoBorder ) )
+ tbrect = QRect( r.x(), r.y(), r.width(), th );
+ titlebar->setGeometry( tbrect );
+
+ if ( style().styleHint( QStyle::SH_TitleBar_NoBorder, titlebar ) )
+ th -= frameWidth();
+ cr = QRect( r.x(), r.y() + th + (shademode ? (frameWidth() * 3) : 0),
+ r.width(), r.height() - th );
+ } else {
+ cr = r;
+ }
+
+ if(statusbar && statusbar->isVisible()) {
+ int sh = statusbar->height();
+ statusbar->setGeometry(r.x(), r.bottom() - sh, r.width(), sh);
+ cr.setBottom(cr.bottom() - sh);
+ }
+
+ if (!childWidget)
+ return;
+
+ windowSize = cr.size();
+ childWidget->setGeometry( cr );
+ ((QWorkspace*) parentWidget() )->updateWorkspace();
+}
+
+QSize QWorkspaceChild::baseSize() const
+{
+ int th = titlebar ? titlebar->sizeHint().height() : 0;
+ if ( style().styleHint( QStyle::SH_TitleBar_NoBorder, titlebar ) )
+ th -= frameWidth();
+ return QSize( 2*frameWidth(), 2*frameWidth() + th );
+}
+
+QSize QWorkspaceChild::sizeHint() const
+{
+ if ( !childWidget )
+ return QFrame::sizeHint() + baseSize();
+
+ QSize prefSize = windowWidget()->sizeHint().expandedTo( windowWidget()->minimumSizeHint() );
+ prefSize = prefSize.expandedTo( windowWidget()->minimumSize() ).boundedTo( windowWidget()->maximumSize() );
+ prefSize += baseSize();
+
+ return prefSize;
+}
+
+QSize QWorkspaceChild::minimumSizeHint() const
+{
+ if ( !childWidget )
+ return QFrame::minimumSizeHint() + baseSize();
+ QSize s = childWidget->minimumSize();
+ if ( s.isEmpty() )
+ s = childWidget->minimumSizeHint();
+ return s + baseSize();
+}
+
+void QWorkspaceChild::activate()
+{
+ ((QWorkspace*)parentWidget())->activateWindow( windowWidget() );
+}
+
+bool QWorkspaceChild::eventFilter( QObject * o, QEvent * e)
+{
+ if ( !isActive() && ( e->type() == QEvent::MouseButtonPress ||
+ e->type() == QEvent::FocusIn ) ) {
+ if ( iconw ) {
+ ((QWorkspace*)parentWidget())->normalizeWindow( windowWidget() );
+ if ( iconw ) {
+ ((QWorkspace*)parentWidget())->removeIcon( iconw->parentWidget() );
+ delete iconw->parentWidget();
+ iconw = 0;
+ }
+ }
+ activate();
+ }
+
+ // for all widgets except the window, that's the only thing we
+ // process, and if we have no childWidget we skip totally
+ if ( o != childWidget || childWidget == 0 )
+ return FALSE;
+
+ switch ( e->type() ) {
+ case QEvent::Show:
+ if ( ((QWorkspace*)parentWidget())->d->focus.find( this ) < 0 )
+ ((QWorkspace*)parentWidget())->d->focus.append( this );
+ if ( isVisibleTo( parentWidget() ) )
+ break;
+ if (( (QShowEvent*)e)->spontaneous() )
+ break;
+ // fall through
+ case QEvent::ShowToParent:
+ if ( windowWidget() && windowWidget()->testWFlags( WStyle_StaysOnTop ) ) {
+ internalRaise();
+ show();
+ }
+ ((QWorkspace*)parentWidget())->showWindow( windowWidget() );
+ break;
+ case QEvent::ShowMaximized:
+ if ( windowWidget()->maximumSize().isValid() &&
+ ( windowWidget()->maximumWidth() < parentWidget()->width() ||
+ windowWidget()->maximumHeight() < parentWidget()->height() ) ) {
+ windowWidget()->resize( windowWidget()->maximumSize() );
+ ((QWorkspace*)windowWidget())->clearWState(WState_Maximized);
+ if (titlebar)
+ titlebar->repaint(FALSE);
+ break;
+ }
+ if ( windowWidget()->testWFlags( WStyle_Maximize ) && !windowWidget()->testWFlags( WStyle_Tool ) )
+ ((QWorkspace*)parentWidget())->maximizeWindow( windowWidget() );
+ else
+ ((QWorkspace*)parentWidget())->normalizeWindow( windowWidget() );
+ break;
+ case QEvent::ShowMinimized:
+ ((QWorkspace*)parentWidget())->minimizeWindow( windowWidget() );
+ break;
+ case QEvent::ShowNormal:
+ ((QWorkspace*)parentWidget())->normalizeWindow( windowWidget() );
+ if (iconw) {
+ ((QWorkspace*)parentWidget())->removeIcon( iconw->parentWidget() );
+ delete iconw->parentWidget();
+ }
+ break;
+ case QEvent::Hide:
+ case QEvent::HideToParent:
+ if ( !childWidget->isVisibleTo( this ) ) {
+ QWidget * w = iconw;
+ if ( w && ( w = w->parentWidget() ) ) {
+ ((QWorkspace*)parentWidget())->removeIcon( w );
+ delete w;
+ }
+ hide();
+ }
+ break;
+ case QEvent::CaptionChange:
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ setCaption( childWidget->caption() );
+ if ( iconw )
+ iconw->setCaption( childWidget->caption() );
+#endif
+ break;
+ case QEvent::IconChange:
+ {
+ QWorkspace* ws = (QWorkspace*)parentWidget();
+ if ( !titlebar )
+ break;
+
+ QPixmap pm;
+ int iconSize = titlebar->size().height();
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ if ( childWidget->icon() ) {
+ pm = *childWidget->icon();
+ if(pm.width() > iconSize || pm.height() > iconSize) {
+ QImage im;
+ im = pm;
+ pm = im.smoothScale( QMIN(iconSize, pm.width()), QMIN(iconSize, pm.height()) );
+ }
+ } else
+#endif
+ {
+ pm.resize( iconSize, iconSize );
+ pm.fill( color1 );
+ pm.setMask(pm.createHeuristicMask());
+ }
+ titlebar->setIcon( pm );
+ if ( iconw )
+ iconw->setIcon( pm );
+
+ if ( ws->d->maxWindow != this )
+ break;
+
+ if ( ws->d->maxtools )
+ ws->d->maxtools->setPixmap( pm );
+ }
+ break;
+ case QEvent::Resize:
+ {
+ QResizeEvent* re = (QResizeEvent*)e;
+ if ( re->size() != windowSize && !shademode )
+ resize( re->size() + baseSize() );
+ }
+ break;
+
+ case QEvent::WindowDeactivate:
+ if ( titlebar )
+ titlebar->setActive( FALSE );
+ repaint( FALSE );
+ break;
+
+ case QEvent::WindowActivate:
+ if ( titlebar )
+ titlebar->setActive( act );
+ repaint( FALSE );
+ break;
+
+ default:
+ break;
+ }
+
+ return QFrame::eventFilter(o, e);
+}
+
+bool QWorkspaceChild::focusNextPrevChild( bool next )
+{
+ QFocusData *f = focusData();
+
+ QWidget *startingPoint = f->home();
+ QWidget *candidate = 0;
+ QWidget *w = next ? f->next() : f->prev();
+ while( !candidate && w != startingPoint ) {
+ if ( w != startingPoint &&
+ (w->focusPolicy() & TabFocus) == TabFocus
+ && w->isEnabled() &&!w->focusProxy() && w->isVisible() )
+ candidate = w;
+ w = next ? f->next() : f->prev();
+ }
+
+ if ( candidate ) {
+ QObjectList *ol = queryList();
+ bool ischild = ol->findRef( candidate ) != -1;
+ delete ol;
+ if ( !ischild ) {
+ startingPoint = f->home();
+ QWidget *nw = next ? f->prev() : f->next();
+ QObjectList *ol2 = queryList();
+ QWidget *lastValid = 0;
+ candidate = startingPoint;
+ while ( nw != startingPoint ) {
+ if ( ( candidate->focusPolicy() & TabFocus ) == TabFocus
+ && candidate->isEnabled() &&!candidate->focusProxy() && candidate->isVisible() )
+ lastValid = candidate;
+ if ( ol2->findRef( nw ) == -1 ) {
+ candidate = lastValid;
+ break;
+ }
+ candidate = nw;
+ nw = next ? f->prev() : f->next();
+ }
+ delete ol2;
+ }
+ }
+
+ if ( !candidate )
+ return FALSE;
+
+ candidate->setFocus();
+ return TRUE;
+}
+
+void QWorkspaceChild::childEvent( QChildEvent* e)
+{
+ if ( e->type() == QEvent::ChildRemoved && e->child() == childWidget ) {
+ childWidget = 0;
+ if ( iconw ) {
+ ((QWorkspace*)parentWidget())->removeIcon( iconw->parentWidget() );
+ delete iconw->parentWidget();
+ }
+ close();
+ }
+}
+
+
+void QWorkspaceChild::doResize()
+{
+ widgetResizeHandler->doResize();
+}
+
+void QWorkspaceChild::doMove()
+{
+ widgetResizeHandler->doMove();
+}
+
+void QWorkspaceChild::enterEvent( QEvent * )
+{
+}
+
+void QWorkspaceChild::leaveEvent( QEvent * )
+{
+#ifndef QT_NO_CURSOR
+ if ( !widgetResizeHandler->isButtonDown() )
+ setCursor( arrowCursor );
+#endif
+}
+
+void QWorkspaceChild::drawFrame( QPainter *p )
+{
+ QStyle::SFlags flags = QStyle::Style_Default;
+ QStyleOption opt(lineWidth(),midLineWidth());
+
+ if ( titlebar && titlebar->isActive() )
+ flags |= QStyle::Style_Active;
+
+ style().drawPrimitive( QStyle::PE_WindowFrame, p, rect(), colorGroup(), flags, opt );
+}
+
+void QWorkspaceChild::styleChange( QStyle & )
+{
+ resizeEvent( 0 );
+ if ( iconw ) {
+ QVBox *vbox = (QVBox*)iconw->parentWidget()->qt_cast( "QVBox" );
+ Q_ASSERT(vbox);
+ if ( !style().styleHint( QStyle::SH_TitleBar_NoBorder ) ) {
+ vbox->setFrameStyle( QFrame::WinPanel | QFrame::Raised );
+ vbox->resize( 196+2*vbox->frameWidth(), 20 + 2*vbox->frameWidth() );
+ } else {
+ vbox->resize( 196, 20 );
+ }
+ }
+}
+
+void QWorkspaceChild::setActive( bool b )
+{
+ if ( !childWidget )
+ return;
+
+ bool hasFocus = isChildOf( focusWidget(), childWidget );
+ if ( act == b && hasFocus )
+ return;
+
+ act = b;
+
+ if ( titlebar )
+ titlebar->setActive( act );
+ if ( iconw )
+ iconw->setActive( act );
+ repaint( FALSE );
+
+ QObjectList* ol = childWidget->queryList( "QWidget" );
+ if ( act ) {
+ QObject *o;
+ for ( o = ol->first(); o; o = ol->next() )
+ o->removeEventFilter( this );
+ if ( !hasFocus ) {
+ if ( lastfocusw && ol->contains( lastfocusw ) &&
+ lastfocusw->focusPolicy() != NoFocus ) {
+ // this is a bug if lastfocusw has been deleted, a new
+ // widget has been created, and the new one is a child
+ // of the same window as the old one. but even though
+ // it's a bug the behaviour is reasonable
+ lastfocusw->setFocus();
+ } else if ( childWidget->focusPolicy() != NoFocus ) {
+ childWidget->setFocus();
+ } else {
+ // find something, anything, that accepts focus, and use that.
+ o = ol->first();
+ while( o && ((QWidget*)o)->focusPolicy() == NoFocus )
+ o = ol->next();
+ if ( o )
+ ((QWidget*)o)->setFocus();
+ }
+ }
+ } else {
+ if ( isChildOf( focusWidget(), childWidget ) )
+ lastfocusw = focusWidget();
+ QObject * o;
+ for ( o = ol->first(); o; o = ol->next() ) {
+ o->removeEventFilter( this );
+ o->installEventFilter( this );
+ }
+ }
+ delete ol;
+}
+
+bool QWorkspaceChild::isActive() const
+{
+ return act;
+}
+
+QWidget* QWorkspaceChild::windowWidget() const
+{
+ return childWidget;
+}
+
+
+QWidget* QWorkspaceChild::iconWidget() const
+{
+ if ( !iconw ) {
+ QWorkspaceChild* that = (QWorkspaceChild*) this;
+
+ // ### why do we even need the vbox? -Brad
+ QVBox* vbox = new QVBox(that, "qt_vbox", WType_TopLevel );
+ QTitleBar *tb = new QTitleBar( windowWidget(), vbox, "_workspacechild_icon_");
+ int th = style().pixelMetric( QStyle::PM_TitleBarHeight, tb );
+ int iconSize = style().pixelMetric( QStyle::PM_MDIMinimizedWidth, this );
+ if ( !style().styleHint( QStyle::SH_TitleBar_NoBorder ) ) {
+ vbox->setFrameStyle( QFrame::WinPanel | QFrame::Raised );
+ vbox->resize( iconSize+2*vbox->frameWidth(), th+2*vbox->frameWidth() );
+ } else {
+ vbox->resize( iconSize, th );
+ }
+ that->iconw = tb;
+ iconw->setActive( isActive() );
+
+ connect( iconw, SIGNAL( doActivate() ),
+ this, SLOT( activate() ) );
+ connect( iconw, SIGNAL( doClose() ),
+ windowWidget(), SLOT( close() ) );
+ connect( iconw, SIGNAL( doNormal() ),
+ this, SLOT( showNormal() ) );
+ connect( iconw, SIGNAL( doMaximize() ),
+ this, SLOT( showMaximized() ) );
+ connect( iconw, SIGNAL( popupOperationMenu(const QPoint&) ),
+ this, SIGNAL( popupOperationMenu(const QPoint&) ) );
+ connect( iconw, SIGNAL( showOperationMenu() ),
+ this, SIGNAL( showOperationMenu() ) );
+ connect( iconw, SIGNAL( doubleClicked() ),
+ this, SLOT( titleBarDoubleClicked() ) );
+ }
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ if ( windowWidget() ) {
+ iconw->setCaption( windowWidget()->caption() );
+ if ( windowWidget()->icon() ) {
+ int iconSize = iconw->sizeHint().height();
+
+ QPixmap pm(*childWidget->icon());
+ if(pm.width() > iconSize || pm.height() > iconSize) {
+ QImage im;
+ im = pm;
+ pm = im.smoothScale( QMIN(iconSize, pm.width()), QMIN(iconSize, pm.height()) );
+ }
+ iconw->setIcon( pm );
+ }
+ }
+#endif
+ return iconw->parentWidget();
+}
+
+void QWorkspaceChild::showMinimized()
+{
+ windowWidget()->setWindowState(WindowMinimized | windowWidget()->windowState());
+}
+
+void QWorkspaceChild::showMaximized()
+{
+ windowWidget()->setWindowState(WindowMaximized | (windowWidget()->windowState() & ~WindowMinimized));
+}
+
+void QWorkspaceChild::showNormal()
+{
+ windowWidget()->setWindowState(windowWidget()->windowState() & ~(WindowMinimized|WindowMaximized));
+}
+
+void QWorkspaceChild::showShaded()
+{
+ if ( !titlebar)
+ return;
+ Q_ASSERT( windowWidget()->testWFlags( WStyle_MinMax ) && windowWidget()->testWFlags( WStyle_Tool ) );
+ ((QWorkspace*)parentWidget())->activateWindow( windowWidget() );
+ if ( shademode ) {
+ QWorkspaceChild* fake = (QWorkspaceChild*)windowWidget();
+ fake->clearWState( WState_Minimized );
+ clearWState( WState_Minimized );
+
+ shademode = FALSE;
+ resize( shadeRestore );
+ setMinimumSize( shadeRestoreMin );
+ style().polish(this);
+ } else {
+ shadeRestore = size();
+ shadeRestoreMin = minimumSize();
+ setMinimumHeight(0);
+ shademode = TRUE;
+ QWorkspaceChild* fake = (QWorkspaceChild*)windowWidget();
+ fake->setWState( WState_Minimized );
+ setWState( WState_Minimized );
+
+ if ( style().styleHint( QStyle::SH_TitleBar_NoBorder ) )
+ resize( width(), titlebar->height() );
+ else
+ resize( width(), titlebar->height() + 2*lineWidth() + 1 );
+ style().polish(this);
+ }
+ titlebar->update();
+}
+
+void QWorkspaceChild::titleBarDoubleClicked()
+{
+ if ( !windowWidget() )
+ return;
+ if ( windowWidget()->testWFlags( WStyle_MinMax ) ) {
+ if ( windowWidget()->testWFlags( WStyle_Tool ) )
+ showShaded();
+ else if ( iconw )
+ showNormal();
+ else if ( windowWidget()->testWFlags( WStyle_Maximize ) )
+ showMaximized();
+ }
+}
+
+void QWorkspaceChild::adjustToFullscreen()
+{
+ if ( !childWidget )
+ return;
+
+ qApp->sendPostedEvents( this, QEvent::Resize );
+ qApp->sendPostedEvents( childWidget, QEvent::Resize );
+ qApp->sendPostedEvents( childWidget, QEvent::Move );
+ if( style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this) ) {
+ setGeometry( 0, 0, parentWidget()->width(), parentWidget()->height());
+ } else {
+ int w = parentWidget()->width() + width() - childWidget->width();
+ int h = parentWidget()->height() + height() - childWidget->height();
+ w = QMAX( w, childWidget->minimumWidth() );
+ h = QMAX( h, childWidget->minimumHeight() );
+ setGeometry( -childWidget->x(), -childWidget->y(), w, h );
+ }
+ setWState( WState_Maximized );
+ ((QWorkspaceChild*)childWidget)->setWState( WState_Maximized );
+}
+
+void QWorkspaceChild::setCaption( const QString& cap )
+{
+ if ( titlebar )
+ titlebar->setCaption( cap );
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ QWidget::setCaption( cap );
+#endif
+}
+
+void QWorkspaceChild::internalRaise()
+{
+ setUpdatesEnabled( FALSE );
+ if ( iconw )
+ iconw->parentWidget()->raise();
+ raise();
+
+ if ( !windowWidget() || windowWidget()->testWFlags( WStyle_StaysOnTop ) ) {
+ setUpdatesEnabled( TRUE );
+ return;
+ }
+
+ QPtrListIterator<QWorkspaceChild> it( ((QWorkspace*)parent())->d->windows );
+ while ( it.current () ) {
+ QWorkspaceChild* c = it.current();
+ ++it;
+ if ( c->windowWidget() &&
+ !c->windowWidget()->isHidden() &&
+ c->windowWidget()->testWFlags( WStyle_StaysOnTop ) )
+ c->raise();
+ }
+ setUpdatesEnabled( TRUE );
+}
+
+void QWorkspaceChild::move( int x, int y )
+{
+ int nx = x;
+ int ny = y;
+
+ if ( windowWidget() && windowWidget()->testWFlags( WStyle_Tool ) ) {
+ int dx = 10;
+ int dy = 10;
+
+ if ( QABS( x ) < dx )
+ nx = 0;
+ if ( QABS( y ) < dy )
+ ny = 0;
+ if ( QABS( x + width() - parentWidget()->width() ) < dx ) {
+ nx = parentWidget()->width() - width();
+ snappedRight = TRUE;
+ } else
+ snappedRight = FALSE;
+
+ if ( QABS( y + height() - parentWidget()->height() ) < dy ) {
+ ny = parentWidget()->height() - height();
+ snappedDown = TRUE;
+ } else
+ snappedDown = FALSE;
+ }
+ QFrame::move( nx, ny );
+}
+
+bool QWorkspace::scrollBarsEnabled() const
+{
+ return d->vbar != 0;
+}
+
+/*!
+ \property QWorkspace::scrollBarsEnabled
+ \brief whether the workspace provides scrollbars
+
+ If this property is set to TRUE, it is possible to resize child
+ windows over the right or the bottom edge out of the visible area
+ of the workspace. The workspace shows scrollbars to make it
+ possible for the user to access those windows. If this property is
+ set to FALSE (the default), resizing windows out of the visible
+ area of the workspace is not permitted.
+*/
+void QWorkspace::setScrollBarsEnabled( bool enable )
+{
+ if ( (d->vbar != 0) == enable )
+ return;
+
+ d->xoffset = d->yoffset = 0;
+ if ( enable ) {
+ d->vbar = new QScrollBar( Vertical, this, "vertical scrollbar" );
+ connect( d->vbar, SIGNAL( valueChanged(int) ), this, SLOT( scrollBarChanged() ) );
+ d->hbar = new QScrollBar( Horizontal, this, "horizontal scrollbar" );
+ connect( d->hbar, SIGNAL( valueChanged(int) ), this, SLOT( scrollBarChanged() ) );
+ d->corner = new QWidget( this, "qt_corner" );
+ updateWorkspace();
+ } else {
+ delete d->vbar;
+ delete d->hbar;
+ delete d->corner;
+ d->vbar = d->hbar = 0;
+ d->corner = 0;
+ }
+
+ QPtrListIterator<QWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ QWorkspaceChild *child = it.current();
+ ++it;
+ child->widgetResizeHandler->setSizeProtection( !enable );
+ }
+}
+
+QRect QWorkspace::updateWorkspace()
+{
+ if ( !isUpdatesEnabled() )
+ return rect();
+
+ QRect cr( rect() );
+
+ if ( scrollBarsEnabled() && !d->maxWindow ) {
+ d->corner->raise();
+ d->vbar->raise();
+ d->hbar->raise();
+ if ( d->maxWindow )
+ d->maxWindow->internalRaise();
+
+ QRect r( 0, 0, 0, 0 );
+ QPtrListIterator<QWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ QWorkspaceChild *child = it.current();
+ ++it;
+ if ( !child->isHidden() )
+ r = r.unite( child->geometry() );
+ }
+ d->vbar->blockSignals( TRUE );
+ d->hbar->blockSignals( TRUE );
+
+ int hsbExt = d->hbar->sizeHint().height();
+ int vsbExt = d->vbar->sizeHint().width();
+
+
+ bool showv = d->yoffset || d->yoffset + r.bottom() - height() + 1 > 0 || d->yoffset + r.top() < 0;
+ bool showh = d->xoffset || d->xoffset + r.right() - width() + 1 > 0 || d->xoffset + r.left() < 0;
+
+ if ( showh && !showv)
+ showv = d->yoffset + r.bottom() - height() + hsbExt + 1 > 0;
+ if ( showv && !showh )
+ showh = d->xoffset + r.right() - width() + vsbExt + 1 > 0;
+
+ if ( !showh )
+ hsbExt = 0;
+ if ( !showv )
+ vsbExt = 0;
+
+ if ( showv ) {
+ d->vbar->setSteps( QMAX( height() / 12, 30 ), height() - hsbExt );
+ d->vbar->setRange( QMIN( 0, d->yoffset + QMIN( 0, r.top() ) ), QMAX( 0, d->yoffset + QMAX( 0, r.bottom() - height() + hsbExt + 1) ) );
+ d->vbar->setGeometry( width() - vsbExt, 0, vsbExt, height() - hsbExt );
+ d->vbar->setValue( d->yoffset );
+ d->vbar->show();
+ } else {
+ d->vbar->hide();
+ }
+
+ if ( showh ) {
+ d->hbar->setSteps( QMAX( width() / 12, 30 ), width() - vsbExt );
+ d->hbar->setRange( QMIN( 0, d->xoffset + QMIN( 0, r.left() ) ), QMAX( 0, d->xoffset + QMAX( 0, r.right() - width() + vsbExt + 1) ) );
+ d->hbar->setGeometry( 0, height() - hsbExt, width() - vsbExt, hsbExt );
+ d->hbar->setValue( d->xoffset );
+ d->hbar->show();
+ } else {
+ d->hbar->hide();
+ }
+
+ if ( showh && showv ) {
+ d->corner->setGeometry( width() - vsbExt, height() - hsbExt, vsbExt, hsbExt );
+ d->corner->show();
+ } else {
+ d->corner->hide();
+ }
+
+ d->vbar->blockSignals( FALSE );
+ d->hbar->blockSignals( FALSE );
+
+ cr.setRect( 0, 0, width() - vsbExt, height() - hsbExt );
+ }
+
+ QPtrListIterator<QWidget> ii( d->icons );
+ while ( ii.current() ) {
+ QWorkspaceChild* w = (QWorkspaceChild*)ii.current();
+ ++ii;
+ int x = w->x();
+ int y = w->y();
+ bool m = FALSE;
+ if ( x+w->width() > cr.width() ) {
+ m = TRUE;
+ x = cr.width() - w->width();
+ }
+ if ( y+w->height() > cr.height() ) {
+ y = cr.height() - w->height();
+ m = TRUE;
+ }
+ if ( m )
+ w->move( x, y );
+ }
+
+ return cr;
+
+}
+
+void QWorkspace::scrollBarChanged()
+{
+ int ver = d->yoffset - d->vbar->value();
+ int hor = d->xoffset - d->hbar->value();
+ d->yoffset = d->vbar->value();
+ d->xoffset = d->hbar->value();
+
+ QPtrListIterator<QWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ QWorkspaceChild *child = it.current();
+ ++it;
+ // we do not use move() due to the reimplementation in QWorkspaceChild
+ child->setGeometry( child->x() + hor, child->y() + ver, child->width(), child->height() );
+ }
+ updateWorkspace();
+}
+
+/*!
+ \enum QWorkspace::WindowOrder
+
+ Specifies the order in which windows are returned from windowList().
+
+ \value CreationOrder The windows are returned in the order of their creation
+ \value StackingOrder The windows are returned in the order of their stacking
+*/
+
+#ifdef QT_WORKSPACE_WINDOWMODE
+/*!
+ \enum QWorkspace::WindowMode
+
+ Determines the Windowing Model QWorkspace will use for sub-windows.
+
+ \value TopLevel Subwindows are treated as toplevel windows
+ \value MDI Subwindows are organized in an MDI interface
+ \value AutoDetect QWorkspace will detect whether TopLevel or MDI
+ is appropriate
+*/
+
+/*!
+ The windowing model influences how the subwindows are actually
+ created. For most platforms the default behavior of a workspace is
+ to operate in MDI mode, with Qt/Mac the default mode is
+ AutoDetect.
+*/
+#else
+/*! \internal */
+#endif
+QWorkspace::WindowMode QWorkspace::windowMode() const
+{
+ return d->wmode;
+}
+
+#ifndef QT_NO_STYLE
+/*!\reimp */
+void QWorkspace::styleChange( QStyle &olds )
+{
+ int fs = style().styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this);
+ if ( isVisibleTo(0) && d->maxWindow &&
+ fs != olds.styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, this)) {
+ if( fs )
+ hideMaximizeControls();
+ else
+ showMaximizeControls();
+ }
+ QWidget::styleChange(olds);
+}
+#endif
+
+
+
+
+#include "qworkspace.moc"
+#endif // QT_NO_WORKSPACE