summaryrefslogtreecommitdiffstats
path: root/src/widgets/qtooltip.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <[email protected]>2011-07-10 15:24:15 -0500
committerTimothy Pearson <[email protected]>2011-07-10 15:24:15 -0500
commitbd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch)
tree7a520322212d48ebcb9fbe1087e7fca28b76185c /src/widgets/qtooltip.cpp
downloadqt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz
qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip
Add Qt3 development HEAD version
Diffstat (limited to 'src/widgets/qtooltip.cpp')
-rw-r--r--src/widgets/qtooltip.cpp1270
1 files changed, 1270 insertions, 0 deletions
diff --git a/src/widgets/qtooltip.cpp b/src/widgets/qtooltip.cpp
new file mode 100644
index 0000000..c327859
--- /dev/null
+++ b/src/widgets/qtooltip.cpp
@@ -0,0 +1,1270 @@
+/****************************************************************************
+**
+** Tool Tips (or Balloon Help) for any widget or rectangle
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the Qt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at [email protected].
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "qtooltip.h"
+#ifndef QT_NO_TOOLTIP
+#include "qlabel.h"
+#include "qptrdict.h"
+#include "qapplication.h"
+#include "qguardedptr.h"
+#include "qtimer.h"
+#include "qeffects_p.h"
+
+static bool globally_enabled = TRUE;
+
+// Magic value meaning an entire widget - if someone tries to insert a
+// tool tip on this part of a widget it will be interpreted as the
+// entire widget.
+
+static inline QRect entireWidget()
+{
+ return QRect( -QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX,
+ 2*QWIDGETSIZE_MAX, 2*QWIDGETSIZE_MAX );
+}
+
+// Internal class - don't touch
+
+class QTipLabel : public QLabel
+{
+ Q_OBJECT
+public:
+ QTipLabel( QWidget* parent, const QString& text) : QLabel( parent, "toolTipTip",
+ WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM )
+ {
+ setMargin(1);
+ setAutoMask( FALSE );
+ setFrameStyle( QFrame::Plain | QFrame::Box );
+ setLineWidth( 1 );
+ setAlignment( AlignAuto | AlignTop );
+ setIndent(0);
+ polish();
+ setText(text);
+ adjustSize();
+ x11SetWindowType( X11WindowTypeTooltip );
+ }
+ void setWidth( int w ) { resize( sizeForWidth( w ) ); }
+};
+
+// Internal class - don't touch
+
+class QTipManager : public QObject
+{
+ Q_OBJECT
+public:
+ QTipManager();
+ ~QTipManager();
+
+ struct Tip
+ {
+ QRect rect;
+ QString text;
+ QString groupText;
+ QToolTipGroup *group;
+ QToolTip *tip;
+ bool autoDelete;
+ QRect geometry;
+ Tip *next;
+ };
+
+ bool eventFilter( QObject * o, QEvent * e );
+ void add( const QRect &gm, QWidget *, const QRect &, const QString& ,
+ QToolTipGroup *, const QString& , QToolTip *, bool );
+ void add( QWidget *, const QRect &, const QString& ,
+ QToolTipGroup *, const QString& , QToolTip *, bool );
+ void remove( QWidget *, const QRect &, bool delayhide = FALSE );
+ void remove( QWidget * );
+
+ void removeFromGroup( QToolTipGroup * );
+
+ void hideTipAndSleep();
+
+ QString find( QWidget *, const QPoint& );
+ void setWakeUpDelay(int);
+
+public slots:
+ void hideTip();
+
+private slots:
+ void labelDestroyed();
+ void clientWidgetDestroyed();
+ void showTip();
+ void allowAnimation();
+
+private:
+ QTimer wakeUp;
+ int wakeUpDelay;
+ QTimer fallAsleep;
+
+ QPtrDict<Tip> *tips;
+ QTipLabel *label;
+ QPoint pos;
+ QGuardedPtr<QWidget> widget;
+ Tip *currentTip;
+ Tip *previousTip;
+ bool preventAnimation;
+ bool isApplicationFilter;
+ QTimer *removeTimer;
+};
+
+
+// We have a global, internal QTipManager object
+
+static QTipManager *tipManager = 0;
+
+static void initTipManager()
+{
+ if ( !tipManager ) {
+ tipManager = new QTipManager;
+ Q_CHECK_PTR( tipManager );
+ }
+}
+
+
+QTipManager::QTipManager()
+ : QObject( qApp, "toolTipManager" )
+{
+ wakeUpDelay = 700;
+ tips = new QPtrDict<QTipManager::Tip>( 313 );
+ currentTip = 0;
+ previousTip = 0;
+ label = 0;
+ preventAnimation = FALSE;
+ isApplicationFilter = FALSE;
+ connect( &wakeUp, SIGNAL(timeout()), SLOT(showTip()) );
+ connect( &fallAsleep, SIGNAL(timeout()), SLOT(hideTip()) );
+ removeTimer = new QTimer( this );
+}
+
+
+QTipManager::~QTipManager()
+{
+ if ( isApplicationFilter && !qApp->closingDown() ) {
+ qApp->setGlobalMouseTracking( FALSE );
+ qApp->removeEventFilter( tipManager );
+ }
+
+ delete label;
+ label = 0;
+
+ if ( tips ) {
+ QPtrDictIterator<QTipManager::Tip> i( *tips );
+ QTipManager::Tip *t, *n;
+ void *k;
+ while( (t = i.current()) != 0 ) {
+ k = i.currentKey();
+ ++i;
+ tips->take( k );
+ while ( t ) {
+ n = t->next;
+ delete t;
+ t = n;
+ }
+ }
+ delete tips;
+ }
+
+ tipManager = 0;
+}
+
+void QTipManager::add( const QRect &gm, QWidget *w,
+ const QRect &r, const QString &s,
+ QToolTipGroup *g, const QString& gs,
+ QToolTip *tt, bool a )
+{
+ remove( w, r, TRUE );
+ QTipManager::Tip *h = (*tips)[ w ];
+ QTipManager::Tip *t = new QTipManager::Tip;
+ t->next = h;
+ t->tip = tt;
+ t->autoDelete = a;
+ t->text = s;
+ t->rect = r;
+ t->groupText = gs;
+ t->group = g;
+ t->geometry = gm;
+
+ if ( h ) {
+ tips->take( w );
+ if ( h != currentTip && h->autoDelete ) {
+ t->next = h->next;
+ delete h;
+ }
+ } else
+ connect( w, SIGNAL(destroyed()), this, SLOT(clientWidgetDestroyed()) );
+
+ tips->insert( w, t );
+
+ if ( a && t->rect.contains( pos ) && (!g || g->enabled()) ) {
+ removeTimer->stop();
+ showTip();
+ }
+
+ if ( !isApplicationFilter && qApp ) {
+ isApplicationFilter = TRUE;
+ qApp->installEventFilter( tipManager );
+ qApp->setGlobalMouseTracking( TRUE );
+ }
+
+ if ( t->group ) {
+ disconnect( removeTimer, SIGNAL( timeout() ),
+ t->group, SIGNAL( removeTip() ) );
+ connect( removeTimer, SIGNAL( timeout() ),
+ t->group, SIGNAL( removeTip() ) );
+ }
+}
+
+void QTipManager::add( QWidget *w, const QRect &r, const QString &s,
+ QToolTipGroup *g, const QString& gs,
+ QToolTip *tt, bool a )
+{
+ add( QRect( -1, -1, -1, -1 ), w, r, s, g, gs, tt, a );
+}
+
+
+void QTipManager::remove( QWidget *w, const QRect & r, bool delayhide )
+{
+ QTipManager::Tip *t = (*tips)[ w ];
+ if ( t == 0 )
+ return;
+
+ if ( t == currentTip )
+ if (!delayhide)
+ hideTip();
+ else
+ currentTip->autoDelete = TRUE;
+
+ if ( t == previousTip )
+ previousTip = 0;
+
+ if ( ( currentTip != t || !delayhide ) && t->rect == r ) {
+ tips->take( w );
+ if ( t->next )
+ tips->insert( w, t->next );
+ delete t;
+ } else {
+ while( t->next && t->next->rect != r && ( currentTip != t->next || !delayhide ))
+ t = t->next;
+ if ( t->next ) {
+ QTipManager::Tip *d = t->next;
+ t->next = t->next->next;
+ delete d;
+ }
+ }
+
+ if ( (*tips)[ w ] == 0 )
+ disconnect( w, SIGNAL(destroyed()), this, SLOT(clientWidgetDestroyed()) );
+#if 0 // not needed, leads sometimes to crashes
+ if ( tips->isEmpty() ) {
+ // the manager will be recreated if needed
+ delete tipManager;
+ tipManager = 0;
+ }
+#endif
+}
+
+
+/*
+ The label was destroyed in the program cleanup phase.
+*/
+
+void QTipManager::labelDestroyed()
+{
+ label = 0;
+}
+
+
+/*
+ Remove sender() from the tool tip data structures.
+*/
+
+void QTipManager::clientWidgetDestroyed()
+{
+ const QObject *s = sender();
+ if ( s )
+ remove( (QWidget*) s );
+}
+
+
+void QTipManager::remove( QWidget *w )
+{
+ QTipManager::Tip *t = (*tips)[ w ];
+ if ( t == 0 )
+ return;
+
+ tips->take( w );
+ QTipManager::Tip * d;
+ while ( t ) {
+ if ( t == currentTip )
+ hideTip();
+ d = t->next;
+ delete t;
+ t = d;
+ }
+
+ disconnect( w, SIGNAL(destroyed()), this, SLOT(clientWidgetDestroyed()) );
+#if 0
+ if ( tips->isEmpty() ) {
+ delete tipManager;
+ tipManager = 0;
+ }
+#endif
+}
+
+
+void QTipManager::removeFromGroup( QToolTipGroup *g )
+{
+ QPtrDictIterator<QTipManager::Tip> i( *tips );
+ QTipManager::Tip *t;
+ while( (t = i.current()) != 0 ) {
+ ++i;
+ while ( t ) {
+ if ( t->group == g ) {
+ if ( t->group )
+ disconnect( removeTimer, SIGNAL( timeout() ),
+ t->group, SIGNAL( removeTip() ) );
+ t->group = 0;
+ }
+ t = t->next;
+ }
+ }
+}
+
+
+
+bool QTipManager::eventFilter( QObject *obj, QEvent *e )
+{
+ // avoid dumping core in case of application madness, and return
+ // quickly for some common but irrelevant events
+ if ( e->type() == QEvent::WindowDeactivate &&
+ qApp && !qApp->activeWindow() &&
+ label && label->isVisible() )
+ hideTipAndSleep();
+
+ if ( !qApp
+ || !obj || !obj->isWidgetType() // isWidgetType() catches most stuff
+ || e->type() == QEvent::Paint
+ || e->type() == QEvent::Timer
+ || e->type() == QEvent::SockAct
+ || !tips )
+ return FALSE;
+ QWidget *w = (QWidget *)obj;
+
+ if ( e->type() == QEvent::FocusOut || e->type() == QEvent::FocusIn ) {
+ // user moved focus somewhere - hide the tip and sleep
+ if ( ((QFocusEvent*)e)->reason() != QFocusEvent::Popup )
+ hideTipAndSleep();
+ return FALSE;
+ }
+
+ QTipManager::Tip *t = 0;
+ while( w && !t ) {
+ t = (*tips)[ w ];
+ if ( !t )
+ w = w->isTopLevel() ? 0 : w->parentWidget();
+ }
+ if ( !w )
+ return FALSE;
+
+ if ( !t && e->type() != QEvent::MouseMove) {
+ if ( ( e->type() >= QEvent::MouseButtonPress &&
+ e->type() <= QEvent::FocusOut) || e->type() == QEvent::Leave )
+ hideTip();
+ return FALSE;
+ }
+
+ // with that out of the way, let's get down to action
+
+ switch( e->type() ) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ // input - turn off tool tip mode
+ hideTipAndSleep();
+ break;
+ case QEvent::MouseMove:
+ {
+ QMouseEvent * m = (QMouseEvent *)e;
+ QPoint mousePos = w->mapFromGlobal( m->globalPos() );
+
+ if ( currentTip && !currentTip->rect.contains( mousePos ) ) {
+ hideTip();
+ if ( m->state() == 0 )
+ return FALSE;
+ }
+
+ wakeUp.stop();
+ if ( m->state() == 0 &&
+ mousePos.x() >= 0 && mousePos.x() < w->width() &&
+ mousePos.y() >= 0 && mousePos.y() < w->height() ) {
+ if ( label && label->isVisible() ) {
+ return FALSE;
+ } else {
+ if ( fallAsleep.isActive() ) {
+ wakeUp.start( 1, TRUE );
+ } else {
+ previousTip = 0;
+ wakeUp.start( wakeUpDelay, TRUE );
+ }
+ if ( t->group && t->group->ena &&
+ !t->group->del && !t->groupText.isEmpty() ) {
+ removeTimer->stop();
+ emit t->group->showTip( t->groupText );
+ currentTip = t;
+ }
+ }
+ widget = w;
+ pos = mousePos;
+ return FALSE;
+ } else {
+ hideTip();
+ }
+ }
+ break;
+ case QEvent::Leave:
+ case QEvent::Hide:
+ case QEvent::Destroy:
+ if ( w == widget )
+ hideTip();
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+
+
+void QTipManager::showTip()
+{
+ if ( !widget || !globally_enabled
+#ifndef Q_WS_X11
+ || !widget->isActiveWindow()
+#endif
+ )
+ return;
+
+ QTipManager::Tip *t = (*tips)[ widget ];
+ while ( t && !t->rect.contains( pos ) )
+ t = t->next;
+ if ( t == 0 )
+ return;
+
+ if ( t == currentTip && label && label->isVisible() )
+ return; // nothing to do
+
+ if ( t->tip ) {
+ t->tip->maybeTip( pos );
+ return;
+ }
+
+ if ( t->group && !t->group->ena )
+ return;
+
+ int scr;
+ if ( QApplication::desktop()->isVirtualDesktop() )
+ scr = QApplication::desktop()->screenNumber( widget->mapToGlobal( pos ) );
+ else
+ scr = QApplication::desktop()->screenNumber( widget );
+
+ if ( label
+#if defined(Q_WS_X11)
+ && label->x11Screen() == widget->x11Screen()
+#endif
+ ) {
+ // the next two lines are a workaround for QLabel being too intelligent.
+ // QLabel turns on the wordbreak flag once it gets a richtext. The two lines below
+ // ensure we get correct textflags when switching back and forth between a richtext and
+ // non richtext tooltip
+ label->setText( "" );
+ label->setAlignment( AlignAuto | AlignTop );
+ label->setText( t->text );
+ label->adjustSize();
+ if ( t->geometry != QRect( -1, -1, -1, -1 ) )
+ label->resize( t->geometry.size() );
+ } else {
+ delete label;
+ label = new QTipLabel( QApplication::desktop()->screen( scr ), t->text);
+ if ( t->geometry != QRect( -1, -1, -1, -1 ) )
+ label->resize( t->geometry.size() );
+ Q_CHECK_PTR( label );
+ connect( label, SIGNAL(destroyed()), SLOT(labelDestroyed()) );
+ }
+ // the above deletion and creation of a QTipLabel causes events to be sent. We had reports that the widget
+ // pointer was 0 after this. This is in principle possible if the wrong kind of events get sent through our event
+ // filter in this time. So better be safe and check widget once again here.
+ if (!widget)
+ return;
+
+#ifdef Q_WS_X11
+ label->x11SetWindowTransient( widget->topLevelWidget());
+#endif
+
+#ifdef Q_WS_MAC
+ QRect screen = QApplication::desktop()->availableGeometry( scr );
+#else
+ QRect screen = QApplication::desktop()->screenGeometry( scr );
+#endif
+ QPoint p;
+ if ( t->geometry == QRect( -1, -1, -1, -1 ) ) {
+ p = widget->mapToGlobal( pos ) +
+#ifdef Q_WS_WIN
+ QPoint( 2, 24 );
+#else
+ QPoint( 2, 16 );
+#endif
+ if ( p.x() + label->width() > screen.x() + screen.width() )
+ p.rx() -= 4 + label->width();
+ if ( p.y() + label->height() > screen.y() + screen.height() )
+ p.ry() -= 24 + label->height();
+ } else {
+ p = widget->mapToGlobal( t->geometry.topLeft() );
+ label->setAlignment( WordBreak | AlignCenter );
+ label->setWidth( t->geometry.width() - 4 );
+ }
+ if ( p.y() < screen.y() )
+ p.setY( screen.y() );
+ if ( p.x() + label->width() > screen.x() + screen.width() )
+ p.setX( screen.x() + screen.width() - label->width() );
+ if ( p.x() < screen.x() )
+ p.setX( screen.x() );
+ if ( p.y() + label->height() > screen.y() + screen.height() )
+ p.setY( screen.y() + screen.height() - label->height() );
+ if ( label->text().length() ) {
+ label->move( p );
+
+#ifndef QT_NO_EFFECTS
+ if ( QApplication::isEffectEnabled( UI_AnimateTooltip ) == FALSE ||
+ previousTip || preventAnimation )
+ label->show();
+ else if ( QApplication::isEffectEnabled( UI_FadeTooltip ) )
+ qFadeEffect( label );
+ else
+ qScrollEffect( label );
+#else
+ label->show();
+#endif
+
+ label->raise();
+ fallAsleep.start( 10000, TRUE );
+ }
+
+ if ( t->group && t->group->del && !t->groupText.isEmpty() ) {
+ removeTimer->stop();
+ emit t->group->showTip( t->groupText );
+ }
+
+ currentTip = t;
+ previousTip = 0;
+}
+
+
+void QTipManager::hideTip()
+{
+ QTimer::singleShot( 250, this, SLOT(allowAnimation()) );
+ preventAnimation = TRUE;
+
+ if ( label && label->isVisible() ) {
+ label->hide();
+ fallAsleep.start( 2000, TRUE );
+ wakeUp.stop();
+ if ( currentTip && currentTip->group )
+ removeTimer->start( 100, TRUE );
+ } else if ( wakeUp.isActive() ) {
+ wakeUp.stop();
+ if ( currentTip && currentTip->group &&
+ !currentTip->group->del && !currentTip->groupText.isEmpty() )
+ removeTimer->start( 100, TRUE );
+ } else if ( currentTip && currentTip->group ) {
+ removeTimer->start( 100, TRUE );
+ }
+
+ previousTip = currentTip;
+ currentTip = 0;
+ if ( previousTip && previousTip->autoDelete )
+ remove( widget, previousTip->rect );
+ widget = 0;
+}
+
+void QTipManager::hideTipAndSleep()
+{
+ hideTip();
+ fallAsleep.stop();
+}
+
+
+void QTipManager::allowAnimation()
+{
+ preventAnimation = FALSE;
+}
+
+QString QTipManager::find( QWidget *w, const QPoint& pos )
+{
+ Tip *t = (*tips)[ w ];
+ while ( t && !t->rect.contains( pos ) )
+ t = t->next;
+
+ return t ? t->text : QString::null;
+}
+
+void QTipManager::setWakeUpDelay ( int i )
+{
+ wakeUpDelay = i;
+}
+
+/*!
+ \class QToolTip qtooltip.h
+ \brief The QToolTip class provides tool tips (balloon help) for
+ any widget or rectangular part of a widget.
+
+ \ingroup helpsystem
+ \mainclass
+
+ The tip is a short, single line of text reminding the user of the
+ widget's or rectangle's function. It is drawn immediately below
+ the region in a distinctive black-on-yellow combination.
+
+ The tip can be any Rich-Text formatted string.
+
+ QToolTipGroup provides a way for tool tips to display another text
+ elsewhere (most often in a \link QStatusBar status bar\endlink).
+
+ At any point in time, QToolTip is either dormant or active. In
+ dormant mode the tips are not shown and in active mode they are.
+ The mode is global, not particular to any one widget.
+
+ QToolTip switches from dormant to active mode when the user hovers
+ the mouse on a tip-equipped region for a second or so and remains
+ active until the user either clicks a mouse button, presses a key,
+ lets the mouse hover for five seconds or moves the mouse outside
+ \e all tip-equipped regions for at least a second.
+
+ The QToolTip class can be used in three different ways:
+ \list 1
+ \i Adding a tip to an entire widget.
+ \i Adding a tip to a fixed rectangle within a widget.
+ \i Adding a tip to a dynamic rectangle within a widget.
+ \endlist
+
+ To add a tip to a widget, call the \e static function
+ QToolTip::add() with the widget and tip as arguments:
+
+ \code
+ QToolTip::add( quitButton, "Leave the application" );
+ \endcode
+
+ This is the simplest and most common use of QToolTip. The tip
+ will be deleted automatically when \e quitButton is deleted, but
+ you can remove it yourself, too:
+
+ \code
+ QToolTip::remove( quitButton );
+ \endcode
+
+ You can also display another text (typically in a \link QStatusBar
+ status bar),\endlink courtesy of \l{QToolTipGroup}. This example
+ assumes that \e grp is a \c{QToolTipGroup *} and is already
+ connected to the appropriate status bar:
+
+ \code
+ QToolTip::add( quitButton, "Leave the application", grp,
+ "Leave the application, prompting to save if necessary" );
+ QToolTip::add( closeButton, "Close this window", grp,
+ "Close this window, prompting to save if necessary" );
+ \endcode
+
+ To add a tip to a fixed rectangle within a widget, call the static
+ function QToolTip::add() with the widget, rectangle and tip as
+ arguments. (See the \c tooltip/tooltip.cpp example.) Again, you
+ can supply a \c{QToolTipGroup *} and another text if you want.
+
+ Both of these are one-liners and cover the majority of cases. The
+ third and most general way to use QToolTip requires you to
+ reimplement a pure virtual function to decide whether to pop up a
+ tool tip. The \c tooltip/tooltip.cpp example demonstrates this
+ too. This mode can be used to implement tips for text that can
+ move as the user scrolls, for example.
+
+ To use QToolTip like this, you must subclass QToolTip and
+ reimplement maybeTip(). QToolTip calls maybeTip() when a tip
+ should pop up, and maybeTip() decides whether to show a tip.
+
+ Tool tips can be globally disabled using
+ QToolTip::setGloballyEnabled() or disabled in groups with
+ QToolTipGroup::setEnabled().
+
+ You can retrieve the text of a tooltip for a given position within
+ a widget using textFor().
+
+ The global tooltip font and palette can be set with the static
+ setFont() and setPalette() functions respectively.
+
+ \sa QStatusBar QWhatsThis QToolTipGroup
+ \link guibooks.html#fowler GUI Design Handbook: Tool Tip\endlink
+*/
+
+
+/*!
+ Returns the font common to all tool tips.
+
+ \sa setFont()
+*/
+
+QFont QToolTip::font()
+{
+ QTipLabel l(0,"");
+ return QApplication::font( &l );
+}
+
+
+/*!
+ Sets the font for all tool tips to \a font.
+
+ \sa font()
+*/
+
+void QToolTip::setFont( const QFont &font )
+{
+ QApplication::setFont( font, TRUE, "QTipLabel" );
+}
+
+
+/*!
+ Returns the palette common to all tool tips.
+
+ \sa setPalette()
+*/
+
+QPalette QToolTip::palette()
+{
+ QTipLabel l(0,"");
+ return QApplication::palette( &l );
+}
+
+
+/*!
+ Sets the palette for all tool tips to \a palette.
+
+ \sa palette()
+*/
+
+void QToolTip::setPalette( const QPalette &palette )
+{
+ QApplication::setPalette( palette, TRUE, "QTipLabel" );
+}
+
+/*!
+ Constructs a tool tip object. This is only necessary if you need
+ tool tips on regions that can move within the widget (most often
+ because the widget's contents can scroll).
+
+ \a widget is the widget you want to add dynamic tool tips to and
+ \a group (optional) is the tool tip group they should belong to.
+
+ \warning QToolTip is not a subclass of QObject, so the instance of
+ QToolTip is not deleted when \a widget is deleted.
+
+ \warning If you delete the tool tip before you have deleted
+ \a widget then you need to make sure you call remove() yourself from
+ \a widget in your reimplemented QToolTip destructor.
+
+ \code
+ MyToolTip::~MyToolTip()
+ {
+ remove( widget );
+ }
+ \endcode
+
+ \sa maybeTip().
+*/
+
+QToolTip::QToolTip( QWidget * widget, QToolTipGroup * group )
+{
+ p = widget;
+ g = group;
+ initTipManager();
+ tipManager->add( p, entireWidget(),
+ QString::null, g, QString::null, this, FALSE );
+}
+
+
+/*!
+ Adds a tool tip to \a widget. \a text is the text to be shown in
+ the tool tip.
+
+ This is the most common entry point to the QToolTip class; it is
+ suitable for adding tool tips to buttons, checkboxes, comboboxes
+ and so on.
+*/
+
+void QToolTip::add( QWidget *widget, const QString &text )
+{
+ initTipManager();
+ tipManager->add( widget, entireWidget(),
+ text, 0, QString::null, 0, FALSE );
+}
+
+
+/*!
+ \overload
+
+ Adds a tool tip to \a widget and to tool tip group \a group.
+
+ \a text is the text shown in the tool tip and \a longText is the
+ text emitted from \a group.
+
+ Normally, \a longText is shown in a \link QStatusBar status
+ bar\endlink or similar.
+*/
+
+void QToolTip::add( QWidget *widget, const QString &text,
+ QToolTipGroup *group, const QString& longText )
+{
+ initTipManager();
+ tipManager->add( widget, entireWidget(), text, group, longText, 0, FALSE );
+}
+
+
+/*!
+ Removes the tool tip from \a widget.
+
+ If there is more than one tool tip on \a widget, only the one
+ covering the entire widget is removed.
+*/
+
+void QToolTip::remove( QWidget * widget )
+{
+ if ( tipManager )
+ tipManager->remove( widget, entireWidget() );
+}
+
+/*!
+ \overload
+
+ Adds a tool tip to a fixed rectangle, \a rect, within \a widget.
+ \a text is the text shown in the tool tip.
+*/
+
+void QToolTip::add( QWidget * widget, const QRect & rect, const QString &text )
+{
+ initTipManager();
+ tipManager->add( widget, rect, text, 0, QString::null, 0, FALSE );
+}
+
+
+/*!
+ \overload
+
+ Adds a tool tip to an entire \a widget and to tool tip group \a
+ group. The tooltip will disappear when the mouse leaves the \a
+ rect.
+
+ \a text is the text shown in the tool tip and \a groupText is the
+ text emitted from \a group.
+
+ Normally, \a groupText is shown in a \link QStatusBar status
+ bar\endlink or similar.
+*/
+
+void QToolTip::add( QWidget *widget, const QRect &rect,
+ const QString& text,
+ QToolTipGroup *group, const QString& groupText )
+{
+ initTipManager();
+ tipManager->add( widget, rect, text, group, groupText, 0, FALSE );
+}
+
+
+/*!
+ \overload
+
+ Removes any tool tip for \a rect from \a widget.
+
+ If there is more than one tool tip on \a widget, only the one
+ covering rectangle \a rect is removed.
+*/
+
+void QToolTip::remove( QWidget * widget, const QRect & rect )
+{
+ if ( tipManager )
+ tipManager->remove( widget, rect );
+}
+
+/*!
+ Returns the tool tip text for \a widget at position \a pos, or
+ QString::null if there is no tool tip for the given widget and
+ position.
+*/
+
+QString QToolTip::textFor( QWidget *widget, const QPoint& pos )
+{
+ if ( tipManager )
+ return tipManager->find( widget, pos );
+ return QString::null;
+}
+
+/*!
+ Hides any tip that is currently being shown.
+
+ Normally, there is no need to call this function; QToolTip takes
+ care of showing and hiding the tips as the user moves the mouse.
+*/
+
+void QToolTip::hide()
+{
+ if ( tipManager )
+ tipManager->hideTipAndSleep();
+}
+
+/*!
+ \fn virtual void QToolTip::maybeTip( const QPoint & p);
+
+ This pure virtual function is half of the most versatile interface
+ QToolTip offers.
+
+ It is called when there is a possibility that a tool tip should be
+ shown and must decide whether there is a tool tip for the point \a
+ p in the widget that this QToolTip object relates to. If so,
+ maybeTip() must call tip() with the rectangle the tip applies to,
+ the tip's text and optionally the QToolTipGroup details and the
+ geometry in screen coordinates.
+
+ \a p is given in that widget's local coordinates. Most maybeTip()
+ implementations will be of the form:
+
+ \code
+ if ( <something> ) {
+ tip( <something>, <something> );
+ }
+ \endcode
+
+ The first argument to tip() (a rectangle) must encompass \a p,
+ i.e. the tip must apply to the current mouse position; otherwise
+ QToolTip's operation is undefined.
+
+ Note that the tip will disappear once the mouse moves outside the
+ rectangle you give to tip(), and will not reappear if the mouse
+ moves back in: maybeTip() is called again instead.
+
+ \sa tip()
+*/
+
+
+/*!
+ Immediately pops up a tip saying \a text and removes the tip once
+ the cursor moves out of rectangle \a rect (which is given in the
+ coordinate system of the widget this QToolTip relates to).
+
+ The tip will not reappear if the cursor moves back; your
+ maybeTip() must reinstate it each time.
+*/
+
+void QToolTip::tip( const QRect & rect, const QString &text )
+{
+ initTipManager();
+ tipManager->add( parentWidget(), rect, text, 0, QString::null, 0, TRUE );
+}
+
+/*!
+ \overload
+
+ Immediately pops up a tip saying \a text and removes that tip once
+ the cursor moves out of rectangle \a rect (which is given in the
+ coordinate system of the widget this QToolTip relates to). \a
+ groupText is the text emitted from the group.
+
+ The tip will not reappear if the cursor moves back; your
+ maybeTip() must reinstate it each time.
+*/
+
+void QToolTip::tip( const QRect & rect, const QString &text,
+ const QString& groupText )
+{
+ initTipManager();
+ tipManager->add( parentWidget(), rect, text, group(), groupText, 0, TRUE );
+}
+
+/*!
+ \overload
+
+ Immediately pops up a tip within the rectangle \a geometry, saying
+ \a text and removes the tip once the cursor moves out of rectangle
+ \a rect. Both rectangles are given in the coordinate system of the
+ widget this QToolTip relates to.
+
+ The tip will not reappear if the cursor moves back; your
+ maybeTip() must reinstate it each time.
+
+ If the tip does not fit inside \a geometry, the tip expands.
+*/
+
+void QToolTip::tip( const QRect &rect, const QString &text, const QRect &geometry )
+{
+ initTipManager();
+ tipManager->add( geometry, parentWidget(), rect, text, 0, QString::null, 0, TRUE );
+}
+
+/*!
+ \overload
+
+ Immediately pops up a tip within the rectangle \a geometry, saying
+ \a text and removes the tip once the cursor moves out of rectangle
+ \a rect. \a groupText is the text emitted from the group. Both
+ rectangles are given in the coordinate system of the widget this
+ QToolTip relates to.
+
+ The tip will not reappear if the cursor moves back; your
+ maybeTip() must reinstate it each time.
+
+ If the tip does not fit inside \a geometry, the tip expands.
+*/
+
+void QToolTip::tip( const QRect &rect, const QString &text, const QString& groupText, const QRect &geometry )
+{
+ initTipManager();
+ tipManager->add( geometry, parentWidget(), rect, text, group(), groupText, 0, TRUE );
+}
+
+
+
+/*!
+ Immediately removes all tool tips for this tooltip's parent
+ widget.
+*/
+
+void QToolTip::clear()
+{
+ if ( tipManager )
+ tipManager->remove( parentWidget() );
+}
+
+
+/*!
+ \fn QWidget * QToolTip::parentWidget() const
+
+ Returns the widget this QToolTip applies to.
+
+ The tool tip is destroyed automatically when the parent widget is
+ destroyed.
+
+ \sa group()
+*/
+
+
+/*!
+ \fn QToolTipGroup * QToolTip::group() const
+
+ Returns the tool tip group this QToolTip is a member of or 0 if it
+ isn't a member of any group.
+
+ The tool tip group is the object responsible for maintaining
+ contact between tool tips and a \link QStatusBar status
+ bar\endlink or something else which can show the longer help text.
+
+ \sa parentWidget(), QToolTipGroup
+*/
+
+
+/*!
+ \class QToolTipGroup qtooltip.h
+ \brief The QToolTipGroup class collects tool tips into related groups.
+
+ \ingroup helpsystem
+
+ Tool tips can display \e two texts: one in the tip and
+ (optionally) one that is typically in a \link QStatusBar status
+ bar\endlink. QToolTipGroup provides a way to link tool tips to
+ this status bar.
+
+ QToolTipGroup has practically no API; it is only used as an
+ argument to QToolTip's member functions, for example like this:
+
+ \code
+ QToolTipGroup * grp = new QToolTipGroup( this, "tool tip relay" );
+ connect( grp, SIGNAL(showTip(const QString&)),
+ myLabel, SLOT(setText(const QString&)) );
+ connect( grp, SIGNAL(removeTip()),
+ myLabel, SLOT(clear()) );
+ QToolTip::add( giraffeButton, "feed giraffe",
+ grp, "Give the giraffe a meal" );
+ QToolTip::add( gorillaButton, "feed gorilla",
+ grp, "Give the gorilla a meal" );
+ \endcode
+
+ This example makes the object myLabel (which you must supply)
+ display (one assumes, though you can make myLabel do anything, of
+ course) the strings "Give the giraffe a meal" and "Give the
+ gorilla a meal" while the relevant tool tips are being displayed.
+
+ Deleting a tool tip group removes the tool tips in it.
+*/
+
+/*!
+ \fn void QToolTipGroup::showTip (const QString &longText)
+
+ This signal is emitted when one of the tool tips in the group is
+ displayed. \a longText is the extra text for the displayed tool
+ tip.
+
+ \sa removeTip()
+*/
+
+/*!
+ \fn void QToolTipGroup::removeTip ()
+
+ This signal is emitted when a tool tip in this group is hidden.
+ See the QToolTipGroup documentation for an example of use.
+
+ \sa showTip()
+*/
+
+
+/*!
+ Constructs a tool tip group called \a name, with parent \a parent.
+*/
+
+QToolTipGroup::QToolTipGroup( QObject *parent, const char *name )
+ : QObject( parent, name )
+{
+ del = TRUE;
+ ena = TRUE;
+}
+
+
+/*!
+ Destroys this tool tip group and all tool tips in it.
+*/
+
+QToolTipGroup::~QToolTipGroup()
+{
+ if ( tipManager )
+ tipManager->removeFromGroup( this );
+}
+
+
+/*!
+ \property QToolTipGroup::delay
+ \brief whether the display of the group text is delayed.
+
+ If set to TRUE (the default), the group text is displayed at the
+ same time as the tool tip. Otherwise, the group text is displayed
+ immediately when the cursor enters the widget.
+*/
+
+bool QToolTipGroup::delay() const
+{
+ return del;
+}
+
+void QToolTipGroup::setDelay( bool enable )
+{
+#if 0
+ if ( enable && !del ) {
+ // maybe we should show the text at once?
+ }
+#endif
+ del = enable;
+}
+
+/*!
+ \fn static void QToolTip::setEnabled( bool enable )
+
+ \obsolete
+*/
+/*!
+ \fn static bool QToolTip::enabled()
+
+ \obsolete
+*/
+/*!
+ \property QToolTipGroup::enabled
+ \brief whether tool tips in the group are enabled.
+
+ This property's default is TRUE.
+*/
+
+void QToolTipGroup::setEnabled( bool enable )
+{
+ ena = enable;
+}
+
+bool QToolTipGroup::enabled() const
+{
+ return (bool)ena;
+}
+
+/*!
+ If \a enable is TRUE sets all tool tips to be enabled (shown when
+ needed); if \a enable is FALSE sets all tool tips to be disabled
+ (never shown).
+
+ By default, tool tips are enabled. Note that this function affects
+ all tool tips in the entire application.
+
+ \sa QToolTipGroup::setEnabled()
+*/
+
+void QToolTip::setGloballyEnabled( bool enable )
+{
+ globally_enabled = enable;
+}
+
+/*!
+ Returns whether tool tips are enabled globally.
+
+ \sa setGloballyEnabled()
+*/
+bool QToolTip::isGloballyEnabled()
+{
+ return globally_enabled;
+}
+
+/*!
+ Sets the wakeup delay for all tooltips to \a i
+ milliseconds.
+*/
+void QToolTip::setWakeUpDelay ( int i )
+{
+ initTipManager();
+ tipManager->setWakeUpDelay(i);
+}
+
+
+#include "qtooltip.moc"
+#endif