~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/widgets/qtoolbutton.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the widgets module of the Qt Toolkit.
 
6
**
 
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.
 
10
**
 
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.
 
15
**
 
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.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
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.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qtoolbutton.h"
 
30
#ifndef QT_NO_TOOLBUTTON
 
31
 
 
32
#include <qapplication.h>
 
33
#include <qdesktopwidget.h>
 
34
#include <qdrawutil.h>
 
35
#include <qevent.h>
 
36
#include <qicon.h>
 
37
#include <qmenu.h>
 
38
#include <qpainter.h>
 
39
#include <qpointer.h>
 
40
#include <qstyle.h>
 
41
#include <qstyleoption.h>
 
42
#include <qtooltip.h>
 
43
#include <qmainwindow.h>
 
44
#include <qtoolbar.h>
 
45
#include <qvariant.h>
 
46
#include <qstylepainter.h>
 
47
#include <private/qabstractbutton_p.h>
 
48
 
 
49
class QToolButtonPrivate : public QAbstractButtonPrivate
 
50
{
 
51
    Q_DECLARE_PUBLIC(QToolButton)
 
52
public:
 
53
    void init();
 
54
    void buttonPressed();
 
55
    void popupTimerDone();
 
56
    void actionTriggered();
 
57
    QStyleOptionToolButton getStyleOption() const;
 
58
    QPointer<QMenu> menu; //the menu set by the user (setMenu)
 
59
    QBasicTimer popupTimer;
 
60
    int delay;
 
61
    Qt::ArrowType arrowType;
 
62
    Qt::ToolButtonStyle toolButtonStyle;
 
63
    QToolButton::ToolButtonPopupMode popupMode;
 
64
    uint menuButtonDown          : 1;
 
65
    uint autoRaise             : 1;
 
66
    uint repeat                : 1;
 
67
    QAction *defaultAction;
 
68
    bool hasMenu() const;
 
69
};
 
70
 
 
71
bool QToolButtonPrivate::hasMenu() const
 
72
{
 
73
    Q_Q(const QToolButton);
 
74
    return (menu || q->actions().size() > (defaultAction ? 1 : 0));
 
75
}
 
76
 
 
77
/*!
 
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.
 
81
 
 
82
    \ingroup basic
 
83
    \mainclass
 
84
 
 
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()).
 
91
 
 
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().
 
96
 
 
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.
 
102
 
 
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.
 
109
 
 
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().
 
118
 
 
119
    \img qdockwindow.png Toolbar with Toolbuttons \caption A floating
 
120
    QToolbar with QToolbuttons
 
121
 
 
122
    \sa QPushButton, QToolBar, QMainWindow, {fowler}{GUI Design Handbook: Push Button}
 
123
*/
 
124
 
 
125
/*!
 
126
    \fn void QToolButton::triggered(QAction *action)
 
127
 
 
128
    This signal is emitted when the given \a action is triggered.
 
129
 
 
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
 
133
    to implement.
 
134
*/
 
135
 
 
136
/*!
 
137
    Constructs an empty tool button with parent \a
 
138
    parent.
 
139
*/
 
140
QToolButton::QToolButton(QWidget * parent)
 
141
    : QAbstractButton(*new QToolButtonPrivate, parent)
 
142
{
 
143
    Q_D(QToolButton);
 
144
    d->init();
 
145
}
 
146
 
 
147
#ifdef QT3_SUPPORT
 
148
/*!
 
149
    Constructs an empty tool button called \a name, with parent \a
 
150
    parent.
 
151
*/
 
152
 
 
153
QToolButton::QToolButton(QWidget * parent, const char *name)
 
154
    : QAbstractButton(*new QToolButtonPrivate, parent)
 
155
{
 
156
    Q_D(QToolButton);
 
157
    setObjectName(name);
 
158
    d->init();
 
159
}
 
160
 
 
161
/*!
 
162
    Constructs a tool button called \a name, that is a child of \a
 
163
    parent.
 
164
 
 
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
 
168
    object \a receiver.
 
169
*/
 
170
 
 
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)
 
176
{
 
177
    Q_D(QToolButton);
 
178
    setObjectName(name);
 
179
    d->init();
 
180
    setIcon(icon);
 
181
    setText(textLabel);
 
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);
 
188
}
 
