diff options
Diffstat (limited to 'tqtinterface/qt4/src/widgets/tqtabwidget.cpp')
-rw-r--r-- | tqtinterface/qt4/src/widgets/tqtabwidget.cpp | 1097 |
1 files changed, 1097 insertions, 0 deletions
diff --git a/tqtinterface/qt4/src/widgets/tqtabwidget.cpp b/tqtinterface/qt4/src/widgets/tqtabwidget.cpp new file mode 100644 index 0000000..5fab113 --- /dev/null +++ b/tqtinterface/qt4/src/widgets/tqtabwidget.cpp @@ -0,0 +1,1097 @@ +/**************************************************************************** +** +** Implementation of TQTabWidget class +** +** Created : 990318 +** +** 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 "tqtabwidget.h" +#ifndef TQT_NO_TABWIDGET +#include "tqobjectlist.h" +#include "tqtabbar.h" +#include "tqapplication.h" +#include "tqwidgetstack.h" +#include "tqbitmap.h" +#include "tqaccel.h" +#include "tqstyle.h" +#include "tqpainter.h" +#include "tqtoolbutton.h" + +#ifdef TQ_OS_MACX +#include <tqmacstyle_mac.h> +#endif + +/*! + \class TQTabWidget tqtabwidget.h + \brief The TQTabWidget class provides a stack of tabbed widgets. + + \ingroup organizers + \ingroup advanced + \mainclass + + A tab widget provides a tab bar of tabs and a `page area' below + (or above, see \l{TabPosition}) the tabs. Each tab is associated + with a different widget (called a `page'). Only the current tab's + page is shown in the page area; all the other tabs' pages are + hidden. The user can show a different page by clicking on its tab + or by pressing its Alt+\e{letter} accelerator if it has one. + + The normal way to use TQTabWidget is to do the following in the + constructor: + \list 1 + \i Create a TQTabWidget. + \i Create a TQWidget for each of the pages in the tab dialog, + insert tqchildren into it, set up tqgeometry management for it and use + addTab() (or insertTab()) to set up a tab and keyboard accelerator + for it. + \i Connect to the Q_SIGNALS and Q_SLOTS. + \endlist + + The position of the tabs is set with setTabPosition(), their tqshape + with setTabShape(), and their margin with setMargin(). + + If you don't call addTab() and the TQTabWidget is already visible, + then the page you have created will not be visible. Don't + confuse the object name you supply to the TQWidget constructor and + the tab label you supply to addTab(). addTab() takes a name which + indicates an accelerator and is meaningful and descriptive to the + user, whereas the widget name is used primarily for debugging. + + The signal currentChanged() is emitted when the user selects a + page. + + The current page is available as an index position with + currentPageIndex() or as a wiget pointer with currentPage(). You + can retrieve a pointer to a page with a given index using page(), + and can tqfind the index position of a page with indexOf(). Use + setCurrentPage() to show a particular page by index, or showPage() + to show a page by widget pointer. + + You can change a tab's label and iconset using changeTab() or + setTabLabel() and setTabIconSet(). A tab page can be removed with + removePage(). + + Each tab is either enabled or disabled at any given time (see + setTabEnabled()). If a tab is enabled, the tab text is drawn + normally and the user can select that tab. If it is disabled, the + tab is drawn in a different way and the user cannot select that + tab. Note that even if a tab is disabled, the page can still be + visible, for example if all of the tabs happen to be disabled. + + Although tab widgets can be a very good way to split up a complex + dialog, it's also very easy to get into a mess. See TQTabDialog for + some design hints. An alternative is to use a TQWidgetStack for + which you provide some means of navigating between pages, for + example, a TQToolBar or a TQListBox. + + Most of the functionality in TQTabWidget is provided by a TQTabBar + (at the top, providing the tabs) and a TQWidgetStack (most of the + area, organizing the individual pages). + + <img src=qtabwidget-m.png> <img src=qtabwidget-w.png> + + \sa TQTabDialog, TQToolBox +*/ + +/*! + \enum TQt::Corner + This enum type specifies a corner in a rectangle: + \value TopLeft top left corner + \value TopRight top right corner + \value BottomLeft bottom left corner + \value BottomRight bottom right corner +*/ + +/*! + \enum TQTabWidget::TabPosition + + This enum type defines where TQTabWidget draws the tab row: + \value Top above the pages + \value Bottom below the pages +*/ + +/*! + \enum TQTabWidget::TabShape + + This enum type defines the tqshape of the tabs: + \value Rounded rounded look (normal) + \value Triangular triangular look (very unusual, included for completeness) +*/ + +/* undocumented now + \obsolete + + \fn void TQTabWidget::selected( const TQString &tabLabel ); + + This signal is emitted whenever a tab is selected (raised), + including during the first show(). + + \sa raise() +*/ + + +/*! + \fn void TQTabWidget::currentChanged( TQWidget* ); + + This signal is emitted whenever the current page changes. The + parameter is the new current page. + + \sa currentPage(), showPage(), tabLabel() +*/ + +class TQTabBarBase : public TQWidget +{ +public: + TQTabBarBase( TQTabWidget* tqparent=0, const char* name=0 ) + : TQWidget( tqparent, name ) {}; +protected: + void paintEvent( TQPaintEvent * ) + { + TQObject * obj = tqparent(); + if( obj ){ + TQTabWidget * t = (TQTabWidget *) obj; + TQPainter p( this ); + TQStyle::SFlags flags = TQStyle::Style_Default; + + if ( t->tabPosition() == TQTabWidget::Top ) + flags |= TQStyle::Style_Top; + if ( t->tabPosition() == TQTabWidget::Bottom ) + flags |= TQStyle::Style_Bottom; + if(parentWidget()->isEnabled()) + flags |= TQStyle::Style_Enabled; + + tqstyle().tqdrawPrimitive( TQStyle::PE_TabBarBase, &p, rect(), + tqcolorGroup(), flags ); + } + } +}; + +class TQTabWidgetData +{ +public: + TQTabWidgetData() + : tabs(0), tabBase(0), stack(0), dirty( TRUE ), + pos( TQTabWidget::Top ), tqshape( TQTabWidget::Rounded ), + leftCornerWidget(0), rightCornerWidget(0) {}; + ~TQTabWidgetData(){}; + TQTabBar* tabs; + TQTabBarBase* tabBase; + TQWidgetStack* stack; + bool dirty; + TQTabWidget::TabPosition pos; + TQTabWidget::TabShape tqshape; + int tqalignment; + TQWidget* leftCornerWidget; + TQWidget* rightCornerWidget; +}; + +/*! + Constructs a tabbed widget called \a name with tqparent \a tqparent, + and widget flags \a f. +*/ +TQTabWidget::TQTabWidget( TQWidget *tqparent, const char *name, WFlags f ) + : TQWidget( tqparent, name, f ) +{ + d = new TQTabWidgetData; + d->stack = new TQWidgetStack( this, "tab pages" ); + d->stack->installEventFilter( this ); + d->tabBase = new TQTabBarBase( this, "tab base" ); + d->tabBase->resize( 1, 1 ); + setTabBar( new TQTabBar( this, "tab control" ) ); + + d->stack->setFrameStyle( TQFrame::TabWidgetPanel | TQFrame::Raised ); +#ifdef TQ_OS_TEMP + d->pos = Bottom; +#endif + + tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) ); + setFocusPolicy( Qt::TabFocus ); + setFocusProxy( d->tabs ); + + installEventFilter( this ); +#ifdef TQ_OS_MACX + if (::tqqt_cast<TQMacStyle*>(&tqstyle())) + setMargin(10); // According to HIGuidelines at least. +#endif +} + +/*! + \reimp +*/ +TQTabWidget::~TQTabWidget() +{ + delete d; +} + +/*! + Adds another tab and page to the tab view. + + The new page is \a child; the tab's label is \a label. Note the + difference between the widget name (which you supply to widget + constructors and to setTabEnabled(), for example) and the tab + label. The name is internal to the program and invariant, whereas + the label is shown on-screen and may vary according to language + and other factors. + + If the tab's \a label tqcontains an ampersand, the letter following + the ampersand is used as an accelerator for the tab, e.g. if the + label is "Bro\&wse" then Alt+W becomes an accelerator which will + move the focus to this tab. + + If you call addTab() after show() the screen will flicker and the + user may be confused. + + Adding the same child twice will have undefined behavior. + + \sa insertTab() +*/ +void TQTabWidget::addTab( TQWidget *child, const TQString &label) +{ + insertTab( child, label ); +} + + +/*! + \overload + + Adds another tab and page to the tab view. + + This function is the same as addTab(), but with an additional \a + iconset. +*/ +void TQTabWidget::addTab( TQWidget *child, const TQIconSet& iconset, const TQString &label ) +{ + insertTab( child, iconset, label ); +} + +/*! + \overload + + This is a low-level function for adding tabs. It is useful if you + are using setTabBar() to set a TQTabBar subclass with an overridden + TQTabBar::paint() function for a subclass of TQTab. The \a child is + the new page and \a tab is the tab to put the \a child on. +*/ +void TQTabWidget::addTab( TQWidget *child, TQTab* tab ) +{ + insertTab( child, tab ); +} + + + +/*! + Inserts another tab and page to the tab view. + + The new page is \a child; the tab's label is \a label. Note the + difference between the widget name (which you supply to widget + constructors and to setTabEnabled(), for example) and the tab + label. The name is internal to the program and invariant, whereas + the label is shown on-screen and may vary according to language + and other factors. + + If the tab's \a label tqcontains an ampersand, the letter following + the ampersand is used as an accelerator for the tab, e.g. if the + label is "Bro\&wse" then Alt+W becomes an accelerator which will + move the focus to this tab. + + If \a index is not specified, the tab is simply appended. + Otherwise it is inserted at the specified position. + + If you call insertTab() after show(), the screen will flicker and + the user may be confused. + + \sa addTab() +*/ +void TQTabWidget::insertTab( TQWidget *child, const TQString &label, int index) +{ + TQTab * t = new TQTab(); + TQ_CHECK_PTR( t ); + t->label = label; + insertTab( child, t, index ); +} + + +/*! + \overload + + Inserts another tab and page to the tab view. + + This function is the same as insertTab(), but with an additional + \a iconset. +*/ +void TQTabWidget::insertTab( TQWidget *child, const TQIconSet& iconset, const TQString &label, int index ) +{ + TQTab * t = new TQTab(); + TQ_CHECK_PTR( t ); + t->label = label; + t->iconset = new TQIconSet( iconset ); + insertTab( child, t, index ); +} + +/*! + \overload + + This is a lower-level method for inserting tabs, similar to the + other insertTab() method. It is useful if you are using + setTabBar() to set a TQTabBar subclass with an overridden + TQTabBar::paint() function for a subclass of TQTab. The \a child is + the new page, \a tab is the tab to put the \a child on and \a + index is the position in the tab bar that this page should occupy. +*/ +void TQTabWidget::insertTab( TQWidget *child, TQTab* tab, int index) +{ + tab->enabled = TRUE; + int id = d->tabs->insertTab( tab, index ); + d->stack->addWidget( child, id ); + if ( d->stack->frameStyle() != ( TQFrame::TabWidgetPanel | TQFrame::Raised ) ) + d->stack->setFrameStyle( TQFrame::TabWidgetPanel | TQFrame::Raised ); + setUpLayout(); +} + + +/*! + Defines a new \a label for page \a{w}'s tab. +*/ +void TQTabWidget::changeTab( TQWidget *w, const TQString &label) +{ + int id = d->stack->id( w ); + if ( id < 0 ) + return; + TQTab* t = d->tabs->tab( id ); + if ( !t ) + return; + // this will update the accelerators + t->setText( label ); + + d->tabs->layoutTabs(); + d->tabs->update(); + setUpLayout(); +} + +/*! + \overload + + Defines a new \a iconset and a new \a label for page \a{w}'s tab. +*/ +void TQTabWidget::changeTab( TQWidget *w, const TQIconSet& iconset, const TQString &label) +{ + int id = d->stack->id( w ); + if ( id < 0 ) + return; + TQTab* t = d->tabs->tab( id ); + if ( !t ) + return; + if ( t->iconset ) { + delete t->iconset; + t->iconset = 0; + } + // this will update the accelerators + t->iconset = new TQIconSet( iconset ); + t->setText( label ); + + d->tabs->layoutTabs(); + d->tabs->update(); + setUpLayout(); +} + +/*! + Returns TRUE if the page \a w is enabled; otherwise returns FALSE. + + \sa setTabEnabled(), TQWidget::isEnabled() +*/ + +bool TQTabWidget::isTabEnabled( TQWidget* w ) const +{ + int id = d->stack->id( w ); + if ( id >= 0 ) + return w->isEnabled(); + else + return FALSE; +} + +/*! + If \a enable is TRUE, page \a w is enabled; otherwise page \a w is + disabled. The page's tab is redrawn appropriately. + + TQTabWidget uses TQWidget::setEnabled() internally, rather than + keeping a separate flag. + + Note that even a disabled tab/page may be visible. If the page is + visible already, TQTabWidget will not hide it; if all the pages are + disabled, TQTabWidget will show one of them. + + \sa isTabEnabled(), TQWidget::setEnabled() +*/ + +void TQTabWidget::setTabEnabled( TQWidget* w, bool enable) +{ + int id = d->stack->id( w ); + if ( id >= 0 ) { + w->setEnabled( enable ); + d->tabs->setTabEnabled( id, enable ); + } +} + +/*! + Sets widget \a w to be the shown in the specified \a corner of the + tab widget. + + Only the horizontal element of the \a corner will be used. + + \sa cornerWidget(), setTabPosition() +*/ +void TQTabWidget::setCornerWidget( TQWidget * w, TQt::Corner corner ) +{ + if ( !w ) + return; + if ( (uint)corner & 1 ) + d->rightCornerWidget = w; + else + d->leftCornerWidget = w; +} + +/*! + Returns the widget shown in the \a corner of the tab widget or 0. +*/ +TQWidget * TQTabWidget::cornerWidget( TQt::Corner corner ) const +{ + if ( (uint)corner & 1 ) + return d->rightCornerWidget; + return d->leftCornerWidget; +} + +/*! + Ensures that page \a w is shown. This is useful mainly for + accelerators. + + \warning Used carelessly, this function can easily surprise or + confuse the user. + + \sa TQTabBar::setCurrentTab() +*/ +void TQTabWidget::showPage( TQWidget * w) +{ + int id = d->stack->id( w ); + if ( id >= 0 ) { + d->stack->raiseWidget( w ); + d->tabs->setCurrentTab( id ); + // ### why overwrite the frame style? + if ( d->stack->frameStyle() != ( TQFrame::TabWidgetPanel |TQFrame::Raised ) ) + d->stack->setFrameStyle( TQFrame::TabWidgetPanel | TQFrame::Raised ); + } +} + +/*! + Removes page \a w from this stack of widgets. Does not delete \a + w. + + \sa addTab(), showPage(), TQWidgetStack::removeWidget() +*/ +void TQTabWidget::removePage( TQWidget * w ) +{ + int id = d->stack->id( w ); + if ( id >= 0 ) { + int oldId = d->stack->id(currentPage()); + bool fixCurrentTab = oldId == id; + //switches to the next enabled tab + d->tabs->setTabEnabled( id, FALSE ); + //if no next enabled page we fix the current page + fixCurrentTab = fixCurrentTab && oldId == d->stack->id(currentPage()); + + d->stack->removeWidget( w ); + d->tabs->removeTab( d->tabs->tab(id) ); + if ( fixCurrentTab ) + showTab( d->tabs->currentTab() ); + setUpLayout(); + + if ( d->tabs->count() == 0 ) + d->stack->setFrameStyle( TQFrame::NoFrame ); + } +} + +/*! + Returns the label text for the tab on page \a w. +*/ + +TQString TQTabWidget::tabLabel( TQWidget * w ) const +{ + TQTab * t = d->tabs->tab( d->stack->id( w ) ); + return t ? t->label : TQString::null; +} + +/*! + Sets the tab label for page \a w to \a l +*/ + +void TQTabWidget::setTabLabel( TQWidget * w, const TQString &l ) +{ + TQTab * t = d->tabs->tab( d->stack->id( w ) ); + if ( t ) + t->label = l; + d->tabs->layoutTabs(); + d->tabs->update(); + setUpLayout(); +} + +/*! + Returns a pointer to the page currently being displayed by the tab + dialog. The tab dialog does its best to make sure that this value + is never 0 (but if you try hard enough, it can be). +*/ + +TQWidget * TQTabWidget::currentPage() const +{ + return page( currentPageIndex() ); +} + +/*! + \property TQTabWidget::autoMask + \brief whether the tab widget is automatically masked + + \sa TQWidget::setAutoMask() +*/ + +/*! + \property TQTabWidget::currentPage + \brief the index position of the current tab page + + \sa TQTabBar::currentTab() +*/ + +int TQTabWidget::currentPageIndex() const +{ + return d->tabs->indexOf( d->tabs->currentTab() ); +} + +void TQTabWidget::setCurrentPage( int index ) +{ + d->tabs->setCurrentTab( d->tabs->tabAt( index ) ); + showTab( d->tabs->currentTab() ); +} + + +/*! + Returns the index position of page \a w, or -1 if the widget + cannot be found. +*/ +int TQTabWidget::indexOf( TQWidget* w ) const +{ + return d->tabs->indexOf( d->stack->id( w ) ); +} + + +/*! + \reimp +*/ +void TQTabWidget::resizeEvent( TQResizeEvent *e ) +{ + TQWidget::resizeEvent( e ); + setUpLayout(); +} + +/*! + Replaces the dialog's TQTabBar heading with the tab bar \a tb. Note + that this must be called \e before any tabs have been added, or + the behavior is undefined. + + \sa tabBar() +*/ +void TQTabWidget::setTabBar( TQTabBar* tb) +{ + if ( tb->parentWidget() != this ) + tb->reparent( this, TQPoint(0,0), TRUE ); + delete d->tabs; + d->tabs = tb; + setFocusProxy( d->tabs ); + connect( d->tabs, TQT_SIGNAL(selected(int)), + this, TQT_SLOT(showTab(int)) ); + setUpLayout(); +} + + +/*! + Returns the current TQTabBar. + + \sa setTabBar() +*/ +TQTabBar* TQTabWidget::tabBar() const +{ + return d->tabs; +} + +/*! + Ensures that the selected tab's page is visible and appropriately + sized. +*/ + +void TQTabWidget::showTab( int i ) +{ + if ( d->stack->widget( i ) ) { + d->stack->raiseWidget( i ); + emit selected( d->tabs->tab( i )->label ); + emit currentChanged( d->stack->widget( i ) ); + } +} + +/* + Set up the tqlayout. +*/ +void TQTabWidget::setUpLayout( bool onlyCheck ) +{ + if ( onlyCheck && !d->dirty ) + return; // nothing to do + + if ( !isVisible() ) { + d->dirty = TRUE; + return; // we'll do it later + } + + TQSize t( 0, d->stack->frameWidth() ); + if ( d->tabs->isVisibleTo(this) ) + t = d->tabs->tqsizeHint(); + int lcw = 0; + if ( d->leftCornerWidget && d->leftCornerWidget->isVisible() ) { + TQSize sz = d->leftCornerWidget->tqsizeHint(); + d->leftCornerWidget->resize(sz); + lcw = sz.width(); + if ( t.height() > lcw ) + lcw = t.height(); + } + int rcw = 0; + if ( d->rightCornerWidget && d->rightCornerWidget->isVisible() ) { + TQSize sz = d->rightCornerWidget->tqsizeHint(); + d->rightCornerWidget->resize(sz); + rcw = sz.width(); + if ( t.height() > rcw ) + rcw = t.height(); + } + int tw = width() - lcw - rcw; + if ( t.width() > tw ) + t.setWidth( tw ); + int lw = d->stack->lineWidth(); + bool reverse = TQApplication::reverseLayout(); + int tabx, taby, stacky, exty, exth, overlap; + + exth = tqstyle().tqpixelMetric( TQStyle::PM_TabBarBaseHeight, this ); + overlap = tqstyle().tqpixelMetric( TQStyle::PM_TabBarBaseOverlap, this ); + + if ( d->pos == Bottom ) { + taby = height() - t.height() - lw; + stacky = 0; + exty = taby - (exth - overlap); + } else { // Top + taby = 0; + stacky = t.height()-lw + (exth - overlap); + exty = taby + t.height() - overlap; + } + + int lhs = (TQMAX( 0, lw - 2 ) + lcw); + int tqalignment = tqstyle().tqstyleHint( TQStyle::SH_TabBar_Alignment, this ); + if ( tqalignment == Qt::AlignHCenter && t.width() < width() ) + tabx = lhs + ((width()-(lcw+rcw))/2 - t.width()/2); + else if(reverse || tqalignment == Qt::AlignRight) + tabx = TQMIN( width() - t.width(), width() - t.width() - lw + 2 ) - lcw; + else + tabx = lhs; + + d->tabs->setGeometry( tabx, taby, t.width(), t.height() ); + d->tabBase->setGeometry( 0, exty, width(), exth ); + if ( exth == 0 ) + d->tabBase->hide(); + else + d->tabBase->show(); + + d->stack->setGeometry( 0, stacky, width(), height() - (exth-overlap) - + t.height()+TQMAX(0, lw-2)); + + d->dirty = FALSE; + + // move cornerwidgets + if ( d->leftCornerWidget ) { + int y = ( t.height() / 2 ) - ( d->leftCornerWidget->height() / 2 ); + int x = ( reverse ? width() - lcw + y : y ); + d->leftCornerWidget->move( x, y + taby ); + } + if ( d->rightCornerWidget ) { + int y = ( t.height() / 2 ) - ( d->rightCornerWidget->height() / 2 ); + int x = ( reverse ? y : width() - rcw + y ); + d->rightCornerWidget->move( x, y + taby ); + } + if ( !onlyCheck ) + update(); + updateGeometry(); + if ( autoMask() ) + updateMask(); +} + +/*! + \reimp +*/ +TQSize TQTabWidget::tqsizeHint() const +{ + TQSize lc(0, 0), rc(0, 0); + + if (d->leftCornerWidget) + lc = d->leftCornerWidget->tqsizeHint(); + if(d->rightCornerWidget) + rc = d->rightCornerWidget->tqsizeHint(); + if ( !d->dirty ) { + TQTabWidget *that = (TQTabWidget*)this; + that->setUpLayout( TRUE ); + } + TQSize s( d->stack->tqsizeHint() ); + TQSize t( d->tabs->tqsizeHint() ); + if(!tqstyle().tqstyleHint(TQStyle::SH_TabBar_PreferNoArrows, d->tabs)) + t = t.boundedTo( TQSize(200,200) ); + else + t = t.boundedTo( TQApplication::desktop()->size() ); + + TQSize sz( TQMAX( s.width(), t.width() + rc.width() + lc.width() ), + s.height() + (TQMAX( rc.height(), TQMAX(lc.height(), t.height()))) + ( d->tabBase->isVisible() ? d->tabBase->height() : 0 ) ); + return tqstyle().tqsizeFromContents(TQStyle::CT_TabWidget, this, sz).expandedTo(TQApplication::globalStrut()); +} + + +/*! + \reimp + + Returns a suitable minimum size for the tab widget. +*/ +TQSize TQTabWidget::tqminimumSizeHint() const +{ + TQSize lc(0, 0), rc(0, 0); + + if(d->leftCornerWidget) + lc = d->leftCornerWidget->tqminimumSizeHint(); + if(d->rightCornerWidget) + rc = d->rightCornerWidget->tqminimumSizeHint(); + if ( !d->dirty ) { + TQTabWidget *that = (TQTabWidget*)this; + that->setUpLayout( TRUE ); + } + TQSize s( d->stack->tqminimumSizeHint() ); + TQSize t( d->tabs->tqminimumSizeHint() ); + + TQSize sz( TQMAX( s.width(), t.width() + rc.width() + lc.width() ), + s.height() + (TQMAX( rc.height(), TQMAX(lc.height(), t.height()))) + ( d->tabBase->isVisible() ? d->tabBase->height() : 0 ) ); + return tqstyle().tqsizeFromContents(TQStyle::CT_TabWidget, this, sz).expandedTo(TQApplication::globalStrut()); +} + +/*! + \reimp + */ +void TQTabWidget::showEvent( TQShowEvent * ) +{ + setUpLayout(); +} + + +/*! + \property TQTabWidget::tabPosition + \brief the position of the tabs in this tab widget + + Possible values for this property are \c TQTabWidget::Top and \c + TQTabWidget::Bottom. + + \sa TabPosition +*/ +TQTabWidget::TabPosition TQTabWidget::tabPosition() const +{ + return d->pos; +} + +void TQTabWidget::setTabPosition( TabPosition pos) +{ + if (d->pos == pos) + return; + d->pos = pos; + if (d->tabs->tqshape() == TQTabBar::TriangularAbove || d->tabs->tqshape() == TQTabBar::TriangularBelow ) { + if ( pos == Bottom ) + d->tabs->setShape( TQTabBar::TriangularBelow ); + else + d->tabs->setShape( TQTabBar::TriangularAbove ); + } + else { + if ( pos == Bottom ) + d->tabs->setShape( TQTabBar::RoundedBelow ); + else + d->tabs->setShape( TQTabBar::RoundedAbove ); + } + d->tabs->layoutTabs(); + setUpLayout(); +} + +/*! + \property TQTabWidget::tabShape + \brief the tqshape of the tabs in this tab widget + + Possible values for this property are \c TQTabWidget::Rounded + (default) or \c TQTabWidget::Triangular. + + \sa TabShape +*/ + +TQTabWidget::TabShape TQTabWidget::tabShape() const +{ + return d->tqshape; +} + +void TQTabWidget::setTabShape( TabShape s ) +{ + if ( d->tqshape == s ) + return; + d->tqshape = s; + if ( d->pos == Top ) { + if ( s == Rounded ) + d->tabs->setShape( TQTabBar::RoundedAbove ); + else + d->tabs->setShape( TQTabBar::TriangularAbove ); + } else { + if ( s == Rounded ) + d->tabs->setShape( TQTabBar::RoundedBelow ); + else + d->tabs->setShape( TQTabBar::TriangularBelow ); + } + d->tabs->layoutTabs(); + setUpLayout(); +} + + +/*! + \property TQTabWidget::margin + \brief the margin in this tab widget + + The margin is the distance between the innermost pixel of the + frame and the outermost pixel of the pages. +*/ +int TQTabWidget::margin() const +{ + return d->stack->margin(); +} + +void TQTabWidget::setMargin( int w ) +{ + d->stack->setMargin( w ); + setUpLayout(); +} + + +/*! + \reimp + */ +void TQTabWidget::styleChange( TQStyle& old ) +{ + TQWidget::styleChange( old ); + setUpLayout(); +} + + +/*! + \reimp + */ +void TQTabWidget::updateMask() +{ + if ( !autoMask() ) + return; + + TQRect r; + TQRegion reg( r ); + reg += TQRegion( d->tabs->tqgeometry() ); + reg += TQRegion( d->stack->tqgeometry() ); + setMask( reg ); +} + + +/*! + \reimp + */ +bool TQTabWidget::eventFilter( TQObject *o, TQEvent * e) +{ + if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) ) { + if ( e->type() == TQEvent::LanguageChange || e->type() == TQEvent::LayoutHint ) { + d->dirty = TRUE; + setUpLayout(); + updateGeometry(); + } else if ( e->type() == TQEvent::KeyPress ) { + TQKeyEvent *ke = (TQKeyEvent*) e; + if ( ( ke->key() == TQt::Key_Tab || ke->key() == TQt::Key_Backtab ) && + count() > 1 && + ke->state() & ControlButton ) { + int page = currentPageIndex(); + if ( ke->key() == TQt::Key_Backtab || ke->state() & ShiftButton ) { + page--; + if ( page < 0 ) + page = count() - 1; + } else { + page++; + if ( page >= count() ) + page = 0; + } + setCurrentPage( page ); + if ( !tqApp->tqfocusWidget() ) + d->tabs->setFocus(); + return TRUE; + } + } + + } else if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->stack) ) { + if ( e->type() == TQEvent::ChildRemoved + && ( (TQChildEvent*)e )->child()->isWidgetType() ) { + removePage( (TQWidget*) ( (TQChildEvent*)e )->child() ); + return TRUE; + } else if ( e->type() == TQEvent::LayoutHint ) { + updateGeometry(); + } + } + return FALSE; +} + +/*! + Returns the tab page at index position \a index or 0 if the \a + index is out of range. +*/ +TQWidget *TQTabWidget::page( int index ) const +{ + TQTab *t = d->tabs->tabAt(index); + if ( t ) + return d->stack->widget( t->id ); + // else + return 0; +} + +/*! + Returns the label of the tab at index position \a index or + TQString::null if the \a index is out of range. +*/ +TQString TQTabWidget::label( int index ) const +{ + TQTab *t = d->tabs->tabAt( index ); + if ( t ) + return t->label; + // else + return TQString::null; +} + +/*! + \property TQTabWidget::count + \brief the number of tabs in the tab bar +*/ +int TQTabWidget::count() const +{ + return d->tabs->count(); +} + +/*! + Returns the iconset of page \a w or a \link TQIconSet::TQIconSet() + null iconset\endlink if \a w is not a tab page or does not have an + iconset. +*/ +TQIconSet TQTabWidget::tabIconSet( TQWidget * w ) const +{ + int id = d->stack->id( w ); + if ( id < 0 ) + return TQIconSet(); + TQTab* t = d->tabs->tab( id ); + if ( !t ) + return TQIconSet(); + if ( t->iconset ) + return TQIconSet( *t->iconset ); + else + return TQIconSet(); +} + +/*! + Sets the iconset for page \a w to \a iconset. +*/ +void TQTabWidget::setTabIconSet( TQWidget * w, const TQIconSet & iconset ) +{ + int id = d->stack->id( w ); + if ( id < 0 ) + return; + TQTab* t = d->tabs->tab( id ); + if ( !t ) + return; + if ( t->iconset ) + delete t->iconset; + t->iconset = new TQIconSet( iconset ); + + d->tabs->layoutTabs(); + d->tabs->update(); + setUpLayout(); +} + +/*! + Sets the tab tool tip for page \a w to \a tip. + + \sa removeTabToolTip(), tabToolTip() +*/ +void TQTabWidget::setTabToolTip( TQWidget * w, const TQString & tip ) +{ + int index = d->tabs->indexOf( d->stack->id( w ) ); + if ( index < 0 ) + return; + d->tabs->setToolTip( index, tip ); +} + +/*! + Returns the tab tool tip for page \a w or TQString::null if no tool + tip has been set. + + \sa setTabToolTip(), removeTabToolTip() +*/ +TQString TQTabWidget::tabToolTip( TQWidget * w ) const +{ + int index = d->tabs->indexOf( d->stack->id( w ) ); + if ( index < 0 ) + return TQString(); + return d->tabs->toolTip( index ); +} + +/*! + Removes the tab tool tip for page \a w. If the page does not have + a tip, nothing happens. + + \sa setTabToolTip(), tabToolTip() +*/ +void TQTabWidget::removeTabToolTip( TQWidget * w ) +{ + int index = d->tabs->indexOf( d->stack->id( w ) ); + if ( index < 0 ) + return; + d->tabs->removeToolTip( index ); +} + +#endif |