src/gui/widgets/qabstractbutton.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtGui module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "qabstractbutton.h"
00025 #include "qbuttongroup.h"
00026 #include "qabstractbutton_p.h"
00027 #include "qevent.h"
00028 #include "qpainter.h"
00029 #include "qapplication.h"
00030 #include "qstyle.h"
00031 #include "qaction.h"
00032 #ifndef QT_NO_ACCESSIBILITY
00033 #include "qaccessible.h"
00034 #endif
00035 
00036 #define AUTO_REPEAT_DELAY  300
00037 #define AUTO_REPEAT_INTERVAL 100
00038 
00039 
00145 QAbstractButtonPrivate::QAbstractButtonPrivate()
00146     :
00147 #ifndef QT_NO_SHORTCUT
00148     shortcutId(0),
00149 #endif
00150     checkable(false), checked(false), autoRepeat(false), autoExclusive(false),
00151     down(false), blockRefresh(false),
00152 #ifndef QT_NO_BUTTONGROUP
00153     group(0),
00154 #endif
00155     autoRepeatDelay(AUTO_REPEAT_DELAY),
00156     autoRepeatInterval(AUTO_REPEAT_INTERVAL)
00157 {}
00158 
00159 #ifndef QT_NO_BUTTONGROUP
00160 
00161 class QButtonGroupPrivate: public QObjectPrivate
00162 {
00163     Q_DECLARE_PUBLIC(QButtonGroup)
00164 
00165 public:
00166     QButtonGroupPrivate():exclusive(true){}
00167     QList<QAbstractButton *> buttonList;
00168     QPointer<QAbstractButton> checkedButton;
00169     void detectCheckedButton();
00170     void notifyChecked(QAbstractButton *button);
00171     bool exclusive;
00172     QMap<QAbstractButton*, int> mapping;
00173 };
00174 
00175 QButtonGroup::QButtonGroup(QObject *parent)
00176     : QObject(*new QButtonGroupPrivate, parent)
00177 {
00178 }
00179 
00180 QButtonGroup::~QButtonGroup()
00181 {
00182     Q_D(QButtonGroup);
00183     for (int i = 0; i < d->buttonList.count(); ++i)
00184         d->buttonList.at(i)->d_func()->group = 0;
00185 }
00186 
00187 
00188 bool QButtonGroup::exclusive() const
00189 {
00190     Q_D(const QButtonGroup);
00191     return d->exclusive;
00192 }
00193 
00194 void QButtonGroup::setExclusive(bool exclusive)
00195 {
00196     Q_D(QButtonGroup);
00197     d->exclusive = exclusive;
00198 }
00199 
00205 void QButtonGroup::addButton(QAbstractButton *button)
00206 {
00207     addButton(button, -1);
00208 }
00209 
00210 void QButtonGroup::addButton(QAbstractButton *button, int id)
00211 {
00212     Q_D(QButtonGroup);
00213     if (QButtonGroup *previous = button->d_func()->group)
00214         previous->removeButton(button);
00215     button->d_func()->group = this;
00216     d->buttonList.append(button);
00217     if (id != -1)
00218         d->mapping[button] = id;
00219     if (d->exclusive && button->isChecked())
00220         button->d_func()->notifyChecked();
00221 }
00222 
00223 void QButtonGroup::removeButton(QAbstractButton *button)
00224 {
00225     Q_D(QButtonGroup);
00226     if (d->checkedButton == button) {
00227         d->detectCheckedButton();
00228     }
00229     if (button->d_func()->group == this) {
00230         button->d_func()->group = 0;
00231         d->buttonList.removeAll(button);
00232         d->mapping.remove(button);
00233     }
00234 }
00235 
00236 QList<QAbstractButton*> QButtonGroup::buttons() const
00237 {
00238     Q_D(const QButtonGroup);
00239     return d->buttonList;
00240 }
00241 
00242 QAbstractButton *QButtonGroup::checkedButton() const
00243 {
00244     Q_D(const QButtonGroup);
00245     return d->checkedButton;
00246 }
00247 
00248 QAbstractButton *QButtonGroup::button(int id) const
00249 {
00250     Q_D(const QButtonGroup);
00251     return d->mapping.key(id);
00252 }
00253 
00254 void QButtonGroup::setId(QAbstractButton *button, int id)
00255 {
00256     Q_D(QButtonGroup);
00257     if (button && id != -1)
00258         d->mapping[button] = id;
00259 }
00260 
00261 int QButtonGroup::id(QAbstractButton *button) const
00262 {
00263     Q_D(const QButtonGroup);
00264     return d->mapping.value(button, -1);
00265 }
00266 
00267 int QButtonGroup::checkedId() const
00268 {
00269     Q_D(const QButtonGroup);
00270     return d->mapping.value(d->checkedButton, -1);
00271 }
00272 
00273 // detect a checked button other than the current one
00274 void QButtonGroupPrivate::detectCheckedButton()
00275 {
00276     QAbstractButton *previous = checkedButton;
00277     checkedButton = 0;
00278     if (exclusive)
00279         return;
00280     for (int i = 0; i < buttonList.count(); i++) {
00281         if (buttonList.at(i) != previous && buttonList.at(i)->isChecked()) {
00282             checkedButton = buttonList.at(i);
00283             return;
00284         }
00285     }
00286 }
00287 
00288 #endif // QT_NO_BUTTONGROUP
00289 
00290 QList<QAbstractButton *>QAbstractButtonPrivate::queryButtonList() const
00291 {
00292 #ifndef QT_NO_BUTTONGROUP
00293     if (group)
00294         return group->d_func()->buttonList;
00295 #endif
00296 
00297     Q_Q(const QAbstractButton);
00298     QList<QAbstractButton*>candidates;
00299     if (q->parentWidget() && autoExclusive) {
00300         candidates =  qFindChildren<QAbstractButton *>(q->parentWidget());
00301         for (int i = candidates.count() - 1; i >= 0; --i) {
00302             QAbstractButton *candidate = candidates.at(i);
00303             if (!candidate->autoExclusive()
00304 #ifndef QT_NO_BUTTONGROUP
00305                 || candidate->group()
00306 #endif
00307                 )
00308                 candidates.removeAt(i);
00309         }
00310     }
00311     return candidates;
00312 }
00313 
00314 QAbstractButton *QAbstractButtonPrivate::queryCheckedButton() const
00315 {
00316 #ifndef QT_NO_BUTTONGROUP
00317     if (group)
00318         return group->d_func()->checkedButton;
00319 #endif
00320 
00321     Q_Q(const QAbstractButton);
00322     QList<QAbstractButton *> buttonList = queryButtonList();
00323     if (buttonList.count() == 1) // no group
00324         return 0;
00325 
00326     for (int i = 0; i < buttonList.count(); ++i) {
00327         QAbstractButton *b = buttonList.at(i);
00328         if (b->d_func()->checked && b != q)
00329             return b;
00330     }
00331     return checked  ? const_cast<QAbstractButton *>(q) : 0;
00332 }
00333 
00334 void QAbstractButtonPrivate::notifyChecked()
00335 {
00336 #ifndef QT_NO_BUTTONGROUP
00337     Q_Q(QAbstractButton);
00338     if (group) {
00339         QAbstractButton *previous = group->d_func()->checkedButton;
00340         group->d_func()->checkedButton = q;
00341         if (group->d_func()->exclusive && previous && previous != q)
00342             previous->nextCheckState();
00343     } else
00344 #endif
00345     if (autoExclusive) {
00346         if (QAbstractButton *b = queryCheckedButton())
00347             b->setChecked(false);
00348     }
00349 }
00350 
00351 void QAbstractButtonPrivate::moveFocus(int key)
00352 {
00353     QList<QAbstractButton *> buttonList = queryButtonList();;
00354 #ifndef QT_NO_BUTTONGROUP
00355     bool exclusive = group ? group->d_func()->exclusive : autoExclusive;
00356 #else
00357     bool exclusive = autoExclusive;
00358 #endif
00359     QWidget *f = qApp->focusWidget();
00360     QAbstractButton *fb = ::qobject_cast<QAbstractButton *>(f);
00361     if (!fb || !buttonList.contains(fb))
00362         return;
00363 
00364     QAbstractButton *candidate = 0;
00365     int bestScore = -1;
00366     QRect fGeometry = f->geometry();
00367 
00368     QPoint goal(f->mapToGlobal(fGeometry.center()));
00369 
00370     for (int i = 0; i < buttonList.count(); ++i) {
00371         QAbstractButton *button = buttonList.at(i);
00372         if (button != f && button->isEnabled()) {
00373             QRect buttonGeometry = button->geometry();
00374             QPoint p(button->mapToGlobal(buttonGeometry.center()));
00375             int score = (p.y() - goal.y())*(p.y() - goal.y()) +
00376                         (p.x() - goal.x())*(p.x() - goal.x());
00377             bool betterScore = score < bestScore || !candidate;
00378             switch(key) {
00379             case Qt::Key_Up:
00380                 if (p.y() < goal.y() && betterScore) {
00381                     if (qAbs(p.x() - goal.x()) < qAbs(p.y() - goal.y())) {
00382                         candidate = button;
00383                         bestScore = score;
00384                     } else if (buttonGeometry.x() == fGeometry.x()) {
00385                         candidate = button;
00386                         bestScore = score/2;
00387                     }
00388                 }
00389                 break;
00390             case Qt::Key_Down:
00391                 if (p.y() > goal.y() && betterScore) {
00392                     if (qAbs(p.x() - goal.x()) < qAbs(p.y() - goal.y())) {
00393                         candidate = button;
00394                         bestScore = score;
00395                     } else if (buttonGeometry.x() == fGeometry.x()) {
00396                         candidate = button;
00397                         bestScore = score/2;
00398                     }
00399                 }
00400                 break;
00401             case Qt::Key_Left:
00402                 if (p.x() < goal.x() && betterScore) {
00403                     if (qAbs(p.y() - goal.y()) < qAbs(p.x() - goal.x())) {
00404                         candidate = button;
00405                         bestScore = score;
00406                     } else if (buttonGeometry.y() == fGeometry.y()) {
00407                         candidate = button;
00408                         bestScore = score/2;
00409                     }
00410                 }
00411                 break;
00412             case Qt::Key_Right:
00413                 if (p.x() > goal.x() && betterScore) {
00414                     if (qAbs(p.y() - goal.y()) < qAbs(p.x() - goal.x())) {
00415                         candidate = button;
00416                         bestScore = score;
00417                     } else if (buttonGeometry.y() == fGeometry.y()) {
00418                         candidate = button;
00419                         bestScore = score/2;
00420                     }
00421                 }
00422                 break;
00423             }
00424         }
00425     }
00426 
00427     if (exclusive
00428 #ifdef QT_KEYPAD_NAVIGATION
00429         && !QApplication::keypadNavigationEnabled()
00430 #endif
00431         && candidate
00432         && fb->d_func()->checked
00433         && candidate->d_func()->checkable)
00434         candidate->click();
00435 
00436     if (candidate) {
00437         if (key == Qt::Key_Up || key == Qt::Key_Left)
00438             candidate->setFocus(Qt::BacktabFocusReason);
00439         else
00440             candidate->setFocus(Qt::TabFocusReason);
00441     }
00442 }
00443 
00444 void QAbstractButtonPrivate::fixFocusPolicy()
00445 {
00446     Q_Q(QAbstractButton);
00447 
00448     QList<QAbstractButton *> buttonList = queryButtonList();
00449     for (int i = 0; i < buttonList.count(); ++i) {
00450         QAbstractButton *b = buttonList.at(i);
00451         if (!b->isCheckable())
00452             continue;
00453         b->setFocusPolicy((Qt::FocusPolicy) ((b == q || !q->isCheckable())
00454                                          ? (b->focusPolicy() | Qt::TabFocus)
00455                                          :  (b->focusPolicy() & ~Qt::TabFocus)));
00456     }
00457 }
00458 
00459 void QAbstractButtonPrivate::init()
00460 {
00461     Q_Q(QAbstractButton);
00462 
00463     q->setFocusPolicy(Qt::FocusPolicy(q->style()->styleHint(QStyle::SH_Button_FocusPolicy)));
00464     q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
00465     q->setForegroundRole(QPalette::ButtonText);
00466     q->setBackgroundRole(QPalette::Button);
00467 }
00468 
00469 void QAbstractButtonPrivate::refresh()
00470 {
00471     Q_Q(QAbstractButton);
00472 
00473     if (blockRefresh)
00474         return;
00475     q->update();
00476 #ifndef QT_NO_ACCESSIBILITY
00477     QAccessible::updateAccessibility(q, 0, QAccessible::StateChanged);
00478 #endif
00479 }
00480 
00481 void QAbstractButtonPrivate::click()
00482 {
00483     Q_Q(QAbstractButton);
00484 
00485     down = false;
00486     blockRefresh = true;
00487     bool changeState = true;
00488     if (checked && queryCheckedButton() == q) {
00489         // the checked button of an exclusive or autoexclusive group cannot be unchecked
00490 #ifndef QT_NO_BUTTONGROUP
00491         if (group ? group->d_func()->exclusive : autoExclusive)
00492 #else
00493         if (autoExclusive)
00494 #endif
00495             changeState = false;
00496     }
00497 
00498     QPointer<QAbstractButton> guard(q);
00499     if (changeState) {
00500         q->nextCheckState();
00501         if (!guard)
00502             return;
00503     }
00504     blockRefresh = false;
00505     refresh();
00506     q->repaint(); //flush paint event before invoking potentially expensive operation
00507     QApplication::flush();
00508     emitReleased();
00509     if (guard)
00510         emitClicked();
00511 }
00512 
00513 void QAbstractButtonPrivate::emitClicked()
00514 {
00515     Q_Q(QAbstractButton);
00516     QPointer<QAbstractButton> guard(q);
00517     emit q->clicked(checked);
00518 #ifndef QT_NO_BUTTONGROUP
00519     if (guard && group) {
00520         emit group->buttonClicked(group->id(q));
00521         emit group->buttonClicked(q);
00522     }
00523 #endif
00524 }
00525 
00526 void QAbstractButtonPrivate::emitPressed()
00527 {
00528     Q_Q(QAbstractButton);
00529     QPointer<QAbstractButton> guard(q);
00530     emit q->pressed();
00531 #ifndef QT_NO_BUTTONGROUP
00532     if (guard && group) {
00533         emit group->buttonPressed(group->id(q));
00534         emit group->buttonPressed(q);
00535     }
00536 #endif
00537 }
00538 
00539 void QAbstractButtonPrivate::emitReleased()
00540 {
00541     Q_Q(QAbstractButton);
00542     QPointer<QAbstractButton> guard(q);
00543     emit q->released();
00544 #ifndef QT_NO_BUTTONGROUP
00545     if (guard && group) {
00546         emit group->buttonReleased(group->id(q));
00547         emit group->buttonReleased(q);
00548     }
00549 #endif
00550 }
00551 
00555 QAbstractButton::QAbstractButton(QWidget *parent)
00556     :QWidget(*new QAbstractButtonPrivate, parent, 0)
00557 {
00558     Q_D(QAbstractButton);
00559     d->init();
00560 }
00561 
00565  QAbstractButton::~QAbstractButton()
00566 {
00567 #ifndef QT_NO_BUTTONGROUP
00568     Q_D(QAbstractButton);
00569     if (d->group)
00570         d->group->removeButton(this);
00571 #endif
00572 }
00573 
00574 
00577 QAbstractButton::QAbstractButton(QAbstractButtonPrivate &dd, QWidget *parent)
00578     : QWidget(dd, parent, 0)
00579 {
00580     Q_D(QAbstractButton);
00581     d->init();
00582 }
00583 
00601 void QAbstractButton::setText(const QString &text)
00602 {
00603     Q_D(QAbstractButton);
00604     if (d->text == text)
00605         return;
00606     d->text = text;
00607 #ifndef QT_NO_SHORTCUT
00608     QKeySequence newMnemonic = QKeySequence::mnemonic(text);
00609     if (!newMnemonic.isEmpty())
00610         setShortcut(newMnemonic);
00611 #endif
00612     update();
00613     updateGeometry();
00614 #ifndef QT_NO_ACCESSIBILITY
00615     QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
00616 #endif
00617 }
00618 
00619 QString QAbstractButton::text() const
00620 {
00621     Q_D(const QAbstractButton);
00622     return d->text;
00623 }
00624 
00625 
00633 void QAbstractButton::setIcon(const QIcon &icon)
00634 {
00635     Q_D(QAbstractButton);
00636     d->icon = icon;
00637     update();
00638     updateGeometry();
00639 }
00640 
00641 QIcon QAbstractButton::icon() const
00642 {
00643     Q_D(const QAbstractButton);
00644     return d->icon;
00645 }
00646 
00647 #ifndef QT_NO_SHORTCUT
00648 
00653 void QAbstractButton::setShortcut(const QKeySequence &key)
00654 {
00655     Q_D(QAbstractButton);
00656     if (d->shortcutId != 0)
00657         releaseShortcut(d->shortcutId);
00658     d->shortcut = key;
00659     d->shortcutId = grabShortcut(key);
00660 }
00661 
00662 QKeySequence QAbstractButton::shortcut() const
00663 {
00664     Q_D(const QAbstractButton);
00665     return d->shortcut;
00666 }
00667 #endif // QT_NO_SHORTCUT
00668 
00677 void QAbstractButton::setCheckable(bool checkable)
00678 {
00679     Q_D(QAbstractButton);
00680     if (d->checkable == checkable)
00681         return;
00682 
00683     d->checkable = checkable;
00684     d->checked = false;
00685 }
00686 
00687 bool QAbstractButton::isCheckable() const
00688 {
00689     Q_D(const QAbstractButton);
00690     return d->checkable;
00691 }
00692 
00701 void QAbstractButton::setChecked(bool checked)
00702 {
00703     Q_D(QAbstractButton);
00704     if (!d->checkable || d->checked == checked) {
00705         if (!d->blockRefresh)
00706             checkStateSet();
00707         return;
00708     }
00709 
00710     if (!checked && d->queryCheckedButton() == this) {
00711         // the checked button of an exclusive or autoexclusive group cannot be  unchecked
00712 #ifndef QT_NO_BUTTONGROUP
00713         if (d->group ? d->group->d_func()->exclusive : d->autoExclusive)
00714             return;
00715         if (d->group)
00716             d->group->d_func()->detectCheckedButton();
00717 #else
00718         if (d->autoExclusive)
00719             return;
00720 #endif
00721     }
00722 
00723     QPointer<QAbstractButton> guard(this);
00724 
00725     d->checked = checked;
00726     if (!d->blockRefresh)
00727         checkStateSet();
00728     d->refresh();
00729 
00730     if (guard && checked)
00731         d->notifyChecked();
00732     if (guard)
00733         emit toggled(checked);
00734 }
00735 
00736 bool QAbstractButton::isChecked() const
00737 {
00738     Q_D(const QAbstractButton);
00739     return d->checked;
00740 }
00741 
00751 void QAbstractButton::setDown(bool down)
00752 {
00753     Q_D(QAbstractButton);
00754     if (d->down == down)
00755         return;
00756     d->down = down;
00757     d->refresh();
00758     if (d->autoRepeat && d->down)
00759         d->repeatTimer.start(d->autoRepeatDelay, this);
00760     else
00761         d->repeatTimer.stop();
00762 }
00763 
00764 bool QAbstractButton::isDown() const
00765 {
00766     Q_D(const QAbstractButton);
00767     return d->down;
00768 }
00769 
00781 void QAbstractButton::setAutoRepeat(bool autoRepeat)
00782 {
00783     Q_D(QAbstractButton);
00784     if (d->autoRepeat == autoRepeat)
00785         return;
00786     d->autoRepeat = autoRepeat;
00787     if (d->autoRepeat && d->down)
00788         d->repeatTimer.start(d->autoRepeatDelay, this);
00789     else
00790         d->repeatTimer.stop();
00791 }
00792 
00793 bool QAbstractButton::autoRepeat() const
00794 {
00795     Q_D(const QAbstractButton);
00796     return d->autoRepeat;
00797 }
00798 
00810 void QAbstractButton::setAutoRepeatDelay(int autoRepeatDelay)
00811 {
00812     Q_D(QAbstractButton);
00813     d->autoRepeatDelay = autoRepeatDelay;
00814 }
00815 
00816 int QAbstractButton::autoRepeatDelay() const
00817 {
00818     Q_D(const QAbstractButton);
00819     return d->autoRepeatDelay;
00820 }
00821 
00833 void QAbstractButton::setAutoRepeatInterval(int autoRepeatInterval)
00834 {
00835     Q_D(QAbstractButton);
00836     d->autoRepeatInterval = autoRepeatInterval;
00837 }
00838 
00839 int QAbstractButton::autoRepeatInterval() const
00840 {
00841     Q_D(const QAbstractButton);
00842     return d->autoRepeatInterval;
00843 }
00844 
00845 
00846 
00864 void QAbstractButton::setAutoExclusive(bool autoExclusive)
00865 {
00866     Q_D(QAbstractButton);
00867     d->autoExclusive = autoExclusive;
00868 }
00869 
00870 bool QAbstractButton::autoExclusive() const
00871 {
00872     Q_D(const QAbstractButton);
00873     return d->autoExclusive;
00874 }
00875 
00876 #ifndef QT_NO_BUTTONGROUP
00877 
00885 QButtonGroup *QAbstractButton::group() const
00886 {
00887     Q_D(const QAbstractButton);
00888     return d->group;
00889 }
00890 #endif // QT_NO_BUTTONGROUP
00891 
00903 void QAbstractButton::animateClick(int msec)
00904 {
00905     if (!isEnabled())
00906         return;
00907     Q_D(QAbstractButton);
00908     if (d->checkable && focusPolicy() != Qt::NoFocus)
00909         setFocus();
00910     setDown(true);
00911     repaint(); //flush paint event before invoking potentially expensive operation
00912     QApplication::flush();
00913     d->emitPressed();
00914     d->animateTimer.start(msec, this);
00915 }
00916 
00929 void QAbstractButton::click()
00930 {
00931     if (!isEnabled())
00932         return;
00933     Q_D(QAbstractButton);
00934     QPointer<QAbstractButton> guard(this);
00935     d->down = true;
00936     d->emitPressed();
00937     if (guard) {
00938         d->down = false;
00939         nextCheckState();
00940         if (guard)
00941             d->emitReleased();
00942         if (guard)
00943             d->emitClicked();
00944     }
00945 }
00946 
00953 void QAbstractButton::toggle()
00954 {
00955     Q_D(QAbstractButton);
00956     setChecked(!d->checked);
00957 }
00958 
00959 
00966 void QAbstractButton::checkStateSet()
00967 {
00968 }
00969 
00977 void QAbstractButton::nextCheckState()
00978 {
00979     if (isCheckable())
00980         setChecked(!isChecked());
00981 }
00982 
00991 bool QAbstractButton::hitButton(const QPoint &pos) const
00992 {
00993     return rect().contains(pos);
00994 }
00995 
00997 bool QAbstractButton::event(QEvent *e)
00998 {
00999     // as opposed to other widgets, disabled buttons accept mouse
01000     // events. This avoids surprising click-through scenarios
01001     if (!isEnabled()) {
01002         switch(e->type()) {
01003         case QEvent::TabletPress:
01004         case QEvent::TabletRelease:
01005         case QEvent::TabletMove:
01006         case QEvent::MouseButtonPress:
01007         case QEvent::MouseButtonRelease:
01008         case QEvent::MouseButtonDblClick:
01009         case QEvent::MouseMove:
01010         case QEvent::HoverMove:
01011         case QEvent::HoverEnter:
01012         case QEvent::HoverLeave:
01013         case QEvent::ContextMenu:
01014 #ifndef QT_NO_WHEELEVENT
01015         case QEvent::Wheel:
01016 #endif
01017             return true;
01018         default:
01019             break;
01020         }
01021     }
01022 
01023 #ifndef QT_NO_SHORTCUT
01024     if (e->type() == QEvent::Shortcut) {
01025         Q_D(QAbstractButton);
01026         QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
01027         if (d->shortcutId != se->shortcutId())
01028             return false;
01029         if (focusPolicy() != Qt::NoFocus)
01030             setFocus();
01031         if (!se->isAmbiguous())
01032             animateClick();
01033         else
01034             window()->setAttribute(Qt::WA_KeyboardFocusChange);
01035         return true;
01036     }
01037 #endif
01038     return QWidget::event(e);
01039 }
01040 
01042 void QAbstractButton::mousePressEvent(QMouseEvent *e)
01043 {
01044     Q_D(QAbstractButton);
01045     if (e->button() != Qt::LeftButton) {
01046         e->ignore();
01047         return;
01048     }
01049     if (hitButton(e->pos())) {
01050         setDown(true);
01051         repaint(); //flush paint event before invoking potentially expensive operation
01052         QApplication::flush();
01053         d->emitPressed();
01054         e->accept();
01055     } else {
01056         e->ignore();
01057     }
01058 }
01059 
01061 void QAbstractButton::mouseReleaseEvent(QMouseEvent *e)
01062 {
01063     Q_D(QAbstractButton);
01064     if (e->button() != Qt::LeftButton) {
01065         // clean up apperance if left button has been pressed
01066         if (d->down)
01067             setDown(false);
01068         e->ignore();
01069         return;
01070     }
01071 
01072     if (!d->down)
01073         return;
01074 
01075     if (hitButton(e->pos())) {
01076         d->click();
01077         e->accept();
01078     } else {
01079         setDown(false);
01080         e->ignore();
01081     }
01082 }
01083 
01085 void QAbstractButton::mouseMoveEvent(QMouseEvent *e)
01086 {
01087     Q_D(QAbstractButton);
01088     if (!(e->buttons() & Qt::LeftButton)) {
01089         e->ignore();
01090         return;
01091     }
01092 
01093     if (hitButton(e->pos()) != d->down) {
01094         setDown(!d->down);
01095         repaint(); //flush paint event before invoking potentially expensive operation
01096         QApplication::flush();
01097         if (d->down)
01098             d->emitPressed();
01099         else
01100             d->emitReleased();
01101         e->accept();
01102     } else if (!hitButton(e->pos())) {
01103         e->ignore();
01104     }
01105 }
01106 
01108 void QAbstractButton::keyPressEvent(QKeyEvent *e)
01109 {
01110     Q_D(QAbstractButton);
01111     bool next = true;
01112     switch (e->key()) {
01113     case Qt::Key_Enter:
01114     case Qt::Key_Return:
01115         e->ignore();
01116         break;
01117     case Qt::Key_Select:
01118     case Qt::Key_Space:
01119         if (!e->isAutoRepeat()) {
01120             setDown(true);
01121             repaint(); //flush paint event before invoking potentially expensive operation
01122             QApplication::flush();
01123             d->emitPressed();
01124         }
01125         break;
01126     case Qt::Key_Up:
01127     case Qt::Key_Left:
01128         next = false;
01129         // fall through
01130     case Qt::Key_Right:
01131     case Qt::Key_Down:
01132 #ifndef QT_NO_BUTTONGROUP
01133         if (d->group || d->autoExclusive) {
01134 #else
01135         if (d->autoExclusive) {
01136 #endif
01137             d->moveFocus(e->key());
01138             if (hasFocus()) // nothing happend, propagate
01139                 e->ignore();
01140         } else {
01141             focusNextPrevChild(next);
01142         }
01143         break;
01144     case Qt::Key_Escape:
01145         if (d->down) {
01146             setDown(false);
01147             repaint(); //flush paint event before invoking potentially expensive operation
01148             QApplication::flush();
01149             d->emitReleased();
01150             break;
01151         }
01152         // fall through
01153     default:
01154         e->ignore();
01155     }
01156 }
01157 
01159 void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
01160 {
01161     Q_D(QAbstractButton);
01162     switch (e->key()) {
01163     case Qt::Key_Select:
01164     case Qt::Key_Space:
01165         if (!e->isAutoRepeat() && d->down)
01166             d->click();
01167         break;
01168     default:
01169         e->ignore();
01170     }
01171 }
01172 
01175 void QAbstractButton::timerEvent(QTimerEvent *e)
01176 {
01177     Q_D(QAbstractButton);
01178     if (e->timerId() == d->repeatTimer.timerId()) {
01179         d->repeatTimer.start(d->autoRepeatInterval, this);
01180         if (d->down) {
01181             QPointer<QAbstractButton> guard(this);
01182             d->emitReleased();
01183             if (guard)
01184                 d->emitClicked();
01185             if (guard)
01186                 d->emitPressed();
01187         }
01188     } else if (e->timerId() == d->animateTimer.timerId()) {
01189         d->animateTimer.stop();
01190         d->click();
01191     }
01192 }
01193 
01195 void QAbstractButton::focusInEvent(QFocusEvent *e)
01196 {
01197     Q_D(QAbstractButton);
01198 #ifdef QT_KEYPAD_NAVIGATION
01199     if (!QApplication::keypadNavigationEnabled())
01200 #endif
01201     d->fixFocusPolicy();
01202     QWidget::focusInEvent(e);
01203 }
01204 
01206 void QAbstractButton::focusOutEvent(QFocusEvent *e)
01207 {
01208     Q_D(QAbstractButton);
01209     if (e->reason() != Qt::PopupFocusReason)
01210         d->down = false;
01211     QWidget::focusOutEvent(e);
01212 }
01213 
01215 void QAbstractButton::changeEvent(QEvent *e)
01216 {
01217 //     Q_D(QAbstractButton);
01218     switch (e->type()) {
01219     case QEvent::EnabledChange:
01220         if (!isEnabled())
01221             setDown(false);
01222         break;
01223     default:
01224         break;
01225     }
01226     QWidget::changeEvent(e);
01227 }
01228 
01308 QSize QAbstractButton::iconSize() const
01309 {
01310     Q_D(const QAbstractButton);
01311     if (d->iconSize.isValid())
01312         return d->iconSize;
01313     int e = style()->pixelMetric(QStyle::PM_ButtonIconSize);
01314     return QSize(e, e);
01315 }
01316 
01317 void QAbstractButton::setIconSize(const QSize &size)
01318 {
01319     Q_D(QAbstractButton);
01320     if (d->iconSize == size)
01321         return;
01322 
01323     d->iconSize = size;
01324     updateGeometry();
01325     if (isVisible()) {
01326         update();
01327     }
01328 }
01329 
01330 
01331 #ifdef QT3_SUPPORT
01332 
01335 QIcon *QAbstractButton::iconSet() const
01336 {
01337     Q_D(const QAbstractButton);
01338     if (!d->icon.isNull())
01339         return const_cast<QIcon *>(&d->icon);
01340     return 0;
01341 }
01342 
01349 QAbstractButton::QAbstractButton(QWidget *parent, const char *name, Qt::WindowFlags f)
01350     : QWidget(*new QAbstractButtonPrivate, parent, f)
01351 {
01352     Q_D(QAbstractButton);
01353     setObjectName(QString::fromAscii(name));
01354     d->init();
01355 }
01356 
01406 #endif

Generated on Thu Mar 15 11:56:39 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1