189
 
 
190
 
 
191
/*!
 
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.
 
195
 
 
196
    An arrow button has auto-repeat turned on by default.
 
197
 
 
198
    The \a parent and \a name arguments are sent to the QWidget
 
199
    constructor.
 
200
*/
 
201
QToolButton::QToolButton(Qt::ArrowType type, QWidget *parent, const char *name)
 
202
    : QAbstractButton(*new QToolButtonPrivate, parent)
 
203
{
 
204
    Q_D(QToolButton);
 
205
    setObjectName(name);
 
206
    d->init();
 
207
    setAutoRepeat(true);
 
208
    d->arrowType = type;
 
209
}
 
210
 
 
211
#endif
 
212
 
 
213
 
 
214
/*  Set-up code common to all the constructors */
 
215
 
 
216
void QToolButtonPrivate::init()
 
217
{
 
218
    Q_Q(QToolButton);
 
219
    delay = q->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, 0, q);
 
220
    menu = 0;
 
221
    defaultAction = 0;
 
222
    autoRaise = false;
 
223
    arrowType = Qt::NoArrow;
 
224
    menuButtonDown = false;
 
225
    popupMode = QToolButton::DelayedPopup;
 
226
 
 
227
 
 
228
    toolButtonStyle = Qt::ToolButtonIconOnly;
 
229
 
 
230
    q->setFocusPolicy(Qt::TabFocus);
 
231
    q->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
 
232
 
 
233
    QObject::connect(q, SIGNAL(pressed()), q, SLOT(buttonPressed()));
 
234
}
 
235
 
 
236
 
 
237
QStyleOptionToolButton QToolButtonPrivate::getStyleOption() const
 
238
{
 
239
    Q_Q(const QToolButton);
 
240
    QStyleOptionToolButton opt;
 
241
    opt.init(q);
 
242
    bool down = q->isDown();
 
243
    bool checked = q->isChecked();
 
244
    opt.text = text;
 
245
    opt.icon = icon;
 
246
    opt.iconSize = q->iconSize();
 
247
    opt.arrowType = arrowType;
 
248
    if (down)
 
249
        opt.state |= QStyle::State_Sunken;
 
250
    if (checked)
 
251
        opt.state |= QStyle::State_On;
 
252
    if (autoRaise)
 
253
        opt.state |= QStyle::State_AutoRaise;
 
254
    if (!checked && !down)
 
255
        opt.state |= QStyle::State_Raised;
 
256
 
 
257
    opt.subControls = QStyle::SC_ToolButton;
 
258
    opt.activeSubControls = QStyle::SC_None;
 
259
//     if (down && !menuButtonDown)
 
260
//         opt.activeSubControls |= QStyle::SC_ToolButton;
 
261
 
 
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;
 
269
        }
 
270
    } else {
 
271
        if (menuButtonDown)
 
272
            opt.state  |= QStyle::State_Sunken;
 
273
    }
 
274
    if (arrowType != Qt::NoArrow)
 
275
        opt.features |= QStyleOptionToolButton::Arrow;
 
276
    if (popupMode == QToolButton::DelayedPopup)
 
277
        opt.features |= QStyleOptionToolButton::PopupDelay;
 
278
    opt.toolButtonStyle = toolButtonStyle;
 
279
    if (icon.isNull()) {
 
280
        if (!text.isEmpty())
 
281
            opt.toolButtonStyle = Qt::ToolButtonTextOnly;
 
282
        else if (opt.toolButtonStyle != Qt::ToolButtonTextOnly)
 
283
            opt.toolButtonStyle = Qt::ToolButtonIconOnly;
 
284
    } else {
 
285
        if (text.isEmpty() && opt.toolButtonStyle != Qt::ToolButtonIconOnly)
 
286
            opt.toolButtonStyle = Qt::ToolButtonIconOnly;
 
287
    }
 
288
 
 
289
    opt.pos = q->pos();
 
290
    opt.font = q->font();
 
291
    return opt;
 
292
}
 
293
 
 
294
/*!
 
295
    Destroys the object and frees any allocated resources.
 
296
*/
 
297
 
 
298
QToolButton::~QToolButton()
 
299
{
 
300
}
 
301
 
 
302
/*!
 
303
    \reimp
 
304
*/
 
305
QSize QToolButton::sizeHint() const
 
