1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the widgets module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qtoolbutton.h"
30
#ifndef QT_NO_TOOLBUTTON
32
#include <qapplication.h>
33
#include <qdesktopwidget.h>
34
#include <qdrawutil.h>
41
#include <qstyleoption.h>
43
#include <qmainwindow.h>
46
#include <qstylepainter.h>
47
#include <private/qabstractbutton_p.h>
49
class QToolButtonPrivate : public QAbstractButtonPrivate
51
Q_DECLARE_PUBLIC(QToolButton)
55
void popupTimerDone();
56
void actionTriggered();
57
QStyleOptionToolButton getStyleOption() const;
58
QPointer<QMenu> menu; //the menu set by the user (setMenu)
59
QBasicTimer popupTimer;
61
Qt::ArrowType arrowType;
62
Qt::ToolButtonStyle toolButtonStyle;
63
QToolButton::ToolButtonPopupMode popupMode;
64
uint menuButtonDown : 1;
67
QAction *defaultAction;
71
bool QToolButtonPrivate::hasMenu() const
73
Q_Q(const QToolButton);
74
return (menu || q->actions().size() > (defaultAction ? 1 : 0));
78
\class QToolButton qtoolbutton.h
79
\brief The QToolButton class provides a quick-access button to
80
commands or options, usually used inside a QToolBar.
85
A tool button is a special button that provides quick-access to
86
specific commands or options. As opposed to a normal command
87
button, a tool button usually doesn't show a text label, but shows
88
an icon instead. Its classic usage is to select tools, for example
89
the "pen" tool in a drawing program. This would be implemented
90
with a QToolButton as toggle button (see setToggleButton()).
92
QToolButton supports auto-raising. In auto-raise mode, the button
93
draws a 3D frame only when the mouse points at it. The feature is
94
automatically turned on when a button is used inside a QToolBar.
95
Change it with setAutoRaise().
97
A tool button's icon is set as QIcon. This makes it possible to
98
specify different pixmaps for the disabled and active state. The
99
disabled pixmap is used when the button's functionality is not
100
available. The active pixmap is displayed when the button is
101
auto-raised because the mouse pointer is hovering over it.
103
The button's look and dimension is adjustable with
104
setToolButtonStyle() and setIconSize(). When used inside a
105
QToolBar in a QMainWindow, the button automatically adjusts to
106
QMainWindow's settings (see QMainWindow::setToolButtonStyle() and
107
QMainWindow::setIconSize()). Instead of an icon, a tool button can
108
also display an arrow symbol, specified with \l arrowType.
110
A tool button can offer additional choices in a popup menu. The
111
popup menu can be set using setMenu(). Use setPopupMode() to
112
configure the different modes available for tool buttons with a
113
menu set. The default mode is DelayedPopupMode which is sometimes
114
used with the "Back" button in a web browser. After pressing and
115
holding the button down for a while, a menu pops up showing a list
116
of possible pages to jump to. The default delay is 600ms; you can
117
adjust it with setPopupDelay().
119
\img qdockwindow.png Toolbar with Toolbuttons \caption A floating
120
QToolbar with QToolbuttons
122
\sa QPushButton, QToolBar, QMainWindow, {fowler}{GUI Design Handbook: Push Button}
126
\fn void QToolButton::triggered(QAction *action)
128
This signal is emitted when the given \a action is triggered.
130
The action may also be associated with other parts of the user interface,
131
such as menu items and keyboard shortcuts. Sharing actions in this
132
way helps make the user interface more consistent and is often less work
137
Constructs an empty tool button with parent \a
140
QToolButton::QToolButton(QWidget * parent)
141
: QAbstractButton(*new QToolButtonPrivate, parent)
149
Constructs an empty tool button called \a name, with parent \a
153
QToolButton::QToolButton(QWidget * parent, const char *name)
154
: QAbstractButton(*new QToolButtonPrivate, parent)
162
Constructs a tool button called \a name, that is a child of \a
165
The tool button will display the given \a icon, with its text
166
label and tool tip set to \a textLabel and its status bar message
167
set to \a statusTip. It will be connected to the \a slot in
171
QToolButton::QToolButton(const QIcon& icon, const QString &textLabel,
172
const QString& statusTip,
173
QObject * receiver, const char *slot,
174
QWidget * parent, const char *name)
175
: QAbstractButton(*new QToolButtonPrivate, parent)
182
if (receiver && slot)
183
connect(this, SIGNAL(clicked()), receiver, slot);
184
if (!textLabel.isEmpty())
185
setToolTip(textLabel);
186
if (!statusTip.isEmpty())
187
setStatusTip(statusTip);
192
Constructs a tool button as an arrow button. The \c Qt::ArrowType \a
193
type defines the arrow direction. Possible values are \c
194
Qt::LeftArrow, \c Qt::RightArrow, \c Qt::UpArrow and \c Qt::DownArrow.
196
An arrow button has auto-repeat turned on by default.
198
The \a parent and \a name arguments are sent to the QWidget
201
QToolButton::QToolButton(Qt::ArrowType type, QWidget *parent, const char *name)
202
: QAbstractButton(*new QToolButtonPrivate, parent)
214
/* Set-up code common to all the constructors */
216
void QToolButtonPrivate::init()
219
delay = q->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, 0, q);
223
arrowType = Qt::NoArrow;
224
menuButtonDown = false;
225
popupMode = QToolButton::DelayedPopup;
228
toolButtonStyle = Qt::ToolButtonIconOnly;
230
q->setFocusPolicy(Qt::TabFocus);
231
q->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
233
QObject::connect(q, SIGNAL(pressed()), q, SLOT(buttonPressed()));
237
QStyleOptionToolButton QToolButtonPrivate::getStyleOption() const
239
Q_Q(const QToolButton);
240
QStyleOptionToolButton opt;
242
bool down = q->isDown();
243
bool checked = q->isChecked();
246
opt.iconSize = q->iconSize();
247
opt.arrowType = arrowType;
249
opt.state |= QStyle::State_Sunken;
251
opt.state |= QStyle::State_On;
253
opt.state |= QStyle::State_AutoRaise;
254
if (!checked && !down)
255
opt.state |= QStyle::State_Raised;
257
opt.subControls = QStyle::SC_ToolButton;
258
opt.activeSubControls = QStyle::SC_None;
259
// if (down && !menuButtonDown)
260
// opt.activeSubControls |= QStyle::SC_ToolButton;
262
opt.features = QStyleOptionToolButton::None;
263
if (popupMode == QToolButton::MenuButtonPopup) {
264
opt.subControls |= QStyle::SC_ToolButtonMenu;
265
opt.features |= QStyleOptionToolButton::Menu;
266
if (menuButtonDown || down) {
267
opt.state |= QStyle::State_MouseOver;
268
opt.activeSubControls |= QStyle::SC_ToolButtonMenu;
272
opt.state |= QStyle::State_Sunken;
274
if (arrowType != Qt::NoArrow)
275
opt.features |= QStyleOptionToolButton::Arrow;
276
if (popupMode == QToolButton::DelayedPopup)
277
opt.features |= QStyleOptionToolButton::PopupDelay;
278
opt.toolButtonStyle = toolButtonStyle;
281
opt.toolButtonStyle = Qt::ToolButtonTextOnly;
282
else if (opt.toolButtonStyle != Qt::ToolButtonTextOnly)
283
opt.toolButtonStyle = Qt::ToolButtonIconOnly;
285
if (text.isEmpty() && opt.toolButtonStyle != Qt::ToolButtonIconOnly)
286
opt.toolButtonStyle = Qt::ToolButtonIconOnly;
290
opt.font = q->font();
295
Destroys the object and frees any allocated resources.
298
QToolButton::~QToolButton()
305
QSize QToolButton::sizeHint() const
307
Q_D(const QToolButton);
311
QStyleOptionToolButton opt = d->getStyleOption();
313
QFontMetrics fm = fontMetrics();
314
if (opt.toolButtonStyle != Qt::ToolButtonTextOnly) {
315
QSize icon = iconSize();
320
if (opt.toolButtonStyle != Qt::ToolButtonIconOnly) {
321
QSize textSize = fm.size(Qt::TextShowMnemonic, text());
322
textSize.setWidth(textSize.width() + fm.width(' ')*2);
323
if (opt.toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
324
h += 4 + textSize.height();
325
if (textSize.width() > w)
326
w = textSize.width();
327
} else if (opt.toolButtonStyle == Qt::ToolButtonTextBesideIcon) {
328
w += 4 + textSize.width();
329
if (textSize.height() > h)
330
h = textSize.height();
332
w = textSize.width();
333
h = textSize.height();
337
opt.rect.setHeight(h); // PM_MenuButtonIndicator depends on the height
338
if (d->popupMode == MenuButtonPopup)
339
w += style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this);
341
return style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), this).
342
expandedTo(QApplication::globalStrut());
348
QSize QToolButton::minimumSizeHint() const
354
\enum QToolButton::TextPosition
357
This enum describes the position of the tool button's text label in
358
relation to the tool button's icon.
360
\value BesideIcon The text appears beside the icon.
361
\value BelowIcon The text appears below the icon.
367
\property QToolButton::toolButtonStyle
368
\brief whether the tool button displays an icon only, text only,
369
or text beside/below the icon.
371
The default is Qt::ToolButtonIconOnly.
373
QToolButton automatically connects this slot to the relevant
374
signal in the QMainWindow in which is resides.
378
\property QToolButton::arrowType
379
\brief whether the button displays an arrow instead of a normal icon
381
This displays an arrow as the icon for the QToolButton.
384
Qt::ToolButtonStyle QToolButton::toolButtonStyle() const
386
Q_D(const QToolButton);
387
return d->toolButtonStyle;
390
Qt::ArrowType QToolButton::arrowType() const
392
Q_D(const QToolButton);
397
void QToolButton::setToolButtonStyle(Qt::ToolButtonStyle style)
400
if (d->toolButtonStyle == style)
403
d->toolButtonStyle = style;
410
void QToolButton::setArrowType(Qt::ArrowType type)
413
if (d->arrowType == type)
424
\fn void QToolButton::paintEvent(QPaintEvent *event)
426
Paints the button in response to the paint \a event.
428
void QToolButton::paintEvent(QPaintEvent *)
431
QStylePainter p(this);
432
p.drawComplexControl(QStyle::CC_ToolButton, d->getStyleOption());
438
void QToolButton::actionEvent(QActionEvent *event)
441
QAction *action = event->action();
442
switch (event->type()) {
443
case QEvent::ActionChanged:
444
if (action == d->defaultAction)
445
setDefaultAction(action); // update button state
447
case QEvent::ActionAdded:
448
connect(action, SIGNAL(triggered()), this, SLOT(actionTriggered()));
450
case QEvent::ActionRemoved:
451
if (d->defaultAction == action) {
452
d->defaultAction = 0;
453
if (action->menu() == d->menu)
456
action->disconnect(this);
461
QAbstractButton::actionEvent(event);
464
void QToolButtonPrivate::actionTriggered()
467
if (QAction *action = qobject_cast<QAction *>(q->sender()))
468
emit q->triggered(action);
474
void QToolButton::enterEvent(QEvent * e)
480
QAbstractButton::enterEvent(e);
487
void QToolButton::leaveEvent(QEvent * e)
493
QAbstractButton::leaveEvent(e);
500
void QToolButton::timerEvent(QTimerEvent *e)
503
if (e->timerId() == d->popupTimer.timerId()) {
507
QAbstractButton::timerEvent(e);
514
void QToolButton::changeEvent(QEvent *e)
517
if (e->type() == QEvent::ParentChange) {
518
if (qobject_cast<QToolBar*>(parentWidget()))
521
QAbstractButton::changeEvent(e);
527
void QToolButton::mousePressEvent(QMouseEvent *e)
530
QStyleOptionToolButton opt = d->getStyleOption();
531
if (e->button() == Qt::LeftButton && d->popupMode == MenuButtonPopup) {
532
QRect popupr = style()->subControlRect(QStyle::CC_ToolButton, &opt,
533
QStyle::SC_ToolButtonMenu, this);
534
if (popupr.isValid() && popupr.contains(e->pos())) {
540
QAbstractButton::mousePressEvent(e);
550
QIcon QToolButton::onIconSet() const
558
QIcon QToolButton::offIconSet() const
567
Use setIcon() instead.
570
void QToolButton::setOnIconSet(const QIcon& set)
574
### Get rid of all qWarning in this file in 4.0.
575
Also consider inlining the obsolete functions then.
577
qWarning("QToolButton::setOnIconSet(): This function is not supported"
584
Use setIcon() instead.
587
void QToolButton::setOffIconSet(const QIcon& set)
596
Since Qt 3.0, QIcon contains both the On and Off icons.
598
For ease of porting, this function ignores the \a on parameter and
599
sets the \l icon property. If you relied on the \a on parameter,
600
you probably want to update your code to use the QIcon On/Off
603
\sa icon QIcon::State
606
void QToolButton::setIconSet(const QIcon & set, bool /* on */)
608
QAbstractButton::setIcon(set);
609
qWarning("QToolButton::setIconSet(): 'on' parameter ignored");
615
Since Qt 3.0, QIcon contains both the On and Off icons.
617
For ease of porting, this function ignores the \a on parameter and
618
returns the \l icon property. If you relied on the \a on
619
parameter, you probably want to update your code to use the QIcon
622
QIcon QToolButton::iconSet(bool /* on */) const
624
return QAbstractButton::icon();
630
Associates the given \a menu with this tool button.
632
The menu will be shown according to the button's \l popupMode.
635
Ownership of the menu is not transferred to the tool button.
639
void QToolButton::setMenu(QMenu* menu)
647
Returns the associated menu, or 0 if no menu has been defined.
651
QMenu* QToolButton::menu() const
653
Q_D(const QToolButton);
658
Shows (pops up) the associated popup menu. If there is no such
659
menu, this function does nothing. This function does not return
660
until the popup menu has been closed by the user.
662
void QToolButton::showMenu()
666
d->menuButtonDown = false;
667
return; // no menu to show
670
d->menuButtonDown = true;
672
d->popupTimer.stop();
676
void QToolButtonPrivate::buttonPressed()
680
return; // no menu to show
682
if (delay > 0 && popupMode == QToolButton::DelayedPopup)
683
popupTimer.start(delay, q);
684
else if (popupMode == QToolButton::InstantPopup)
688
void QToolButtonPrivate::popupTimerDone()
692
if (!menuButtonDown && !down)
695
menuButtonDown = true;
696
QPointer<QMenu> actualMenu;
699
if (q->actions().size() > 1)
700
qWarning("QToolButton: menu in setMenu() overriding actions set in addAction!");
702
actualMenu = new QMenu(q);
703
QList<QAction*> actions = q->actions();
704
for(int i = 0; i < actions.size(); i++)
705
actualMenu->addAction(actions.at(i));
707
repeat = q->autoRepeat();
708
q->setAutoRepeat(false);
709
bool horizontal = true;
710
#if !defined(QT_NO_TOOLBAR)
711
QToolBar *tb = qobject_cast<QToolBar*>(q->parentWidget());
712
if (tb && tb->orientation() == Qt::Vertical)
716
QRect screen = qApp->desktop()->availableGeometry(q);
717
QSize sh = actualMenu->sizeHint();
718
QRect rect = q->rect();
720
if (q->isRightToLeft()) {
721
if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.height()) {
722
p = q->mapToGlobal(rect.bottomRight());
724
p = q->mapToGlobal(rect.topRight() - QPoint(0, sh.height()));
726
p.rx() -= sh.width();
728
if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.height()) {
729
p = q->mapToGlobal(rect.bottomLeft());
731
p = q->mapToGlobal(rect.topLeft() - QPoint(0, sh.height()));
735
if (q->isRightToLeft()) {
736
if (q->mapToGlobal(QPoint(rect.left(), 0)).x() - sh.width() <= screen.x()) {
737
p = q->mapToGlobal(rect.topRight());
739
p = q->mapToGlobal(rect.topLeft());
740
p.rx() -= sh.width();
743
if (q->mapToGlobal(QPoint(rect.right(), 0)).x() + sh.width() <= screen.width()) {
744
p = q->mapToGlobal(rect.topRight());
746
p = q->mapToGlobal(rect.topLeft() - QPoint(sh.width(), 0));
750
p.rx() = qMax(0, qMin(p.x(), screen.right() - sh.width()));
752
QPointer<QToolButton> that = q;
753
actualMenu->setNoReplayFor(q);
755
if (actualMenu != menu)
761
q->setAutoRepeat(true);
762
menuButtonDown = false;
771
\fn void QToolButton::setPopupDelay(int delay)
773
Use the style hint QStyle::SH_ToolButton_PopupDelay instead.
775
void QToolButton::setPopupDelay(int delay)
784
Use the style hint QStyle::SH_ToolButton_PopupDelay instead.
786
int QToolButton::popupDelay() const
788
Q_D(const QToolButton);
793
/*! \enum QToolButton::ToolButtonPopupMode
795
Describes how a menu should be popped up for tool buttons that has
796
a menu set or contains a list of actions.
798
\value DelayedPopup After pressing and holding the tool button
799
down for a certain amount of time (the timeout is style dependant,
800
see QStyle::SH_ToolButton_PopupDelay), the menu is displayed. A
801
typical application example is the "back" button in some web
802
browsers's tool bars. If the user clicks it, the browser simply
803
browses back to the previous page. If the user presses and holds
804
the button down for a while, the tool button shows a menu
805
containing the current history list
807
\value MenuButtonPopup In this mode the tool button displays a
808
special arrow to indicate that a menu is present. The menu is
809
displayed when the arrow part of the button is pressed.
811
\value InstantPopup The menu is displayed, without delay, when
812
the tool button is pressed. In this mode, the button's own action
817
\property QToolButton::popupMode
818
\brief describes the way that popup menus are used with tool buttons
821
void QToolButton::setPopupMode(ToolButtonPopupMode mode)
827
QToolButton::ToolButtonPopupMode QToolButton::popupMode() const
829
Q_D(const QToolButton);
835
\property QToolButton::autoRaise
836
\brief whether auto-raising is enabled or not.
838
The default is disabled (i.e. false).
840
void QToolButton::setAutoRaise(bool enable)
843
d->autoRaise = enable;
848
bool QToolButton::autoRaise() const
850
Q_D(const QToolButton);
855
Sets the default action to \a action.
857
If a tool button has a default action, the action defines the
858
button's properties like text, icon, tool tip, etc.
860
void QToolButton::setDefaultAction(QAction *action)
863
if (d->defaultAction && d->menu == d->defaultAction->menu())
865
d->defaultAction = action;
868
if (!actions().contains(action))
870
setText(action->iconText());
871
setIcon(action->icon());
872
setToolTip(action->toolTip());
873
setStatusTip(action->statusTip());
874
setWhatsThis(action->whatsThis());
875
if (QMenu *menu = action->menu())
877
setCheckable(action->isCheckable());
878
setChecked(action->isChecked());
879
setEnabled(action->isEnabled());
880
setFont(action->font());
885
Returns the default action.
887
\sa setDefaultAction()
889
QAction *QToolButton::defaultAction() const
891
Q_D(const QToolButton);
892
return d->defaultAction;
900
void QToolButton::nextCheckState()
903
if (!d->defaultAction)
904
QAbstractButton::nextCheckState();
906
d->defaultAction->trigger();
911
QToolButton::QToolButton(QToolButtonPrivate &dd, QWidget *parent)
912
:QAbstractButton(dd, parent)
919
\fn void QToolButton::setPixmap(const QPixmap &pixmap)
921
Use setIcon(QIcon(pixmap)) instead.
925
\fn void QToolButton::setIconSet(const QIcon &icon)
927
Use setIcon() instead.
931
\fn void QToolButton::setTextLabel(const QString &text, bool tooltip)
933
Use setText() and setToolTip() instead.
937
\fn QString QToolButton::textLabel() const
943
\fn QIcon QToolButton::iconSet() const
949
\fn void QToolButton::openPopup()
951
Use showMenu() instead.
955
\fn void QToolButton::setPopup(QMenu* popup)
957
Use setMenu() instead.
961
\fn QMenu* QToolButton::popup() const
967
\fn TextPosition QToolButton::textPosition() const
969
Use toolButtonStyle() instead.
973
\fn void QToolButton::setTextPosition(TextPosition pos)
975
Use setToolButtonStyle() instead.
979
\fn bool QToolButton::usesBigPixmap() const
981
Use iconSize() instead.
985
\fn void QToolButton::setUsesBigPixmap(bool enable)
987
Use setIconSize() instead.
991
\fn bool QToolButton::usesTextLabel() const
993
Use toolButtonStyle() instead.
997
\fn void QToolButton::setUsesTextLabel(bool enable)
999
Use setToolButtonStyle() instead.
1001
#include "moc_qtoolbutton.cpp"