diff options
Diffstat (limited to 'experimental/tqtinterface/qt4/src/widgets/tqwidgetstack.cpp')
-rw-r--r-- | experimental/tqtinterface/qt4/src/widgets/tqwidgetstack.cpp | 1183 |
1 files changed, 1183 insertions, 0 deletions
diff --git a/experimental/tqtinterface/qt4/src/widgets/tqwidgetstack.cpp b/experimental/tqtinterface/qt4/src/widgets/tqwidgetstack.cpp new file mode 100644 index 000000000..4bf824e59 --- /dev/null +++ b/experimental/tqtinterface/qt4/src/widgets/tqwidgetstack.cpp @@ -0,0 +1,1183 @@ +#include "tqtglobaldefines.h" + +#ifdef USE_QT4 + +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "tqwidgetstack.h" +#include "tqlayout.h" +#include "private/tqlayoutengine_p.h" +#include "Qt/qapplication.h" +#include "Qt/qpainter.h" + +QT_BEGIN_NAMESPACE + +using namespace Qt; + +class TQWidgetStackPrivate { +public: + class Invisible: public TQWidget + { + public: + Invisible(TQWidgetStack * parent): TQWidget(parent, "qt_invisible_widgetstack") + { + setBackgroundMode(TQt::NoBackground); + } + const char * className() const + { + return "TQWidgetStackPrivate::Invisible"; + } + protected: + void paintEvent(QPaintEvent *) + { + QPainter(this).eraseRect(rect()); + } + }; + + int nextNegativeID; + int nextPositiveID; +}; + + + +/*! + \class TQWidgetStack + \brief The TQWidgetStack class provides a stack of widgets of which + only the top widget is user-visible. + + \compat + + The application programmer can move any widget to the top of the + stack at any time using raiseWidget(), and add or remove widgets + using addWidget() and removeWidget(). It is not sufficient to pass + the widget stack as parent to a widget which should be inserted into + the widgetstack. + + visibleWidget() is the \e get equivalent of raiseWidget(); it + returns a pointer to the widget that is currently at the top of + the stack. + + TQWidgetStack also provides the ability to manipulate widgets + through application-specified integer IDs. You can also translate + from widget pointers to IDs using id() and from IDs to widget + pointers using widget(). These numeric IDs are unique (per + TQWidgetStack, not globally), but TQWidgetStack does not attach any + additional meaning to them. + + The default widget stack is frameless, but you can use the usual + TQFrame functions (such as setFrameStyle()) to add a frame. + + TQWidgetStack provides a signal, aboutToShow(), which is emitted + just before a managed widget is shown. + + \sa TQTabDialog QTabWidget QTabBar TQFrame +*/ + + +/*! + Constructs an empty widget stack. + + The \a parent, \a name and \a f arguments are passed to the TQFrame + constructor. +*/ +TQWidgetStack::TQWidgetStack(TQWidget * parent, const char *name, WFlags f) + : TQFrame(parent, name, f) //## merge constructors in 4.0 +{ + init(); +} + +void TQWidgetStack::init() +{ + d = new TQWidgetStackPrivate(); + d->nextNegativeID = -2; + d->nextPositiveID = 0; + dict = new TQIntDict<TQWidget>; + focusWidgets = 0; + topWidget = 0; + invisible = 0; + invisible = new TQWidgetStackPrivate::Invisible(this); + invisible->hide(); +} + + +/*! + Destroys the object and frees any allocated resources. +*/ + +TQWidgetStack::~TQWidgetStack() +{ + delete focusWidgets; + delete d; + delete dict; +} + + +/*! + Adds widget \a w to this stack of widgets, with ID \a id. + + If you pass an id \>= 0 this ID is used. If you pass an \a id of + -1 (the default), the widgets will be numbered automatically. If + you pass -2 a unique negative integer will be generated. No widget + has an ID of -1. Returns the ID or -1 on failure (e.g. \a w is 0). + + If you pass an id that is already used, then a unique negative + integer will be generated to prevent two widgets having the same + id. + + If \a w already exists in the stack the widget will be removed first. + + If \a w is not a child of this TQWidgetStack moves it using + reparent(). +*/ + +int TQWidgetStack::addWidget(TQWidget * w, int id) +{ + if (!w || w == invisible || invisible == 0) + return -1; + + // prevent duplicates + removeWidget(w); + + if (id >= 0 && dict->tqfind(id)) + id = -2; + if (id < -1) + id = d->nextNegativeID--; + else if (id == -1) + id = d->nextPositiveID++; + else + d->nextPositiveID = qMax(d->nextPositiveID, id + 1); + // use id >= 0 as-is + + dict->insert(id, w); + + // preserve existing focus + TQWidget * f = TQT_TQWIDGET(w->focusWidget()); + while(f && f != w) + f = TQT_TQWIDGET(f->parentWidget()); + if (f) { + if (!focusWidgets) + focusWidgets = new TQPtrDict<TQWidget>(17); + focusWidgets->tqreplace(w, TQT_TQWIDGET(w->focusWidget())); + } + + w->hide(); + if (w->parent() != this) + w->reparent(this, contentsRect().topLeft(), false); + w->setGeometry(contentsRect()); + updateGeometry(); + return id; +} + + +/*! + Removes widget \a w from this stack of widgets. Does not delete \a + w. If \a w is the currently visible widget, no other widget is + substituted. + + \sa visibleWidget() raiseWidget() +*/ + +void TQWidgetStack::removeWidget(TQWidget * w) +{ + int i; + if (!w || (i = id(w)) == -1) + return ; + + dict->take(i); + if (w == topWidget) + topWidget = 0; + if (dict->isEmpty()) + invisible->hide(); // let background shine through again + updateGeometry(); +} + + +/*! + Raises the widget with ID \a id to the top of the widget stack. + + \sa visibleWidget() +*/ + +void TQWidgetStack::raiseWidget(int id) +{ + if (id == -1) + return; + TQWidget * w = dict->tqfind(id); + if (w) + raiseWidget(w); +} + +static bool isChildOf(TQWidget* child, TQWidget *parent) +{ + if (!child) + return false; + for (int i = 0; i < parent->childrenListObject().count(); ++i) { + TQObject *obj = parent->childrenListObject().at(i); + if (!obj->isWidgetType()) + continue; + TQWidget *widget = TQT_TQWIDGET((QWidget*)obj); + if (!widget->isWindow()) + continue; + if (widget == child || isChildOf(child, widget)) + return true; + } + return false; +} + +/*! + \overload + + Raises widget \a w to the top of the widget stack. +*/ + +void TQWidgetStack::raiseWidget(TQWidget *w) +{ + if (!w || w == invisible || w->parent() != this || w == topWidget) + return; + + if (id(w) == -1) + addWidget(w); + if (!isVisible()) { + topWidget = w; + return; + } + + if (w->maximumSize().width() < invisible->width() + || w->maximumSize().height() < invisible->height()) + invisible->setBackgroundMode(backgroundMode()); + else if (invisible->backgroundMode() != TQt::NoBackground) + invisible->setBackgroundMode(TQt::NoBackground); + + if (invisible->isHidden()) { + invisible->setGeometry(contentsRect()); + invisible->lower(); + invisible->show(); + QApplication::sendPostedEvents(invisible, QEvent::ShowWindowRequest); + } + + // try to move focus onto the incoming widget if focus + // was somewhere on the outgoing widget. + if (topWidget) { + TQWidget * fw = TQT_TQWIDGET(window()->focusWidget()); + if (topWidget->isAncestorOf(fw)) { // focus was on old page + // look for the best focus widget we can find + TQWidget *p = TQT_TQWIDGET(w->focusWidget()); + if (!p) { + // second best == first child widget in the focus chain + TQWidget *i = fw; + while ((i = TQT_TQWIDGET(i->nextInFocusChain())) != fw) { + if (((i->focusPolicy() & Qt::TabFocus) == Qt::TabFocus) + && !i->focusProxy() && i->isVisibleTo(w) && i->isEnabled() + && w->isAncestorOf(i)) { + p = i; + break; + } + } + } + if (p) + p->setFocus(); + } else { + // the focus wasn't on the old page, so we have to ensure focus doesn't go to + // the widget in the page that last had focus when we show the page again. + TQWidget *oldfw = TQT_TQWIDGET(topWidget->focusWidget()); + if (oldfw) + oldfw->clearFocus(); + } + } + + if (isVisible()) { + emit aboutToShow(w); + int i = id(w); + if (i != -1) + emit aboutToShow(i); + } + + topWidget = w; + + for (int i = 0; i < childrenListObject().count(); ++i) { + TQObject * o = childrenListObject().at(i); + if (o->isWidgetType() && TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(w) && TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(invisible)) + TQT_TQWIDGET((QWidget*)o)->hide(); + } + + w->setGeometry(invisible->geometry()); + w->show(); +} + +/*! + \reimp +*/ + +void TQWidgetStack::frameChanged() +{ + TQFrame::frameChanged(); + setChildGeometries(); +} + + +/*! + \internal +*/ + +void TQWidgetStack::setFrameRect(const QRect & r) +{ + // ### this function used to be virtual in QFrame in Qt 3; it is no longer virtual in Qt 4 + TQFrame::setFrameRect(r); + setChildGeometries(); +} + + +/*! + Fixes up the children's geometries. +*/ + +void TQWidgetStack::setChildGeometries() +{ + invisible->setGeometry(contentsRect()); + if (topWidget) + topWidget->setGeometry(invisible->geometry()); +} + + +/*! + \reimp +*/ +void TQWidgetStack::setVisible(bool visible) +{ + if (visible) { + // Reimplemented in order to set the children's geometries + // appropriately and to pick the first widget as d->topWidget if no + // topwidget was defined + if (!isVisible() && !childrenListObject().isEmpty()) { + for (int i = 0; i < childrenListObject().count(); ++i) { + TQObject * o = childrenListObject().at(i); + if (o->isWidgetType()) { + if (!topWidget && TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(invisible)) + topWidget = TQT_TQWIDGET((QWidget*)o); + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(topWidget)) + TQT_TQWIDGET((QWidget*)o)->show(); + else + TQT_TQWIDGET((QWidget*)o)->hide(); + } + } + setChildGeometries(); + } + } + TQFrame::setVisible(visible); +} + + +/*! + Returns the widget with ID \a id. Returns 0 if this widget stack + does not manage a widget with ID \a id. + + \sa id() addWidget() +*/ + +TQWidget * TQWidgetStack::widget(int id) const +{ + return id != -1 ? dict->tqfind(id) : 0; +} + + +/*! + Returns the ID of the \a widget. Returns -1 if \a widget is 0 or + is not being managed by this widget stack. + + \sa widget() addWidget() +*/ + +int TQWidgetStack::id(TQWidget * widget) const +{ + if (!widget) + return -1; + + TQIntDictIterator<TQWidget> it(*dict); + while (it.current() && it.current() != widget) + ++it; + return it.current() == widget ? it.currentKey() : -1; +} + + +/*! + Returns the currently visible widget (the one at the top of the + stack), or 0 if nothing is currently being shown. + + \sa aboutToShow() id() raiseWidget() +*/ + +TQWidget * TQWidgetStack::visibleWidget() const +{ + return topWidget; +} + + +/*! + \fn void TQWidgetStack::aboutToShow(int id) + + This signal is emitted just before a managed widget is shown if + that managed widget has an ID != -1. The \a id parameter is the numeric + ID of the widget. + + If you call visibleWidget() in a slot connected to aboutToShow(), + the widget it returns is the one that is currently visible, not + the one that is about to be shown. +*/ + + +/*! + \fn void TQWidgetStack::aboutToShow(QWidget *widget) + + \overload + + This signal is emitted just before a managed widget is shown. The + argument is a pointer to the \a widget. + + If you call visibleWidget() in a slot connected to aboutToShow(), + the widget returned is the one that is currently visible, not the + one that is about to be shown. +*/ + + +/*! + \reimp +*/ + +void TQWidgetStack::resizeEvent(TQResizeEvent * e) +{ + TQFrame::resizeEvent(e); + setChildGeometries(); +} + +/*! + \reimp +*/ + +TQSize TQWidgetStack::tqsizeHint() const +{ + constPolish(); + + TQSize size(0, 0); + + TQIntDictIterator<TQWidget> it(*dict); + TQWidget *w; + + while ((w = it.current()) != 0) { + ++it; + TQSize sh = w->tqsizeHint(); + if (w->tqsizePolicy().horData() == QSizePolicy::Ignored) + sh.rwidth() = 0; + if (w->tqsizePolicy().verData() == QSizePolicy::Ignored) + sh.rheight() = 0; +#ifndef QT_NO_LAYOUT + size = size.expandedTo(sh).expandedTo(tqSmartMinSize(w)); +#endif + } + if (size.isNull()) + size = TQSize(128, 64); + size += TQSize(2*frameWidth(), 2*frameWidth()); + return size; +} + + +/*! + \reimp +*/ +TQSize TQWidgetStack::tqminimumSizeHint() const +{ + constPolish(); + + TQSize size(0, 0); + + TQIntDictIterator<TQWidget> it(*dict); + TQWidget *w; + + while ((w = it.current()) != 0) { + ++it; + TQSize sh = w->tqminimumSizeHint(); + if (w->tqsizePolicy().horData() == QSizePolicy::Ignored) + sh.rwidth() = 0; + if (w->tqsizePolicy().verData() == QSizePolicy::Ignored) + sh.rheight() = 0; +#ifndef QT_NO_LAYOUT + size = size.expandedTo(sh).expandedTo(w->minimumSize()); +#endif + } + if (size.isNull()) + size = TQSize(64, 32); + size += TQSize(2*frameWidth(), 2*frameWidth()); + return size; +} + +/*! + \reimp +*/ +void TQWidgetStack::childEvent(TQChildEvent *e) +{ + if (e->child()->isWidgetType() && e->removed()) + removeWidget((TQWidget *) e->child()); +} + + +/*! + \reimp +*/ +bool TQWidgetStack::event(TQEvent* e) +{ + if (e->type() == TQEvent::LayoutRequest || e->type() == TQEvent::LayoutHint ) + updateGeometry(); // propgate layout hints to parent + return TQFrame::event(e); +} + +QT_END_NAMESPACE + +#else // USE_QT4 + +/**************************************************************************** +** +** Implementation of TQWidgetStack class +** +** Created : 980128 +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of the widgets 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 "tqwidgetstack.h" +#include "tqlayout.h" +#include "../kernel/tqlayoutengine_p.h" +#ifndef TQT_NO_WIDGETSTACK + +#include "tqobjectlist.h" +#include "tqfocusdata.h" +#include "tqbutton.h" +#include "tqbuttongroup.h" + +#include "tqapplication.h" + +class TQWidgetStackPrivate { +public: + class Invisible: public TQWidget + { + public: + Invisible( TQWidgetStack * tqparent ): TQWidget( tqparent, "qt_invisible_widgetstack" ) + { + setBackgroundMode( TQt::NoBackground ); + } + const char * className() const + { + return "TQWidgetStackPrivate::Invisible"; + } + }; +}; + + +#if (TQT_VERSION-0 >= 0x040000) +#if defined(TQ_CC_GNU) +#warning "Remove TQWidgetStackEventFilter" +#endif +#endif +class TQWidgetStackEventFilter : public TQObject +{ + /* For binary compatibility, since we cannot implement virtual + functions and rely on them being called. This is what we should + have + + bool TQWidgetStack::event( TQEvent* e ) + { + if ( e->type() == TQEvent::LayoutHint ) + updateGeometry(); // propgate tqlayout hints to tqparent + return TQFrame::event( e ); + } + */ +public: + + TQWidgetStackEventFilter( TQObject *tqparent = 0, const char * name = 0 ) + : TQObject( tqparent, name ) {} + bool eventFilter( TQObject *o, TQEvent * e ) { + if ( e->type() == TQEvent::LayoutHint && o->isWidgetType() ) + ((TQWidget*)o)->updateGeometry(); + return FALSE; + } +}; + + +/*! + \class TQWidgetStack + \brief The TQWidgetStack class provides a stack of widgets of which + only the top widget is user-visible. + + \ingroup organizers + \mainclass + + The application programmer can move any widget to the top of the + stack at any time using raiseWidget(), and add or remove widgets + using addWidget() and removeWidget(). It is not sufficient to pass + the widget stack as tqparent to a widget which should be inserted into + the widgetstack. + + visibleWidget() is the \e get equivalent of raiseWidget(); it + returns a pointer to the widget that is currently at the top of + the stack. + + TQWidgetStack also provides the ability to manipulate widgets + through application-specified integer IDs. You can also translate + from widget pointers to IDs using id() and from IDs to widget + pointers using widget(). These numeric IDs are unique (per + TQWidgetStack, not globally), but TQWidgetStack does not attach any + additional meaning to them. + + The default widget stack is frameless, but you can use the usual + TQFrame functions (such as setFrameStyle()) to add a frame. + + TQWidgetStack provides a signal, aboutToShow(), which is emitted + just before a managed widget is shown. + + \sa TQTabDialog TQTabBar TQFrame +*/ + + +/*! + Constructs an empty widget stack. + + The \a tqparent and \a name arguments are passed to the TQFrame + constructor. +*/ + +TQWidgetStack::TQWidgetStack( TQWidget * tqparent, const char *name ) + : TQFrame( tqparent, name ) +{ + init(); +} + +/*! + Constructs an empty widget stack. + + The \a tqparent, \a name and \a f arguments are passed to the TQFrame + constructor. +*/ +TQWidgetStack::TQWidgetStack( TQWidget * tqparent, const char *name, WFlags f ) + : TQFrame( tqparent, name, f ) //## merge constructors in 4.0 +{ + init(); +} + +void TQWidgetStack::init() +{ + d = 0; + TQWidgetStackEventFilter *ef = new TQWidgetStackEventFilter( TQT_TQOBJECT(this) ); + installEventFilter( ef ); + dict = new TQIntDict<TQWidget>; + tqfocusWidgets = 0; + topWidget = 0; + invisible = new TQWidgetStackPrivate::Invisible( this ); + invisible->hide(); +} + + +/*! + Destroys the object and frees any allocated resources. +*/ + +TQWidgetStack::~TQWidgetStack() +{ + delete tqfocusWidgets; + delete d; + delete dict; +} + + +/*! + Adds widget \a w to this stack of widgets, with ID \a id. + + If you pass an id \>= 0 this ID is used. If you pass an \a id of + -1 (the default), the widgets will be numbered automatically. If + you pass -2 a unique negative integer will be generated. No widget + has an ID of -1. Returns the ID or -1 on failure (e.g. \a w is 0). + + If you pass an id that is already used, then a unique negative + integer will be generated to prevent two widgets having the same + id. + + If \a w already exists in the stack the widget will be removed first. + + If \a w is not a child of this TQWidgetStack moves it using + reparent(). +*/ + +int TQWidgetStack::addWidget( TQWidget * w, int id ) +{ + static int nseq_no = -2; + static int pseq_no = 0; + + if ( !w || w == invisible ) + return -1; + + // prevent duplicates + removeWidget( w ); + + if ( id >= 0 && dict->tqfind( id ) ) + id = -2; + if ( id < -1 ) + id = nseq_no--; + else if ( id == -1 ) + id = pseq_no++; + else + pseq_no = TQMAX(pseq_no, id + 1); + // use id >= 0 as-is + + dict->insert( id, w ); + + // preserve existing focus + TQWidget * f = w->tqfocusWidget(); + while( f && f != w ) + f = f->parentWidget(); + if ( f ) { + if ( !tqfocusWidgets ) + tqfocusWidgets = new TQPtrDict<TQWidget>( 17 ); + tqfocusWidgets->tqreplace( w, w->tqfocusWidget() ); + } + + w->hide(); + if ( w->tqparent() != TQT_TQOBJECT(this) ) + w->reparent( this, contentsRect().topLeft(), FALSE ); + w->setGeometry( contentsRect() ); + updateGeometry(); + return id; +} + + +/*! + Removes widget \a w from this stack of widgets. Does not delete \a + w. If \a w is the currently visible widget, no other widget is + substituted. + + \sa visibleWidget() raiseWidget() +*/ + +void TQWidgetStack::removeWidget( TQWidget * w ) +{ + if ( !w ) + return; + int i = id( w ); + if ( i != -1 ) + dict->take( i ); + + if ( w == topWidget ) + topWidget = 0; + if ( dict->isEmpty() ) + invisible->hide(); // let background shine through again + updateGeometry(); +} + + +/*! + Raises the widget with ID \a id to the top of the widget stack. + + \sa visibleWidget() +*/ + +void TQWidgetStack::raiseWidget( int id ) +{ + if ( id == -1 ) + return; + TQWidget * w = dict->tqfind( id ); + if ( w ) + raiseWidget( w ); +} + +static bool isChildOf( TQWidget* child, TQWidget *tqparent ) +{ + if ( !child || !tqparent->childrenListObject().isEmpty() ) + return FALSE; + TQObjectListIt it(tqparent->childrenListObject()); + TQObject *obj; + while ( (obj = it.current()) ) { + ++it; + if ( !obj->isWidgetType() || ((TQWidget *)obj)->isTopLevel() ) + continue; + TQWidget *widget = (TQWidget *)obj; + if ( widget == child || isChildOf( child, widget ) ) + return TRUE; + } + return FALSE; +} + +/*! + \overload + + Raises widget \a w to the top of the widget stack. +*/ + +void TQWidgetStack::raiseWidget( TQWidget *w ) +{ + if ( !w || w == invisible || w->tqparent() != TQT_TQOBJECT(this) || w == topWidget ) + return; + + if ( id(w) == -1 ) + addWidget( w ); + if ( !isVisible() ) { + topWidget = w; + return; + } + + if (w->tqmaximumSize().width() < invisible->width() + || w->tqmaximumSize().height() < invisible->height()) + invisible->setBackgroundMode(backgroundMode()); + else if (invisible->backgroundMode() != TQt::NoBackground) + invisible->setBackgroundMode(TQt::NoBackground); + + if ( invisible->isHidden() ) { + invisible->setGeometry( contentsRect() ); + invisible->lower(); + invisible->show(); + TQApplication::sendPostedEvents( invisible, TQEvent::ShowWindowRequest ); + } + + // try to move focus onto the incoming widget if focus + // was somewhere on the outgoing widget. + if ( topWidget ) { + TQWidget * fw = tqfocusWidget(); + TQWidget* p = fw; + while ( p && p != topWidget ) + p = p->parentWidget(); + if ( p == topWidget ) { // focus was on old page + if ( !tqfocusWidgets ) + tqfocusWidgets = new TQPtrDict<TQWidget>( 17 ); + tqfocusWidgets->tqreplace( topWidget, fw ); + fw->clearFocus(); + // look for the best focus widget we can tqfind + // best == what we had (which may be deleted) + fw = tqfocusWidgets->take( w ); + if ( isChildOf( fw, w ) ) { + fw->setFocus(); + } else { + // second best == first child widget in the focus chain + TQFocusData *f = focusData(); + TQWidget* home = f->home(); + TQWidget *i = home; + do { + if ( ( ( i->focusPolicy() & Qt::TabFocus ) == Qt::TabFocus ) + && !i->focusProxy() && i->isVisibleTo(w) && i->isEnabled() ) { + p = i; + while ( p && p != w ) + p = p->parentWidget(); + if ( p == w ) { + i->setFocus(); + break; + } + } + i = f->next(); + } while( i != home ); + } + } + } + + if ( isVisible() ) { + emit aboutToShow( w ); + int i = id( w ); + if ( i != -1 ) + emit aboutToShow( i ); + } + + topWidget = w; + + TQObjectListIt it( childrenListObject() ); + TQObject * o; + + while( (o=it.current()) != 0 ) { + ++it; + if ( o->isWidgetType() && o != TQT_TQOBJECT(w) && o != TQT_TQOBJECT(invisible) ) + ((TQWidget *)o)->hide(); + } + + w->setGeometry( invisible->tqgeometry() ); + w->show(); +} + +/*! + \reimp +*/ + +void TQWidgetStack::frameChanged() +{ + TQFrame::frameChanged(); + setChildGeometries(); +} + + +/*! + \reimp +*/ + +void TQWidgetStack::setFrameRect( const TQRect & r ) +{ + TQFrame::setFrameRect( r ); + setChildGeometries(); +} + + +/*! + Fixes up the tqchildren's geometries. +*/ + +void TQWidgetStack::setChildGeometries() +{ + invisible->setGeometry( contentsRect() ); + if ( topWidget ) + topWidget->setGeometry( invisible->tqgeometry() ); +} + + +/*! + \reimp +*/ +void TQWidgetStack::show() +{ + // Reimplemented in order to set the tqchildren's geometries + // appropriately and to pick the first widget as topWidget if no + // topwidget was defined + if ( !isVisible() && !childrenListObject().isEmpty() ) { + TQObjectListIt it( childrenListObject() ); + TQObject * o; + + while( (o=it.current()) != 0 ) { + ++it; + if ( o->isWidgetType() ) { + if ( !topWidget && o != TQT_TQOBJECT(invisible) ) + topWidget = (TQWidget*)o; + if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(topWidget) ) + ((TQWidget *)o)->show(); + else + ((TQWidget *)o)->hide(); + } + } + setChildGeometries(); + } + TQFrame::show(); +} + + +/*! + Returns the widget with ID \a id. Returns 0 if this widget stack + does not manage a widget with ID \a id. + + \sa id() addWidget() +*/ + +TQWidget * TQWidgetStack::widget( int id ) const +{ + return id != -1 ? dict->tqfind( id ) : 0; +} + + +/*! + Returns the ID of the \a widget. Returns -1 if \a widget is 0 or + is not being managed by this widget stack. + + \sa widget() addWidget() +*/ + +int TQWidgetStack::id( TQWidget * widget ) const +{ + if ( !widget ) + return -1; + + TQIntDictIterator<TQWidget> it( *dict ); + while ( it.current() && it.current() != widget ) + ++it; + return it.current() == widget ? it.currentKey() : -1; +} + + +/*! + Returns the currently visible widget (the one at the top of the + stack), or 0 if nothing is currently being shown. + + \sa aboutToShow() id() raiseWidget() +*/ + +TQWidget * TQWidgetStack::visibleWidget() const +{ + return topWidget; +} + + +/*! + \fn void TQWidgetStack::aboutToShow( int ) + + This signal is emitted just before a managed widget is shown if + that managed widget has an ID != -1. The argument is the numeric + ID of the widget. + + If you call visibleWidget() in a slot connected to aboutToShow(), + the widget it returns is the one that is currently visible, not + the one that is about to be shown. +*/ + + +/*! + \fn void TQWidgetStack::aboutToShow( TQWidget * ) + + \overload + + This signal is emitted just before a managed widget is shown. The + argument is a pointer to the widget. + + If you call visibleWidget() in a slot connected to aboutToShow(), + the widget returned is the one that is currently visible, not the + one that is about to be shown. +*/ + + +/*! + \reimp +*/ + +void TQWidgetStack::resizeEvent( TQResizeEvent * e ) +{ + TQFrame::resizeEvent( e ); + setChildGeometries(); +} + + +/*! + \reimp +*/ + +TQSize TQWidgetStack::tqsizeHint() const +{ + constPolish(); + + TQSize size( 0, 0 ); + + TQIntDictIterator<TQWidget> it( *dict ); + TQWidget *w; + + while ( (w = it.current()) != 0 ) { + ++it; + TQSize sh = w->tqsizeHint(); + if ( w->tqsizePolicy().horData() == TQSizePolicy::Ignored ) + sh.rwidth() = 0; + if ( w->tqsizePolicy().verData() == TQSizePolicy::Ignored ) + sh.rheight() = 0; +#ifndef TQT_NO_LAYOUT + size = size.expandedTo( sh ).expandedTo( tqSmartMinSize(w) ); +#endif + } + if ( size.isNull() ) + size = TQSize( 128, 64 ); + size += TQSize( 2*frameWidth(), 2*frameWidth() ); + return size; +} + + +/*! + \reimp +*/ +TQSize TQWidgetStack::tqminimumSizeHint() const +{ + constPolish(); + + TQSize size( 0, 0 ); + + TQIntDictIterator<TQWidget> it( *dict ); + TQWidget *w; + + while ( (w = it.current()) != 0 ) { + ++it; + TQSize sh = w->tqminimumSizeHint(); + if ( w->tqsizePolicy().horData() == TQSizePolicy::Ignored ) + sh.rwidth() = 0; + if ( w->tqsizePolicy().verData() == TQSizePolicy::Ignored ) + sh.rheight() = 0; +#ifndef TQT_NO_LAYOUT + size = size.expandedTo( sh ).expandedTo( w->tqminimumSize() ); +#endif + } + if ( size.isNull() ) + size = TQSize( 64, 32 ); + size += TQSize( 2*frameWidth(), 2*frameWidth() ); + return size; +} + +/*! + \reimp +*/ +void TQWidgetStack::childEvent( TQChildEvent * e) +{ + if ( e->child()->isWidgetType() && e->removed() ) + removeWidget( (TQWidget*) e->child() ); +} +#endif + +#endif // USE_QT4 |