306
{
 
307
    Q_D(const QToolButton);
 
308
    ensurePolished();
 
309
 
 
310
    int w = 0, h = 0;
 
311
    QStyleOptionToolButton opt = d->getStyleOption();
 
312
 
 
313
    QFontMetrics fm = fontMetrics();
 
314
    if (opt.toolButtonStyle != Qt::ToolButtonTextOnly) {
 
315
        QSize icon = iconSize();
 
316
        w = icon.width();
 
317
        h = icon.height();
 
318
    }
 
319
 
 
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();
 
331
        } else { // TextOnly
 
332
            w = textSize.width();
 
333
            h = textSize.height();
 
334
        }
 
335
    }
 
336
 
 
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);
 
340
 
 
341
    return style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), this).
 
342
            expandedTo(QApplication::globalStrut());
 
343
}
 
344
 
 
345
/*!
 
346
    \reimp
 
347
 */
 
348
QSize QToolButton::minimumSizeHint() const
 
349
{
 
350
    return sizeHint();
 
351
}
 
352
 
 
353
/*!
 
354
    \enum QToolButton::TextPosition
 
355
    \compat
 
356
 
 
357
    This enum describes the position of the tool button's text label in
 
358
    relation to the tool button's icon.
 
359
 
 
360
    \value BesideIcon The text appears beside the icon.
 
361
    \value BelowIcon The text appears below the icon.
 
362
    \omitvalue Right
 
363
    \omitvalue Under
 
364
*/
 
365
 
 
366
/*!
 
367
    \property QToolButton::toolButtonStyle
 
368
    \brief whether the tool button displays an icon only, text only,
 
369
    or text beside/below the icon.
 
370
 
 
371
    The default is Qt::ToolButtonIconOnly.
 
372
 
 
373
    QToolButton automatically connects this slot to the relevant
 
374
    signal in the QMainWindow in which is resides.
 
375
*/
 
376
 
 
377
/*!
 
378
    \property QToolButton::arrowType
 
379
    \brief whether the button displays an arrow instead of a normal icon
 
380
 
 
381
    This displays an arrow as the icon for the QToolButton.
 
382
*/
 
383
 
 
384
Qt::ToolButtonStyle QToolButton::toolButtonStyle() const
 
385
{
 
386
    Q_D(const QToolButton);
 
387
    return d->toolButtonStyle;
 
388
}
 
389
 
 
390
Qt::ArrowType QToolButton::arrowType() const
 
391
{
 
392
    Q_D(const QToolButton);
 
393
    return d->arrowType;
 
394
}
 
395
 
 
396
 
 
397
void QToolButton::setToolButtonStyle(Qt::ToolButtonStyle style)
 
398
{
 
399
    Q_D(QToolButton);
 
400
    if (d->toolButtonStyle == style)
 
401
        return;
 
402
 
 
403
    d->toolButtonStyle = style;
 
404
    updateGeometry();
 
405
    if (isVisible()) {
 
406
        update();
 
407
    }
 
408
}
 
409
 
 
410
void QToolButton::setArrowType(Qt::ArrowType type)
 
411
{
 
412
    Q_D(QToolButton);
 
413
    if (d->arrowType == type)
 
414
        return;
 
415
 
 
416
    d->arrowType = type;
 
417
    updateGeometry();
 
418
    if (isVisible()) {
 
419
        update();
 
420
    }
 
421
}
 
422
 
 
423
/*!
 
424
    \fn void QToolButton::paintEvent(QPaintEvent *event)
 
425
 
 
426
    Paints the button in response to the paint \a event.
 
427
*/
 
428
void QToolButton::paintEvent(QPaintEvent *)
 
429
{
 
430
    Q_D(QToolButton);
 
431
    QStylePainter p(this);
 
432
    p.drawComplexControl(QStyle::CC_ToolButton, d->getStyleOption());
 
433
}
 
434
 
 
435
/*!
 
436
    \reimp
 
437
 */
 
438
void QToolButton::actionEvent(QActionEvent *event)
 
