diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:17:53 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:17:53 -0500 |
commit | 37e3f157c7d76f13de807fa66e36df209e1005fb (patch) | |
tree | 7a4f131b2ee065337dac341bff34515310efba4f /experimental/tqtinterface/qt4/src/workspace | |
parent | 16630c3eff313238fa8412275555285c9195981b (diff) | |
download | tde-37e3f157c7d76f13de807fa66e36df209e1005fb.tar.gz tde-37e3f157c7d76f13de807fa66e36df209e1005fb.zip |
Added TQt4 HEAD
Diffstat (limited to 'experimental/tqtinterface/qt4/src/workspace')
3 files changed, 3209 insertions, 0 deletions
diff --git a/experimental/tqtinterface/qt4/src/workspace/qt_workspace.pri b/experimental/tqtinterface/qt4/src/workspace/qt_workspace.pri new file mode 100644 index 000000000..1e7469d6a --- /dev/null +++ b/experimental/tqtinterface/qt4/src/workspace/qt_workspace.pri @@ -0,0 +1,6 @@ +# Qt workspace module + +workspace { + HEADERS += $$WORKSPACE_H/tqworkspace.h + SOURCES += $$WORKSPACE_CPP/tqworkspace.cpp +} diff --git a/experimental/tqtinterface/qt4/src/workspace/tqworkspace.cpp b/experimental/tqtinterface/qt4/src/workspace/tqworkspace.cpp new file mode 100644 index 000000000..164a670ff --- /dev/null +++ b/experimental/tqtinterface/qt4/src/workspace/tqworkspace.cpp @@ -0,0 +1,3033 @@ +/**************************************************************************** +** +** Implementation of the TQWorkspace class +** +** Created : 931107 +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of the workspace module of the TQt 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 TQt 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.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** 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 "tqworkspace.h" +#ifndef TQT_NO_WORKSPACE +#include "tqapplication.h" +#include "../widgets/tqtitlebar_p.h" +#include "tqobjectlist.h" +#include "tqlayout.h" +#include "tqtoolbutton.h" +#include "tqlabel.h" +#include "tqvbox.h" +#include "tqaccel.h" +#include "tqcursor.h" +#include "tqpopupmenu.h" +#include "tqmenubar.h" +#include "tqguardedptr.h" +#include "tqiconset.h" +#include "../widgets/tqwidgetresizehandler_p.h" +#include "tqfocusdata.h" +#include "tqdatetime.h" +#include "tqtooltip.h" +#include "tqwmatrix.h" +#include "tqimage.h" +#include "tqscrollbar.h" +#include "tqstyle.h" +#include "tqbitmap.h" + +// magic non-mdi things +#include "tqtimer.h" +#include "tqdockarea.h" +#include "tqstatusbar.h" +#include "tqmainwindow.h" +#include "tqdockwindow.h" +#include "tqtoolbar.h" + +#define BUTTON_WIDTH 16 +#define BUTTON_HEIGHT 14 + +/*! + \class TQWorkspace tqworkspace.h + \brief The TQWorkspace 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 TQWorkspace. The workspace itself tqcontains zero, one or more + document windows, each of which is a widget. + + The workspace itself is an ordinary TQt widget. It has a standard + constructor that takes a tqparent widget and an object name. The + tqparent window is usually a TQMainWindow, but it need not be. + + Document windows (i.e. MDI windows) are also ordinary TQt widgets + which have the workspace as their tqparent 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 tqlayout of the decoration or the + behaviour of the widget itself. + + To change or retrieve the tqgeometry 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. + + TQWorkspace provides two built-in tqlayout strategies for child + windows: cascade() and tile(). Both are Q_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 tqcontains a menu bar and a document window + is maximised, TQWorkspace 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 TQWorkspaceChild : public TQFrame +{ + Q_OBJECT + TQ_OBJECT + + friend class TQWorkspace; + friend class TQTitleBar; + +public: + TQWorkspaceChild( TQWidget* window, + TQWorkspace* tqparent=0, const char* name=0 ); + ~TQWorkspaceChild(); + + void setActive( bool ); + bool isActive() const; + + void adjustToFullscreen(); + + void setqStatusBar(TQStatusBar *); + TQWidget* windowWidget() const; + TQWidget* iconWidget() const; + + void doResize(); + void doMove(); + + TQSize tqsizeHint() const; + TQSize tqminimumSizeHint() const; + + TQSize baseSize() const; + +Q_SIGNALS: + void showOperationMenu(); + void popupOperationMenu( const TQPoint& ); + +public Q_SLOTS: + void activate(); + void showMinimized(); + void showMaximized(); + void showNormal(); + void showShaded(); + void setCaption( const TQString& ); + void internalRaise(); + void titleBarDoubleClicked(); + + void move( int x, int y ); + +protected: + bool event(TQEvent * ); + void enterEvent( TQEvent * ); + void leaveEvent( TQEvent * ); + void childEvent( TQChildEvent* ); + void resizeEvent( TQResizeEvent * ); + void moveEvent( TQMoveEvent * ); + bool eventFilter( TQObject *, TQEvent * ); + + bool focusNextPrevChild( bool ); + + void drawFrame( TQPainter * ); + void styleChange( TQStyle & ); + +private: + TQWidget* childWidget; + TQGuardedPtr<TQWidget> lastfocusw; + TQWidgetResizeHandler *widgetResizeHandler; + TQTitleBar* titlebar; + TQGuardedPtr<TQStatusBar> statusbar; + TQGuardedPtr<TQTitleBar> iconw; + TQSize windowSize; + TQSize shadeRestore; + TQSize shadeRestoreMin; + bool act :1; + bool shademode :1; + bool snappedRight :1; + bool snappedDown :1; +#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator= + TQWorkspaceChild( const TQWorkspaceChild & ); + TQWorkspaceChild &operator=( const TQWorkspaceChild & ); +#endif +}; + +class TQMainWindow; + +class TQWorkspacePrivate { +public: + TQWorkspaceChild* active; + TQPtrList<TQWorkspaceChild> windows; + TQPtrList<TQWorkspaceChild> focus; + TQPtrList<TQWidget> icons; + TQWorkspaceChild* maxWindow; + TQRect maxRestore; + TQGuardedPtr<TQFrame> maxcontrols; + TQGuardedPtr<TQMenuBar> maxmenubar; + + int px; + int py; + TQWidget *becomeActive; + TQGuardedPtr<TQLabel> maxtools; + TQPopupMenu* popup; + TQPopupMenu* toolPopup; + int menuId; + int controlId; + TQString topCaption; + + TQScrollBar *vbar, *hbar; + TQWidget *corner; + int yoffset, xoffset; + + // toplevel mdi fu + TQWorkspace::WindowMode wmode; + TQGuardedPtr<TQMainWindow> mainwindow; + TQPtrList<TQDockWindow> dockwindows, newdocks; +}; + +static bool isChildOf( TQWidget * child, TQWidget * tqparent ) +{ + if ( !tqparent || !child ) + return FALSE; + TQWidget * w = child; + while( w && w != tqparent ) + w = w->parentWidget(); + return w != 0; +} + +/*! + Constructs a workspace with a \a tqparent and a \a name. +*/ +TQWorkspace::TQWorkspace( TQWidget *tqparent, const char *name ) + : TQWidget( tqparent, name ) +{ + init(); +} + +#ifdef TQT_WORKSPACE_WINDOWMODE +/*! + Constructs a workspace with a \a tqparent and a \a name. This + constructor will also set the WindowMode to \a mode. + + \sa windowMode() +*/ +TQWorkspace::TQWorkspace( TQWorkspace::WindowMode mode, TQWidget *tqparent, const char *name ) + : TQWidget( tqparent, name ) +{ + init(); + d->wmode = mode; +} +#endif + + +/*! + \internal +*/ +void +TQWorkspace::init() +{ + d = new TQWorkspacePrivate; + d->maxcontrols = 0; + d->active = 0; + d->maxWindow = 0; + d->maxtools = 0; + d->px = 0; + d->py = 0; + d->becomeActive = 0; +#if defined( TQT_WORKSPACE_WINDOWMODE ) && defined( TQ_WS_MAC ) + d->wmode = AutoDetect; +#else + d->wmode = MDI; +#endif + d->mainwindow = 0; +#if defined(TQ_WS_WIN) + d->popup = new TQPopupMenu( this, "qt_internal_mdi_popup" ); + d->toolPopup = new TQPopupMenu( this, "qt_internal_mdi_popup" ); +#else + d->popup = new TQPopupMenu( parentWidget(), "qt_internal_mdi_popup" ); + d->toolPopup = new TQPopupMenu( parentWidget(), "qt_internal_mdi_popup" ); +#endif + + d->menuId = -1; + d->controlId = -1; + connect( d->popup, TQT_SIGNAL( aboutToShow() ), this, TQT_SLOT(operationMenuAboutToShow() )); + connect( d->popup, TQT_SIGNAL( activated(int) ), this, TQT_SLOT( operationMenuActivated(int) ) ); + d->popup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarNormalButton)), tqtr("&Restore"), 1); + d->popup->insertItem(tqtr("&Move"), 2); + d->popup->insertItem(tqtr("&Size"), 3); + d->popup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarMinButton)), tqtr("Mi&nimize"), 4); + d->popup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarMaxButton)), tqtr("Ma&ximize"), 5); + d->popup->insertSeparator(); + d->popup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarCloseButton)), + TQT_TQSTRING(tqtr("&Close") +#ifndef TQT_NO_ACCEL + +"\t"+TQAccel::keyToString(TQt::CTRL+Qt::Key_F4) +#endif + ), TQT_TQOBJECT(this), TQT_SLOT( closeActiveWindow() ) ); + + connect( d->toolPopup, TQT_SIGNAL( aboutToShow() ), this, TQT_SLOT(toolMenuAboutToShow() )); + connect( d->toolPopup, TQT_SIGNAL( activated(int) ), this, TQT_SLOT( operationMenuActivated(int) ) ); + d->toolPopup->insertItem(tqtr("&Move"), 2); + d->toolPopup->insertItem(tqtr("&Size"), 3); + d->toolPopup->insertItem(tqtr("Stay on &Top"), 7); + d->toolPopup->setItemChecked( 7, TRUE ); + d->toolPopup->setCheckable( TRUE ); + d->toolPopup->insertSeparator(); + d->toolPopup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarShadeButton)), tqtr("Sh&ade"), 6); + d->toolPopup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarCloseButton)), + TQT_TQSTRING(tqtr("&Close") +#ifndef TQT_NO_ACCEL + +"\t"+TQAccel::keyToString( TQt::CTRL+Qt::Key_F4) +#endif + ), TQT_TQOBJECT(this), TQT_SLOT( closeActiveWindow() ) ); + +#ifndef TQT_NO_ACCEL + TQAccel* a = new TQAccel( this ); + a->connectItem( a->insertItem( TQt::ALT + Qt::Key_Minus), + this, TQT_SLOT( showOperationMenu() ) ); + + a->connectItem( a->insertItem( TQt::CTRL + Qt::Key_F6), + this, TQT_SLOT( activateNextWindow() ) ); + a->connectItem( a->insertItem( TQt::CTRL + Qt::Key_Tab), + this, TQT_SLOT( activateNextWindow() ) ); + a->connectItem( a->insertItem( Qt::Key_Forward ), + this, TQT_SLOT( activateNextWindow() ) ); + + a->connectItem( a->insertItem( TQt::CTRL + TQt::SHIFT + Qt::Key_F6), + this, TQT_SLOT( activatePreviousWindow() ) ); + a->connectItem( a->insertItem( TQt::CTRL + TQt::SHIFT + Qt::Key_Tab), + this, TQT_SLOT( activatePreviousWindow() ) ); + a->connectItem( a->insertItem( Qt::Key_Back ), + this, TQT_SLOT( activatePreviousWindow() ) ); + + a->connectItem( a->insertItem( TQt::CTRL + Qt::Key_F4 ), + this, TQT_SLOT( closeActiveWindow() ) ); +#endif + + setBackgroundMode( TQt::PaletteDark ); + tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) ); + +#ifndef TQT_NO_WIDGET_TOPEXTRA + d->topCaption = tqtopLevelWidget()->caption(); +#endif + + d->hbar = d->vbar = 0; + d->corner = 0; + d->xoffset = d->yoffset = 0; + + updateWorkspace(); + + tqtopLevelWidget()->installEventFilter( this ); +} + +/*! Destroys the workspace and frees any allocated resources. */ + +TQWorkspace::~TQWorkspace() +{ + delete d; + d = 0; +} + +/*!\reimp */ +TQSize TQWorkspace::tqsizeHint() const +{ + TQSize s( TQApplication::desktop()->size() ); + return TQSize( s.width()*2/3, s.height()*2/3); +} + +/*! \reimp */ +void TQWorkspace::setPaletteBackgroundColor( const TQColor & c ) +{ + setEraseColor( c ); +} + + +/*! \reimp */ +void TQWorkspace::setPaletteBackgroundPixmap( const TQPixmap & pm ) +{ + setErasePixmap( pm ); +} + +/*! \reimp */ +void TQWorkspace::childEvent( TQChildEvent * e) +{ + if (e->inserted() && e->child()->isWidgetType()) { + TQWidget* w = static_cast<TQWidget*>(static_cast<QWidget*>(e->child())); + if ( !w || !w->testWFlags( (WFlags)(TQt::WStyle_Title | TQt::WStyle_NormalBorder | TQt::WStyle_DialogBorder) ) || w->testWFlags(TQt::WType_Dialog) + || d->icons.tqcontains( 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( TQt::WState_Resized ); + int x = w->x(); + int y = w->y(); + bool hasPos = x != 0 || y != 0; + TQSize s = w->size().expandedTo( w->minimumSizeHint() ); + if ( !hasSize && w->sizeHint().isValid() ) { + w->adjustSize(); + } + + TQWorkspaceChild* child = new TQWorkspaceChild( w, this, "qt_workspacechild" ); + child->installEventFilter( this ); + + connect( child, TQT_SIGNAL( popupOperationMenu(const TQPoint&) ), + this, TQT_SLOT( popupOperationMenu(const TQPoint&) ) ); + connect( child, TQT_SIGNAL( showOperationMenu() ), + this, TQT_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.tqcontains( (TQWorkspaceChild*)e->child() ) ) { + d->windows.removeRef( (TQWorkspaceChild*)e->child() ); + d->focus.removeRef( (TQWorkspaceChild*)e->child() ); + if (d->maxWindow == e->child()) + d->maxWindow = 0; + updateWorkspace(); + } + } +} + +/*! \reimp +*/ +#ifndef TQT_NO_WHEELEVENT +void TQWorkspace::wheelEvent( TQWheelEvent *e ) +{ + if ( !scrollBarsEnabled() ) + return; + if ( d->vbar && d->vbar->isVisible() && !( e->state() & TQt::AltButton ) ) + TQApplication::sendEvent( d->vbar, e ); + else if ( d->hbar && d->hbar->isVisible() ) + TQApplication::sendEvent( d->hbar, e ); +} +#endif + +void TQWorkspace::activateWindow( TQWidget* 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( tqfocusWidget(), w ) ) // child window does not have focus + d->active->setActive( TRUE ); + return; + } + + d->active = 0; + // First deactivate all other workspace clients + TQPtrListIterator<TQWorkspaceChild> it( d->windows ); + while ( it.current () ) { + TQWorkspaceChild* c = it.current(); + ++it; + if(windowMode() == TQWorkspace::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( TQt::WStyle_MinMax ) && + !d->active->windowWidget()->testWFlags( TQt::WStyle_Tool ) ) { + d->active->showMaximized(); + if ( d->maxtools ) { +#ifndef TQT_NO_WIDGET_TOPEXTRA + if ( w->icon() ) { + TQPixmap pm(*w->icon()); + int iconSize = d->maxtools->size().height(); + if(pm.width() > iconSize || pm.height() > iconSize) { + TQImage im; + im = pm; + pm = im.smoothScale( TQMIN(iconSize, pm.width()), TQMIN(iconSize, pm.height()) ); + } + d->maxtools->setPixmap( pm ); + } else +#endif + { + TQPixmap pm(14,14); + pm.fill( Qt::color1 ); + pm.setMask(pm.createHeuristicMask()); + d->maxtools->setPixmap( pm ); + } + } + } else { // done implicitly in maximizeWindow otherwise + d->active->internalRaise(); + } + + if ( change_focus ) { + if ( d->focus.tqfind( 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. +*/ +TQWidget* TQWorkspace::activeWindow() const +{ + return d->active?d->active->windowWidget():0; +} + + +void TQWorkspace::place( TQWidget* w) +{ + TQPtrList<TQWidget> widgets; + for(TQPtrListIterator<TQWorkspaceChild> it( d->windows ); it.current(); ++it) + if ((*it) != w) + widgets.append((*it)); + + if(d->wmode == TopLevel) { + for(TQPtrListIterator<TQDockWindow> it( d->dockwindows ); it.current(); ++it) + if ((*it) != w) + widgets.append((*it)); + } + + int overlap, minOverlap = 0; + int possible; + + TQRect r1(0, 0, 0, 0); + TQRect r2(0, 0, 0, 0); + TQRect maxRect = rect(); + if(d->wmode == TopLevel) { + const TQDesktopWidget *dw = tqApp->desktop(); + maxRect = dw->availableGeometry(dw->screenNumber(tqtopLevelWidget())); + } + int x = maxRect.left(), y = maxRect.top(); + TQPoint 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()); + + TQWidget *l; + TQPtrListIterator<TQWidget> 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(TQMAX(r1.left(), r2.left()), + TQMAX(r1.top(), r2.top()), + TQMIN(r1.right(), r2.right()), + TQMIN(r1.bottom(), r2.bottom()) + ); + + overlap += (r2.right() - r2.left()) * + (r2.bottom() - r2.top()); + } + } + } + + if (overlap == 0) { + wpos = TQPoint(x, y); + break; + } + + if (firstPass) { + firstPass = FALSE; + minOverlap = overlap; + } else if ( overlap >= 0 && overlap < minOverlap) { + minOverlap = overlap; + wpos = TQPoint(x, y); + } + + if ( overlap > 0 ) { + possible = maxRect.right(); + if ( possible - w->width() > x) possible -= w->width(); + + TQWidget *l; + TQPtrListIterator<TQWidget> 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(); + + TQWidget *l; + TQPtrListIterator<TQWidget> 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() == TQWorkspace::TopLevel && wpos.y()) { + TQPoint fr = w->tqtopLevelWidget()->frameGeometry().topLeft(), + r = w->tqtopLevelWidget()->tqgeometry().topLeft(); + wpos += TQPoint(r.x() - fr.x(), r.y() - fr.y()); + } +#endif + w->move(wpos); + updateWorkspace(); +} + + +void TQWorkspace::insertIcon( TQWidget* w ) +{ + if ( !w || d->icons.tqcontains( w ) ) + return; + d->icons.append( w ); + if (w->parentWidget() != this ) + w->reparent( this, 0, TQPoint(0,0), FALSE); + TQRect cr = updateWorkspace(); + int x = 0; + int y = cr.height() - w->height(); + + TQPtrListIterator<TQWidget> it( d->icons ); + while ( it.current () ) { + TQWidget* i = it.current(); + ++it; + if ( x > 0 && x + i->width() > cr.width() ){ + x = 0; + y -= i->height(); + } + + if ( i != w && + i->tqgeometry().intersects( TQRect( x, y, w->width(), w->height() ) ) ) + x += i->width(); + } + w->move( x, y ); + + if ( isVisibleTo( parentWidget() ) ) { + w->show(); + w->lower(); + } + updateWorkspace(); +} + + +void TQWorkspace::removeIcon( TQWidget* w) +{ + if ( !d->icons.tqcontains( w ) ) + return; + d->icons.remove( w ); + w->hide(); +} + + +/*! \reimp */ +void TQWorkspace::resizeEvent( TQResizeEvent * ) +{ + if ( d->maxWindow ) { + d->maxWindow->adjustToFullscreen(); + if (d->maxWindow->windowWidget()) + ((TQWorkspace*)d->maxWindow->windowWidget())->setWState( TQt::WState_Maximized ); + } + + TQRect cr = updateWorkspace(); + + TQPtrListIterator<TQWorkspaceChild> it( d->windows ); + while ( it.current () ) { + TQWorkspaceChild* c = it.current(); + ++it; + if ( c->windowWidget() && !c->windowWidget()->testWFlags( TQt::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 TQWorkspace::handleUndock(TQDockWindow *w) +{ + const TQDesktopWidget *dw = tqApp->desktop(); + TQRect maxRect = dw->availableGeometry(dw->screenNumber(d->mainwindow)); + TQPoint wpos(maxRect.left(), maxRect.top()); + int possible = 0; + if(!::tqqt_cast<TQToolBar*>(w)) { + struct place_score { int o, x, y; } score = {0, 0, 0}; + int left = 1, x = wpos.x(), y = wpos.y(); + TQPtrListIterator<TQDockWindow> 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; + } + } + + TQDockWindow *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; + } + } + } + TQRect r2(x, y, w->width(), w->height()); + if(!nearest || !nearest->tqgeometry().intersects(r2)) { + wpos = TQPoint(x, y); //best possible outcome + possible = 2; + break; + } + + TQDockWindow *o = NULL; + int overlap = 0; + for( it.toFirst(); it.current(); ++it ) { + l = it.current(); + if ( l != w && l->tqgeometry().intersects(TQRect(TQPoint(x, y), w->size()))) { + overlap++; + o = l; + } + } + if(o && overlap == 1 && w->isVisible() && !o->isVisible()) { + wpos = TQPoint(x, y); + possible = 2; + while(d->dockwindows.remove(o)); + d->newdocks.append(o); + if(d->newdocks.count() == 1) + TQTimer::singleShot(0, this, TQT_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(); + + TQPoint 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->tqgeometry().intersects(TQRect(sc_pt, w->size()))) + sc.o++; + } + if(maxRect.tqcontains(TQRect(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(); + TQSize olds(w->size()); + if(w->place() == TQDockWindow::InDock) + w->undock(); + w->move(wpos); + w->resize(olds); + if(!ishidden) + w->show(); + else + w->hide(); +} + +void TQWorkspace::dockWindowsShow() +{ + TQPtrList<TQDockWindow> lst = d->newdocks; + d->newdocks.clear(); + for(TQPtrListIterator<TQDockWindow> dw_it(lst); (*dw_it); ++dw_it) { + if(d->dockwindows.tqfind((*dw_it)) != -1) + continue; + handleUndock((*dw_it)); + d->dockwindows.append((*dw_it)); + } +} + +/*! \reimp */ +void TQWorkspace::showEvent( TQShowEvent *e ) +{ + /* This is all magic, be carefull when playing with this code - this tries to allow people to + use TQWorkspace as a high level abstraction for window management, but removes enforcement that + TQWorkspace be used as an MDI. */ + if(d->wmode == AutoDetect) { + d->wmode = MDI; + TQWidget *o = tqtopLevelWidget(); + if(::tqqt_cast<TQMainWindow*>(o)) { + d->wmode = TopLevel; + for(TQObjectListIt it(o->childrenListObject()); it; ++it) { + if((*it)->isWidgetType() && !((TQWidget *)(*it))->isTopLevel() && + !::tqqt_cast<TQHBox*>(*it) && !::tqqt_cast<TQVBox*>(*it) && + !::tqqt_cast<TQWorkspaceChild*>(*it) && !(*it)->inherits("TQHideDock") && + !::tqqt_cast<TQDockArea*>(*it) && !::tqqt_cast<TQWorkspace*>(*it) && + !::tqqt_cast<TQMenuBar*>(*it) && !::tqqt_cast<TQStatusBar*>(*it)) { + d->wmode = MDI; + break; + } + } + } + } + if(d->wmode == TopLevel) { + TQWidget *o = tqtopLevelWidget(); + d->mainwindow = ::tqqt_cast<TQMainWindow*>(o); + const TQObjectList tqchildren = o->childrenListObject(); + for(TQObjectListIt it(tqchildren); it; ++it) { + if(!(*it)->isWidgetType()) + continue; + TQWidget *w = (TQWidget *)(*it); + if(w->isTopLevel()) + continue; + if(::tqqt_cast<TQDockArea*>(w)) { + if(!w->childrenListObject().isEmpty()) { + TQPtrList<TQToolBar> tb_list; + for(TQObjectListIt dock_it(w->childrenListObject()); dock_it; ++dock_it) { + if(!(*dock_it)->isWidgetType()) + continue; + if(::tqqt_cast<TQToolBar*>(*dock_it)) { + tb_list.append((TQToolBar *)(*dock_it)); + } else if (::tqqt_cast<TQDockWindow*>(*dock_it)) { + TQDockWindow *dw = (TQDockWindow*)(*dock_it); + dw->move(dw->mapToGlobal(TQPoint(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) { + TQToolBar *tb = tb_list.first(); + tb->move(0, 0); + d->newdocks.prepend(tb); + } else if(tb_list.count()) { + TQDockWindow *dw = new TQDockWindow(TQDockWindow::OutsideDock, + w->parentWidget(), + (TQString("TQMagicDock_") + w->name()).ascii()); + dw->installEventFilter(this); + dw->setResizeEnabled(TRUE); + dw->setCloseMode( TQDockWindow::Always ); + dw->setResizeEnabled(FALSE); +#ifndef TQT_NO_WIDGET_TOPEXTRA + dw->setCaption(o->caption()); +#endif + TQSize os(w->size()); + if(w->tqlayout() && w->tqlayout()->hasHeightForWidth()) { + w->tqlayout()->tqinvalidate(); + os.setHeight(w->tqlayout()->heightForWidth(os.width())); + } + if(!w->isHidden()) + dw->show(); + w->reparent(dw, TQPoint(0, 0)); + dw->setWidget(w); + dw->tqsetSizePolicy(TQSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum)); + dw->setGeometry(0, 0, os.width(), os.height() + dw->sizeHint().height()); + d->newdocks.prepend(dw); + ((TQDockArea*)w)->setAcceptDockWindow(dw, FALSE); + w->show(); + } + } + w->installEventFilter(this); + } else if(::tqqt_cast<TQStatusBar*>(w)) { + if(activeWindow()) { + TQWorkspaceChild *c; + if ( ( c = tqfindChild(activeWindow()) ) ) + c->setqStatusBar((TQStatusBar*)w); + } + } else if(::tqqt_cast<TQWorkspaceChild*>(w)) { + w->reparent(this, w->testWFlags((WFlags)((WFlags)(~(0))) | (WFlags)TQt::WType_TopLevel), w->pos()); + } + } + dockWindowsShow(); //now place and undock windows discovered + + TQWidget *w = new TQWidget(NULL, "TQDoesNotExist", + (WFlags)(TQt::WType_Dialog | WStyle_Customize | TQt::WStyle_NoBorder)); +// if(tqApp->mainWidget() == o) +// TQObject::connect(tqApp, TQT_SIGNAL(lastWindowClosed()), tqApp, TQT_SLOT(quit())); + TQDesktopWidget *dw = TQApplication::desktop(); + w->setGeometry(dw->availableGeometry(dw->screenNumber(o))); + o->reparent(w, TQPoint(0, 0), TRUE); + { + TQMenuBar *mb = 0; + if(::tqqt_cast<TQMainWindow*>(o)) + mb = ((TQMainWindow *)o)->menuBar(); + if(!mb) + mb = (TQMenuBar*)o->child(NULL, "TQMenuBar"); + if(mb) + mb->reparent(w, TQPoint(0, 0)); + } + reparent(w, TQPoint(0,0)); + setGeometry(0, 0, w->width(), w->height()); +#if 0 + /* Hide really isn't acceptable because I need to make the rest of TQt + think it is visible, so instead I set it to an empty tqmask. 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 TQt/Mac) */ +// w->setMask(TQRegion()); +// w->show(); +#else + w->hide(); +#endif + } + + //done with that nastiness, on with your regularly scheduled programming.. + if ( d->maxWindow && !tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this)) + showMaximizeControls(); + TQWidget::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 tqrepaint - this is a workaround for what seems to be a bug + // introduced when changing the TQWidget::show() implementation. Might be + // a windows bug as well though. + for (TQPtrListIterator<TQWorkspaceChild> it( d->windows ); it.current(); ++it ) { + TQWorkspaceChild* c = it.current(); + TQApplication::postEvent(c, new TQPaintEvent(c->rect(), TRUE)); + } + + updateWorkspace(); +} + +/*! \reimp */ +void TQWorkspace::hideEvent( TQHideEvent * ) +{ + if ( !isVisibleTo(0) && !tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this)) + hideMaximizeControls(); +} + +void TQWorkspace::minimizeWindow( TQWidget* w) +{ + TQWorkspaceChild* c = tqfindChild( w ); + + if ( !w || (w && (!w->testWFlags( TQt::WStyle_Minimize ) || w->testWFlags( TQt::WStyle_Tool) )) ) + return; + + if ( c ) { + TQWorkspace *fake = (TQWorkspace*)w; + + setUpdatesEnabled( FALSE ); + bool wasMax = FALSE; + if ( c == d->maxWindow ) { + wasMax = TRUE; + d->maxWindow = 0; + inCaptionChange = TRUE; +#ifndef TQT_NO_WIDGET_TOPEXTRA + if ( !!d->topCaption ) + tqtopLevelWidget()->setCaption( d->topCaption ); +#endif + inCaptionChange = FALSE; + if ( !tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this) ) + hideMaximizeControls(); + for (TQPtrListIterator<TQWorkspaceChild> it( d->windows ); it.current(); ++it ) { + TQWorkspaceChild* 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( TQt::WState_Maximized ); + fake->setWState( TQt::WState_Minimized ); + c->clearWState( TQt::WState_Maximized ); + c->setWState( TQt::WState_Minimized ); + } +} + +void TQWorkspace::normalizeWindow( TQWidget* w) +{ + TQWorkspaceChild* c = tqfindChild( w ); + if ( !w ) + return; + if ( c ) { + TQWorkspace *fake = (TQWorkspace*)w; + fake->clearWState( TQt::WState_Minimized | TQt::WState_Maximized ); + if ( !tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this) && d->maxWindow ) { + hideMaximizeControls(); + } else { + if ( w->tqminimumSize() != w->tqmaximumSize() ) + c->widgetResizeHandler->setActive( TRUE ); + if ( c->titlebar ) + c->titlebar->setMovable(TRUE); + } + fake->clearWState( TQt::WState_Minimized | TQt::WState_Maximized ); + c->clearWState( TQt::WState_Minimized | TQt::WState_Maximized ); + + if ( c == d->maxWindow ) { + c->setGeometry( d->maxRestore ); + d->maxWindow = 0; +#ifndef TQT_NO_WIDGET_TOPEXTRA + inCaptionChange = TRUE; + if ( !!d->topCaption ) + tqtopLevelWidget()->setCaption( d->topCaption ); + inCaptionChange = FALSE; +#endif + } else { + if ( c->iconw ) + removeIcon( c->iconw->parentWidget() ); + c->show(); + } + + if ( !tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this)) + hideMaximizeControls(); + for (TQPtrListIterator<TQWorkspaceChild> it( d->windows ); it.current(); ++it ) { + TQWorkspaceChild* c = it.current(); + if ( c->titlebar ) + c->titlebar->setMovable( TRUE ); + if ( c->childWidget && c->childWidget->tqminimumSize() != c->childWidget->tqmaximumSize() ) + c->widgetResizeHandler->setActive( TRUE ); + } + activateWindow( w, TRUE ); + updateWorkspace(); + } +} + +void TQWorkspace::maximizeWindow( TQWidget* w) +{ + TQWorkspaceChild* c = tqfindChild( w ); + + if ( !w || (w && (!w->testWFlags( TQt::WStyle_Maximize ) || w->testWFlags( TQt::WStyle_Tool) )) ) + return; + + if ( c ) { + setUpdatesEnabled( FALSE ); + if (c->iconw && d->icons.tqcontains( c->iconw->parentWidget() ) ) + normalizeWindow( w ); + TQWorkspace *fake = (TQWorkspace*)w; + + TQRect r( c->tqgeometry() ); + c->adjustToFullscreen(); + c->show(); + c->internalRaise(); + tqApp->sendPostedEvents( c, TQEvent::Resize ); + tqApp->sendPostedEvents( c, TQEvent::Move ); + tqApp->sendPostedEvents( c, TQEvent::ShowWindowRequest ); + if ( d->maxWindow != c ) { + if ( d->maxWindow ) + d->maxWindow->setGeometry( d->maxRestore ); + d->maxWindow = c; + d->maxRestore = r; + } + + activateWindow( w ); + if(!tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this)) { + showMaximizeControls(); + } else { + c->widgetResizeHandler->setActive( FALSE ); + if ( c->titlebar ) + c->titlebar->setMovable( FALSE ); + } +#ifndef TQT_NO_WIDGET_TOPEXTRA + inCaptionChange = TRUE; + if ( !!d->topCaption ) + tqtopLevelWidget()->setCaption( tqtr("%1 - [%2]") + .arg(d->topCaption).arg(c->caption()) ); + inCaptionChange = FALSE; +#endif + setUpdatesEnabled( TRUE ); + + updateWorkspace(); + + fake->clearWState( TQt::WState_Minimized ); + fake->setWState( TQt::WState_Maximized ); + c->clearWState( TQt::WState_Minimized ); + c->setWState( TQt::WState_Maximized ); + } +} + +void TQWorkspace::showWindow( TQWidget* w) +{ + if ( d->maxWindow && w->testWFlags( TQt::WStyle_Maximize ) && !w->testWFlags( TQt::WStyle_Tool) ) + maximizeWindow(w); + else if (w->isMinimized() && !w->testWFlags(TQt::WStyle_Tool)) + minimizeWindow(w); + else if ( !w->testWFlags( TQt::WStyle_Tool ) ) + normalizeWindow(w); + else + w->parentWidget()->show(); + if ( d->maxWindow ) + d->maxWindow->internalRaise(); + updateWorkspace(); +} + + +TQWorkspaceChild* TQWorkspace::tqfindChild( TQWidget* w) +{ + TQPtrListIterator<TQWorkspaceChild> it( d->windows ); + while ( it.current () ) { + TQWorkspaceChild* c = it.current(); + ++it; + if (c->windowWidget() == w) + return c; + } + return 0; +} + +/*! + \obsolete + \overload + */ +TQWidgetList TQWorkspace::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. + + TQWidgetList is the same as TQPtrList<TQWidget>. + + \sa TQPtrList +*/ +TQWidgetList TQWorkspace::windowList( WindowOrder order ) const +{ + TQWidgetList windows; + if ( order == StackingOrder ) { + if ( !childrenListObject().isEmpty() ) { + TQObjectListIt it( childrenListObject() ); + while (it.current()) { + TQObject *o = it.current(); + ++it; + TQWorkspaceChild *c = ::tqqt_cast<TQWorkspaceChild*>(o); + if (c && c->windowWidget()) + windows.append(c->windowWidget()); + } + } + } else { + TQPtrListIterator<TQWorkspaceChild> it( d->windows ); + while (it.current()) { + TQWorkspaceChild* c = it.current(); + ++it; + if ( c->windowWidget() ) + windows.append( c->windowWidget() ); + } + } + return windows; +} + +/*!\reimp*/ +bool TQWorkspace::eventFilter( TQObject *o, TQEvent * e) +{ + if(d->wmode == TopLevel && d->mainwindow && TQT_BASE_OBJECT(TQT_TQOBJECT(o)->tqparent()) == TQT_BASE_OBJECT(d->mainwindow)) { + if((e->type() == TQEvent::ChildInserted || e->type() == TQEvent::Reparent) && + ::tqqt_cast<TQDockArea*>(o) && !((TQWidget*)o)->isVisible()) { + TQChildEvent *ce = (TQChildEvent*)e; + if(!::tqqt_cast<TQDockWindow*>(ce->child())) { + qDebug("No idea what to do.."); + return FALSE; + } + TQDockWindow *w = (TQDockWindow*)ce->child(); + if(d->newdocks.tqfind(w) == -1 && d->dockwindows.tqfind(w) == -1) { + if(::tqqt_cast<TQToolBar*>(w)) + d->newdocks.prepend(w); + else + d->newdocks.append(w); + if(d->newdocks.count() == 1) + TQTimer::singleShot(0, this, TQT_SLOT(dockWindowsShow())); + } + } else if(e->type() == TQEvent::Hide && !e->spontaneous() && !tqstrncmp(o->name(), "TQMagicDock_", 11)) { +// d->mainwindow->close(); + } + return TQWidget::eventFilter(o, e); + } + + static TQTime* t = 0; + static TQWorkspace* tc = 0; +#ifndef TQT_NO_MENUBAR + if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->maxtools) && d->menuId != -1 ) { + switch ( e->type() ) { + case TQEvent::MouseButtonPress: + { + TQMenuBar* b = (TQMenuBar*)o->tqparent(); + if ( !t ) + t = new TQTime; + if ( tc != this || t->elapsed() > TQApplication::doubleClickInterval() ) { + if ( TQApplication::reverseLayout() ) { + TQPoint p = b->mapToGlobal( TQPoint( b->x() + b->width(), b->y() + b->height() ) ); + p.rx() -= d->popup->sizeHint().width(); + popupOperationMenu( p ); + } else { + popupOperationMenu( b->mapToGlobal( TQPoint( b->x(), b->y() + b->height() ) ) ); + } + t->start(); + tc = this; + } else { + tc = 0; + closeActiveWindow(); + } + return TRUE; + } + default: + break; + } + return TQWidget::eventFilter( o, e ); + } +#endif + switch ( e->type() ) { + case TQEvent::Hide: + case TQEvent::HideToParent: + if ( !o->isA( "TQWorkspaceChild" ) || !isVisible() || e->spontaneous() ) + break; + if ( TQT_BASE_OBJECT(d->active) == TQT_BASE_OBJECT(o) ) { + int a = d->focus.tqfind( d->active ); + if (a < 0) { + printf("[WARNING] In TQWorkspace TQEvent::HideToParent handler: Expected active window to be present in focus list but this was not the case! Avoiding infinite loop but the root cause of this problem should be repaired. d->focus.count(): %d\n\r", d->focus.count()); + break; + } + for ( ;; ) { + if ( --a < 0 ) + a = d->focus.count()-1; + TQWorkspaceChild* c = d->focus.at( a ); + if ( !c || TQT_BASE_OBJECT(c) == TQT_BASE_OBJECT(o) ) { + if ( c && c->iconw && d->icons.tqcontains( c->iconw->parentWidget() ) ) + break; + activateWindow( 0 ); + break; + } + if ( c->isShown() ) { + activateWindow( c->windowWidget(), FALSE ); + break; + } + } + } + d->focus.removeRef( (TQWorkspaceChild*)o ); + if ( TQT_BASE_OBJECT(d->maxWindow) == TQT_BASE_OBJECT(o) && d->maxWindow->isHidden() ) { + d->maxWindow->setGeometry( d->maxRestore ); + d->maxWindow = 0; + if ( d->active ) + maximizeWindow( d->active ); + + if ( !d->maxWindow ) { + + if ( tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this)) { + TQWorkspaceChild *wc = (TQWorkspaceChild *)o; + wc->widgetResizeHandler->setActive( TRUE ); + if ( wc->titlebar ) + wc->titlebar->setMovable( TRUE ); + } else { + hideMaximizeControls(); + } +#ifndef TQT_NO_WIDGET_TOPEXTRA + inCaptionChange = TRUE; + if ( !!d->topCaption ) + tqtopLevelWidget()->setCaption( d->topCaption ); + inCaptionChange = FALSE; +#endif + } + } + updateWorkspace(); + break; + case TQEvent::Show: + if ( o->isA("TQWorkspaceChild") && !d->focus.tqcontainsRef( (TQWorkspaceChild*)o ) ) { + d->focus.append( (TQWorkspaceChild*)o ); + } + updateWorkspace(); + break; + case TQEvent::CaptionChange: + if ( inCaptionChange ) + break; + +#ifndef TQT_NO_WIDGET_TOPEXTRA + inCaptionChange = TRUE; + if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(tqtopLevelWidget()) ) { + TQWidget *tlw = (TQWidget*)o; + if ( !d->maxWindow + || tlw->caption() != tqtr("%1 - [%2]").arg(d->topCaption).arg(d->maxWindow->caption()) ) + d->topCaption = tlw->caption(); + } + + if ( d->maxWindow && !!d->topCaption ) + tqtopLevelWidget()->setCaption( tqtr("%1 - [%2]") + .arg(d->topCaption).arg(d->maxWindow->caption())); + inCaptionChange = FALSE; +#endif + + break; + case TQEvent::Close: + if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(tqtopLevelWidget()) ) + { + TQPtrListIterator<TQWorkspaceChild> it( d->windows ); + while ( it.current () ) { + TQWorkspaceChild* c = it.current(); + ++it; + if ( c->shademode ) + c->showShaded(); + } + } else if ( ::tqqt_cast<TQWorkspaceChild*>(o) ) { + d->popup->hide(); + } + updateWorkspace(); + break; + default: + break; + } + return TQWidget::eventFilter( o, e); +} + +void TQWorkspace::showMaximizeControls() +{ +#ifndef TQT_NO_MENUBAR + TQ_ASSERT(d->maxWindow); + TQMenuBar* b = 0; + + // Do a breadth-first search first on every tqparent, + TQWidget* w = parentWidget(); + TQObjectList * l = 0; + while ( !l && w ) { + l = w->queryList( "TQMenuBar", 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 = tqtopLevelWidget()->queryList( "TQMenuBar", 0, 0, TRUE ); + } + if ( l && l->count() ) + b = (TQMenuBar *)l->first(); + delete l; + + if ( !b ) + return; + + if ( !d->maxcontrols ) { + d->maxmenubar = b; + d->maxcontrols = new TQFrame( tqtopLevelWidget(), "qt_maxcontrols" ); + TQHBoxLayout* l = new TQHBoxLayout( d->maxcontrols, + d->maxcontrols->frameWidth(), 0 ); + if ( d->maxWindow->windowWidget() && + d->maxWindow->windowWidget()->testWFlags(TQt::WStyle_Minimize) ) { + TQToolButton* iconB = new TQToolButton( d->maxcontrols, "iconify" ); +#ifndef TQT_NO_TOOLTIP + TQToolTip::add( iconB, tqtr( "Minimize" ) ); +#endif + l->addWidget( iconB ); + iconB->setFocusPolicy( Qt::NoFocus ); + iconB->setIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarMinButton)); + iconB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT); + connect( iconB, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( minimizeActiveWindow() ) ); + } + + TQToolButton* restoreB = new TQToolButton( d->maxcontrols, "restore" ); +#ifndef TQT_NO_TOOLTIP + TQToolTip::add( restoreB, tqtr( "Restore Down" ) ); +#endif + l->addWidget( restoreB ); + restoreB->setFocusPolicy( Qt::NoFocus ); + restoreB->setIconSet( tqstyle().stylePixmap(TQStyle::SP_TitleBarNormalButton)); + restoreB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT); + connect( restoreB, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( normalizeActiveWindow() ) ); + + l->addSpacing( 2 ); + TQToolButton* closeB = new TQToolButton( d->maxcontrols, "close" ); +#ifndef TQT_NO_TOOLTIP + TQToolTip::add( closeB, tqtr( "Close" ) ); +#endif + l->addWidget( closeB ); + closeB->setFocusPolicy( Qt::NoFocus ); + closeB->setIconSet( tqstyle().stylePixmap(TQStyle::SP_TitleBarCloseButton) ); + closeB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT); + connect( closeB, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( closeActiveWindow() ) ); + + d->maxcontrols->setFixedSize( d->maxcontrols->minimumSizeHint() ); + } + + if ( d->controlId == -1 || b->indexOf( d->controlId ) == -1 ) { + TQFrame* dmaxcontrols = d->maxcontrols; + d->controlId = b->insertItem( dmaxcontrols, -1, b->count() ); + } + if ( !d->active && d->becomeActive ) { + d->active = (TQWorkspaceChild*)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 TQLabel( tqtopLevelWidget(), "qt_maxtools" ); + d->maxtools->installEventFilter( this ); + } +#ifndef TQT_NO_WIDGET_TOPEXTRA + if ( d->active->windowWidget() && d->active->windowWidget()->icon() ) { +// TQPixmap pm(*d->active->windowWidget()->icon()); + TQPixmap pm(d->active->windowWidget()->windowIcon().pixmap(14,14)); // [FIXME] Is there any way around hardcoding this value??? + int iconSize = d->maxcontrols->size().height(); + if(pm.width() > iconSize || pm.height() > iconSize) { + TQImage im; + im = pm; + pm = im.smoothScale( TQMIN(iconSize, pm.width()), TQMIN(iconSize, pm.height()) ); + } + d->maxtools->setPixmap( pm ); + } else +#endif + { + TQPixmap pm(14,14); + pm.fill( Qt::color1 ); + pm.setMask(pm.createHeuristicMask()); + d->maxtools->setPixmap( pm ); + } + d->menuId = b->insertItem( d->maxtools, -1, 0 ); + } +#endif +} + + +void TQWorkspace::hideMaximizeControls() +{ +#ifndef TQT_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 TQWorkspace::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 TQWorkspace::closeAllWindows() +{ + bool did_close = TRUE; + TQPtrListIterator<TQWorkspaceChild> it( d->windows ); + TQWorkspaceChild *c = 0; + while ( ( c = it.current() ) && did_close ) { + ++it; + if ( c->windowWidget() ) + did_close = c->windowWidget()->close(); + } +} + +void TQWorkspace::normalizeActiveWindow() +{ + if ( d->maxWindow ) + d->maxWindow->showNormal(); + else if ( d->active ) + d->active->showNormal(); +} + +void TQWorkspace::minimizeActiveWindow() +{ + if ( d->maxWindow ) + d->maxWindow->showMinimized(); + else if ( d->active ) + d->active->showMinimized(); +} + +void TQWorkspace::showOperationMenu() +{ + if ( !d->active || !d->active->windowWidget() ) + return; + TQ_ASSERT( d->active->windowWidget()->testWFlags( TQt::WStyle_SysMenu ) ); + TQPoint p; + TQPopupMenu *popup = d->active->windowWidget()->testWFlags( TQt::WStyle_Tool ) ? d->toolPopup : d->popup; + if ( TQApplication::reverseLayout() ) { + p = TQPoint( d->active->windowWidget()->mapToGlobal( TQPoint(d->active->windowWidget()->width(),0) ) ); + p.rx() -= popup->sizeHint().width(); + } else { + p = TQPoint( d->active->windowWidget()->mapToGlobal( TQPoint(0,0) ) ); + } + if ( !d->active->isVisible() ) { + p = d->active->iconWidget()->mapToGlobal( TQPoint(0,0) ); + p.ry() -= popup->sizeHint().height(); + } + popupOperationMenu( p ); +} + +void TQWorkspace::popupOperationMenu( const TQPoint& p) +{ + if ( !d->active || !d->active->windowWidget() || !d->active->windowWidget()->testWFlags( TQt::WStyle_SysMenu ) ) + return; + if ( d->active->windowWidget()->testWFlags( TQt::WStyle_Tool )) + d->toolPopup->popup( p ); + else + d->popup->popup( p ); +} + +void TQWorkspace::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; + + TQWidget *windowWidget = d->active->windowWidget(); + bool canResize = windowWidget->tqmaximumSize() != windowWidget->tqminimumSize(); + d->popup->setItemEnabled( 3, canResize ); + d->popup->setItemEnabled( 4, windowWidget->testWFlags( TQt::WStyle_Minimize ) ); + d->popup->setItemEnabled( 5, windowWidget->testWFlags( TQt::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 TQWorkspace::toolMenuAboutToShow() +{ + if ( !d->active || !d->active->windowWidget() ) + return; + + TQWidget *windowWidget = d->active->windowWidget(); + bool canResize = windowWidget->tqmaximumSize() != windowWidget->tqminimumSize(); + + d->toolPopup->setItemEnabled( 3, !d->active->shademode && canResize ); + if ( d->active->shademode ) + d->toolPopup->changeItem( 6, + TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarUnshadeButton)), tqtr("&Unshade") ); + else + d->toolPopup->changeItem( 6, TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarShadeButton)), tqtr("Sh&ade") ); + d->toolPopup->setItemEnabled( 6, d->active->windowWidget()->testWFlags( TQt::WStyle_MinMax ) ); + d->toolPopup->setItemChecked( 7, d->active->windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) ); +} + +void TQWorkspace::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: + { + TQWorkspace* w = (TQWorkspace*)d->active->windowWidget(); + if ( !w ) + break; + if ( w->testWFlags( TQt::WStyle_StaysOnTop ) ) { + w->clearWFlags( TQt::WStyle_StaysOnTop ); + } else { + w->setWFlags( TQt::WStyle_StaysOnTop ); + w->parentWidget()->raise(); + } + } + break; + default: + break; + } +} + +/*! + Activates the next window in the child window chain. + + \sa activatePrevWindow() +*/ +void TQWorkspace::activateNextWindow() +{ + if ( d->focus.isEmpty() ) + return; + if ( !d->active ) { + if ( d->focus.first() ) { + activateWindow( d->focus.first()->windowWidget(), FALSE ); + } + return; + } + + int a = d->focus.tqfind( d->active ) + 1; + + a = a % d->focus.count(); + + if ( d->focus.at( a ) ) + activateWindow( d->focus.at( a )->windowWidget(), FALSE ); + else + activateWindow(0); +} + +void TQWorkspace::activatePreviousWindow() +{ + activatePrevWindow(); +} + +/*! + Activates the previous window in the child window chain. + + \sa activateNextWindow() +*/ +void TQWorkspace::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.tqfind( 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 TQWorkspace::windowActivated( TQWidget* 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 TQWorkspace::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 + TQPtrList<TQWorkspaceChild> widgets; + TQWorkspaceChild* wc = 0; + for ( wc = d->focus.first(); wc; wc = d->focus.next() ) + if ( wc->windowWidget()->isVisibleTo( this ) && !wc->windowWidget()->testWFlags( TQt::WStyle_Tool ) && !wc->iconw ) + widgets.append( wc ); + + int x = 0; + int y = 0; + + setUpdatesEnabled( FALSE ); + TQPtrListIterator<TQWorkspaceChild> it( widgets ); + while ( it.current () ) { + TQWorkspaceChild *child = it.current(); + ++it; + child->setUpdatesEnabled( FALSE ); + TQSize prefSize = child->windowWidget()->sizeHint().expandedTo( child->windowWidget()->minimumSizeHint() ); + + if ( !prefSize.isValid() ) + prefSize = child->windowWidget()->size(); + prefSize = prefSize.expandedTo( child->windowWidget()->tqminimumSize() ).boundedTo( child->windowWidget()->tqmaximumSize() ); + if (prefSize.isValid()) + prefSize += TQSize( child->baseSize().width(), child->baseSize().height() ); + + int w = prefSize.width(); + int h = prefSize.height(); + + child->showNormal(); + tqApp->sendPostedEvents( 0, TQEvent::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 TQWorkspace::tile() +{ + blockSignals(TRUE); + TQWidget *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; + TQWorkspaceChild* c; + + TQPtrListIterator<TQWorkspaceChild> it( d->windows ); + while ( it.current () ) { + c = it.current(); + ++it; + if ( !c->windowWidget()->isHidden() && + !c->windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) && + !c->windowWidget()->testWFlags( TQt::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( TQt::WStyle_Tool ) ) + continue; + if (!row && !col) { + w -= c->baseSize().width(); + h -= c->baseSize().height(); + } + if ( c->windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) ) { + TQPoint 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->TQFrame::move( p ); + } else { + c->showNormal(); + tqApp->sendPostedEvents( 0, TQEvent::ShowNormal ); + used[row*cols+col] = TRUE; + TQSize sz(w, h); + TQSize bsize(c->baseSize()); + sz = sz.expandedTo(c->windowWidget()->tqminimumSize()).boundedTo(c->windowWidget()->tqmaximumSize()); + 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); +} + +TQWorkspaceChild::TQWorkspaceChild( TQWidget* window, TQWorkspace *tqparent, + const char *name ) + : TQFrame( tqparent, name, + (WFlags)((tqparent->windowMode() == TQWorkspace::TopLevel ? (TQt::WStyle_MinMax | TQt::WStyle_SysMenu | TQt::WType_TopLevel) : + TQt::WStyle_NoBorder ) | WStyle_Customize | TQt::WDestructiveClose | TQt::WNoMousePropagation | TQt::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 Qt::NoFocus: + window->setFocusPolicy(Qt::ClickFocus); + break; + case Qt::TabFocus: + window->setFocusPolicy(Qt::StrongFocus); + break; + default: + break; + } + } + + if ( window && window->testWFlags( TQt::WStyle_Title ) && tqparent->windowMode() != TQWorkspace::TopLevel ) { + titlebar = new TQTitleBar( window, this, "qt_ws_titlebar" ); + connect( titlebar, TQT_SIGNAL( doActivate() ), + this, TQT_SLOT( activate() ) ); + connect( titlebar, TQT_SIGNAL( doClose() ), + window, TQT_SLOT( close() ) ); + connect( titlebar, TQT_SIGNAL( doMinimize() ), + this, TQT_SLOT( showMinimized() ) ); + connect( titlebar, TQT_SIGNAL( doNormal() ), + this, TQT_SLOT( showNormal() ) ); + connect( titlebar, TQT_SIGNAL( doMaximize() ), + this, TQT_SLOT( showMaximized() ) ); + connect( titlebar, TQT_SIGNAL( popupOperationMenu(const TQPoint&) ), + this, TQT_SIGNAL( popupOperationMenu(const TQPoint&) ) ); + connect( titlebar, TQT_SIGNAL( showOperationMenu() ), + this, TQT_SIGNAL( showOperationMenu() ) ); + connect( titlebar, TQT_SIGNAL( doShade() ), + this, TQT_SLOT( showShaded() ) ); + connect( titlebar, TQT_SIGNAL( doubleClicked() ), + this, TQT_SLOT( titleBarDoubleClicked() ) ); + } + + setFrameStyle( TQFrame::StyledPanel | TQFrame::Raised ); + setLineWidth( tqstyle().tqpixelMetric(TQStyle::PM_MDIFrameWidth, this) ); + setMinimumSize( 128, 0 ); + + childWidget = window; + if (!childWidget) + return; + +#ifndef TQT_NO_WIDGET_TOPEXTRA + setCaption( childWidget->caption() ); +#endif + + TQPoint p; + TQSize s; + TQSize cs; + + bool hasBeenResized = childWidget->testWState( TQt::WState_Resized ); + + if ( !hasBeenResized ) + cs = childWidget->sizeHint().expandedTo( childWidget->minimumSizeHint() ); + else + cs = childWidget->size(); + + int th = titlebar ? titlebar->sizeHint().height() : 0; + if ( titlebar ) { +#ifndef TQT_NO_WIDGET_TOPEXTRA + int iconSize = th; + if( childWidget->icon() ) { + TQPixmap pm(childWidget->iconPixmap()); + if(pm.width() > iconSize || pm.height() > iconSize) { + TQImage im; + im = pm; + pm = im.smoothScale( TQMIN(iconSize, pm.width()), TQMIN(iconSize, pm.height()) ); + } + titlebar->setIcon( pm ); + } +#endif + if ( !tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder, titlebar ) ) + th += frameWidth(); + else + th -= contentsRect().y(); + + p = TQPoint( contentsRect().x(), + th + contentsRect().y() ); + s = TQSize( cs.width() + 2*frameWidth(), + cs.height() + 2*frameWidth() + th ); + } else { + p = TQPoint( contentsRect().x(), contentsRect().y() ); + s = TQSize( cs.width() + 2*frameWidth(), + cs.height() + 2*frameWidth() ); + } + + childWidget->reparent( this, p); + resize( s ); + + childWidget->installEventFilter( this ); + + widgetResizeHandler = new TQWidgetResizeHandler( this, window ); + widgetResizeHandler->setSizeProtection( !tqparent->scrollBarsEnabled() ); + connect( widgetResizeHandler, TQT_SIGNAL( activate() ), + this, TQT_SLOT( activate() ) ); + if ( !tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder, titlebar ) ) + widgetResizeHandler->setExtraHeight( th + contentsRect().y() - 2*frameWidth() ); + else + widgetResizeHandler->setExtraHeight( th + contentsRect().y() - frameWidth() ); + if(tqparent->windowMode() == TQWorkspace::TopLevel && isTopLevel()) { + move(0, 0); + widgetResizeHandler->setActive( FALSE ); + } + if ( childWidget->tqminimumSize() == childWidget->tqmaximumSize() ) + widgetResizeHandler->setActive( TQWidgetResizeHandler::Resize, FALSE ); + setBaseSize( baseSize() ); +} + +TQWorkspaceChild::~TQWorkspaceChild() +{ + if ( iconw ) + delete iconw->parentWidget(); + TQWorkspace *workspace = ::tqqt_cast<TQWorkspace*>(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 TQWorkspaceChild::event( TQEvent *e ) +{ + if(((TQWorkspace*)parentWidget())->windowMode() == TQWorkspace::TopLevel) { + switch(e->type()) { + case TQEvent::Close: + if(windowWidget()) { + if(!windowWidget()->close()) { + if(((TQWorkspace*) parentWidget() )->d->active == this) + ((TQWorkspace*) parentWidget() )->activatePrevWindow(); + return TRUE; + } + } + break; +#if 0 + case TQEvent::WindowDeactivate: + if(statusbar) { + TQSize newsize(width(), height() - statusbar->height()); + if(statusbar->parentWidget() == this) + statusbar->hide(); + statusbar = 0; + resize(newsize); + } + break; +#endif + case TQEvent::WindowActivate: + if(((TQWorkspace*)parentWidget())->activeWindow() == windowWidget()) + activate(); + if(statusbar) + statusbar->show(); + else if(((TQWorkspace*) parentWidget() )->d->mainwindow) + setqStatusBar(((TQWorkspace*) parentWidget() )->d->mainwindow->statusBar()); + break; + default: + break; + } + } + return TQWidget::event(e); +} + +void TQWorkspaceChild::setqStatusBar( TQStatusBar *sb ) +{ + if(((TQWorkspace*) parentWidget() )->windowMode() == TQWorkspace::TopLevel) { + TQSize newsize; + if(sb) { + sb->show(); + if(sb != statusbar) { + sb->reparent(this, TQPoint(0, height()), TRUE); + newsize = TQSize(width(), height() + sb->height()); + } + } + statusbar = sb; + if(!newsize.isNull()) + resize(newsize); + } +} + +void TQWorkspaceChild::moveEvent( TQMoveEvent *e ) +{ + if(((TQWorkspace*) parentWidget() )->windowMode() == TQWorkspace::TopLevel && !e->spontaneous()) { + TQPoint p = parentWidget()->tqtopLevelWidget()->pos(); + if(x() < p.x() || y() < p.y()) + move(TQMAX(x(), p.x()), TQMAX(y(), p.y())); + } + ((TQWorkspace*) parentWidget() )->updateWorkspace(); +} + +void TQWorkspaceChild::resizeEvent( TQResizeEvent * ) +{ + TQRect r = contentsRect(); + TQRect cr; + + if ( titlebar ) { + int th = titlebar->sizeHint().height(); + TQRect tbrect( 0, 0, width(), th ); + if ( !tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder ) ) + tbrect = TQRect( r.x(), r.y(), r.width(), th ); + titlebar->setGeometry( tbrect ); + + if ( tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder, titlebar ) ) + th -= frameWidth(); + cr = TQRect( 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 ); + ((TQWorkspace*) parentWidget() )->updateWorkspace(); +} + +TQSize TQWorkspaceChild::baseSize() const +{ + int th = titlebar ? titlebar->sizeHint().height() : 0; + if ( tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder, titlebar ) ) + th -= frameWidth(); + return TQSize( 2*frameWidth(), 2*frameWidth() + th ); +} + +TQSize TQWorkspaceChild::tqsizeHint() const +{ + if ( !childWidget ) + return TQFrame::tqsizeHint() + baseSize(); + + TQSize prefSize = windowWidget()->sizeHint().expandedTo( windowWidget()->minimumSizeHint() ); + prefSize = prefSize.expandedTo( windowWidget()->tqminimumSize() ).boundedTo( windowWidget()->tqmaximumSize() ); + prefSize += baseSize(); + + return prefSize; +} + +TQSize TQWorkspaceChild::tqminimumSizeHint() const +{ + if ( !childWidget ) + return TQFrame::tqminimumSizeHint() + baseSize(); + TQSize s = childWidget->tqminimumSize(); + if ( s.isEmpty() ) + s = childWidget->minimumSizeHint(); + return s + baseSize(); +} + +void TQWorkspaceChild::activate() +{ + ((TQWorkspace*)parentWidget())->activateWindow( windowWidget() ); +} + +bool TQWorkspaceChild::eventFilter( TQObject * o, TQEvent * e) +{ + if ( !isActive() && ( e->type() == TQEvent::MouseButtonPress || + e->type() == TQEvent::FocusIn ) ) { + if ( iconw ) { + ((TQWorkspace*)parentWidget())->normalizeWindow( windowWidget() ); + if ( iconw ) { + ((TQWorkspace*)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 ( TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(childWidget) || childWidget == 0 ) + return FALSE; + + switch ( e->type() ) { + case TQEvent::Show: + if ( ((TQWorkspace*)parentWidget())->d->focus.tqfind( this ) < 0 ) + ((TQWorkspace*)parentWidget())->d->focus.append( this ); + if ( isVisibleTo( parentWidget() ) ) + break; + if (( (TQShowEvent*)e)->spontaneous() ) + break; + // fall through + case TQEvent::ShowToParent: + if ( windowWidget() && windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) ) { + internalRaise(); + show(); + } + ((TQWorkspace*)parentWidget())->showWindow( windowWidget() ); + break; + case TQEvent::ShowMaximized: + if ( windowWidget()->tqmaximumSize().isValid() && + ( windowWidget()->maximumWidth() < parentWidget()->width() || + windowWidget()->maximumHeight() < parentWidget()->height() ) ) { + windowWidget()->resize( windowWidget()->tqmaximumSize() ); + ((TQWorkspace*)windowWidget())->clearWState(TQt::WState_Maximized); + if (titlebar) + titlebar->tqrepaint(FALSE); + break; + } + if ( windowWidget()->testWFlags( TQt::WStyle_Maximize ) && !windowWidget()->testWFlags( TQt::WStyle_Tool ) ) + ((TQWorkspace*)parentWidget())->maximizeWindow( windowWidget() ); + else + ((TQWorkspace*)parentWidget())->normalizeWindow( windowWidget() ); + break; + case TQEvent::ShowMinimized: + ((TQWorkspace*)parentWidget())->minimizeWindow( windowWidget() ); + break; + case TQEvent::ShowNormal: + ((TQWorkspace*)parentWidget())->normalizeWindow( windowWidget() ); + if (iconw) { + ((TQWorkspace*)parentWidget())->removeIcon( iconw->parentWidget() ); + delete iconw->parentWidget(); + } + break; + case TQEvent::Hide: + case TQEvent::HideToParent: + if ( !childWidget->isVisibleTo( this ) ) { + TQWidget * w = iconw; + if ( w && ( w = w->parentWidget() ) ) { + ((TQWorkspace*)parentWidget())->removeIcon( w ); + delete w; + } + hide(); + } + break; + case TQEvent::CaptionChange: +#ifndef TQT_NO_WIDGET_TOPEXTRA + setCaption( childWidget->caption() ); + if ( iconw ) + iconw->setCaption( childWidget->caption() ); +#endif + break; + case TQEvent::IconChange: + { + TQWorkspace* ws = (TQWorkspace*)parentWidget(); + if ( !titlebar ) + break; + + TQPixmap pm; + int iconSize = titlebar->size().height(); +#ifndef TQT_NO_WIDGET_TOPEXTRA + if ( childWidget->icon() ) { + pm = *childWidget->icon(); + if(pm.width() > iconSize || pm.height() > iconSize) { + TQImage im; + im = pm; + pm = im.smoothScale( TQMIN(iconSize, pm.width()), TQMIN(iconSize, pm.height()) ); + } + } else +#endif + { + pm.resize( iconSize, iconSize ); + pm.fill( Qt::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 TQEvent::Resize: + { + TQResizeEvent* re = (TQResizeEvent*)e; + if ( re->size() != windowSize && !shademode ) + resize( re->size() + baseSize() ); + } + break; + + case TQEvent::WindowDeactivate: + if ( titlebar ) + titlebar->setActive( FALSE ); + tqrepaint( FALSE ); + break; + + case TQEvent::WindowActivate: + if ( titlebar ) + titlebar->setActive( act ); + tqrepaint( FALSE ); + break; + + default: + break; + } + + return TQFrame::eventFilter(o, e); +} + +bool TQWorkspaceChild::focusNextPrevChild( bool next ) +{ + TQFocusData *f = focusData(); + + TQWidget *startingPoint = f->home(); + TQWidget *candidate = 0; + TQWidget *w = next ? f->next() : f->prev(); + while( !candidate && w != startingPoint ) { + if ( w != startingPoint && + (w->focusPolicy() & Qt::TabFocus) == Qt::TabFocus + && w->isEnabled() &&!w->focusProxy() && w->isVisible() ) + candidate = w; + w = next ? f->next() : f->prev(); + } + + if ( candidate ) { + TQObjectList *ol = queryList(); + bool ischild = ol->tqfindRef( TQT_TQOBJECT(candidate) ) != -1; + delete ol; + if ( !ischild ) { + startingPoint = f->home(); + TQWidget *nw = next ? f->prev() : f->next(); + TQObjectList *ol2 = queryList(); + TQWidget *lastValid = 0; + candidate = startingPoint; + while ( nw != startingPoint ) { + if ( ( candidate->focusPolicy() & Qt::TabFocus ) == Qt::TabFocus + && candidate->isEnabled() &&!candidate->focusProxy() && candidate->isVisible() ) + lastValid = candidate; + if ( ol2->tqfindRef( TQT_TQOBJECT(nw) ) == -1 ) { + candidate = lastValid; + break; + } + candidate = nw; + nw = next ? f->prev() : f->next(); + } + delete ol2; + } + } + + if ( !candidate ) + return FALSE; + + candidate->setFocus(); + return TRUE; +} + +void TQWorkspaceChild::childEvent( TQChildEvent* e) +{ + if ( e->type() == TQEvent::ChildRemoved && e->child() == childWidget ) { + childWidget = 0; + if ( iconw ) { + ((TQWorkspace*)parentWidget())->removeIcon( iconw->parentWidget() ); + delete iconw->parentWidget(); + } + close(); + } +} + + +void TQWorkspaceChild::doResize() +{ + widgetResizeHandler->doResize(); +} + +void TQWorkspaceChild::doMove() +{ + widgetResizeHandler->doMove(); +} + +void TQWorkspaceChild::enterEvent( TQEvent * ) +{ +} + +void TQWorkspaceChild::leaveEvent( TQEvent * ) +{ +#ifndef TQT_NO_CURSOR + if ( !widgetResizeHandler->isButtonDown() ) + setCursor( Qt::ArrowCursor ); +#endif +} + +void TQWorkspaceChild::drawFrame( TQPainter *p ) +{ + TQStyle::SFlags flags = TQStyle::Style_Default; + TQStyleOption opt(lineWidth(),midLineWidth()); + + if ( titlebar && titlebar->isActive() ) + flags |= TQStyle::Style_Active; + + tqstyle().tqdrawPrimitive( TQStyle::PE_WindowFrame, p, rect(), tqcolorGroup(), flags, opt ); +} + +void TQWorkspaceChild::styleChange( TQStyle & ) +{ + resizeEvent( 0 ); + if ( iconw ) { + TQVBox *vbox = (TQVBox*)iconw->parentWidget()->tqqt_cast( "TQVBox" ); + TQ_ASSERT(vbox); + if ( !tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder ) ) { + vbox->setFrameStyle( TQFrame::WinPanel | TQFrame::Raised ); + vbox->resize( 196+2*vbox->frameWidth(), 20 + 2*vbox->frameWidth() ); + } else { + vbox->resize( 196, 20 ); + } + } +} + +void TQWorkspaceChild::setActive( bool b ) +{ + if ( !childWidget ) + return; + + bool hasFocus = isChildOf( tqfocusWidget(), childWidget ); + if ( act == b && hasFocus ) + return; + + act = b; + + if ( titlebar ) + titlebar->setActive( act ); + if ( iconw ) + iconw->setActive( act ); + tqrepaint( FALSE ); + + TQObjectList* ol = childWidget->queryList( "TQWidget" ); + if ( act ) { + TQObject *o; + for ( o = ol->first(); o; o = ol->next() ) + o->removeEventFilter( this ); + if ( !hasFocus ) { + if ( lastfocusw && ol->tqcontains( TQT_TQOBJECT(lastfocusw) ) && + lastfocusw->focusPolicy() != Qt::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() != Qt::NoFocus ) { + childWidget->setFocus(); + } else { + // tqfind something, anything, that accepts focus, and use that. + o = ol->first(); + while( o && ((TQWidget*)o)->focusPolicy() == Qt::NoFocus ) + o = ol->next(); + if ( o ) + ((TQWidget*)o)->setFocus(); + } + } + } else { + if ( isChildOf( tqfocusWidget(), childWidget ) ) + lastfocusw = tqfocusWidget(); + TQObject * o; + for ( o = ol->first(); o; o = ol->next() ) { + o->removeEventFilter( this ); + o->installEventFilter( this ); + } + } + delete ol; +} + +bool TQWorkspaceChild::isActive() const +{ + return act; +} + +TQWidget* TQWorkspaceChild::windowWidget() const +{ + return childWidget; +} + + +TQWidget* TQWorkspaceChild::iconWidget() const +{ + if ( !iconw ) { + TQWorkspaceChild* that = (TQWorkspaceChild*) this; + + // ### why do we even need the vbox? -Brad + TQVBox* vbox = new TQVBox(that, "qt_vbox", (WFlags)TQt::WType_TopLevel ); + TQTitleBar *tb = new TQTitleBar( windowWidget(), vbox, "_workspacechild_icon_"); + int th = tqstyle().tqpixelMetric( TQStyle::PM_TitleBarHeight, tb ); + int iconSize = tqstyle().tqpixelMetric( TQStyle::PM_MDIMinimizedWidth, this ); + if ( !tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder ) ) { + vbox->setFrameStyle( TQFrame::WinPanel | TQFrame::Raised ); + vbox->resize( iconSize+2*vbox->frameWidth(), th+2*vbox->frameWidth() ); + } else { + vbox->resize( iconSize, th ); + } + that->iconw = tb; + iconw->setActive( isActive() ); + + connect( iconw, TQT_SIGNAL( doActivate() ), + this, TQT_SLOT( activate() ) ); + connect( iconw, TQT_SIGNAL( doClose() ), + windowWidget(), TQT_SLOT( close() ) ); + connect( iconw, TQT_SIGNAL( doNormal() ), + this, TQT_SLOT( showNormal() ) ); + connect( iconw, TQT_SIGNAL( doMaximize() ), + this, TQT_SLOT( showMaximized() ) ); + connect( iconw, TQT_SIGNAL( popupOperationMenu(const TQPoint&) ), + this, TQT_SIGNAL( popupOperationMenu(const TQPoint&) ) ); + connect( iconw, TQT_SIGNAL( showOperationMenu() ), + this, TQT_SIGNAL( showOperationMenu() ) ); + connect( iconw, TQT_SIGNAL( doubleClicked() ), + this, TQT_SLOT( titleBarDoubleClicked() ) ); + } +#ifndef TQT_NO_WIDGET_TOPEXTRA + if ( windowWidget() ) { + iconw->setCaption( windowWidget()->caption() ); + if ( windowWidget()->icon() ) { + int iconSize = iconw->sizeHint().height(); + + TQPixmap pm(*childWidget->icon()); + if(pm.width() > iconSize || pm.height() > iconSize) { + TQImage im; + im = pm; + pm = im.smoothScale( TQMIN(iconSize, pm.width()), TQMIN(iconSize, pm.height()) ); + } + iconw->setIcon( pm ); + } + } +#endif + return iconw->parentWidget(); +} + +void TQWorkspaceChild::showMinimized() +{ + windowWidget()->setWindowState((WState)(TQt::WindowMinimized | windowWidget()->windowState())); +} + +void TQWorkspaceChild::showMaximized() +{ + windowWidget()->setWindowState((WState)(TQt::WindowMaximized | (windowWidget()->windowState() & ~TQt::WindowMinimized))); +} + +void TQWorkspaceChild::showNormal() +{ + windowWidget()->setWindowState((WState)(windowWidget()->windowState() & ~(TQt::WindowMinimized|TQt::WindowMaximized))); +} + +void TQWorkspaceChild::showShaded() +{ + if ( !titlebar) + return; + TQ_ASSERT( windowWidget()->testWFlags( TQt::WStyle_MinMax ) && windowWidget()->testWFlags( TQt::WStyle_Tool ) ); + ((TQWorkspace*)parentWidget())->activateWindow( windowWidget() ); + if ( shademode ) { + TQWorkspaceChild* fake = (TQWorkspaceChild*)windowWidget(); + fake->clearWState( TQt::WState_Minimized ); + clearWState( TQt::WState_Minimized ); + + shademode = FALSE; + resize( shadeRestore ); + setMinimumSize( shadeRestoreMin ); + tqstyle().polish(this); + } else { + shadeRestore = size(); + shadeRestoreMin = tqminimumSize(); + setMinimumHeight(0); + shademode = TRUE; + TQWorkspaceChild* fake = (TQWorkspaceChild*)windowWidget(); + fake->setWState( TQt::WState_Minimized ); + setWState( TQt::WState_Minimized ); + + if ( tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder ) ) + resize( width(), titlebar->height() ); + else + resize( width(), titlebar->height() + 2*lineWidth() + 1 ); + tqstyle().polish(this); + } + titlebar->update(); +} + +void TQWorkspaceChild::titleBarDoubleClicked() +{ + if ( !windowWidget() ) + return; + if ( windowWidget()->testWFlags( TQt::WStyle_MinMax ) ) { + if ( windowWidget()->testWFlags( TQt::WStyle_Tool ) ) + showShaded(); + else if ( iconw ) + showNormal(); + else if ( windowWidget()->testWFlags( TQt::WStyle_Maximize ) ) + showMaximized(); + } +} + +void TQWorkspaceChild::adjustToFullscreen() +{ + if ( !childWidget ) + return; + + tqApp->sendPostedEvents( this, TQEvent::Resize ); + tqApp->sendPostedEvents( childWidget, TQEvent::Resize ); + tqApp->sendPostedEvents( childWidget, TQEvent::Move ); + if( tqstyle().tqstyleHint(TQStyle::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 = TQMAX( w, childWidget->minimumWidth() ); + h = TQMAX( h, childWidget->minimumHeight() ); + setGeometry( -childWidget->x(), -childWidget->y(), w, h ); + } + setWState( TQt::WState_Maximized ); + ((TQWorkspaceChild*)childWidget)->setWState( TQt::WState_Maximized ); +} + +void TQWorkspaceChild::setCaption( const TQString& cap ) +{ + if ( titlebar ) + titlebar->setCaption( cap ); +#ifndef TQT_NO_WIDGET_TOPEXTRA + TQWidget::setCaption( cap ); +#endif +} + +void TQWorkspaceChild::internalRaise() +{ + setUpdatesEnabled( FALSE ); + if ( iconw ) + iconw->parentWidget()->raise(); + raise(); + + if ( !windowWidget() || windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) ) { + setUpdatesEnabled( TRUE ); + return; + } + + TQPtrListIterator<TQWorkspaceChild> it( ((TQWorkspace*)tqparent())->d->windows ); + while ( it.current () ) { + TQWorkspaceChild* c = it.current(); + ++it; + if ( c->windowWidget() && + !c->windowWidget()->isHidden() && + c->windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) ) + c->raise(); + } + setUpdatesEnabled( TRUE ); +} + +void TQWorkspaceChild::move( int x, int y ) +{ + int nx = x; + int ny = y; + + if ( windowWidget() && windowWidget()->testWFlags( TQt::WStyle_Tool ) ) { + int dx = 10; + int dy = 10; + + if ( TQABS( x ) < dx ) + nx = 0; + if ( TQABS( y ) < dy ) + ny = 0; + if ( TQABS( x + width() - parentWidget()->width() ) < dx ) { + nx = parentWidget()->width() - width(); + snappedRight = TRUE; + } else + snappedRight = FALSE; + + if ( TQABS( y + height() - parentWidget()->height() ) < dy ) { + ny = parentWidget()->height() - height(); + snappedDown = TRUE; + } else + snappedDown = FALSE; + } + TQFrame::move( nx, ny ); +} + +bool TQWorkspace::scrollBarsEnabled() const +{ + return d->vbar != 0; +} + +/*! + \property TQWorkspace::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 TQWorkspace::setScrollBarsEnabled( bool enable ) +{ + if ( (d->vbar != 0) == enable ) + return; + + d->xoffset = d->yoffset = 0; + if ( enable ) { + d->vbar = new TQScrollBar( Qt::Vertical, this, "vertical scrollbar" ); + connect( d->vbar, TQT_SIGNAL( valueChanged(int) ), this, TQT_SLOT( scrollBarChanged() ) ); + d->hbar = new TQScrollBar( Qt::Horizontal, this, "horizontal scrollbar" ); + connect( d->hbar, TQT_SIGNAL( valueChanged(int) ), this, TQT_SLOT( scrollBarChanged() ) ); + d->corner = new TQWidget( this, "qt_corner" ); + updateWorkspace(); + } else { + delete d->vbar; + delete d->hbar; + delete d->corner; + d->vbar = d->hbar = 0; + d->corner = 0; + } + + TQPtrListIterator<TQWorkspaceChild> it( d->windows ); + while ( it.current () ) { + TQWorkspaceChild *child = it.current(); + ++it; + child->widgetResizeHandler->setSizeProtection( !enable ); + } +} + +TQRect TQWorkspace::updateWorkspace() +{ + if ( !isUpdatesEnabled() ) + return rect(); + + TQRect cr( rect() ); + + if ( scrollBarsEnabled() && !d->maxWindow ) { + d->corner->raise(); + d->vbar->raise(); + d->hbar->raise(); + if ( d->maxWindow ) + d->maxWindow->internalRaise(); + + TQRect r( 0, 0, 0, 0 ); + TQPtrListIterator<TQWorkspaceChild> it( d->windows ); + while ( it.current () ) { + TQWorkspaceChild *child = it.current(); + ++it; + if ( !child->isHidden() ) + r = r.unite( child->tqgeometry() ); + } + 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( TQMAX( height() / 12, 30 ), height() - hsbExt ); + d->vbar->setRange( TQMIN( 0, d->yoffset + TQMIN( 0, r.top() ) ), TQMAX( 0, d->yoffset + TQMAX( 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( TQMAX( width() / 12, 30 ), width() - vsbExt ); + d->hbar->setRange( TQMIN( 0, d->xoffset + TQMIN( 0, r.left() ) ), TQMAX( 0, d->xoffset + TQMAX( 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 ); + } + + TQPtrListIterator<TQWidget> ii( d->icons ); + while ( ii.current() ) { + TQWorkspaceChild* w = (TQWorkspaceChild*)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 TQWorkspace::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(); + + TQPtrListIterator<TQWorkspaceChild> it( d->windows ); + while ( it.current () ) { + TQWorkspaceChild *child = it.current(); + ++it; + // we do not use move() due to the reimplementation in TQWorkspaceChild + child->setGeometry( child->x() + hor, child->y() + ver, child->width(), child->height() ); + } + updateWorkspace(); +} + +/*! + \enum TQWorkspace::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 TQT_WORKSPACE_WINDOWMODE +/*! + \enum TQWorkspace::WindowMode + + Determines the Windowing Model TQWorkspace will use for sub-windows. + + \value TopLevel Subwindows are treated as toplevel windows + \value MDI Subwindows are organized in an MDI interface + \value AutoDetect TQWorkspace 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 TQt/Mac the default mode is + AutoDetect. +*/ +#else +/*! \internal */ +#endif +TQWorkspace::WindowMode TQWorkspace::windowMode() const +{ + return d->wmode; +} + +#ifndef TQT_NO_STYLE +/*!\reimp */ +void TQWorkspace::styleChange( TQStyle &olds ) +{ + int fs = tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this); + if ( isVisibleTo(0) && d->maxWindow && + fs != olds.tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this)) { + if( fs ) + hideMaximizeControls(); + else + showMaximizeControls(); + } + TQWidget::styleChange(olds); +} +#endif + + + + +#include "tqworkspace.tqmoc" +#endif // TQT_NO_WORKSPACE diff --git a/experimental/tqtinterface/qt4/src/workspace/tqworkspace.h b/experimental/tqtinterface/qt4/src/workspace/tqworkspace.h new file mode 100644 index 000000000..2b128eca9 --- /dev/null +++ b/experimental/tqtinterface/qt4/src/workspace/tqworkspace.h @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Definition of the TQWorkspace class +** +** Created : 990210 +** +** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the workspace module of the TQt 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 TQt 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.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** 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. +** +**********************************************************************/ + +#ifndef TQWORKSPACE_H +#define TQWORKSPACE_H + +#ifndef TQT_H +#include "tqwidget.h" +#include "tqwidgetlist.h" +#endif // TQT_H + +#ifndef TQT_NO_WORKSPACE + +#if !defined( TQT_MODULE_WORKSPACE ) || defined( TQT_INTERNAL_WORKSPACE ) +#define TQM_EXPORT_WORKSPACE +#else +#define TQM_EXPORT_WORKSPACE TQ_EXPORT +#endif + +class TQWorkspaceChild; +class TQShowEvent; +class TQWorkspacePrivate; +class TQPopupMenu; +class TQDockWindow; + +class TQM_EXPORT_WORKSPACE TQWorkspace : public TQWidget +{ + Q_OBJECT + TQ_OBJECT + Q_PROPERTY( bool scrollBarsEnabled READ scrollBarsEnabled WRITE setScrollBarsEnabled ) + +#ifdef TQT_WORKSPACE_WINDOWMODE +public: +#endif + enum WindowMode { TopLevel, MDI, AutoDetect }; + WindowMode windowMode() const; +#ifdef TQT_WORKSPACE_WINDOWMODE +private: +#endif + +public: +#ifdef TQT_WORKSPACE_WINDOWMODE + TQWorkspace( WindowMode mode, TQWidget* tqparent=0, const char* name=0 ); +#endif + TQWorkspace( TQWidget* tqparent=0, const char* name=0 ); + + ~TQWorkspace(); + + enum WindowOrder { CreationOrder, StackingOrder }; + + TQWidget* activeWindow() const; + TQWidgetList windowList() const; // ### merge with below in 4.0 + TQWidgetList windowList( WindowOrder order ) const; + + TQSize tqsizeHint() const; + + bool scrollBarsEnabled() const; + void setScrollBarsEnabled( bool enable ); + + void setPaletteBackgroundColor( const TQColor & ); + void setPaletteBackgroundPixmap( const TQPixmap & ); + +Q_SIGNALS: + void windowActivated( TQWidget* w); + +public Q_SLOTS: + void cascade(); + void tile(); + void closeActiveWindow(); + void closeAllWindows(); + void activateNextWindow(); + void activatePrevWindow(); + +protected: +#ifndef TQT_NO_STYLE + void styleChange( TQStyle& ); +#endif + void childEvent( TQChildEvent * ); + void resizeEvent( TQResizeEvent * ); + bool eventFilter( TQObject *, TQEvent * ); + void showEvent( TQShowEvent *e ); + void hideEvent( TQHideEvent *e ); +#ifndef TQT_NO_WHEELEVENT + void wheelEvent( TQWheelEvent *e ); +#endif + +private Q_SLOTS: + void normalizeActiveWindow(); + void minimizeActiveWindow(); + void showOperationMenu(); + void popupOperationMenu( const TQPoint& ); + void operationMenuActivated( int ); + void operationMenuAboutToShow(); + void toolMenuAboutToShow(); + void activatePreviousWindow(); // ### remove in TQt 4.0 + void dockWindowsShow(); + void scrollBarChanged(); + +private: + void init(); + void handleUndock( TQDockWindow* w); + void insertIcon( TQWidget* w); + void removeIcon( TQWidget* w); + void place( TQWidget* ); + + TQWorkspaceChild* tqfindChild( TQWidget* w); + void showMaximizeControls(); + void hideMaximizeControls(); + void activateWindow( TQWidget* w, bool change_focus = TRUE ); + void showWindow( TQWidget* w); + void maximizeWindow( TQWidget* w); + void minimizeWindow( TQWidget* w); + void normalizeWindow( TQWidget* w); + + TQRect updateWorkspace(); + + TQPopupMenu* popup; + TQWorkspacePrivate* d; + + friend class TQWorkspacePrivate; + friend class TQWorkspaceChild; + +private: // Disabled copy constructor and operator= +#if defined(TQ_DISABLE_COPY) + TQWorkspace( const TQWorkspace & ); + TQWorkspace& operator=( const TQWorkspace & ); +#endif +}; + + +#endif // TQT_NO_WORKSPACE + +#endif // TQWORKSPACE_H |