00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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)
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
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();
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
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();
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
01000
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();
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
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();
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();
01122 QApplication::flush();
01123 d->emitPressed();
01124 }
01125 break;
01126 case Qt::Key_Up:
01127 case Qt::Key_Left:
01128 next = false;
01129
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())
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();
01148 QApplication::flush();
01149 d->emitReleased();
01150 break;
01151 }
01152
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
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