diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
commit | bd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch) | |
tree | 7a520322212d48ebcb9fbe1087e7fca28b76185c /src/widgets/qstatusbar.cpp | |
download | qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip |
Add Qt3 development HEAD version
Diffstat (limited to 'src/widgets/qstatusbar.cpp')
-rw-r--r-- | src/widgets/qstatusbar.cpp | 526 |
1 files changed, 526 insertions, 0 deletions
diff --git a/src/widgets/qstatusbar.cpp b/src/widgets/qstatusbar.cpp new file mode 100644 index 0000000..9a57704 --- /dev/null +++ b/src/widgets/qstatusbar.cpp @@ -0,0 +1,526 @@ +/**************************************************************************** +** +** Implementation of QStatusBar class +** +** Created : 980119 +** +** 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 "qstatusbar.h" +#ifndef QT_NO_STATUSBAR + +#include "qptrlist.h" +#include "qlayout.h" +#include "qpainter.h" +#include "qtimer.h" +#include "qdrawutil.h" +#include "qstyle.h" +#include "qsizegrip.h" + +/*! + \class QStatusBar qstatusbar.h + \brief The QStatusBar class provides a horizontal bar suitable for + presenting status information. + + \ingroup application + \ingroup helpsystem + \mainclass + + Each status indicator falls into one of three categories: + + \list + \i \e Temporary - briefly occupies most of the status bar. Used + to explain tool tip texts or menu entries, for example. + \i \e Normal - occupies part of the status bar and may be hidden + by temporary messages. Used to display the page and line + number in a word processor, for example. + \i \e Permanent - is never hidden. Used for important mode + indications, for example, some applications put a Caps Lock + indicator in the status bar. + \endlist + + QStatusBar lets you display all three types of indicators. + + To display a \e temporary message, call message() (perhaps by + connecting a suitable signal to it). To remove a temporary + message, call clear(). There are two variants of message(): one + that displays the message until the next clear() or message() and + one that has a time limit: + + \code + connect( loader, SIGNAL(progressMessage(const QString&)), + statusBar(), SLOT(message(const QString&)) ); + + statusBar()->message("Loading..."); // Initial message + loader.loadStuff(); // Emits progress messages + statusBar()->message("Done.", 2000); // Final message for 2 seconds + \endcode + + \e Normal and \e Permanent messages are displayed by creating a + small widget and then adding it to the status bar with + addWidget(). Widgets like QLabel, QProgressBar or even QToolButton + are useful for adding to status bars. removeWidget() is used to + remove widgets. + + \code + statusBar()->addWidget(new MyReadWriteIndication(statusBar())); + \endcode + + By default QStatusBar provides a QSizeGrip in the lower-right + corner. You can disable it with setSizeGripEnabled(FALSE); + + <img src=qstatusbar-m.png> <img src=qstatusbar-w.png> + + \sa QToolBar QMainWindow QLabel + \link guibooks.html#fowler GUI Design Handbook: Status Bar.\endlink +*/ + + +class QStatusBarPrivate +{ +public: + QStatusBarPrivate() {} + + struct SBItem { + SBItem( QWidget* widget, int stretch, bool permanent ) + : s( stretch ), w( widget ), p( permanent ) {} + int s; + QWidget * w; + bool p; + }; + + QPtrList<SBItem> items; + QString tempItem; + + QBoxLayout * box; + QTimer * timer; + +#ifndef QT_NO_SIZEGRIP + QSizeGrip * resizer; +#endif + + int savedStrut; +}; + + +/*! + Constructs a status bar called \a name with parent \a parent and + with a size grip. + + \sa setSizeGripEnabled() +*/ +QStatusBar::QStatusBar( QWidget * parent, const char *name ) + : QWidget( parent, name ) +{ + d = new QStatusBarPrivate; + d->items.setAutoDelete( TRUE ); + d->box = 0; + d->timer = 0; + +#ifndef QT_NO_SIZEGRIP + d->resizer = 0; + setSizeGripEnabled(TRUE); // causes reformat() +#else + reformat(); +#endif +} + + +/*! + Destroys the status bar and frees any allocated resources and + child widgets. +*/ +QStatusBar::~QStatusBar() +{ + delete d; + d = 0; +} + + +/*! + Adds \a widget to this status bar. \a widget is reparented if it + isn't already a child of the QStatusBar. + + \a widget is permanently visible if \a permanent is TRUE and may + be obscured by temporary messages if \a permanent is FALSE. The + default is FALSE. + + If \a permanent is TRUE, \a widget is located at the far right of + the status bar. If \a permanent is FALSE (the default), \a widget + is located just to the left of the first permanent widget. + + \a stretch is used to compute a suitable size for \a widget as the + status bar grows and shrinks. The default of 0 uses a minimum of + space. + + This function may cause some flicker. + + \sa removeWidget() +*/ + +void QStatusBar::addWidget( QWidget * widget, int stretch, bool permanent ) +{ + if ( !widget ) { +#if defined(QT_CHECK_NULL) + qWarning( "QStatusBar::addWidget(): Cannot add null widget" ); +#endif + return; + } + + if ( widget->parentWidget() != this ) + widget->reparent( this, QPoint(0, 0), TRUE ); + + QStatusBarPrivate::SBItem* item + = new QStatusBarPrivate::SBItem( widget, stretch, permanent ); + + d->items.last(); + while( !permanent && d->items.current() && d->items.current()->p ) + d->items.prev(); + + d->items.insert( d->items.at() >= 0 ? d->items.at()+1 : 0, item ); + + if ( !d->tempItem.isEmpty() && !permanent ) + widget->hide(); + + reformat(); +} + + +/*! + Removes \a widget from the status bar. + + This function may cause some flicker. + + Note that \a widget is not deleted. + + \sa addWidget() +*/ + +void QStatusBar::removeWidget( QWidget* widget ) +{ + if ( !widget ) + return; + bool found = FALSE; + QStatusBarPrivate::SBItem* item = d->items.first(); + while ( item && !found ) { + if ( item->w == widget ) { + d->items.remove(); + found = TRUE; + } + item = d->items.next(); + } + + if ( found ) + reformat(); +#if defined(QT_DEBUG) + else + qDebug( "QStatusBar::removeWidget(): Widget not found." ); +#endif +} + +/*! + \property QStatusBar::sizeGripEnabled + \brief whether the QSizeGrip in the bottom right of the status bar is enabled + + Enables or disables the QSizeGrip in the bottom right of the + status bar. By default, the size grip is enabled. +*/ + +bool QStatusBar::isSizeGripEnabled() const +{ +#ifdef QT_NO_SIZEGRIP + return FALSE; +#else + return !!d->resizer; +#endif +} + +void QStatusBar::setSizeGripEnabled(bool enabled) +{ +#ifndef QT_NO_SIZEGRIP + if ( !enabled != !d->resizer ) { + if ( enabled ) { + d->resizer = new QSizeGrip( this, "QStatusBar::resizer" ); + } else { + delete d->resizer; + d->resizer = 0; + } + reformat(); + if ( d->resizer && isVisible() ) + d->resizer->show(); + } +#endif +} + + +/*! + Changes the status bar's appearance to account for item changes. + Special subclasses may need this, but geometry management will + usually take care of any necessary rearrangements. +*/ +void QStatusBar::reformat() +{ + if ( d->box ) + delete d->box; + + QBoxLayout *vbox; + if ( isSizeGripEnabled() ) { + d->box = new QHBoxLayout( this ); + vbox = new QVBoxLayout( d->box ); + } else { + vbox = d->box = new QVBoxLayout( this ); + } + vbox->addSpacing( 3 ); + QBoxLayout* l = new QHBoxLayout( vbox ); + l->addSpacing( 3 ); + l->setSpacing( 4 ); + + int maxH = fontMetrics().height(); + + QStatusBarPrivate::SBItem* item = d->items.first(); + while ( item && !item->p ) { + l->addWidget( item->w, item->s ); + int itemH = QMIN(item->w->sizeHint().height(), + item->w->maximumHeight()); + maxH = QMAX( maxH, itemH ); + item = d->items.next(); + } + + l->addStretch( 0 ); + + while ( item ) { + l->addWidget( item->w, item->s ); + int itemH = QMIN(item->w->sizeHint().height(), + item->w->maximumHeight()); + maxH = QMAX( maxH, itemH ); + item = d->items.next(); + } + l->addSpacing( 4 ); +#ifndef QT_NO_SIZEGRIP + if ( d->resizer ) { + maxH = QMAX( maxH, d->resizer->sizeHint().height() ); + d->box->addSpacing( 1 ); + d->box->addWidget( d->resizer, 0, AlignBottom ); + } +#endif + l->addStrut( maxH ); + d->savedStrut = maxH; + vbox->addSpacing( 2 ); + d->box->activate(); + repaint(); +} + + + + +/*! + Hides the normal status indicators and displays \a message until + clear() or another message() is called. + + \sa clear() +*/ +void QStatusBar::message( const QString &message ) +{ + if ( d->tempItem == message ) + return; + d->tempItem = message; + if ( d->timer ) { + delete d->timer; + d->timer = 0; + } + hideOrShow(); +} + + +/*! + \overload + + Hides the normal status indications and displays \a message for \a + ms milli-seconds or until clear() or another message() is called, + whichever occurs first. +*/ +void QStatusBar::message( const QString &message, int ms ) +{ + d->tempItem = message; + + if ( !d->timer ) { + d->timer = new QTimer( this ); + connect( d->timer, SIGNAL(timeout()), this, SLOT(clear()) ); + } + if ( ms > 0 ) { + d->timer->start( ms ); + } else if ( d->timer ) { + delete d->timer; + d->timer = 0; + } + + hideOrShow(); +} + + +/*! + Removes any temporary message being shown. + + \sa message() +*/ + +void QStatusBar::clear() +{ + if ( d->tempItem.isEmpty() ) + return; + if ( d->timer ) { + delete d->timer; + d->timer = 0; + } + d->tempItem = QString::null; + hideOrShow(); +} + +/*! + \fn QStatusBar::messageChanged( const QString &message ) + + This signal is emitted when the temporary status messages + changes. \a message is the new temporary message, and is a + null-string when the message has been removed. + + \sa message(), clear() +*/ + +/*! + Ensures that the right widgets are visible. Used by message() and + clear(). +*/ +void QStatusBar::hideOrShow() +{ + bool haveMessage = !d->tempItem.isEmpty(); + + QStatusBarPrivate::SBItem* item = d->items.first(); + + while( item && !item->p ) { + if ( haveMessage ) + item->w->hide(); + else + item->w->show(); + item = d->items.next(); + } + + emit messageChanged( d->tempItem ); + repaint(); +} + + +/*! + Shows the temporary message, if appropriate. +*/ +void QStatusBar::paintEvent( QPaintEvent * ) +{ + bool haveMessage = !d->tempItem.isEmpty(); + + QPainter p( this ); + QStatusBarPrivate::SBItem* item = d->items.first(); + +#ifndef QT_NO_SIZEGRIP + int psx = ( d->resizer && d->resizer->isVisible() ) ? d->resizer->x() : width()-12; +#else + int psx = width() - 12; +#endif + + while ( item ) { + if ( !haveMessage || item->p ) + if ( item->w->isVisible() ) { + if ( item->p && item->w->x()-1 < psx ) + psx = item->w->x()-1; + style().drawPrimitive( QStyle::PE_StatusBarSection, &p, + QRect(item->w->x() - 1, item->w->y() - 1, + item->w->width()+2, item->w->height()+2), + colorGroup(), QStyle::Style_Default, + QStyleOption(item->w) ); + } + item = d->items.next(); + } + if ( haveMessage ) { + p.setPen( colorGroup().foreground() ); + p.drawText( 6, 0, psx, height(), AlignVCenter | SingleLine, d->tempItem ); + } +} + +/*! + \reimp +*/ +void QStatusBar::resizeEvent( QResizeEvent * e ) +{ + QWidget::resizeEvent( e ); +} + +/*! + \reimp +*/ + +bool QStatusBar::event( QEvent *e ) +{ + if ( e->type() == QEvent::LayoutHint ) { + // Calculate new strut height and call reformat() if it has changed + int maxH = fontMetrics().height(); + + QStatusBarPrivate::SBItem* item = d->items.first(); + while ( item ) { + int itemH = QMIN(item->w->sizeHint().height(), + item->w->maximumHeight()); + maxH = QMAX( maxH, itemH ); + item = d->items.next(); + } + +#ifndef QT_NO_SIZEGRIP + if ( d->resizer ) + maxH = QMAX( maxH, d->resizer->sizeHint().height() ); +#endif + + if ( maxH != d->savedStrut ) + reformat(); + else + update(); + } + if ( e->type() == QEvent::ChildRemoved ) { + QStatusBarPrivate::SBItem* item = d->items.first(); + while ( item ) { + if ( item->w == ( (QChildEvent*)e )->child() ) + d->items.removeRef( item ); + item = d->items.next(); + } + } + return QWidget::event( e ); +} + +#endif |