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