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/qbutton.cpp | |
download | qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip |
Add Qt3 development HEAD version
Diffstat (limited to 'src/widgets/qbutton.cpp')
-rw-r--r-- | src/widgets/qbutton.cpp | 1008 |
1 files changed, 1008 insertions, 0 deletions
diff --git a/src/widgets/qbutton.cpp b/src/widgets/qbutton.cpp new file mode 100644 index 0000000..57178fb --- /dev/null +++ b/src/widgets/qbutton.cpp @@ -0,0 +1,1008 @@ +/**************************************************************************** +** +** Implementation of QButton widget class +** +** Created : 940206 +** +** 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. +** +**********************************************************************/ + +#undef QT_NO_COMPAT +#include "qbutton.h" +#ifndef QT_NO_BUTTON +#include "qbuttongroup.h" +#include "qbitmap.h" +#include "qpainter.h" +#include "qtimer.h" +#include "qaccel.h" +#include "qpixmapcache.h" +#include "qapplication.h" +#include "qpushbutton.h" +#include "qradiobutton.h" +#include "qguardedptr.h" +#include "../kernel/qinternal_p.h" + +#if defined(QT_ACCESSIBILITY_SUPPORT) +#include "qaccessible.h" +#endif + +#define AUTO_REPEAT_DELAY 300 +#define AUTO_REPEAT_PERIOD 100 + +class QButtonData +{ +public: + QButtonData() { +#ifndef QT_NO_BUTTONGROUP + group = 0; +#endif +#ifndef QT_NO_ACCEL + a = 0; +#endif + } +#ifndef QT_NO_BUTTONGROUP + QButtonGroup *group; +#endif + QTimer timer; +#ifndef QT_NO_ACCEL + QAccel *a; +#endif +}; + + +void QButton::ensureData() +{ + if ( !d ) { + d = new QButtonData; + Q_CHECK_PTR( d ); + connect(&d->timer, SIGNAL(timeout()), this, SLOT(autoRepeatTimeout())); + } +} + + +/*! + Returns the group that this button belongs to. + + If the button is not a member of any QButtonGroup, this function + returns 0. + + \sa QButtonGroup +*/ + +QButtonGroup *QButton::group() const +{ +#ifndef QT_NO_BUTTONGROUP + return d ? d->group : 0; +#else + return 0; +#endif +} + + +void QButton::setGroup( QButtonGroup* g ) +{ +#ifndef QT_NO_BUTTONGROUP + ensureData(); + d->group = g; +#endif +} + + +QTimer *QButton::timer() +{ + ensureData(); + return &d->timer; +} + + +/*! + \class QButton qbutton.h + \brief The QButton class is the abstract base class of button + widgets, providing functionality common to buttons. + + \ingroup abstractwidgets + + <b>If you want to create a button use QPushButton.</b> + + The QButton class implements an \e abstract button, and lets + subclasses specify how to reply to user actions and how to draw + the button. + + QButton provides both push and toggle buttons. The QRadioButton + and QCheckBox classes provide only toggle buttons; QPushButton and + QToolButton provide both toggle and push buttons. + + Any button can have either a text or pixmap label. setText() sets + the button to be a text button and setPixmap() sets it to be a + pixmap button. The text/pixmap is manipulated as necessary to + create the "disabled" appearance when the button is disabled. + + QButton provides most of the states used for buttons: + \list + \i isDown() indicates whether the button is \e pressed down. + \i isOn() indicates whether the button is \e on. + Only toggle buttons can be switched on and off (see below). + \i isEnabled() indicates whether the button can be pressed by the + user. + \i setAutoRepeat() sets whether the button will auto-repeat + if the user holds it down. + \i setToggleButton() sets whether the button is a toggle + button or not. + \endlist + + The difference between isDown() and isOn() is as follows: When the + user clicks a toggle button to toggle it on, the button is first + \e pressed and then released into the \e on state. When the user + clicks it again (to toggle it off), the button moves first to the + \e pressed state, then to the \e off state (isOn() and isDown() + are both FALSE). + + Default buttons (as used in many dialogs) are provided by + QPushButton::setDefault() and QPushButton::setAutoDefault(). + + QButton provides five signals: + \list 1 + \i pressed() is emitted when the button is pressed. E.g. with the mouse + or when animateClick() is called. + \i released() is emitted when the button is released. E.g. when the mouse + is released or the cursor is moved outside the widget. + \i clicked() is emitted when the button is first pressed and then + released when the accelerator key is typed, or when + animateClick() is called. + \i toggled(bool) is emitted when the state of a toggle button changes. + \i stateChanged(int) is emitted when the state of a tristate + toggle button changes. + \endlist + + If the button is a text button with an ampersand (\&) in its text, + QButton creates an automatic accelerator key. This code creates a + push button labelled "Ro<u>c</u>k \& Roll" (where the c is + underlined). The button gets an automatic accelerator key, Alt+C: + + \code + QPushButton *p = new QPushButton( "Ro&ck && Roll", this ); + \endcode + + In this example, when the user presses Alt+C the button will call + animateClick(). + + You can also set a custom accelerator using the setAccel() + function. This is useful mostly for pixmap buttons because they + have no automatic accelerator. + + \code + p->setPixmap( QPixmap("print.png") ); + p->setAccel( ALT+Key_F7 ); + \endcode + + All of the buttons provided by Qt (\l QPushButton, \l QToolButton, + \l QCheckBox and \l QRadioButton) can display both text and + pixmaps. + + To subclass QButton, you must reimplement at least drawButton() + (to draw the button's outline) and drawButtonLabel() (to draw its + text or pixmap). It is generally advisable to reimplement + sizeHint() as well, and sometimes hitButton() (to determine + whether a button press is within the button). + + To reduce flickering, QButton::paintEvent() sets up a pixmap that + the drawButton() function draws in. You should not reimplement + paintEvent() for a subclass of QButton unless you want to take + over all drawing. + + \sa QButtonGroup +*/ + + +/*! + \enum QButton::ToggleType + + This enum type defines what a button can do in response to a + mouse/keyboard press: + + \value SingleShot pressing the button causes an action, then the + button returns to the unpressed state. + + \value Toggle pressing the button toggles it between an \c On and + an \c Off state. + + \value Tristate pressing the button cycles between the three + states \c On, \c Off and \c NoChange +*/ + +/*! + \enum QButton::ToggleState + + This enum defines the state of a toggle button. + + \value Off the button is in the "off" state + \value NoChange the button is in the default/unchanged state + \value On the button is in the "on" state +*/ + +/*! + \property QButton::accel + \brief the accelerator associated with the button + + This property is 0 if there is no accelerator set. If you set this + property to 0 then any current accelerator is removed. +*/ + +/*! + \property QButton::autoRepeat + \brief whether autoRepeat is enabled + + If autoRepeat is enabled then the clicked() signal is emitted at + regular intervals if the button is down. This property has no + effect on toggle buttons. autoRepeat is off by default. +*/ + +/*! \property QButton::autoResize + \brief whether autoResize is enabled + \obsolete + + If autoResize is enabled then the button will resize itself + whenever the contents are changed. +*/ + +/*! + \property QButton::down + \brief whether the button is pressed + + If this property is TRUE, the button is pressed down. The signals + pressed() and clicked() are not emitted if you set this property + to TRUE. The default is FALSE. +*/ + +/*! + \property QButton::exclusiveToggle + \brief whether the button is an exclusive toggle + + If this property is TRUE and the button is in a QButtonGroup, the + button can only be toggled off by another one being toggled on. + The default is FALSE. +*/ + +/*! + \property QButton::on + \brief whether the button is toggled + + This property should only be set for toggle buttons. +*/ + +/*! + \fn void QButton::setOn( bool on ) + + Sets the state of this button to On if \a on is TRUE; otherwise to + Off. + + \sa toggleState +*/ + +/*! + \property QButton::pixmap + \brief the pixmap shown on the button + + If the pixmap is monochrome (i.e. it is a QBitmap or its \link + QPixmap::depth() depth\endlink is 1) and it does not have a mask, + this property will set the pixmap to be its own mask. The purpose + of this is to draw transparent bitmaps which are important for + toggle buttons, for example. + + pixmap() returns 0 if no pixmap was set. +*/ + +/*! + \property QButton::text + \brief the text shown on the button + + This property will return a QString::null if the button has no + text. If the text has an ampersand (\&) in it, then an + accelerator is automatically created for it using the character + that follows the '\&' as the accelerator key. Any previous + accelerator will be overwritten, or cleared if no accelerator is + defined by the text. + + There is no default text. +*/ + +/*! + \property QButton::toggleButton + \brief whether the button is a toggle button + + The default value is FALSE. +*/ + +/*! + \fn QButton::setToggleButton( bool b ) + + If \a b is TRUE, this button becomes a toggle button; if \a b is + FALSE, this button becomes a command button. + + \sa toggleButton +*/ + +/*! + \property QButton::toggleState + \brief the state of the toggle button + + If this property is changed then it does not cause the button + to be repainted. +*/ + +/*! + \property QButton::toggleType + \brief the type of toggle on the button + + The default toggle type is \c SingleShot. + + \sa QButton::ToggleType +*/ + +/*! + Constructs a standard button called \a name with parent \a parent, + using the widget flags \a f. + + If \a parent is a QButtonGroup, this constructor calls + QButtonGroup::insert(). +*/ + +QButton::QButton( QWidget *parent, const char *name, WFlags f ) + : QWidget( parent, name, f ) +{ + bpixmap = 0; + toggleTyp = SingleShot; // button is simple + buttonDown = FALSE; // button is up + stat = Off; // button is off + mlbDown = FALSE; // mouse left button up + autoresize = FALSE; // not auto resizing + animation = FALSE; // no pending animateClick + repeat = FALSE; // not in autorepeat mode + d = 0; +#ifndef QT_NO_BUTTONGROUP + if ( ::qt_cast<QButtonGroup*>(parent) ) { + setGroup((QButtonGroup*)parent); + group()->insert( this ); // insert into button group + } +#endif + setFocusPolicy( TabFocus ); +} + +/*! + Destroys the button. + */ +QButton::~QButton() +{ +#ifndef QT_NO_BUTTONGROUP + if ( group() ) + group()->remove( this ); +#endif + delete bpixmap; + delete d; +} + + +/*! + \fn void QButton::pressed() + + This signal is emitted when the button is pressed down. + + \sa released(), clicked() +*/ + +/*! + \fn void QButton::released() + + This signal is emitted when the button is released. + + \sa pressed(), clicked(), toggled() +*/ + +/*! + \fn void QButton::clicked() + + This signal is emitted when the button is activated (i.e. first + pressed down and then released when the mouse cursor is inside the + button), when the accelerator key is typed or when animateClick() + is called. This signal is \e not emitted if you call setDown(). + + The QButtonGroup::clicked() signal does the same job, if you want + to connect several buttons to the same slot. + + \warning Don't launch a model dialog in response to this signal + for a button that has \c autoRepeat turned on. + + \sa pressed(), released(), toggled() autoRepeat down +*/ + +/*! + \fn void QButton::toggled( bool on ) + + This signal is emitted whenever a toggle button changes status. \a + on is TRUE if the button is on, or FALSE if the button is off. + + This may be the result of a user action, toggle() slot activation, + or because setOn() was called. + + \sa clicked() +*/ + +/*! + \fn void QButton::stateChanged( int state ) + + This signal is emitted whenever a toggle button changes state. \a + state is \c On if the button is on, \c NoChange if it is in the + \link QCheckBox::setTristate() "no change" state\endlink or \c Off + if the button is off. + + This may be the result of a user action, toggle() slot activation, + setState(), or because setOn() was called. + + \sa clicked() QButton::ToggleState +*/ + +void QButton::setText( const QString &text ) +{ + if ( btext == text ) + return; + btext = text; +#ifndef QT_NO_ACCEL + setAccel( QAccel::shortcutKey( text ) ); +#endif + + if ( bpixmap ) { + delete bpixmap; + bpixmap = 0; + } + + if ( autoresize ) + adjustSize(); + + update(); + updateGeometry(); + +#if defined(QT_ACCESSIBILITY_SUPPORT) + QAccessible::updateAccessibility( this, 0, QAccessible::NameChanged ); +#endif +} + +void QButton::setPixmap( const QPixmap &pixmap ) +{ + if ( bpixmap && bpixmap->serialNumber() == pixmap.serialNumber() ) + return; + + bool newSize; + if ( bpixmap ) { + newSize = pixmap.width() != bpixmap->width() || + pixmap.height() != bpixmap->height(); + *bpixmap = pixmap; + } else { + newSize = TRUE; + bpixmap = new QPixmap( pixmap ); + Q_CHECK_PTR( bpixmap ); + } + if ( bpixmap->depth() == 1 && !bpixmap->mask() ) + bpixmap->setMask( *((QBitmap *)bpixmap) ); + if ( !btext.isNull() ) { + btext = QString::null; +#ifndef QT_NO_ACCEL + setAccel( QKeySequence() ); +#endif + } + if ( autoresize && newSize ) + adjustSize(); + if ( autoMask() ) + updateMask(); + update(); + if ( newSize ) + updateGeometry(); +} + + +#ifndef QT_NO_ACCEL +QKeySequence QButton::accel() const +{ + if ( d && d->a ) + return d->a->key( 0 ); + return QKeySequence(); +} + +void QButton::setAccel( const QKeySequence& key ) +{ + if ( d && d->a ) + d->a->clear(); + if ( key.isEmpty() ) + return; + ensureData(); + if ( !d->a ) { + d->a = new QAccel( this, "buttonAccel" ); + connect( d->a, SIGNAL( activated(int) ), this, SLOT( animateClick() ) ); + connect( d->a, SIGNAL( activatedAmbiguously(int) ), this, SLOT( setFocus() ) ); + } + d->a->insertItem( key, 0 ); +} +#endif + +#ifndef QT_NO_COMPAT + +void QButton::setAutoResize( bool enable ) +{ + if ( (bool)autoresize != enable ) { + autoresize = enable; + if ( autoresize ) + adjustSize(); // calls resize which repaints + } +} + +#endif + +void QButton::setAutoRepeat( bool enable ) +{ + repeat = (uint)enable; + if ( repeat && mlbDown ) + timer()->start( AUTO_REPEAT_DELAY, TRUE ); +} + +/*! + Performs an animated click: the button is pressed and released a + short while later. + + The pressed(), released(), clicked(), toggled(), and + stateChanged() signals are emitted as appropriate. + + This function does nothing if the button is \link setEnabled() + disabled. \endlink + + \sa setAccel() +*/ + +void QButton::animateClick() +{ + if ( !isEnabled() || animation ) + return; + animation = TRUE; + buttonDown = TRUE; + repaint( FALSE ); + emit pressed(); + QTimer::singleShot( 100, this, SLOT(animateTimeout()) ); +} + +void QButton::emulateClick() +{ + if ( !isEnabled() || animation ) + return; + animation = TRUE; + buttonDown = TRUE; + emit pressed(); + animateTimeout(); +} + +void QButton::setDown( bool enable ) +{ + if ( d ) + timer()->stop(); + mlbDown = FALSE; // the safe setting + if ( (bool)buttonDown != enable ) { + buttonDown = enable; + repaint( FALSE ); +#if defined(QT_ACCESSIBILITY_SUPPORT) + QAccessible::updateAccessibility( this, 0, QAccessible::StateChanged ); +#endif + } +} + +/*! + Sets the toggle state of the button to \a s. \a s can be \c Off, \c + NoChange or \c On. +*/ + +void QButton::setState( ToggleState s ) +{ + if ( !toggleTyp ) { +#if defined(QT_CHECK_STATE) + qWarning( "QButton::setState() / setOn: (%s) Only toggle buttons " + "may be switched", name( "unnamed" ) ); +#endif + return; + } + + if ( (ToggleState)stat != s ) { // changed state + bool was = stat != Off; + stat = s; + if ( autoMask() ) + updateMask(); + repaint( FALSE ); +#if defined(QT_ACCESSIBILITY_SUPPORT) + QAccessible::updateAccessibility( this, 0, QAccessible::StateChanged ); +#endif + // ### toggled for tristate makes no sense. Don't emit the signal in 4.0 + if ( was != (stat != Off) ) + emit toggled( stat != Off ); + emit stateChanged( s ); + } +} + + +/*! + Returns TRUE if \a pos is inside the clickable button rectangle; + otherwise returns FALSE. + + By default, the clickable area is the entire widget. Subclasses + may reimplement it, though. +*/ +bool QButton::hitButton( const QPoint &pos ) const +{ + return rect().contains( pos ); +} + +/*! + Draws the button. The default implementation does nothing. + + This virtual function is reimplemented by subclasses to draw real + buttons. At some point, these reimplementations should call + drawButtonLabel(). + + \sa drawButtonLabel(), paintEvent() +*/ +#if (QT_VERSION-0 >= 0x040000) +#error "QButton. Make pure virtual" +#endif +void QButton::drawButton( QPainter * ) +{ + return; +} + +/*! + Draws the button text or pixmap. + + This virtual function is reimplemented by subclasses to draw real + buttons. It is invoked by drawButton(). + + \sa drawButton(), paintEvent() +*/ + +void QButton::drawButtonLabel( QPainter * ) +{ + return; +} + +/*! \reimp */ +void QButton::keyPressEvent( QKeyEvent *e ) +{ + switch ( e->key() ) { + case Key_Enter: + case Key_Return: + { +#ifndef QT_NO_PUSHBUTTON + QPushButton *pb = (QPushButton*)qt_cast( "QPushButton" ); + if ( pb && ( pb->autoDefault() || pb->isDefault() ) ) + emit clicked(); + else +#endif + e->ignore(); + } + break; + case Key_Space: + if ( !e->isAutoRepeat() ) { + setDown( TRUE ); +#ifndef QT_NO_PUSHBUTTON + if ( ::qt_cast<QPushButton*>(this) ) + emit pressed(); + else +#endif + e->ignore(); + } + break; + case Key_Up: + case Key_Left: +#ifndef QT_NO_BUTTONGROUP + if ( group() ) { + group()->moveFocus( e->key() ); + } else +#endif + { + QFocusEvent::setReason(QFocusEvent::Backtab); + focusNextPrevChild( FALSE ); + QFocusEvent::resetReason(); + } + break; + case Key_Right: + case Key_Down: +#ifndef QT_NO_BUTTONGROUP + if ( group() ) { + group()->moveFocus( e->key() ); + } else +#endif + { + QFocusEvent::setReason(QFocusEvent::Tab); + focusNextPrevChild( TRUE ); + QFocusEvent::resetReason(); + } + break; + case Key_Escape: + if ( buttonDown ) { + buttonDown = FALSE; + update(); + break; + } + // fall through + default: + e->ignore(); + } +} + +/*! \reimp */ +void QButton::keyReleaseEvent( QKeyEvent * e) +{ + switch ( e->key() ) { + case Key_Space: + if ( buttonDown && !e->isAutoRepeat() ) { + buttonDown = FALSE; + nextState(); + emit released(); + emit clicked(); + } + break; + default: + e->ignore(); + } +} + +/*! \reimp */ +void QButton::mousePressEvent( QMouseEvent *e ) +{ + if ( e->button() != LeftButton ) { + e->ignore(); + return; + } + bool hit = hitButton( e->pos() ); + if ( hit ) { // mouse press on button + mlbDown = TRUE; // left mouse button down + buttonDown = TRUE; + if ( autoMask() ) + updateMask(); + + repaint( FALSE ); +#if defined(QT_ACCESSIBILITY_SUPPORT) + QAccessible::updateAccessibility( this, 0, QAccessible::StateChanged ); +#endif + QGuardedPtr<QTimer> t = timer(); + emit pressed(); + if ( t && repeat ) + t->start( AUTO_REPEAT_DELAY, TRUE ); + } +} + +/*! \reimp */ +void QButton::mouseReleaseEvent( QMouseEvent *e) +{ + if ( e->button() != LeftButton ) { + + // clean up apperance if left button has been pressed + if (mlbDown || buttonDown) { + mlbDown = FALSE; + buttonDown = FALSE; + + if ( autoMask() ) + updateMask(); + repaint( FALSE ); + } + + e->ignore(); + return; + } + if ( !mlbDown ) + return; + if ( d ) + timer()->stop(); + + const bool oldButtonDown = buttonDown; + mlbDown = FALSE; // left mouse button up + buttonDown = FALSE; + if ( hitButton( e->pos() ) ) { // mouse release on button + nextState(); +#if defined(QT_ACCESSIBILITY_SUPPORT) + QAccessible::updateAccessibility( this, 0, QAccessible::StateChanged ); +#endif + emit released(); + emit clicked(); + } else { + repaint( FALSE ); +#if defined(QT_ACCESSIBILITY_SUPPORT) + QAccessible::updateAccessibility( this, 0, QAccessible::StateChanged ); +#endif + if (oldButtonDown) + emit released(); + } +} + +/*! \reimp */ +void QButton::mouseMoveEvent( QMouseEvent *e ) +{ + if ( !((e->state() & LeftButton) && mlbDown) ) { + e->ignore(); + return; // left mouse button is up + } + if ( hitButton(e->pos()) ) { // mouse move in button + if ( !buttonDown ) { + buttonDown = TRUE; + repaint( FALSE ); +#if defined(QT_ACCESSIBILITY_SUPPORT) + QAccessible::updateAccessibility( this, 0, QAccessible::StateChanged ); +#endif + emit pressed(); + } + } else { // mouse move outside button + if ( buttonDown ) { + buttonDown = FALSE; + repaint( FALSE ); +#if defined(QT_ACCESSIBILITY_SUPPORT) + QAccessible::updateAccessibility( this, 0, QAccessible::StateChanged ); +#endif + emit released(); + } + } +} + + +/*! + Handles paint events for buttons. Small and typically complex + buttons are painted double-buffered to reduce flicker. The + actually drawing is done in the virtual functions drawButton() and + drawButtonLabel(). + + \sa drawButton(), drawButtonLabel() +*/ +void QButton::paintEvent( QPaintEvent *) +{ + QSharedDoubleBuffer buffer( this ); + drawButton( buffer.painter() ); +} + +/*! \reimp */ +void QButton::focusInEvent( QFocusEvent * e) +{ + QWidget::focusInEvent( e ); +} + +/*! \reimp */ +void QButton::focusOutEvent( QFocusEvent * e ) +{ + buttonDown = FALSE; + QWidget::focusOutEvent( e ); +} + +/*! + Internal slot used for auto repeat. +*/ +void QButton::autoRepeatTimeout() +{ + if ( mlbDown && isEnabled() && autoRepeat() ) { + QGuardedPtr<QTimer> t = timer(); + if ( buttonDown ) { + emit released(); + emit clicked(); + emit pressed(); + } + if ( t ) + t->start( AUTO_REPEAT_PERIOD, TRUE ); + } +} + +/*! + Internal slot used for the second stage of animateClick(). +*/ +void QButton::animateTimeout() +{ + if ( !animation ) + return; + animation = FALSE; + buttonDown = FALSE; + nextState(); + emit released(); + emit clicked(); +} + + +void QButton::nextState() +{ + bool t = isToggleButton() && !( isOn() && isExclusiveToggle() ); + bool was = stat != Off; + if ( t ) { + if ( toggleTyp == Tristate ) + stat = ( stat + 1 ) % 3; + else + stat = stat ? Off : On; + } + if ( autoMask() ) + updateMask(); + repaint( FALSE ); + if ( t ) { +#if defined(QT_ACCESSIBILITY_SUPPORT) + QAccessible::updateAccessibility( this, 0, QAccessible::StateChanged ); +#endif + if ( was != (stat != Off) ) + emit toggled( stat != Off ); + emit stateChanged( stat ); + } +} + +/*! \reimp */ +void QButton::enabledChange( bool e ) +{ + if ( !isEnabled() ) + setDown( FALSE ); + QWidget::enabledChange( e ); +} + + +/*! + Toggles the state of a toggle button. + + \sa isOn(), setOn(), toggled(), isToggleButton() +*/ +void QButton::toggle() +{ + if ( isToggleButton() ) + setOn( !isOn() ); +} + +/*! + Sets the toggle type of the button to \a type. + + \a type can be set to \c SingleShot, \c Toggle and \c Tristate. +*/ +void QButton::setToggleType( ToggleType type ) +{ + toggleTyp = type; + if ( type != Tristate && stat == NoChange ) + setState( On ); +#if defined(QT_ACCESSIBILITY_SUPPORT) + else + QAccessible::updateAccessibility( this, 0, QAccessible::StateChanged ); +#endif +} + +bool QButton::isExclusiveToggle() const +{ +#ifndef QT_NO_BUTTONGROUP + return group() && ( group()->isExclusive() || + group()->isRadioButtonExclusive() && + ::qt_cast<QRadioButton*>(this) ); +#else + return FALSE; +#endif +} + +#endif |