439
{
 
440
    Q_D(QToolButton);
 
441
    QAction *action = event->action();
 
442
    switch (event->type()) {
 
443
    case QEvent::ActionChanged:
 
444
        if (action == d->defaultAction)
 
445
            setDefaultAction(action); // update button state
 
446
        break;
 
447
    case QEvent::ActionAdded:
 
448
        connect(action, SIGNAL(triggered()), this, SLOT(actionTriggered()));
 
449
        break;
 
450
    case QEvent::ActionRemoved:
 
451
        if (d->defaultAction == action) {
 
452
            d->defaultAction = 0;
 
453
            if (action->menu() == d->menu)
 
454
                d->menu = 0;
 
455
        }
 
456
        action->disconnect(this);
 
457
        break;
 
458
    default:
 
459
        ;
 
460
    }
 
461
    QAbstractButton::actionEvent(event);
 
462
}
 
463
 
 
464
void QToolButtonPrivate::actionTriggered()
 
465
{
 
466
    Q_Q(QToolButton);
 
467
    if (QAction *action = qobject_cast<QAction *>(q->sender()))
 
468
        emit q->triggered(action);
 
469
}
 
470
 
 
471
/*!
 
472
    \reimp
 
473
 */
 
474
void QToolButton::enterEvent(QEvent * e)
 
475
{
 
476
    Q_D(QToolButton);
 
477
    if (d->autoRaise)
 
478
        update();
 
479
 
 
480
    QAbstractButton::enterEvent(e);
 
481
}
 
482
 
 
483
 
 
484
/*!
 
485
    \reimp
 
486
 */
 
487
void QToolButton::leaveEvent(QEvent * e)
 
488
{
 
489
    Q_D(QToolButton);
 
490
    if (d->autoRaise)
 
491
        update();
 
492
 
 
493
    QAbstractButton::leaveEvent(e);
 
494
}
 
495
 
 
496
 
 
497
/*!
 
498
    \reimp
 
499
 */
 
500
void QToolButton::timerEvent(QTimerEvent *e)
 
501
{
 
502
    Q_D(QToolButton);
 
503
    if (e->timerId() == d->popupTimer.timerId()) {
 
504
        d->popupTimerDone();
 
505
        return;
 
506
    }
 
507
    QAbstractButton::timerEvent(e);
 
508
}
 
509
 
 
510
 
 
511
/*!
 
512
    \reimp
 
513
*/
 
514
void QToolButton::changeEvent(QEvent *e)
 
515
{
 
516
    Q_D(QToolButton);
 
517
    if (e->type() == QEvent::ParentChange) {
 
518
        if (qobject_cast<QToolBar*>(parentWidget()))
 
519
            d->autoRaise = true;
 
520
    }
 
521
    QAbstractButton::changeEvent(e);
 
522
}
 
523
 
 
524
/*!
 
525
    \reimp
 
526
*/
 
527
void QToolButton::mousePressEvent(QMouseEvent *e)
 
528
{
 
529
    Q_D(QToolButton);
 
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())) {
 
535
            showMenu();
 
536
            return;
 
537
        }
 
538
    }
 
539
 
 
540
    QAbstractButton::mousePressEvent(e);
 
541
}
 
542
 
 
543
 
 
544
 
 
545
#ifdef QT3_SUPPORT
 
546
 
 
547
/*!
 
548
    Use icon() instead.
 
549
*/
 
550
QIcon QToolButton::onIconSet() const
 
551
{
 
552
    return icon();
 
553
}
 
554
 
 
555
/*!
 
556
    Use icon() instead.
 
557
*/
 
558
QIcon QToolButton::offIconSet() const
 
559
{
 
560
    return icon();
 
561
}
 
562
 
 
563
 
 
564
/*!
 
565
  \obsolete
 
566
 
 
567
  Use setIcon() instead.
 
568
 
 
569
*/
 
570
void QToolButton::setOnIconSet(const QIcon& set)
 
571
{
 
572
    setIcon(set);
 
573
    /*
 
574
      ### Get rid of all qWarning in this file in 4.0.
 
575
      Also consider inlining the obsolete functions then.
 
576
    */
 
577
    qWarning("QToolButton::setOnIconSet(): This function is not supported"
 
578
              " anymore");
 
579
}
 
580
 
 
581
/*!
 
582
  \obsolete
 
583
 
 
584
  Use setIcon() instead.
 
585
 
 
586
*/
 
587
void QToolButton::setOffIconSet(const QIcon& set)
 
588
{
 
589
    setIcon(set);
 
590
}
 
