source: vendor/trolltech/current/src/widgets/qtooltip.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: 32.6 KB
Line 
1/****************************************************************************
2** $Id: qtooltip.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Tool Tips (or Balloon Help) for any widget or rectangle
5**
6** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
7**
8** This file is part of the widgets module of the Qt GUI Toolkit.
9**
10** This file may be distributed under the terms of the Q Public License
11** as defined by Trolltech AS of Norway and appearing in the file
12** LICENSE.QPL included in the packaging of this file.
13**
14** This file may be distributed and/or modified under the terms of the
15** GNU General Public License version 2 as published by the Free Software
16** Foundation and appearing in the file LICENSE.GPL included in the
17** packaging of this file.
18**
19** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
20** licenses may use this file in accordance with the Qt Commercial License
21** Agreement provided with the Software.
22**
23** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25**
26** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
27** information about Qt Commercial License Agreements.
28** See http://www.trolltech.com/qpl/ for QPL licensing information.
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
36#include "qtooltip.h"
37#ifndef QT_NO_TOOLTIP
38#include "qlabel.h"
39#include "qptrdict.h"
40#include "qapplication.h"
41#include "qguardedptr.h"
42#include "qtimer.h"
43#include "qeffects_p.h"
44
45static bool globally_enabled = TRUE;
46
47// Magic value meaning an entire widget - if someone tries to insert a
48// tool tip on this part of a widget it will be interpreted as the
49// entire widget.
50
51static inline QRect entireWidget()
52{
53 return QRect( -QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX,
54 2*QWIDGETSIZE_MAX, 2*QWIDGETSIZE_MAX );
55}
56
57// Internal class - don't touch
58
59class QTipLabel : public QLabel
60{
61 Q_OBJECT
62public:
63 QTipLabel( QWidget* parent, const QString& text) : QLabel( parent, "toolTipTip",
64 WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM )
65 {
66 setMargin(1);
67 setAutoMask( FALSE );
68 setFrameStyle( QFrame::Plain | QFrame::Box );
69 setLineWidth( 1 );
70 setAlignment( AlignAuto | AlignTop );
71 setIndent(0);
72 polish();
73 setText(text);
74 adjustSize();
75 }
76 void setWidth( int w ) { resize( sizeForWidth( w ) ); }
77};
78
79// Internal class - don't touch
80
81class QTipManager : public QObject
82{
83 Q_OBJECT
84public:
85 QTipManager();
86 ~QTipManager();
87
88 struct Tip
89 {
90 QRect rect;
91 QString text;
92 QString groupText;
93 QToolTipGroup *group;
94 QToolTip *tip;
95 bool autoDelete;
96 QRect geometry;
97 Tip *next;
98 };
99
100 bool eventFilter( QObject * o, QEvent * e );
101 void add( const QRect &gm, QWidget *, const QRect &, const QString& ,
102 QToolTipGroup *, const QString& , QToolTip *, bool );
103 void add( QWidget *, const QRect &, const QString& ,
104 QToolTipGroup *, const QString& , QToolTip *, bool );
105 void remove( QWidget *, const QRect &, bool delayhide = FALSE );
106 void remove( QWidget * );
107
108 void removeFromGroup( QToolTipGroup * );
109
110 void hideTipAndSleep();
111
112 QString find( QWidget *, const QPoint& );
113 void setWakeUpDelay(int);
114
115public slots:
116 void hideTip();
117
118private slots:
119 void labelDestroyed();
120 void clientWidgetDestroyed();
121 void showTip();
122 void allowAnimation();
123
124private:
125 QTimer wakeUp;
126 int wakeUpDelay;
127 QTimer fallAsleep;
128
129 QPtrDict<Tip> *tips;
130 QTipLabel *label;
131 QPoint pos;
132 QGuardedPtr<QWidget> widget;
133 Tip *currentTip;
134 Tip *previousTip;
135 bool preventAnimation;
136 bool isApplicationFilter;
137 QTimer *removeTimer;
138};
139
140
141// We have a global, internal QTipManager object
142
143static QTipManager *tipManager = 0;
144
145static void initTipManager()
146{
147 if ( !tipManager ) {
148 tipManager = new QTipManager;
149 Q_CHECK_PTR( tipManager );
150 }
151}
152
153
154QTipManager::QTipManager()
155 : QObject( qApp, "toolTipManager" )
156{
157 wakeUpDelay = 700;
158 tips = new QPtrDict<QTipManager::Tip>( 313 );
159 currentTip = 0;
160 previousTip = 0;
161 label = 0;
162 preventAnimation = FALSE;
163 isApplicationFilter = FALSE;
164 connect( &wakeUp, SIGNAL(timeout()), SLOT(showTip()) );
165 connect( &fallAsleep, SIGNAL(timeout()), SLOT(hideTip()) );
166 removeTimer = new QTimer( this );
167}
168
169
170QTipManager::~QTipManager()
171{
172 if ( isApplicationFilter && !qApp->closingDown() ) {
173 qApp->setGlobalMouseTracking( FALSE );
174 qApp->removeEventFilter( tipManager );
175 }
176
177 if ( tips ) {
178 QPtrDictIterator<QTipManager::Tip> i( *tips );
179 QTipManager::Tip *t, *n;
180 void *k;
181 while( (t = i.current()) != 0 ) {
182 k = i.currentKey();
183 ++i;
184 tips->take( k );
185 while ( t ) {
186 n = t->next;
187 delete t;
188 t = n;
189 }
190 }
191 delete tips;
192 }
193
194 delete label;
195
196 tipManager = 0;
197}
198
199void QTipManager::add( const QRect &gm, QWidget *w,
200 const QRect &r, const QString &s,
201 QToolTipGroup *g, const QString& gs,
202 QToolTip *tt, bool a )
203{
204 remove( w, r, TRUE );
205 QTipManager::Tip *h = (*tips)[ w ];
206 QTipManager::Tip *t = new QTipManager::Tip;
207 t->next = h;
208 t->tip = tt;
209 t->autoDelete = a;
210 t->text = s;
211 t->rect = r;
212 t->groupText = gs;
213 t->group = g;
214 t->geometry = gm;
215
216 if ( h ) {
217 tips->take( w );
218 if ( h != currentTip && h->autoDelete ) {
219 t->next = h->next;
220 delete h;
221 }
222 } else
223 connect( w, SIGNAL(destroyed()), this, SLOT(clientWidgetDestroyed()) );
224
225 tips->insert( w, t );
226
227 if ( a && t->rect.contains( pos ) && (!g || g->enabled()) ) {
228 removeTimer->stop();
229 showTip();
230 }
231
232 if ( !isApplicationFilter && qApp ) {
233 isApplicationFilter = TRUE;
234 qApp->installEventFilter( tipManager );
235 qApp->setGlobalMouseTracking( TRUE );
236 }
237
238 if ( t->group ) {
239 disconnect( removeTimer, SIGNAL( timeout() ),
240 t->group, SIGNAL( removeTip() ) );
241 connect( removeTimer, SIGNAL( timeout() ),
242 t->group, SIGNAL( removeTip() ) );
243 }
244}
245
246void QTipManager::add( QWidget *w, const QRect &r, const QString &s,
247 QToolTipGroup *g, const QString& gs,
248 QToolTip *tt, bool a )
249{
250 add( QRect( -1, -1, -1, -1 ), w, r, s, g, gs, tt, a );
251}
252
253
254void QTipManager::remove( QWidget *w, const QRect & r, bool delayhide )
255{
256 QTipManager::Tip *t = (*tips)[ w ];
257 if ( t == 0 )
258 return;
259
260 if ( t == currentTip )
261 if (!delayhide)
262 hideTip();
263 else
264 currentTip->autoDelete = true;
265
266 if ( t == previousTip )
267 previousTip = 0;
268
269 if ( ( currentTip != t || !delayhide ) && t->rect == r ) {
270 tips->take( w );
271 if ( t->next )
272 tips->insert( w, t->next );
273 delete t;
274 } else {
275 while( t->next && t->next->rect != r && ( currentTip != t->next || !delayhide ))
276 t = t->next;
277 if ( t->next ) {
278 QTipManager::Tip *d = t->next;
279 t->next = t->next->next;
280 delete d;
281 }
282 }
283
284 if ( (*tips)[ w ] == 0 )
285 disconnect( w, SIGNAL(destroyed()), this, SLOT(clientWidgetDestroyed()) );
286#if 0 // not needed, leads sometimes to crashes
287 if ( tips->isEmpty() ) {
288 // the manager will be recreated if needed
289 delete tipManager;
290 tipManager = 0;
291 }
292#endif
293}
294
295
296/*
297 The label was destroyed in the program cleanup phase.
298*/
299
300void QTipManager::labelDestroyed()
301{
302 label = 0;
303}
304
305
306/*
307 Remove sender() from the tool tip data structures.
308*/
309
310void QTipManager::clientWidgetDestroyed()
311{
312 const QObject *s = sender();
313 if ( s )
314 remove( (QWidget*) s );
315}
316
317
318void QTipManager::remove( QWidget *w )
319{
320 QTipManager::Tip *t = (*tips)[ w ];
321 if ( t == 0 )
322 return;
323
324 tips->take( w );
325 QTipManager::Tip * d;
326 while ( t ) {
327 if ( t == currentTip )
328 hideTip();
329 d = t->next;
330 delete t;
331 t = d;
332 }
333
334 disconnect( w, SIGNAL(destroyed()), this, SLOT(clientWidgetDestroyed()) );
335#if 0
336 if ( tips->isEmpty() ) {
337 delete tipManager;
338 tipManager = 0;
339 }
340#endif
341}
342
343
344void QTipManager::removeFromGroup( QToolTipGroup *g )
345{
346 QPtrDictIterator<QTipManager::Tip> i( *tips );
347 QTipManager::Tip *t;
348 while( (t = i.current()) != 0 ) {
349 ++i;
350 while ( t ) {
351 if ( t->group == g ) {
352 if ( t->group )
353 disconnect( removeTimer, SIGNAL( timeout() ),
354 t->group, SIGNAL( removeTip() ) );
355 t->group = 0;
356 }
357 t = t->next;
358 }
359 }
360}
361
362
363
364bool QTipManager::eventFilter( QObject *obj, QEvent *e )
365{
366 // avoid dumping core in case of application madness, and return
367 // quickly for some common but irrelevant events
368 if ( e->type() == QEvent::WindowDeactivate &&
369 qApp && !qApp->activeWindow() &&
370 label && label->isVisible() )
371 hideTipAndSleep();
372
373 if ( !qApp
374 || !obj || !obj->isWidgetType() // isWidgetType() catches most stuff
375 || e->type() == QEvent::Paint
376 || e->type() == QEvent::Timer
377 || e->type() == QEvent::SockAct
378 || !tips )
379 return FALSE;
380 QWidget *w = (QWidget *)obj;
381
382 if ( e->type() == QEvent::FocusOut || e->type() == QEvent::FocusIn ) {
383 // user moved focus somewhere - hide the tip and sleep
384 if ( ((QFocusEvent*)e)->reason() != QFocusEvent::Popup )
385 hideTipAndSleep();
386 return FALSE;
387 }
388
389 QTipManager::Tip *t = 0;
390 while( w && !t ) {
391 t = (*tips)[ w ];
392 if ( !t )
393 w = w->isTopLevel() ? 0 : w->parentWidget();
394 }
395 if ( !w )
396 return FALSE;
397
398 if ( !t && e->type() != QEvent::MouseMove) {
399 if ( ( e->type() >= QEvent::MouseButtonPress &&
400 e->type() <= QEvent::FocusOut) || e->type() == QEvent::Leave )
401 hideTip();
402 return FALSE;
403 }
404
405 // with that out of the way, let's get down to action
406
407 switch( e->type() ) {
408 case QEvent::MouseButtonPress:
409 case QEvent::MouseButtonRelease:
410 case QEvent::MouseButtonDblClick:
411 case QEvent::KeyPress:
412 case QEvent::KeyRelease:
413 // input - turn off tool tip mode
414 hideTipAndSleep();
415 break;
416 case QEvent::MouseMove:
417 {
418 QMouseEvent * m = (QMouseEvent *)e;
419 QPoint mousePos = w->mapFromGlobal( m->globalPos() );
420
421 if ( currentTip && !currentTip->rect.contains( mousePos ) ) {
422 hideTip();
423 if ( m->state() == 0 )
424 return FALSE;
425 }
426
427 wakeUp.stop();
428 if ( m->state() == 0 &&
429 mousePos.x() >= 0 && mousePos.x() < w->width() &&
430 mousePos.y() >= 0 && mousePos.y() < w->height() ) {
431 if ( label && label->isVisible() ) {
432 return FALSE;
433 } else {
434 if ( fallAsleep.isActive() ) {
435 wakeUp.start( 1, TRUE );
436 } else {
437 previousTip = 0;
438 wakeUp.start( wakeUpDelay, TRUE );
439 }
440 if ( t->group && t->group->ena &&
441 !t->group->del && !t->groupText.isEmpty() ) {
442 removeTimer->stop();
443 emit t->group->showTip( t->groupText );
444 currentTip = t;
445 }
446 }
447 widget = w;
448 pos = mousePos;
449 return FALSE;
450 } else {
451 hideTip();
452 }
453 }
454 break;
455 case QEvent::Leave:
456 case QEvent::Hide:
457 case QEvent::Destroy:
458 if ( w == widget )
459 hideTip();
460 break;
461 default:
462 break;
463 }
464 return FALSE;
465}
466
467
468
469void QTipManager::showTip()
470{
471 if ( !widget || !globally_enabled
472#ifndef Q_WS_X11
473 || !widget->isActiveWindow()
474#endif
475 )
476 return;
477
478 QTipManager::Tip *t = (*tips)[ widget ];
479 while ( t && !t->rect.contains( pos ) )
480 t = t->next;
481 if ( t == 0 )
482 return;
483
484 if ( t == currentTip && label && label->isVisible() )
485 return; // nothing to do
486
487 if ( t->tip ) {
488 t->tip->maybeTip( pos );
489 return;
490 }
491
492 if ( t->group && !t->group->ena )
493 return;
494
495 int scr;
496 if ( QApplication::desktop()->isVirtualDesktop() )
497 scr = QApplication::desktop()->screenNumber( widget->mapToGlobal( pos ) );
498 else
499 scr = QApplication::desktop()->screenNumber( widget );
500
501 if ( label
502#if defined(Q_WS_X11)
503 && label->x11Screen() == widget->x11Screen()
504#endif
505 ) {
506 // the next two lines are a workaround for QLabel being too intelligent.
507 // QLabel turns on the wordbreak flag once it gets a richtext. The two lines below
508 // ensure we get correct textflags when switching back and forth between a richtext and
509 // non richtext tooltip
510 label->setText( "" );
511 label->setAlignment( AlignAuto | AlignTop );
512 label->setText( t->text );
513 label->adjustSize();
514 if ( t->geometry != QRect( -1, -1, -1, -1 ) )
515 label->resize( t->geometry.size() );
516 } else {
517 delete label;
518 label = new QTipLabel( QApplication::desktop()->screen( scr ), t->text);
519 if ( t->geometry != QRect( -1, -1, -1, -1 ) )
520 label->resize( t->geometry.size() );
521 Q_CHECK_PTR( label );
522 connect( label, SIGNAL(destroyed()), SLOT(labelDestroyed()) );
523 }
524 // the above deletion and creation of a QTipLabel causes events to be sent. We had reports that the widget
525 // pointer was 0 after this. This is in principle possible if the wrong kind of events get sent through our event
526 // filter in this time. So better be safe and check widget once again here.
527 if (!widget)
528 return;
529
530#ifdef Q_WS_MAC
531 QRect screen = QApplication::desktop()->availableGeometry( scr );
532#else
533 QRect screen = QApplication::desktop()->screenGeometry( scr );
534#endif
535 QPoint p;
536 if ( t->geometry == QRect( -1, -1, -1, -1 ) ) {
537 p = widget->mapToGlobal( pos ) +
538#ifdef Q_WS_WIN
539 QPoint( 2, 24 );
540#else
541 QPoint( 2, 16 );
542#endif
543 if ( p.x() + label->width() > screen.x() + screen.width() )
544 p.rx() -= 4 + label->width();
545 if ( p.y() + label->height() > screen.y() + screen.height() )
546 p.ry() -= 24 + label->height();
547 } else {
548 p = widget->mapToGlobal( t->geometry.topLeft() );
549 label->setAlignment( WordBreak | AlignCenter );
550 label->setWidth( t->geometry.width() - 4 );
551 }
552 if ( p.y() < screen.y() )
553 p.setY( screen.y() );
554 if ( p.x() + label->width() > screen.x() + screen.width() )
555 p.setX( screen.x() + screen.width() - label->width() );
556 if ( p.x() < screen.x() )
557 p.setX( screen.x() );
558 if ( p.y() + label->height() > screen.y() + screen.height() )
559 p.setY( screen.y() + screen.height() - label->height() );
560 if ( label->text().length() ) {
561 label->move( p );
562
563#ifndef QT_NO_EFFECTS
564 if ( QApplication::isEffectEnabled( UI_AnimateTooltip ) == FALSE ||
565 previousTip || preventAnimation )
566 label->show();
567 else if ( QApplication::isEffectEnabled( UI_FadeTooltip ) )
568 qFadeEffect( label );
569 else
570 qScrollEffect( label );
571#else
572 label->show();
573#endif
574
575 label->raise();
576 fallAsleep.start( 10000, TRUE );
577 }
578
579 if ( t->group && t->group->del && !t->groupText.isEmpty() ) {
580 removeTimer->stop();
581 emit t->group->showTip( t->groupText );
582 }
583
584 currentTip = t;
585 previousTip = 0;
586}
587
588
589void QTipManager::hideTip()
590{
591 QTimer::singleShot( 250, this, SLOT(allowAnimation()) );
592 preventAnimation = TRUE;
593
594 if ( label && label->isVisible() ) {
595 label->hide();
596 fallAsleep.start( 2000, TRUE );
597 wakeUp.stop();
598 if ( currentTip && currentTip->group )
599 removeTimer->start( 100, TRUE );
600 } else if ( wakeUp.isActive() ) {
601 wakeUp.stop();
602 if ( currentTip && currentTip->group &&
603 !currentTip->group->del && !currentTip->groupText.isEmpty() )
604 removeTimer->start( 100, TRUE );
605 } else if ( currentTip && currentTip->group ) {
606 removeTimer->start( 100, TRUE );
607 }
608
609 previousTip = currentTip;
610 currentTip = 0;
611 if ( previousTip && previousTip->autoDelete )
612 remove( widget, previousTip->rect );
613 widget = 0;
614}
615
616void QTipManager::hideTipAndSleep()
617{
618 hideTip();
619 fallAsleep.stop();
620}
621
622
623void QTipManager::allowAnimation()
624{
625 preventAnimation = FALSE;
626}
627
628QString QTipManager::find( QWidget *w, const QPoint& pos )
629{
630 Tip *t = (*tips)[ w ];
631 while ( t && !t->rect.contains( pos ) )
632 t = t->next;
633
634 return t ? t->text : QString::null;
635}
636
637void QTipManager::setWakeUpDelay ( int i )
638{
639 wakeUpDelay = i;
640}
641
642/*!
643 \class QToolTip qtooltip.h
644 \brief The QToolTip class provides tool tips (balloon help) for
645 any widget or rectangular part of a widget.
646
647 \ingroup helpsystem
648 \mainclass
649
650 The tip is a short, single line of text reminding the user of the
651 widget's or rectangle's function. It is drawn immediately below
652 the region in a distinctive black-on-yellow combination.
653
654 The tip can be any Rich-Text formatted string.
655
656 QToolTipGroup provides a way for tool tips to display another text
657 elsewhere (most often in a \link QStatusBar status bar\endlink).
658
659 At any point in time, QToolTip is either dormant or active. In
660 dormant mode the tips are not shown and in active mode they are.
661 The mode is global, not particular to any one widget.
662
663 QToolTip switches from dormant to active mode when the user hovers
664 the mouse on a tip-equipped region for a second or so and remains
665 active until the user either clicks a mouse button, presses a key,
666 lets the mouse hover for five seconds or moves the mouse outside
667 \e all tip-equipped regions for at least a second.
668
669 The QToolTip class can be used in three different ways:
670 \list 1
671 \i Adding a tip to an entire widget.
672 \i Adding a tip to a fixed rectangle within a widget.
673 \i Adding a tip to a dynamic rectangle within a widget.
674 \endlist
675
676 To add a tip to a widget, call the \e static function
677 QToolTip::add() with the widget and tip as arguments:
678
679 \code
680 QToolTip::add( quitButton, "Leave the application" );
681 \endcode
682
683 This is the simplest and most common use of QToolTip. The tip
684 will be deleted automatically when \e quitButton is deleted, but
685 you can remove it yourself, too:
686
687 \code
688 QToolTip::remove( quitButton );
689 \endcode
690
691 You can also display another text (typically in a \link QStatusBar
692 status bar),\endlink courtesy of \l{QToolTipGroup}. This example
693 assumes that \e grp is a \c{QToolTipGroup *} and is already
694 connected to the appropriate status bar:
695
696 \code
697 QToolTip::add( quitButton, "Leave the application", grp,
698 "Leave the application, prompting to save if necessary" );
699 QToolTip::add( closeButton, "Close this window", grp,
700 "Close this window, prompting to save if necessary" );
701 \endcode
702
703 To add a tip to a fixed rectangle within a widget, call the static
704 function QToolTip::add() with the widget, rectangle and tip as
705 arguments. (See the \c tooltip/tooltip.cpp example.) Again, you
706 can supply a \c{QToolTipGroup *} and another text if you want.
707
708 Both of these are one-liners and cover the majority of cases. The
709 third and most general way to use QToolTip requires you to
710 reimplement a pure virtual function to decide whether to pop up a
711 tool tip. The \c tooltip/tooltip.cpp example demonstrates this
712 too. This mode can be used to implement tips for text that can
713 move as the user scrolls, for example.
714
715 To use QToolTip like this, you must subclass QToolTip and
716 reimplement maybeTip(). QToolTip calls maybeTip() when a tip
717 should pop up, and maybeTip() decides whether to show a tip.
718
719 Tool tips can be globally disabled using
720 QToolTip::setGloballyEnabled() or disabled in groups with
721 QToolTipGroup::setEnabled().
722
723 You can retrieve the text of a tooltip for a given position within
724 a widget using textFor().
725
726 The global tooltip font and palette can be set with the static
727 setFont() and setPalette() functions respectively.
728
729 \sa QStatusBar QWhatsThis QToolTipGroup
730 \link guibooks.html#fowler GUI Design Handbook: Tool Tip\endlink
731*/
732
733
734/*!
735 Returns the font common to all tool tips.
736
737 \sa setFont()
738*/
739
740QFont QToolTip::font()
741{
742 QTipLabel l(0,"");
743 return QApplication::font( &l );
744}
745
746
747/*!
748 Sets the font for all tool tips to \a font.
749
750 \sa font()
751*/
752
753void QToolTip::setFont( const QFont &font )
754{
755 QApplication::setFont( font, TRUE, "QTipLabel" );
756}
757
758
759/*!
760 Returns the palette common to all tool tips.
761
762 \sa setPalette()
763*/
764
765QPalette QToolTip::palette()
766{
767 QTipLabel l(0,"");
768 return QApplication::palette( &l );
769}
770
771
772/*!
773 Sets the palette for all tool tips to \a palette.
774
775 \sa palette()
776*/
777
778void QToolTip::setPalette( const QPalette &palette )
779{
780 QApplication::setPalette( palette, TRUE, "QTipLabel" );
781}
782
783/*!
784 Constructs a tool tip object. This is only necessary if you need
785 tool tips on regions that can move within the widget (most often
786 because the widget's contents can scroll).
787
788 \a widget is the widget you want to add dynamic tool tips to and
789 \a group (optional) is the tool tip group they should belong to.
790
791 \warning QToolTip is not a subclass of QObject, so the instance of
792 QToolTip is not deleted when \a widget is deleted.
793
794 \warning If you delete the tool tip before you have deleted
795 \a widget then you need to make sure you call remove() yourself from
796 \a widget in your reimplemented QToolTip destructor.
797
798 \code
799 MyToolTip::~MyToolTip()
800 {
801 remove( widget );
802 }
803 \endcode
804
805 \sa maybeTip().
806*/
807
808QToolTip::QToolTip( QWidget * widget, QToolTipGroup * group )
809{
810 p = widget;
811 g = group;
812 initTipManager();
813 tipManager->add( p, entireWidget(),
814 QString::null, g, QString::null, this, FALSE );
815}
816
817
818/*!
819 Adds a tool tip to \a widget. \a text is the text to be shown in
820 the tool tip.
821
822 This is the most common entry point to the QToolTip class; it is
823 suitable for adding tool tips to buttons, checkboxes, comboboxes
824 and so on.
825*/
826
827void QToolTip::add( QWidget *widget, const QString &text )
828{
829 initTipManager();
830 tipManager->add( widget, entireWidget(),
831 text, 0, QString::null, 0, FALSE );
832}
833
834
835/*!
836 \overload
837
838 Adds a tool tip to \a widget and to tool tip group \a group.
839
840 \a text is the text shown in the tool tip and \a longText is the
841 text emitted from \a group.
842
843 Normally, \a longText is shown in a \link QStatusBar status
844 bar\endlink or similar.
845*/
846
847void QToolTip::add( QWidget *widget, const QString &text,
848 QToolTipGroup *group, const QString& longText )
849{
850 initTipManager();
851 tipManager->add( widget, entireWidget(), text, group, longText, 0, FALSE );
852}
853
854
855/*!
856 Removes the tool tip from \a widget.
857
858 If there is more than one tool tip on \a widget, only the one
859 covering the entire widget is removed.
860*/
861
862void QToolTip::remove( QWidget * widget )
863{
864 if ( tipManager )
865 tipManager->remove( widget, entireWidget() );
866}
867
868/*!
869 \overload
870
871 Adds a tool tip to a fixed rectangle, \a rect, within \a widget.
872 \a text is the text shown in the tool tip.
873*/
874
875void QToolTip::add( QWidget * widget, const QRect & rect, const QString &text )
876{
877 initTipManager();
878 tipManager->add( widget, rect, text, 0, QString::null, 0, FALSE );
879}
880
881
882/*!
883 \overload
884
885 Adds a tool tip to an entire \a widget and to tool tip group \a
886 group. The tooltip will disappear when the mouse leaves the \a
887 rect.
888
889 \a text is the text shown in the tool tip and \a groupText is the
890 text emitted from \a group.
891
892 Normally, \a groupText is shown in a \link QStatusBar status
893 bar\endlink or similar.
894*/
895
896void QToolTip::add( QWidget *widget, const QRect &rect,
897 const QString& text,
898 QToolTipGroup *group, const QString& groupText )
899{
900 initTipManager();
901 tipManager->add( widget, rect, text, group, groupText, 0, FALSE );
902}
903
904
905/*!
906 \overload
907
908 Removes any tool tip for \a rect from \a widget.
909
910 If there is more than one tool tip on \a widget, only the one
911 covering rectangle \a rect is removed.
912*/
913
914void QToolTip::remove( QWidget * widget, const QRect & rect )
915{
916 if ( tipManager )
917 tipManager->remove( widget, rect );
918}
919
920/*!
921 Returns the tool tip text for \a widget at position \a pos, or
922 QString::null if there is no tool tip for the given widget and
923 position.
924*/
925
926QString QToolTip::textFor( QWidget *widget, const QPoint& pos )
927{
928 if ( tipManager )
929 return tipManager->find( widget, pos );
930 return QString::null;
931}
932
933/*!
934 Hides any tip that is currently being shown.
935
936 Normally, there is no need to call this function; QToolTip takes
937 care of showing and hiding the tips as the user moves the mouse.
938*/
939
940void QToolTip::hide()
941{
942 if ( tipManager )
943 tipManager->hideTipAndSleep();
944}
945
946/*!
947 \fn virtual void QToolTip::maybeTip( const QPoint & p);
948
949 This pure virtual function is half of the most versatile interface
950 QToolTip offers.
951
952 It is called when there is a possibility that a tool tip should be
953 shown and must decide whether there is a tool tip for the point \a
954 p in the widget that this QToolTip object relates to. If so,
955 maybeTip() must call tip() with the rectangle the tip applies to,
956 the tip's text and optionally the QToolTipGroup details and the
957 geometry in screen coordinates.
958
959 \a p is given in that widget's local coordinates. Most maybeTip()
960 implementations will be of the form:
961
962 \code
963 if ( <something> ) {
964 tip( <something>, <something> );
965 }
966 \endcode
967
968 The first argument to tip() (a rectangle) must encompass \a p,
969 i.e. the tip must apply to the current mouse position; otherwise
970 QToolTip's operation is undefined.
971
972 Note that the tip will disappear once the mouse moves outside the
973 rectangle you give to tip(), and will not reappear if the mouse
974 moves back in: maybeTip() is called again instead.
975
976 \sa tip()
977*/
978
979
980/*!
981 Immediately pops up a tip saying \a text and removes the tip once
982 the cursor moves out of rectangle \a rect (which is given in the
983 coordinate system of the widget this QToolTip relates to).
984
985 The tip will not reappear if the cursor moves back; your
986 maybeTip() must reinstate it each time.
987*/
988
989void QToolTip::tip( const QRect & rect, const QString &text )
990{
991 initTipManager();
992 tipManager->add( parentWidget(), rect, text, 0, QString::null, 0, TRUE );
993}
994
995/*!
996 \overload
997
998 Immediately pops up a tip saying \a text and removes that tip once
999 the cursor moves out of rectangle \a rect (which is given in the
1000 coordinate system of the widget this QToolTip relates to). \a
1001 groupText is the text emitted from the group.
1002
1003 The tip will not reappear if the cursor moves back; your
1004 maybeTip() must reinstate it each time.
1005*/
1006
1007void QToolTip::tip( const QRect & rect, const QString &text,
1008 const QString& groupText )
1009{
1010 initTipManager();
1011 tipManager->add( parentWidget(), rect, text, group(), groupText, 0, TRUE );
1012}
1013
1014/*!
1015 \overload
1016
1017 Immediately pops up a tip within the rectangle \a geometry, saying
1018 \a text and removes the tip once the cursor moves out of rectangle
1019 \a rect. Both rectangles are given in the coordinate system of the
1020 widget this QToolTip relates to.
1021
1022 The tip will not reappear if the cursor moves back; your
1023 maybeTip() must reinstate it each time.
1024
1025 If the tip does not fit inside \a geometry, the tip expands.
1026*/
1027
1028void QToolTip::tip( const QRect &rect, const QString &text, const QRect &geometry )
1029{
1030 initTipManager();
1031 tipManager->add( geometry, parentWidget(), rect, text, 0, QString::null, 0, TRUE );
1032}
1033
1034/*!
1035 \overload
1036
1037 mmediately pops up a tip within the rectangle \a geometry, saying
1038 \a text and removes the tip once the cursor moves out of rectangle
1039 \a rect. \a groupText is the text emitted from the group. Both
1040 rectangles are given in the coordinate system of the widget this
1041 QToolTip relates to.
1042
1043 The tip will not reappear if the cursor moves back; your
1044 maybeTip() must reinstate it each time.
1045
1046 If the tip does not fit inside \a geometry, the tip expands.
1047*/
1048
1049void QToolTip::tip( const QRect &rect, const QString &text, const QString& groupText, const QRect &geometry )
1050{
1051 initTipManager();
1052 tipManager->add( geometry, parentWidget(), rect, text, group(), groupText, 0, TRUE );
1053}
1054
1055
1056
1057/*!
1058 Immediately removes all tool tips for this tooltip's parent
1059 widget.
1060*/
1061
1062void QToolTip::clear()
1063{
1064 if ( tipManager )
1065 tipManager->remove( parentWidget() );
1066}
1067
1068
1069/*!
1070 \fn QWidget * QToolTip::parentWidget() const
1071
1072 Returns the widget this QToolTip applies to.
1073
1074 The tool tip is destroyed automatically when the parent widget is
1075 destroyed.
1076
1077 \sa group()
1078*/
1079
1080
1081/*!
1082 \fn QToolTipGroup * QToolTip::group() const
1083
1084 Returns the tool tip group this QToolTip is a member of or 0 if it
1085 isn't a member of any group.
1086
1087 The tool tip group is the object responsible for maintaining
1088 contact between tool tips and a \link QStatusBar status
1089 bar\endlink or something else which can show the longer help text.
1090
1091 \sa parentWidget(), QToolTipGroup
1092*/
1093
1094
1095/*!
1096 \class QToolTipGroup qtooltip.h
1097 \brief The QToolTipGroup class collects tool tips into related groups.
1098
1099 \ingroup helpsystem
1100
1101 Tool tips can display \e two texts: one in the tip and
1102 (optionally) one that is typically in a \link QStatusBar status
1103 bar\endlink. QToolTipGroup provides a way to link tool tips to
1104 this status bar.
1105
1106 QToolTipGroup has practically no API; it is only used as an
1107 argument to QToolTip's member functions, for example like this:
1108
1109 \code
1110 QToolTipGroup * grp = new QToolTipGroup( this, "tool tip relay" );
1111 connect( grp, SIGNAL(showTip(const QString&)),
1112 myLabel, SLOT(setText(const QString&)) );
1113 connect( grp, SIGNAL(removeTip()),
1114 myLabel, SLOT(clear()) );
1115 QToolTip::add( giraffeButton, "feed giraffe",
1116 grp, "Give the giraffe a meal" );
1117 QToolTip::add( gorillaButton, "feed gorilla",
1118 grp, "Give the gorilla a meal" );
1119 \endcode
1120
1121 This example makes the object myLabel (which you must supply)
1122 display (one assumes, though you can make myLabel do anything, of
1123 course) the strings "Give the giraffe a meal" and "Give the
1124 gorilla a meal" while the relevant tool tips are being displayed.
1125
1126 Deleting a tool tip group removes the tool tips in it.
1127*/
1128
1129/*!
1130 \fn void QToolTipGroup::showTip (const QString &longText)
1131
1132 This signal is emitted when one of the tool tips in the group is
1133 displayed. \a longText is the extra text for the displayed tool
1134 tip.
1135
1136 \sa removeTip()
1137*/
1138
1139/*!
1140 \fn void QToolTipGroup::removeTip ()
1141
1142 This signal is emitted when a tool tip in this group is hidden.
1143 See the QToolTipGroup documentation for an example of use.
1144
1145 \sa showTip()
1146*/
1147
1148
1149/*!
1150 Constructs a tool tip group called \a name, with parent \a parent.
1151*/
1152
1153QToolTipGroup::QToolTipGroup( QObject *parent, const char *name )
1154 : QObject( parent, name )
1155{
1156 del = TRUE;
1157 ena = TRUE;
1158}
1159
1160
1161/*!
1162 Destroys this tool tip group and all tool tips in it.
1163*/
1164
1165QToolTipGroup::~QToolTipGroup()
1166{
1167 if ( tipManager )
1168 tipManager->removeFromGroup( this );
1169}
1170
1171
1172/*!
1173 \property QToolTipGroup::delay
1174 \brief whether the display of the group text is delayed.
1175
1176 If set to TRUE (the default), the group text is displayed at the
1177 same time as the tool tip. Otherwise, the group text is displayed
1178 immediately when the cursor enters the widget.
1179*/
1180
1181bool QToolTipGroup::delay() const
1182{
1183 return del;
1184}
1185
1186void QToolTipGroup::setDelay( bool enable )
1187{
1188#if 0
1189 if ( enable && !del ) {
1190 // maybe we should show the text at once?
1191 }
1192#endif
1193 del = enable;
1194}
1195
1196/*!
1197 \fn static void QToolTip::setEnabled( bool enable )
1198
1199 \obsolete
1200*/
1201/*!
1202 \fn static bool QToolTip::enabled()
1203
1204 \obsolete
1205*/
1206/*!
1207 \property QToolTipGroup::enabled
1208 \brief whether tool tips in the group are enabled.
1209
1210 This property's default is TRUE.
1211*/
1212
1213void QToolTipGroup::setEnabled( bool enable )
1214{
1215 ena = enable;
1216}
1217
1218bool QToolTipGroup::enabled() const
1219{
1220 return (bool)ena;
1221}
1222
1223/*!
1224 If \a enable is TRUE sets all tool tips to be enabled (shown when
1225 needed); if \a enable is FALSE sets all tool tips to be disabled
1226 (never shown).
1227
1228 By default, tool tips are enabled. Note that this function affects
1229 all tool tips in the entire application.
1230
1231 \sa QToolTipGroup::setEnabled()
1232*/
1233
1234void QToolTip::setGloballyEnabled( bool enable )
1235{
1236 globally_enabled = enable;
1237}
1238
1239/*!
1240 Returns whether tool tips are enabled globally.
1241
1242 \sa setGloballyEnabled()
1243*/
1244bool QToolTip::isGloballyEnabled()
1245{
1246 return globally_enabled;
1247}
1248
1249/*!
1250 Sets the wakeup delay for all tooltips to \a i.
1251*/
1252void QToolTip::setWakeUpDelay ( int i )
1253{
1254 initTipManager();
1255 tipManager->setWakeUpDelay(i);
1256}
1257
1258
1259#include "qtooltip.moc"
1260#endif
Note: See TracBrowser for help on using the repository browser.