summaryrefslogtreecommitdiffstats
path: root/src/widgets/qtoolbox.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
commitbd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch)
tree7a520322212d48ebcb9fbe1087e7fca28b76185c /src/widgets/qtoolbox.cpp
downloadqt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz
qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip
Add Qt3 development HEAD version
Diffstat (limited to 'src/widgets/qtoolbox.cpp')
-rw-r--r--src/widgets/qtoolbox.cpp692
1 files changed, 692 insertions, 0 deletions
diff --git a/src/widgets/qtoolbox.cpp b/src/widgets/qtoolbox.cpp
new file mode 100644
index 0000000..64fc148
--- /dev/null
+++ b/src/widgets/qtoolbox.cpp
@@ -0,0 +1,692 @@
+/****************************************************************************
+**
+** Implementation of QToolBox widget class
+**
+** Created : 961105
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the Qt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "qtoolbox.h"
+
+#ifndef QT_NO_TOOLBOX
+
+#include <qbutton.h>
+#include <qlayout.h>
+#include <qscrollview.h>
+#include <qpainter.h>
+#include <qstyle.h>
+#include <qobjectlist.h>
+#include <qapplication.h>
+#include <qwidgetlist.h>
+#include <qlayout.h>
+#include <qvaluelist.h>
+#include <qtooltip.h>
+#include <qeventloop.h>
+#include <qdatetime.h>
+
+class QToolBoxButton : public QButton
+{
+public:
+ QToolBoxButton( QWidget *parent, const char *name )
+ : QButton( parent, name ), selected( FALSE )
+ {
+ setBackgroundMode(PaletteBackground);
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
+ setFocusPolicy(NoFocus);
+ }
+
+ inline void setSelected( bool b ) { selected = b; update(); }
+ inline void setTextLabel( const QString &text ) { label = text; update(); }
+ inline QString textLabel() const { return label; }
+ inline void setIconSet( const QIconSet &is ) { icon = is; update(); }
+ inline QIconSet iconSet() const { return icon; }
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+protected:
+ void drawButton( QPainter * );
+
+private:
+ bool selected;
+ QString label;
+ QIconSet icon;
+};
+
+class QToolBoxPrivate
+{
+public:
+ struct Page
+ {
+ QToolBoxButton *button;
+ QScrollView *sv;
+ QWidget *widget;
+ QString toolTip;
+
+ inline void setTextLabel( const QString &text ) { button->setTextLabel(text); }
+ inline void setIconSet( const QIconSet &is ) { button->setIconSet(is); }
+ inline void setToolTip( const QString &tip )
+ {
+ toolTip = tip;
+ QToolTip::remove( button );
+ if ( !tip.isNull() )
+ QToolTip::add( button, tip );
+ }
+
+ inline bool operator==(const Page& other) const
+ {
+ return widget == other.widget;
+ }
+ };
+ typedef QValueList<Page> PageList;
+
+ inline QToolBoxPrivate()
+ : currentPage( 0 )
+ {
+ }
+
+ Page *page( QWidget *widget );
+ Page *page( int index );
+
+ void updateTabs();
+
+ PageList pageList;
+ QVBoxLayout *layout;
+ Page *currentPage;
+};
+
+QToolBoxPrivate::Page *QToolBoxPrivate::page( QWidget *widget )
+{
+ if ( !widget )
+ return 0;
+
+ for ( PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i )
+ if ( (*i).widget == widget )
+ return (Page*) &(*i);
+ return 0;
+}
+
+QToolBoxPrivate::Page *QToolBoxPrivate::page( int index )
+{
+ if (index >= 0 && index < (int)pageList.size() )
+ return &*pageList.at(index);
+ return 0;
+}
+
+void QToolBoxPrivate::updateTabs()
+{
+ QToolBoxButton *lastButton = currentPage ? currentPage->button : 0;
+ bool after = FALSE;
+ for ( PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i ) {
+ if (after) {
+ (*i).button->setEraseColor((*i).widget->eraseColor());
+ (*i).button->update();
+ } else if ( (*i).button->backgroundMode() != Qt::PaletteBackground ) {
+ (*i).button->setBackgroundMode( Qt::PaletteBackground );
+ (*i).button->update();
+ }
+ after = (*i).button == lastButton;
+ }
+}
+
+QSize QToolBoxButton::sizeHint() const
+{
+ QSize iconSize(8, 8);
+ if ( !icon.isNull() )
+ iconSize += icon.pixmap( QIconSet::Small, QIconSet::Normal ).size() + QSize( 2, 0 );
+ QSize textSize = fontMetrics().size( Qt::ShowPrefix, label ) + QSize(0, 8);
+
+ QSize total(iconSize.width() + textSize.width(), QMAX(iconSize.height(), textSize.height()));
+ return total.expandedTo(QApplication::globalStrut());
+}
+
+QSize QToolBoxButton::minimumSizeHint() const
+{
+ if ( icon.isNull() )
+ return QSize();
+ return QSize(8, 8) + icon.pixmap( QIconSet::Small, QIconSet::Normal ).size();
+}
+
+void QToolBoxButton::drawButton( QPainter *p )
+{
+ QStyle::SFlags flags = QStyle::Style_Default;
+ const QColorGroup &cg = colorGroup();
+
+ if ( isEnabled() )
+ flags |= QStyle::Style_Enabled;
+ if ( selected )
+ flags |= QStyle::Style_Selected;
+ if ( hasFocus() )
+ flags |= QStyle::Style_HasFocus;
+ if (isDown())
+ flags |= QStyle::Style_Down;
+ style().drawControl( QStyle::CE_ToolBoxTab, p, parentWidget(), rect(), cg, flags );
+
+ QPixmap pm = icon.pixmap( QIconSet::Small, isEnabled() ? QIconSet::Normal : QIconSet::Disabled );
+
+ QRect cr = style().subRect( QStyle::SR_ToolBoxTabContents, this );
+ QRect tr, ir;
+ int ih = 0;
+ if ( pm.isNull() ) {
+ tr = cr;
+ tr.addCoords( 4, 0, -8, 0 );
+ } else {
+ int iw = pm.width() + 4;
+ ih = pm.height();
+ ir = QRect( cr.left() + 4, cr.top(), iw + 2, ih );
+ tr = QRect( ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height() );
+ }
+
+ if ( selected && style().styleHint( QStyle::SH_ToolBox_SelectedPageTitleBold ) ) {
+ QFont f( p->font() );
+ f.setBold( TRUE );
+ p->setFont( f );
+ }
+
+ QString txt;
+ if ( p->fontMetrics().width(label) < tr.width() ) {
+ txt = label;
+ } else {
+ txt = label.left( 1 );
+ int ew = p->fontMetrics().width( "..." );
+ int i = 1;
+ while ( p->fontMetrics().width( txt ) + ew +
+ p->fontMetrics().width( label[i] ) < tr.width() )
+ txt += label[i++];
+ txt += "...";
+ }
+
+ if ( ih )
+ p->drawPixmap( ir.left(), (height() - ih) / 2, pm );
+
+ QToolBox *tb = (QToolBox*)parentWidget();
+
+ const QColor* fill = 0;
+ if ( selected &&
+ style().styleHint( QStyle::SH_ToolBox_SelectedPageTitleBold ) &&
+ tb->backgroundMode() != NoBackground )
+ fill = &cg.color( QPalette::foregroundRoleFromMode( tb->backgroundMode() ) );
+
+ int alignment = AlignLeft | AlignVCenter | ShowPrefix;
+ if (!style().styleHint(QStyle::SH_UnderlineAccelerator, this))
+ alignment |= NoAccel;
+ style().drawItem( p, tr, alignment, cg,
+ isEnabled(), 0, txt, -1, fill );
+
+ if ( !txt.isEmpty() && hasFocus() )
+ style().drawPrimitive( QStyle::PE_FocusRect, p, tr, cg );
+}
+
+/*!
+ \class QToolBox
+
+ \brief The QToolBox class provides a column of tabbed widget
+ items.
+
+ \mainclass
+ \ingroup advanced
+
+ A toolbox is a widget that displays a column of tabs one above the
+ other, with the current item displayed below the current tab.
+ Every tab has an index position within the column of tabs. A tab's
+ item is a QWidget.
+
+ Each item has an itemLabel(), an optional icon, itemIconSet(), an
+ optional itemToolTip(), and a \link item() widget\endlink. The
+ item's attributes can be changed with setItemLabel(),
+ setItemIconSet() and setItemToolTip().
+
+ Items are added using addItem(), or inserted at particular
+ positions using insertItem(). The total number of items is given
+ by count(). Items can be deleted with delete, or removed from the
+ toolbox with removeItem(). Combining removeItem() and insertItem()
+ allows to move items to different positions.
+
+ The current item widget is returned by currentItem() and set with
+ setCurrentItem(). If you prefer you can work in terms of indexes
+ using currentIndex(), setCurrentIndex(), indexOf() and item().
+
+ The currentChanged() signal is emitted when the current item is
+ changed.
+
+ \sa QTabWidget
+*/
+
+/*!
+ \fn void QToolBox::currentChanged( int index )
+
+ This signal is emitted when the current item changed. The new
+ current item's index is passed in \a index, or -1 if there is no
+ current item.
+*/
+
+/*!
+ Constructs a toolbox called \a name with parent \a parent and flags \a f.
+*/
+
+QToolBox::QToolBox( QWidget *parent, const char *name, WFlags f )
+ : QFrame( parent, name, f )
+{
+ d = new QToolBoxPrivate;
+ d->layout = new QVBoxLayout( this );
+ QWidget::setBackgroundMode( PaletteButton );
+}
+
+/*! \reimp */
+
+QToolBox::~QToolBox()
+{
+ delete d;
+}
+
+/*!
+ \fn int QToolBox::addItem( QWidget *w, const QString &label )
+ \overload
+
+ Adds the widget \a w in a new tab at bottom of the toolbox. The
+ new tab's label is set to \a label. Returns the new tab's index.
+*/
+
+/*!
+ \fn int QToolBox::addItem( QWidget *item, const QIconSet &iconSet,const QString &label )
+ Adds the widget \a item in a new tab at bottom of the toolbox. The
+ new tab's label is set to \a label, and the \a iconSet is
+ displayed to the left of the \a label. Returns the new tab's index.
+*/
+
+/*!
+ \fn int QToolBox::insertItem( int index, QWidget *item, const QString &label )
+ \overload
+
+ Inserts the widget \a item at position \a index, or at the bottom
+ of the toolbox if \a index is out of range. The new item's label is
+ set to \a label. Returns the new item's index.
+*/
+
+/*!
+ Inserts the widget \a item at position \a index, or at the bottom
+ of the toolbox if \a index is out of range. The new item's label
+ is set to \a label, and the \a iconSet is displayed to the left of
+ the \a label. Returns the new item's index.
+*/
+
+int QToolBox::insertItem( int index, QWidget *item, const QIconSet &iconSet,
+ const QString &label )
+{
+ if ( !item )
+ return -1;
+
+ connect(item, SIGNAL(destroyed(QObject*)), this, SLOT(itemDestroyed(QObject*)));
+
+ QToolBoxPrivate::Page c;
+ c.widget = item;
+ c.button = new QToolBoxButton( this, label.latin1() );
+ connect( c.button, SIGNAL( clicked() ), this, SLOT( buttonClicked() ) );
+
+ c.sv = new QScrollView( this );
+ c.sv->hide();
+ c.sv->setResizePolicy( QScrollView::AutoOneFit );
+ c.sv->addChild( item );
+ c.sv->setFrameStyle( QFrame::NoFrame );
+
+ c.setTextLabel( label );
+ c.setIconSet( iconSet );
+
+ if ( index < 0 || index >= (int)d->pageList.count() ) {
+ index = (int)d->pageList.count();
+ d->pageList.append( c );
+ d->layout->addWidget( c.button );
+ d->layout->addWidget( c.sv );
+ if ( index == 0 )
+ setCurrentIndex( index );
+ } else {
+ d->pageList.insert( d->pageList.at(index), c );
+ relayout();
+ if (d->currentPage) {
+ QWidget *current = d->currentPage->widget;
+ int oldindex = indexOf(current);
+ if ( index <= oldindex ) {
+ d->currentPage = 0; // trigger change
+ setCurrentIndex(oldindex);
+ }
+ }
+ }
+
+ c.button->show();
+
+ d->updateTabs();
+ itemInserted(index);
+ return index;
+}
+
+void QToolBox::buttonClicked()
+{
+ QToolBoxButton *tb = ::qt_cast<QToolBoxButton*>(sender());
+ QWidget* item = 0;
+ for ( QToolBoxPrivate::PageList::ConstIterator i = d->pageList.constBegin(); i != d->pageList.constEnd(); ++i )
+ if ( (*i).button == tb ) {
+ item = (*i).widget;
+ break;
+ }
+
+ setCurrentItem( item );
+}
+
+/*!
+ \property QToolBox::count
+ \brief The number of items contained in the toolbox.
+*/
+
+int QToolBox::count() const
+{
+ return (int)d->pageList.count();
+}
+
+void QToolBox::setCurrentIndex( int index )
+{
+ setCurrentItem( item( index ) );
+}
+
+/*!
+ Sets the current item to be \a item.
+*/
+
+void QToolBox::setCurrentItem( QWidget *item )
+{
+ QToolBoxPrivate::Page *c = d->page( item );
+ if ( !c || d->currentPage == c )
+ return;
+
+ c->button->setSelected( TRUE );
+ if ( d->currentPage ) {
+ d->currentPage->sv->hide();
+ d->currentPage->button->setSelected(FALSE);
+ }
+ d->currentPage = c;
+ d->currentPage->sv->show();
+ d->updateTabs();
+ emit currentChanged( indexOf(item) );
+}
+
+void QToolBox::relayout()
+{
+ delete d->layout;
+ d->layout = new QVBoxLayout( this );
+ for ( QToolBoxPrivate::PageList::ConstIterator i = d->pageList.constBegin(); i != d->pageList.constEnd(); ++i ) {
+ d->layout->addWidget( (*i).button );
+ d->layout->addWidget( (*i).sv );
+ }
+}
+
+void QToolBox::itemDestroyed(QObject *object)
+{
+ // no verification - vtbl corrupted already
+ QWidget *page = (QWidget*)object;
+
+ QToolBoxPrivate::Page *c = d->page(page);
+ if ( !page || !c )
+ return;
+
+ d->layout->remove( c->sv );
+ d->layout->remove( c->button );
+ c->sv->deleteLater(); // page might still be a child of sv
+ delete c->button;
+
+ bool removeCurrent = c == d->currentPage;
+ d->pageList.remove( *c );
+
+ if ( !d->pageList.count() ) {
+ d->currentPage = 0;
+ emit currentChanged(-1);
+ } else if ( removeCurrent ) {
+ d->currentPage = 0;
+ setCurrentIndex(0);
+ }
+}
+
+/*!
+ Removes the widget \a item from the toolbox. Note that the widget
+ is \e not deleted. Returns the removed widget's index, or -1 if
+ the widget was not in this tool box.
+*/
+
+int QToolBox::removeItem( QWidget *item )
+{
+ int index = indexOf(item);
+ if (index >= 0) {
+ disconnect(item, SIGNAL(destroyed(QObject*)), this, SLOT(itemDestroyed(QObject*)));
+ item->reparent( this, QPoint(0,0) );
+ // destroy internal data
+ itemDestroyed(item);
+ }
+ itemRemoved(index);
+ return index;
+}
+
+
+/*!
+ Returns the toolbox's current item, or 0 if the toolbox is empty.
+*/
+
+QWidget *QToolBox::currentItem() const
+{
+ return d->currentPage ? d->currentPage->widget : 0;
+}
+
+/*!
+ \property QToolBox::currentIndex
+ \brief the index of the current item, or -1 if the toolbox is empty.
+ \sa currentItem(), indexOf(), item()
+*/
+
+
+int QToolBox::currentIndex() const
+{
+ return d->currentPage ? indexOf( d->currentPage->widget ) : -1;
+}
+
+/*!
+ Returns the item at position \a index, or 0 if there is no such
+ item.
+*/
+
+QWidget *QToolBox::item( int index ) const
+{
+ if ( index < 0 || index >= (int) d->pageList.size() )
+ return 0;
+ return (*d->pageList.at( index )).widget;
+}
+
+/*!
+ Returns the index of item \a item, or -1 if the item does not
+ exist.
+*/
+
+int QToolBox::indexOf( QWidget *item ) const
+{
+ QToolBoxPrivate::Page *c = d->page(item);
+ return c ? d->pageList.findIndex( *c ) : -1;
+}
+
+/*!
+ If \a enabled is TRUE then the item at position \a index is enabled; otherwise item
+ \a index is disabled.
+*/
+
+void QToolBox::setItemEnabled( int index, bool enabled )
+{
+ QToolBoxPrivate::Page *c = d->page( index );
+ if ( !c )
+ return;
+
+ c->button->setEnabled( enabled );
+ if ( !enabled && c == d->currentPage ) {
+ int curIndexUp = index;
+ int curIndexDown = curIndexUp;
+ const int count = (int)d->pageList.count();
+ while ( curIndexUp > 0 || curIndexDown < count-1 ) {
+ if ( curIndexDown < count-1 ) {
+ if (d->page(++curIndexDown)->button->isEnabled()) {
+ index = curIndexDown;
+ break;
+ }
+ }
+ if ( curIndexUp > 0 ) {
+ if (d->page(--curIndexUp)->button->isEnabled()) {
+ index = curIndexUp;
+ break;
+ }
+ }
+ }
+ setCurrentIndex(index);
+ }
+}
+
+
+/*!
+ Sets the label of the item at position \a index to \a label.
+*/
+
+void QToolBox::setItemLabel( int index, const QString &label )
+{
+ QToolBoxPrivate::Page *c = d->page( index );
+ if ( c )
+ c->setTextLabel( label );
+}
+
+/*!
+ Sets the icon of the item at position \a index to \a iconSet.
+*/
+
+void QToolBox::setItemIconSet( int index, const QIconSet &iconSet )
+{
+ QToolBoxPrivate::Page *c = d->page( index );
+ if ( c )
+ c->setIconSet( iconSet );
+}
+
+/*!
+ Sets the tooltip of the item at position \a index to \a toolTip.
+*/
+
+void QToolBox::setItemToolTip( int index, const QString &toolTip )
+{
+ QToolBoxPrivate::Page *c = d->page( index );
+ if ( c )
+ c->setToolTip( toolTip );
+}
+
+/*!
+ Returns TRUE if the item at position \a index is enabled; otherwise returns FALSE.
+*/
+
+bool QToolBox::isItemEnabled( int index ) const
+{
+ QToolBoxPrivate::Page *c = d->page( index );
+ return c && c->button->isEnabled();
+}
+
+/*!
+ Returns the label of the item at position \a index, or a null string if
+ \a index is out of range.
+*/
+
+QString QToolBox::itemLabel( int index ) const
+{
+ QToolBoxPrivate::Page *c = d->page( index );
+ return ( c ? c->button->textLabel() : QString::null );
+}
+
+/*!
+ Returns the icon of the item at position \a index, or a null
+ icon if \a index is out of range.
+*/
+
+QIconSet QToolBox::itemIconSet( int index ) const
+{
+ QToolBoxPrivate::Page *c = d->page( index );
+ return ( c ? c->button->iconSet() : QIconSet() );
+}
+
+/*!
+ Returns the tooltip of the item at position \a index, or a null
+ string if \a index is out of range.
+*/
+
+QString QToolBox::itemToolTip( int index ) const
+{
+ QToolBoxPrivate::Page *c = d->page( index );
+ return ( c ? c->toolTip : QString::null );
+}
+
+/*! \reimp */
+void QToolBox::showEvent( QShowEvent *e )
+{
+ QWidget::showEvent( e );
+}
+
+/*! \reimp */
+void QToolBox::frameChanged()
+{
+ d->layout->setMargin( frameWidth() );
+ QFrame::frameChanged();
+}
+
+/*! \reimp */
+void QToolBox::styleChange(QStyle &style)
+{
+ d->updateTabs();
+ QFrame::styleChange(style);
+}
+
+/*!
+ This virtual handler is called after a new item was added or
+ inserted at position \a index.
+ */
+void QToolBox::itemInserted( int index )
+{
+ Q_UNUSED(index)
+}
+
+/*!
+ This virtual handler is called after an item was removed from
+ position \a index.
+ */
+void QToolBox::itemRemoved( int index )
+{
+ Q_UNUSED(index)
+}
+
+#endif //QT_NO_TOOLBOX