591
 
 
592
 
 
593
/*! \overload
 
594
    \obsolete
 
595
 
 
596
  Since Qt 3.0, QIcon contains both the On and Off icons.
 
597
 
 
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
 
601
  mechanism.
 
602
 
 
603
  \sa icon QIcon::State
 
604
*/
 
605
 
 
606
void QToolButton::setIconSet(const QIcon & set, bool /* on */)
 
607
{
 
608
    QAbstractButton::setIcon(set);
 
609
    qWarning("QToolButton::setIconSet(): 'on' parameter ignored");
 
610
}
 
611
 
 
612
/*! \overload
 
613
    \obsolete
 
614
 
 
615
  Since Qt 3.0, QIcon contains both the On and Off icons.
 
616
 
 
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
 
620
  On/Off mechanism.
 
621
*/
 
622
QIcon QToolButton::iconSet(bool /* on */) const
 
623
{
 
624
    return QAbstractButton::icon();
 
625
}
 
626
 
 
627
#endif
 
628
 
 
629
/*!
 
630
    Associates the given \a menu with this tool button.
 
631
 
 
632
    The menu will be shown according to the button's \l popupMode.
 
633
.
 
634
 
 
635
    Ownership of the menu is not transferred to the tool button.
 
636
 
 
637
    \sa menu()
 
638
*/
 
639
void QToolButton::setMenu(QMenu* menu)
 
640
{
 
641
    Q_D(QToolButton);
 
642
    d->menu = menu;
 
643
    update();
 
644
}
 
645
 
 
646
/*!
 
647
    Returns the associated menu, or 0 if no menu has been defined.
 
648
 
 
649
    \sa setMenu()
 
650
*/
 
651
QMenu* QToolButton::menu() const
 
652
{
 
653
    Q_D(const QToolButton);
 
654
    return d->menu;
 
655
}
 
656
 
 
657
/*!
 
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.
 
661
*/
 
662
void QToolButton::showMenu()
 
663
{
 
664
    Q_D(QToolButton);
 
665
    if (!d->hasMenu()) {
 
666
        d->menuButtonDown = false;
 
667
        return; // no menu to show
 
668
    }
 
669
 
 
670
    d->menuButtonDown = true;
 
671
    repaint();
 
672
    d->popupTimer.stop();
 
673
    d->popupTimerDone();
 
674
}
 
675
 
 
676
void QToolButtonPrivate::buttonPressed()
 
677
{
 
678
    Q_Q(QToolButton);
 
679
    if (!hasMenu())
 
680
        return; // no menu to show
 
681
 
 
682
    if (delay > 0 && popupMode == QToolButton::DelayedPopup)
 
683
        popupTimer.start(delay, q);
 
684
    else if  (popupMode == QToolButton::InstantPopup)
 
685
        q->showMenu();
 
686
}
 
687
 
 
688
void QToolButtonPrivate::popupTimerDone()
 
689
{
 
690
    Q_Q(QToolButton);
 
691
    popupTimer.stop();
 
692
    if (!menuButtonDown && !down)
 
693
        return;
 
694
 
 
695
    menuButtonDown = true;
 
696
    QPointer<QMenu> actualMenu;
 
697
    if(menu) {
 
698
        actualMenu = menu;
 
699
        if (q->actions().size() > 1)
 
700
            qWarning("QToolButton: menu in setMenu() overriding actions set in addAction!");
 
701
    } else {
 
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));
 
706
    }
 
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)
 
713
        horizontal = false;
 
714
#endif
 
715
    QPoint p;
 
716
    QRect screen = qApp->desktop()->availableGeometry(q);
 
717
    QSize sh = actualMenu->sizeHint();
 
718
    QRect rect = q->rect();
 
719
    if (horizontal) {
 
720
        if (q->isRightToLeft()) {
 
721
            if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.height()) {
 
722
                p = q->mapToGlobal(rect.bottomRight());
 
723
            } else {
 
724
                p = q->mapToGlobal(rect.topRight() - QPoint(0, sh.height()));
 
725
            }
 
726
            p.rx() -= sh.width();
 
727
        } else {
 
728
            if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.height()) {
 
729
                p = q->mapToGlobal(rect.bottomLeft());
 
730
            } else {
 
731
                p = q->mapToGlobal(rect.topLeft() - QPoint(0, sh.height()));
 
732
            }
 
