source: vendor/trolltech/current/src/widgets/qtoolbutton.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 26.6 KB
Line 
1/****************************************************************************
2** $Id: qtoolbutton.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QToolButton class
5**
6** Created : 980320
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the widgets module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#undef QT_NO_COMPAT
39#include "qtoolbutton.h"
40#ifndef QT_NO_TOOLBUTTON
41
42#include "qdrawutil.h"
43#include "qpainter.h"
44#include "qpixmap.h"
45#include "qwmatrix.h"
46#include "qapplication.h"
47#include "qstyle.h"
48#include "qmainwindow.h"
49#include "qtooltip.h"
50#include "qtoolbar.h"
51#include "qimage.h"
52#include "qiconset.h"
53#include "qtimer.h"
54#include "qpopupmenu.h"
55#include "qguardedptr.h"
56
57class QToolButtonPrivate
58{
59 // ### add tool tip magic here
60public:
61#ifndef QT_NO_POPUPMENU
62 QGuardedPtr<QPopupMenu> popup;
63 QTimer* popupTimer;
64 int delay;
65#endif
66 Qt::ArrowType arrow;
67 uint instantPopup : 1;
68 uint autoraise : 1;
69 uint repeat : 1;
70 uint discardNextMouseEvent : 1;
71 QToolButton::TextPosition textPos;
72};
73
74
75/*!
76 \class QToolButton qtoolbutton.h
77 \brief The QToolButton class provides a quick-access button to
78 commands or options, usually used inside a QToolBar.
79
80 \ingroup basic
81 \mainclass
82
83 A tool button is a special button that provides quick-access to
84 specific commands or options. As opposed to a normal command
85 button, a tool button usually doesn't show a text label, but shows
86 an icon instead. Its classic usage is to select tools, for example
87 the "pen" tool in a drawing program. This would be implemented
88 with a QToolButton as toggle button (see setToggleButton() ).
89
90 QToolButton supports auto-raising. In auto-raise mode, the button
91 draws a 3D frame only when the mouse points at it. The feature is
92 automatically turned on when a button is used inside a QToolBar.
93 Change it with setAutoRaise().
94
95 A tool button's icon is set as QIconSet. This makes it possible to
96 specify different pixmaps for the disabled and active state. The
97 disabled pixmap is used when the button's functionality is not
98 available. The active pixmap is displayed when the button is
99 auto-raised because the mouse pointer is hovering over it.
100
101 The button's look and dimension is adjustable with
102 setUsesBigPixmap() and setUsesTextLabel(). When used inside a
103 QToolBar in a QMainWindow, the button automatically adjusts to
104 QMainWindow's settings (see QMainWindow::setUsesTextLabel() and
105 QMainWindow::setUsesBigPixmaps()). The pixmap set on a QToolButton
106 will be set to 22x22 if it is bigger than this size. If
107 usesBigPixmap() is TRUE, then the pixmap will be set to 32x32.
108
109 A tool button can offer additional choices in a popup menu. The
110 feature is sometimes used with the "Back" button in a web browser.
111 After pressing and holding the button down for a while, a menu
112 pops up showing a list of possible pages to jump to. With
113 QToolButton you can set a popup menu using setPopup(). The default
114 delay is 600ms; you can adjust it with setPopupDelay().
115
116 \img qdockwindow.png Toolbar with Toolbuttons \caption A floating
117 QToolbar with QToolbuttons
118
119 \sa QPushButton QToolBar QMainWindow \link guibooks.html#fowler
120 GUI Design Handbook: Push Button\endlink
121*/
122
123/*!
124 \enum QToolButton::TextPosition
125
126 The position of the tool button's textLabel in relation to the
127 tool button's icon.
128
129 \value BesideIcon The text appears beside the icon.
130 \value BelowIcon The text appears below the icon.
131*/
132
133
134/*!
135 Constructs an empty tool button called \a name, with parent \a
136 parent.
137*/
138
139QToolButton::QToolButton( QWidget * parent, const char *name )
140 : QButton( parent, name )
141{
142 init();
143#ifndef QT_NO_TOOLBAR
144 QToolBar* tb = ::qt_cast<QToolBar*>(parent);
145 if ( tb ) {
146 setAutoRaise( TRUE );
147 if ( tb->mainWindow() ) {
148 connect( tb->mainWindow(), SIGNAL(pixmapSizeChanged(bool)),
149 this, SLOT(setUsesBigPixmap(bool)) );
150 setUsesBigPixmap( tb->mainWindow()->usesBigPixmaps() );
151 connect( tb->mainWindow(), SIGNAL(usesTextLabelChanged(bool)),
152 this, SLOT(setUsesTextLabel(bool)) );
153 setUsesTextLabel( tb->mainWindow()->usesTextLabel() );
154 } else {
155 setUsesBigPixmap( FALSE );
156 }
157 } else
158#endif
159 {
160 setUsesBigPixmap( FALSE );
161 }
162}
163
164
165/*!
166 Constructs a tool button as an arrow button. The \c ArrowType \a
167 type defines the arrow direction. Possible values are \c
168 LeftArrow, \c RightArrow, \c UpArrow and \c DownArrow.
169
170 An arrow button has auto-repeat turned on by default.
171
172 The \a parent and \a name arguments are sent to the QWidget
173 constructor.
174*/
175QToolButton::QToolButton( ArrowType type, QWidget *parent, const char *name )
176 : QButton( parent, name )
177{
178 init();
179 setUsesBigPixmap( FALSE );
180 setAutoRepeat( TRUE );
181 d->arrow = type;
182 hasArrow = TRUE;
183}
184
185
186/* Set-up code common to all the constructors */
187
188void QToolButton::init()
189{
190 d = new QToolButtonPrivate;
191 d->textPos = Under;
192#ifndef QT_NO_POPUPMENU
193 d->delay = 600;
194 d->popup = 0;
195 d->popupTimer = 0;
196#endif
197 d->autoraise = FALSE;
198 d->arrow = LeftArrow;
199 d->instantPopup = FALSE;
200 d->discardNextMouseEvent = FALSE;
201 bpID = bp.serialNumber();
202 spID = sp.serialNumber();
203
204 utl = FALSE;
205 ubp = TRUE;
206 hasArrow = FALSE;
207
208 s = 0;
209
210 setFocusPolicy( NoFocus );
211 setBackgroundMode( PaletteButton);
212 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) );
213}
214
215#ifndef QT_NO_TOOLBAR
216
217/*!
218 Constructs a tool button called \a name, that is a child of \a
219 parent (which must be a QToolBar).
220
221 The tool button will display \a iconSet, with its text label and
222 tool tip set to \a textLabel and its status bar message set to \a
223 grouptext. It will be connected to the \a slot in object \a
224 receiver.
225*/
226
227QToolButton::QToolButton( const QIconSet& iconSet, const QString &textLabel,
228 const QString& grouptext,
229 QObject * receiver, const char *slot,
230 QToolBar * parent, const char *name )
231 : QButton( parent, name )
232{
233 init();
234 setAutoRaise( TRUE );
235 setIconSet( iconSet );
236 setTextLabel( textLabel );
237 if ( receiver && slot )
238 connect( this, SIGNAL(clicked()), receiver, slot );
239 if ( parent->mainWindow() ) {
240 connect( parent->mainWindow(), SIGNAL(pixmapSizeChanged(bool)),
241 this, SLOT(setUsesBigPixmap(bool)) );
242 setUsesBigPixmap( parent->mainWindow()->usesBigPixmaps() );
243 connect( parent->mainWindow(), SIGNAL(usesTextLabelChanged(bool)),
244 this, SLOT(setUsesTextLabel(bool)) );
245 setUsesTextLabel( parent->mainWindow()->usesTextLabel() );
246 } else {
247 setUsesBigPixmap( FALSE );
248 }
249#ifndef QT_NO_TOOLTIP
250 if ( !textLabel.isEmpty() ) {
251 if ( !grouptext.isEmpty() )
252 QToolTip::add( this, textLabel,
253 parent->mainWindow()->toolTipGroup(), grouptext );
254 else
255 QToolTip::add( this, textLabel );
256 } else if ( !grouptext.isEmpty() )
257 QToolTip::add( this, QString::null,
258 parent->mainWindow()->toolTipGroup(), grouptext );
259#endif
260}
261
262#endif
263
264
265/*!
266 Destroys the object and frees any allocated resources.
267*/
268
269QToolButton::~QToolButton()
270{
271#ifndef QT_NO_POPUPMENU
272 d->popupTimer = 0;
273 d->popup = 0;
274#endif
275 delete d;
276 delete s;
277}
278
279
280/*!
281 \property QToolButton::backgroundMode
282 \brief the toolbutton's background mode
283
284 Get this property with backgroundMode().
285
286 \sa QWidget::setBackgroundMode()
287*/
288
289/*!
290 \property QToolButton::toggleButton
291 \brief whether this tool button is a toggle button.
292
293 Toggle buttons have an on/off state similar to \link QCheckBox
294 check boxes. \endlink A tool button is not a toggle button by
295 default.
296
297 \sa setOn(), toggle()
298*/
299
300void QToolButton::setToggleButton( bool enable )
301{
302 QButton::setToggleButton( enable );
303}
304
305
306/*!
307 \reimp
308*/
309QSize QToolButton::sizeHint() const
310{
311 constPolish();
312
313 int w = 0, h = 0;
314
315 if ( iconSet().isNull() && !text().isNull() && !usesTextLabel() ) {
316 w = fontMetrics().width( text() );
317 h = fontMetrics().height(); // boundingRect()?
318 } else if ( usesBigPixmap() ) {
319 QPixmap pm = iconSet().pixmap( QIconSet::Large, QIconSet::Normal );
320 w = pm.width();
321 h = pm.height();
322 QSize iconSize = QIconSet::iconSize( QIconSet::Large );
323 if ( w < iconSize.width() )
324 w = iconSize.width();
325 if ( h < iconSize.height() )
326 h = iconSize.height();
327 } else if ( !iconSet().isNull() ) {
328 // ### in 3.1, use QIconSet::iconSize( QIconSet::Small );
329 QPixmap pm = iconSet().pixmap( QIconSet::Small, QIconSet::Normal );
330 w = pm.width();
331 h = pm.height();
332 if ( w < 16 )
333 w = 16;
334 if ( h < 16 )
335 h = 16;
336 }
337
338 if ( usesTextLabel() ) {
339 QSize textSize = fontMetrics().size( Qt::ShowPrefix, textLabel() );
340 textSize.setWidth( textSize.width() + fontMetrics().width(' ')*2 );
341 if ( d->textPos == Under ) {
342 h += 4 + textSize.height();
343 if ( textSize.width() > w )
344 w = textSize.width();
345 } else { // Right
346 w += 4 + textSize.width();
347 if ( textSize.height() > h )
348 h = textSize.height();
349 }
350 }
351
352#ifndef QT_NO_POPUPMENU
353 if ( popup() && ! popupDelay() )
354 w += style().pixelMetric(QStyle::PM_MenuButtonIndicator, this);
355#endif
356 return (style().sizeFromContents(QStyle::CT_ToolButton, this, QSize(w, h)).
357 expandedTo(QApplication::globalStrut()));
358}
359
360/*!
361 \reimp
362 */
363QSize QToolButton::minimumSizeHint() const
364{
365 return sizeHint();
366}
367
368/*!
369 \property QToolButton::usesBigPixmap
370 \brief whether this toolbutton uses big pixmaps.
371
372 QToolButton automatically connects this property to the relevant
373 signal in the QMainWindow in which it resides. We strongly
374 recommend that you use QMainWindow::setUsesBigPixmaps() instead.
375
376 This property's default is TRUE.
377
378 \warning If you set some buttons (in a QMainWindow) to have big
379 pixmaps and others to have small pixmaps, QMainWindow may not get
380 the geometry right.
381*/
382
383void QToolButton::setUsesBigPixmap( bool enable )
384{
385 if ( (bool)ubp == enable )
386 return;
387
388 ubp = enable;
389 if ( isVisible() ) {
390 update();
391 updateGeometry();
392 }
393}
394
395
396/*!
397 \property QToolButton::usesTextLabel
398 \brief whether the toolbutton displays a text label below the button pixmap.
399
400 The default is FALSE.
401
402 QToolButton automatically connects this slot to the relevant
403 signal in the QMainWindow in which is resides.
404*/
405
406void QToolButton::setUsesTextLabel( bool enable )
407{
408 if ( (bool)utl == enable )
409 return;
410
411 utl = enable;
412 if ( isVisible() ) {
413 update();
414 updateGeometry();
415 }
416}
417
418
419/*!
420 \property QToolButton::on
421 \brief whether this tool button is on.
422
423 This property has no effect on \link isToggleButton() non-toggling
424 buttons. \endlink The default is FALSE (i.e. off).
425
426 \sa isToggleButton() toggle()
427*/
428
429void QToolButton::setOn( bool enable )
430{
431 if ( !isToggleButton() )
432 return;
433 QButton::setOn( enable );
434}
435
436
437/*!
438 Toggles the state of this tool button.
439
440 This function has no effect on \link isToggleButton() non-toggling
441 buttons. \endlink
442
443 \sa isToggleButton() toggled()
444*/
445
446void QToolButton::toggle()
447{
448 if ( !isToggleButton() )
449 return;
450 QButton::setOn( !isOn() );
451}
452
453
454/*!
455 \reimp
456*/
457void QToolButton::drawButton( QPainter * p )
458{
459 QStyle::SCFlags controls = QStyle::SC_ToolButton;
460 QStyle::SCFlags active = QStyle::SC_None;
461
462 Qt::ArrowType arrowtype = d->arrow;
463
464 if (isDown())
465 active |= QStyle::SC_ToolButton;
466
467#ifndef QT_NO_POPUPMENU
468 if (d->popup && !d->delay) {
469 controls |= QStyle::SC_ToolButtonMenu;
470 if (d->instantPopup || isDown())
471 active |= QStyle::SC_ToolButtonMenu;
472 }
473#endif
474
475 QStyle::SFlags flags = QStyle::Style_Default;
476 if (isEnabled())
477 flags |= QStyle::Style_Enabled;
478 if (hasFocus())
479 flags |= QStyle::Style_HasFocus;
480 if (isDown())
481 flags |= QStyle::Style_Down;
482 if (isOn())
483 flags |= QStyle::Style_On;
484 if (autoRaise()) {
485 flags |= QStyle::Style_AutoRaise;
486 if (uses3D()) {
487 flags |= QStyle::Style_MouseOver;
488 if (! isOn() && ! isDown())
489 flags |= QStyle::Style_Raised;
490 }
491 } else if (! isOn() && ! isDown())
492 flags |= QStyle::Style_Raised;
493
494 style().drawComplexControl(QStyle::CC_ToolButton, p, this, rect(), colorGroup(),
495 flags, controls, active,
496 hasArrow ? QStyleOption(arrowtype) :
497 QStyleOption());
498 drawButtonLabel(p);
499}
500
501
502/*!
503 \reimp
504*/
505void QToolButton::drawButtonLabel(QPainter *p)
506{
507 QRect r =
508 QStyle::visualRect(style().subRect(QStyle::SR_ToolButtonContents, this), this);
509
510 Qt::ArrowType arrowtype = d->arrow;
511
512 QStyle::SFlags flags = QStyle::Style_Default;
513 if (isEnabled())
514 flags |= QStyle::Style_Enabled;
515 if (hasFocus())
516 flags |= QStyle::Style_HasFocus;
517 if (isDown())
518 flags |= QStyle::Style_Down;
519 if (isOn())
520 flags |= QStyle::Style_On;
521 if (autoRaise()) {
522 flags |= QStyle::Style_AutoRaise;
523 if (uses3D()) {
524 flags |= QStyle::Style_MouseOver;
525 if (! isOn() && ! isDown())
526 flags |= QStyle::Style_Raised;
527 }
528 } else if (! isOn() && ! isDown())
529 flags |= QStyle::Style_Raised;
530
531 style().drawControl(QStyle::CE_ToolButtonLabel, p, this, r,
532 colorGroup(), flags,
533 hasArrow ? QStyleOption(arrowtype) :
534 QStyleOption());
535}
536
537
538/*!
539 \reimp
540 */
541void QToolButton::enterEvent( QEvent * e )
542{
543 if ( autoRaise() && isEnabled() )
544 repaint(FALSE);
545
546 QButton::enterEvent( e );
547}
548
549
550/*!
551 \reimp
552 */
553void QToolButton::leaveEvent( QEvent * e )
554{
555 if ( autoRaise() && isEnabled() )
556 repaint(FALSE);
557
558 QButton::leaveEvent( e );
559}
560
561/*!
562 \reimp
563 */
564void QToolButton::moveEvent( QMoveEvent * )
565{
566 // Reimplemented to handle pseudo transparency in case the toolbars
567 // has a fancy pixmap background.
568 if ( parentWidget() && parentWidget()->backgroundPixmap() &&
569 autoRaise() && !uses3D() )
570 repaint( FALSE );
571}
572
573/*!
574 \reimp
575*/
576void QToolButton::mousePressEvent( QMouseEvent *e )
577{
578 QRect popupr =
579 QStyle::visualRect( style().querySubControlMetrics(QStyle::CC_ToolButton, this,
580 QStyle::SC_ToolButtonMenu), this );
581 d->instantPopup = (popupr.isValid() && popupr.contains(e->pos()));
582
583#ifndef QT_NO_POPUPMENU
584 if ( d->discardNextMouseEvent ) {
585 d->discardNextMouseEvent = FALSE;
586 d->instantPopup = FALSE;
587 d->popup->removeEventFilter( this );
588 return;
589 }
590 if ( e->button() == LeftButton && d->delay <= 0 && d->popup && d->instantPopup && !d->popup->isVisible() ) {
591 openPopup();
592 return;
593 }
594#endif
595
596 d->instantPopup = FALSE;
597 QButton::mousePressEvent( e );
598}
599
600/*!
601 \reimp
602*/
603bool QToolButton::eventFilter( QObject *o, QEvent *e )
604{
605#ifndef QT_NO_POPUPMENU
606 if ( o != d->popup )
607 return QButton::eventFilter( o, e );
608 switch ( e->type() ) {
609 case QEvent::MouseButtonPress:
610 case QEvent::MouseButtonDblClick:
611 {
612 QMouseEvent *me = (QMouseEvent*)e;
613 QPoint p = me->globalPos();
614 if ( QApplication::widgetAt( p, TRUE ) == this )
615 d->discardNextMouseEvent = TRUE;
616 }
617 break;
618 default:
619 break;
620 }
621#endif
622 return QButton::eventFilter( o, e );
623}
624
625/*!
626 Returns TRUE if this button should be drawn using raised edges;
627 otherwise returns FALSE.
628
629 \sa drawButton()
630*/
631
632bool QToolButton::uses3D() const
633{
634 return style().styleHint(QStyle::SH_ToolButton_Uses3D)
635 && (!autoRaise() || ( hasMouse() && isEnabled() )
636#ifndef QT_NO_POPUPMENU
637 || ( d->popup && d->popup->isVisible() && d->delay <= 0 ) || d->instantPopup
638#endif
639 );
640}
641
642
643/*!
644 \property QToolButton::textLabel
645 \brief the label of this button.
646
647 Setting this property automatically sets the text as a tool tip
648 too. There is no default text.
649*/
650
651void QToolButton::setTextLabel( const QString &newLabel )
652{
653 setTextLabel( newLabel, TRUE );
654}
655
656/*!
657 \overload
658
659 Sets the label of this button to \a newLabel and automatically
660 sets it as a tool tip if \a tipToo is TRUE.
661*/
662
663void QToolButton::setTextLabel( const QString &newLabel , bool tipToo )
664{
665 if ( tl == newLabel )
666 return;
667
668#ifndef QT_NO_TOOLTIP
669 if ( tipToo ) {
670 QToolTip::remove( this );
671 QToolTip::add( this, newLabel );
672 }
673#endif
674
675 tl = newLabel;
676 if ( usesTextLabel() && isVisible() ) {
677 update();
678 updateGeometry();
679 }
680
681}
682
683#ifndef QT_NO_COMPAT
684
685QIconSet QToolButton::onIconSet() const
686{
687 return iconSet();
688}
689
690QIconSet QToolButton::offIconSet( ) const
691{
692 return iconSet();
693}
694
695
696/*!
697 \property QToolButton::onIconSet
698 \brief the icon set that is used when the button is in an "on" state
699
700 \obsolete
701
702 Since Qt 3.0, QIconSet contains both the On and Off icons. There is
703 now an \l QToolButton::iconSet property that replaces both \l
704 QToolButton::onIconSet and \l QToolButton::offIconSet.
705
706 For ease of porting, this property is a synonym for \l
707 QToolButton::iconSet. You probably want to go over your application
708 code and use the QIconSet On/Off mechanism.
709
710 \sa iconSet QIconSet::State
711*/
712void QToolButton::setOnIconSet( const QIconSet& set )
713{
714 setIconSet( set );
715 /*
716 ### Get rid of all qWarning in this file in 4.0.
717 Also consider inlining the obsolete functions then.
718 */
719 qWarning( "QToolButton::setOnIconSet(): This function is not supported"
720 " anymore" );
721}
722
723/*!
724 \property QToolButton::offIconSet
725 \brief the icon set that is used when the button is in an "off" state
726
727 \obsolete
728
729 Since Qt 3.0, QIconSet contains both the On and Off icons. There is
730 now an \l QToolButton::iconSet property that replaces both \l
731 QToolButton::onIconSet and \l QToolButton::offIconSet.
732
733 For ease of porting, this property is a synonym for \l
734 QToolButton::iconSet. You probably want to go over your application
735 code and use the QIconSet On/Off mechanism.
736
737 \sa iconSet QIconSet::State
738*/
739void QToolButton::setOffIconSet( const QIconSet& set )
740{
741 setIconSet( set );
742}
743
744#endif
745
746/*! \property QToolButton::pixmap
747 \brief the pixmap of the button
748
749 The pixmap property has no meaning for tool buttons. Use the
750 iconSet property instead.
751*/
752
753/*!
754 \property QToolButton::iconSet
755 \brief the icon set providing the icon shown on the button
756
757 Setting this property sets \l QToolButton::pixmap to a null
758 pixmap. There is no default iconset.
759
760 \sa pixmap(), setToggleButton(), isOn()
761*/
762void QToolButton::setIconSet( const QIconSet & set )
763{
764 if ( s )
765 delete s;
766 setPixmap( QPixmap() );
767 s = new QIconSet( set );
768 if ( isVisible() )
769 update();
770}
771
772/*! \overload
773 \obsolete
774
775 Since Qt 3.0, QIconSet contains both the On and Off icons.
776
777 For ease of porting, this function ignores the \a on parameter and
778 sets the \l iconSet property. If you relied on the \a on parameter,
779 you probably want to update your code to use the QIconSet On/Off
780 mechanism.
781
782 \sa iconSet QIconSet::State
783*/
784
785#ifndef QT_NO_COMPAT
786
787void QToolButton::setIconSet( const QIconSet & set, bool /* on */ )
788{
789 setIconSet( set );
790 qWarning( "QToolButton::setIconSet(): 'on' parameter ignored" );
791}
792
793#endif
794
795QIconSet QToolButton::iconSet() const
796{
797 QToolButton *that = (QToolButton *) this;
798
799 if ( pixmap() && !pixmap()->isNull() &&
800 (!that->s || (that->s->pixmap().serialNumber() !=
801 pixmap()->serialNumber())) ) {
802 if ( that->s )
803 delete that->s;
804 that->s = new QIconSet( *pixmap() );
805 }
806 if ( that->s )
807 return *that->s;
808 /*
809 In 2.x, we used to return a temporary nonnull QIconSet. If you
810 revert to the old behavior, you will break calls to
811 QIconSet::isNull() in this file.
812 */
813 return QIconSet();
814}
815
816#ifndef QT_NO_COMPAT
817/*! \overload
818 \obsolete
819
820 Since Qt 3.0, QIconSet contains both the On and Off icons.
821
822 For ease of porting, this function ignores the \a on parameter and
823 returns the \l iconSet property. If you relied on the \a on
824 parameter, you probably want to update your code to use the QIconSet
825 On/Off mechanism.
826*/
827QIconSet QToolButton::iconSet( bool /* on */ ) const
828{
829 return iconSet();
830}
831
832#endif
833
834#ifndef QT_NO_POPUPMENU
835/*!
836 Associates the popup menu \a popup with this tool button.
837
838 The popup will be shown each time the tool button has been pressed
839 down for a certain amount of time. A typical application example
840 is the "back" button in some web browsers's tool bars. If the user
841 clicks it, the browser simply browses back to the previous page.
842 If the user presses and holds the button down for a while, the
843 tool button shows a menu containing the current history list.
844
845 Ownership of the popup menu is not transferred to the tool button.
846
847 \sa popup()
848*/
849void QToolButton::setPopup( QPopupMenu* popup )
850{
851 if ( popup && !d->popupTimer ) {
852 connect( this, SIGNAL( pressed() ), this, SLOT( popupPressed() ) );
853 d->popupTimer = new QTimer( this );
854 connect( d->popupTimer, SIGNAL( timeout() ), this, SLOT( popupTimerDone() ) );
855 }
856 d->popup = popup;
857
858 update();
859}
860
861/*!
862 Returns the associated popup menu, or 0 if no popup menu has been
863 defined.
864
865 \sa setPopup()
866*/
867QPopupMenu* QToolButton::popup() const
868{
869 return d->popup;
870}
871
872/*!
873 Opens (pops up) the associated popup menu. If there is no such
874 menu, this function does nothing. This function does not return
875 until the popup menu has been closed by the user.
876*/
877void QToolButton::openPopup()
878{
879 if ( !d->popup )
880 return;
881
882 d->instantPopup = TRUE;
883 repaint( FALSE );
884 if ( d->popupTimer )
885 d->popupTimer->stop();
886 QGuardedPtr<QToolButton> that = this;
887 popupTimerDone();
888 if ( !that )
889 return;
890 d->instantPopup = FALSE;
891 repaint( FALSE );
892}
893
894void QToolButton::popupPressed()
895{
896 if ( d->popupTimer && d->delay > 0 )
897 d->popupTimer->start( d->delay, TRUE );
898}
899
900void QToolButton::popupTimerDone()
901{
902 if ( (!isDown() && d->delay > 0 ) || !d->popup )
903 return;
904
905 d->popup->installEventFilter( this );
906 d->repeat = autoRepeat();
907 setAutoRepeat( FALSE );
908 bool horizontal = TRUE;
909#ifndef QT_NO_TOOLBAR
910 QToolBar *tb = ::qt_cast<QToolBar*>(parentWidget());
911 if ( tb && tb->orientation() == Vertical )
912 horizontal = FALSE;
913#endif
914 QPoint p;
915 QRect screen = qApp->desktop()->availableGeometry( this );
916 if ( horizontal ) {
917 if ( QApplication::reverseLayout() ) {
918 if ( mapToGlobal( QPoint( 0, rect().bottom() ) ).y() + d->popup->sizeHint().height() <= screen.height() ) {
919 p = mapToGlobal( rect().bottomRight() );
920 } else {
921 p = mapToGlobal( rect().topRight() - QPoint( 0, d->popup->sizeHint().height() ) );
922 }
923 p.rx() -= d->popup->sizeHint().width();
924 } else {
925 if ( mapToGlobal( QPoint( 0, rect().bottom() ) ).y() + d->popup->sizeHint().height() <= screen.height() ) {
926 p = mapToGlobal( rect().bottomLeft() );
927 } else {
928 p = mapToGlobal( rect().topLeft() - QPoint( 0, d->popup->sizeHint().height() ) );
929 }
930 }
931 } else {
932 if ( QApplication::reverseLayout() ) {
933 if ( mapToGlobal( QPoint( rect().left(), 0 ) ).x() - d->popup->sizeHint().width() <= screen.x() ) {
934 p = mapToGlobal( rect().topRight() );
935 } else {
936 p = mapToGlobal( rect().topLeft() );
937 p.rx() -= d->popup->sizeHint().width();
938 }
939 } else {
940 if ( mapToGlobal( QPoint( rect().right(), 0 ) ).x() + d->popup->sizeHint().width() <= screen.width() ) {
941 p = mapToGlobal( rect().topRight() );
942 } else {
943 p = mapToGlobal( rect().topLeft() - QPoint( d->popup->sizeHint().width(), 0 ) );
944 }
945 }
946 }
947 QGuardedPtr<QToolButton> that = this;
948 d->popup->exec( p, -1 );
949 if ( !that )
950 return;
951
952 setDown( FALSE );
953 if ( d->repeat )
954 setAutoRepeat( TRUE );
955}
956
957/*!
958 \property QToolButton::popupDelay
959 \brief the time delay between pressing the button and the appearance of the associated popup menu in milliseconds.
960
961 Usually this is around half a second. A value of 0 draws the down
962 arrow button to the side of the button which can be used to open
963 up the popup menu.
964
965 \sa setPopup()
966*/
967void QToolButton::setPopupDelay( int delay )
968{
969 d->delay = delay;
970
971 update();
972}
973
974int QToolButton::popupDelay() const
975{
976 return d->delay;
977}
978#endif
979
980
981/*!
982 \property QToolButton::autoRaise
983 \brief whether auto-raising is enabled or not.
984
985 The default is disabled (i.e. FALSE).
986*/
987void QToolButton::setAutoRaise( bool enable )
988{
989 d->autoraise = enable;
990
991 update();
992}
993
994bool QToolButton::autoRaise() const
995{
996 return d->autoraise;
997}
998
999/*!
1000 \property QToolButton::textPosition
1001 \brief the position of the text label of this button.
1002*/
1003
1004QToolButton::TextPosition QToolButton::textPosition() const
1005{
1006 return d->textPos;
1007}
1008
1009void QToolButton::setTextPosition( TextPosition pos )
1010{
1011 d->textPos = pos;
1012 updateGeometry();
1013 update();
1014}
1015
1016/*! \reimp */
1017
1018void QToolButton::setText( const QString &txt )
1019{
1020 QButton::setText( txt );
1021 if ( !text().isEmpty() ) {
1022 delete s;
1023 s = 0;
1024 }
1025}
1026
1027#ifndef QT_NO_PALETTE
1028/*!
1029 \reimp
1030*/
1031void QToolButton::paletteChange( const QPalette & )
1032{
1033 if ( s )
1034 s->clearGenerated();
1035}
1036#endif
1037
1038#endif
Note: See TracBrowser for help on using the repository browser.