733
        }
 
734
    } else {
 
735
        if (q->isRightToLeft()) {
 
736
            if (q->mapToGlobal(QPoint(rect.left(), 0)).x() - sh.width() <= screen.x()) {
 
737
                p = q->mapToGlobal(rect.topRight());
 
738
            } else {
 
739
                p = q->mapToGlobal(rect.topLeft());
 
740
                p.rx() -= sh.width();
 
741
            }
 
742
        } else {
 
743
            if (q->mapToGlobal(QPoint(rect.right(), 0)).x() + sh.width() <= screen.width()) {
 
744
                p = q->mapToGlobal(rect.topRight());
 
745
            } else {
 
746
                p = q->mapToGlobal(rect.topLeft() - QPoint(sh.width(), 0));
 
747
            }
 
748
        }
 
749
    }
 
750
    p.rx() = qMax(0, qMin(p.x(), screen.right() - sh.width()));
 
751
    p.ry() += 1;
 
752
    QPointer<QToolButton> that = q;
 
753
    actualMenu->setNoReplayFor(q);
 
754
    actualMenu->exec(p);
 
755
    if (actualMenu != menu)
 
756
        delete actualMenu;
 
757
    if (!that)
 
758
        return;
 
759
 
 
760
    if (repeat)
 
761
        q->setAutoRepeat(true);
 
762
    menuButtonDown = false;
 
763
    if (q->isDown())
 
764
        q->setDown(false);
 
765
    else
 
766
        q->repaint();
 
767
}
 
768
 
 
769
#ifdef QT3_SUPPORT
 
770
/*!
 
771
    \fn void QToolButton::setPopupDelay(int delay)
 
772
 
 
773
    Use the style hint QStyle::SH_ToolButton_PopupDelay instead.
 
774
*/
 
775
void QToolButton::setPopupDelay(int delay)
 
776
{
 
777
    Q_D(QToolButton);
 
778
    d->delay = delay;
 
779
 
 
780
    update();
 
781
}
 
782
 
 
783
/*!
 
784
    Use the style hint QStyle::SH_ToolButton_PopupDelay instead.
 
785
*/
 
786
int QToolButton::popupDelay() const
 
787
{
 
788
    Q_D(const QToolButton);
 
789
    return d->delay;
 
790
}
 
791
#endif
 
792
 
 
793
/*! \enum QToolButton::ToolButtonPopupMode
 
794
 
 
795
    Describes how a menu should be popped up for tool buttons that has
 
796
    a menu set or contains a list of actions.
 
797
 
 
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
 
806
 
 
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.
 
810
 
 
811
    \value InstantPopup The menu is displayed, without delay, when
 
812
    the tool button is pressed. In this mode, the button's own action
 
813
    is not triggered.
 
814
*/
 
815
 
 
816
/*!
 
817
    \property QToolButton::popupMode
 
818
    \brief describes the way that popup menus are used with tool buttons
 
819
*/
 
820
 
 
821
void QToolButton::setPopupMode(ToolButtonPopupMode mode)
 
822
{
 
823
    Q_D(QToolButton);
 
824
    d->popupMode = mode;
 
825
}
 
826
 
 
827
QToolButton::ToolButtonPopupMode QToolButton::popupMode() const
 
828
{
 
829
    Q_D(const QToolButton);
 
830
    return d->popupMode;
 
831
}
 
832
 
 
833
 
 
834
/*!
 
835
    \property QToolButton::autoRaise
 
836
    \brief whether auto-raising is enabled or not.
 
837
 
 
838
    The default is disabled (i.e. false).
 
839
*/
 
840
void QToolButton::setAutoRaise(bool enable)
 
841
{
 
842
    Q_D(QToolButton);
 
843
    d->autoRaise = enable;
 
844
 
 
845
    update();
 
846
}
 
847
 
 
848
bool QToolButton::autoRaise() const
 
849
{
 
850
    Q_D(const QToolButton);
 
851
    return d->autoRaise;
 
852
}
 
853
 
 
854
/*!
 
855
  Sets the default action to \a action.
 
856
 
 
857
  If a tool button has a default action, the action defines the
 
858
  button's properties like text, icon, tool tip, etc.
 
859
 */
 
860
void QToolButton::setDefaultAction(QAction *action)
 
861
{
 
862
    Q_D(QToolButton);
 
863
    if (d->defaultAction && d->menu == d->defaultAction->menu())
 
864
        d->menu = 0;
 
865
    d->defaultAction = action;
 
866
    if (!action)
 
867
        return;
 
868
    if (!actions().contains(action))
 
869
        addAction(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())
 
876
        setMenu(menu);
 
877
    setCheckable(action->isCheckable());
 
878
    setChecked(action->isChecked());
 
879
    setEnabled(action->isEnabled());
 
880
    setFont(action->font());
 
881
}
 
882
 
 
883
 
 
884
/*!
 
885
  Returns the default action.
 
886
 
 
887
  \sa setDefaultAction()
 
888
 */
 
889
QAction *QToolButton::defaultAction() const
 
890
{
 
891
    Q_D(const QToolButton);
 
892
    return d->defaultAction;
 
893
}
 
894
 
 
895
 
 
896
 
 
897
/*!
 
898
  \reimp
 
899
 */
 
900
void QToolButton::nextCheckState()
 
901
{
 
902
    Q_D(QToolButton);
 
903
    if (!d->defaultAction)
 
904
        QAbstractButton::nextCheckState();
 
905
    else
 
906
        d->defaultAction->trigger();
 
907
}
 
908
 
 
909
/*! \internal
 
910
 */
 
911
QToolButton::QToolButton(QToolButtonPrivate &dd, QWidget *parent)
 
912
    :QAbstractButton(dd, parent)
 
913
{
 
914
    Q_D(QToolButton);
 
915
    d->init();
 
916
}
 
917
 
 
918
/*!
 
919
    \fn void QToolButton::setPixmap(const QPixmap &pixmap)
 
920
 
 
921
    Use setIcon(QIcon(pixmap)) instead.
 
922
*/
 
923
 
 
924
/*!
 
925
    \fn void QToolButton::setIconSet(const QIcon &icon)
 
926
 
 
927
    Use setIcon() instead.
 
928
*/
 
929
 
 
930
/*!
 
931
    \fn void QToolButton::setTextLabel(const QString &text, bool tooltip)
 
932
 
 
933
    Use setText() and setToolTip() instead.
 
934
*/
 
935
 
 
936
/*!
 
937
    \fn QString QToolButton::textLabel() const
 
938
 
 
939
    Use text() instead.
 
940
*/
 
941
 
 
942
/*!
 
943
    \fn QIcon QToolButton::iconSet() const
 
944
 
 
945
    Use icon() instead.
 
946
*/
 
947
 
 
948
/*!
 
949
    \fn void QToolButton::openPopup()
 
950
 
 
951
    Use showMenu() instead.
 
952
*/
 
953
 
 
954
/*!
 
955
    \fn void QToolButton::setPopup(QMenu* popup)
 
956
 
 
957
    Use setMenu() instead.
 
958
*/
 
959
 
 
960
/*!
 
961
    \fn QMenu* QToolButton::popup() const
 
962
 
 
963
    Use menu() instead.
 
964
*/
 
965
 
 
966
/*!
 
967
    \fn TextPosition QToolButton::textPosition() const
 
968
 
 
969
    Use toolButtonStyle() instead.
 
970
*/
 
971
 
 
972
/*!
 
973
    \fn void QToolButton::setTextPosition(TextPosition pos)
 
974
 
 
975
    Use setToolButtonStyle() instead.
 
976
*/
 
977
 
 
978
/*!
 
979
    \fn bool QToolButton::usesBigPixmap() const
 
980
 
 
981
    Use iconSize() instead.
 
982
*/
 
983
 
 
984
/*!
 
985
    \fn void QToolButton::setUsesBigPixmap(bool enable)
 
986
 
 
987
    Use setIconSize() instead.
 
988
*/
 
989
 
 
990
/*!
 
991
    \fn bool QToolButton::usesTextLabel() const
 
992
 
 
993
    Use toolButtonStyle() instead.
 
994
*/
 
995
 
 
996
/*!
 
997
    \fn void QToolButton::setUsesTextLabel(bool enable)
 
998
 
 
999
    Use setToolButtonStyle() instead.
 
1000
*/
 
1001
#include "moc_qtoolbutton.cpp"
 
1002
 
 
1003
#endif