summaryrefslogtreecommitdiffstats
path: root/experimental/tqtinterface/qt4/src/widgets/tqwhatsthis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'experimental/tqtinterface/qt4/src/widgets/tqwhatsthis.cpp')
-rw-r--r--experimental/tqtinterface/qt4/src/widgets/tqwhatsthis.cpp1004
1 files changed, 1004 insertions, 0 deletions
diff --git a/experimental/tqtinterface/qt4/src/widgets/tqwhatsthis.cpp b/experimental/tqtinterface/qt4/src/widgets/tqwhatsthis.cpp
new file mode 100644
index 000000000..80e984c8c
--- /dev/null
+++ b/experimental/tqtinterface/qt4/src/widgets/tqwhatsthis.cpp
@@ -0,0 +1,1004 @@
+/****************************************************************************
+**
+** Implementation of TQWhatsThis class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt 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 TQt 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 sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** 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 "tqwhatsthis.h"
+#ifndef TQT_NO_WHATSTHIS
+#include "tqapplication.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqpixmap.h"
+#include "tqpainter.h"
+#include "tqtimer.h"
+#include "tqptrdict.h"
+#include "tqtoolbutton.h"
+#include "tqshared.h"
+#include "tqcursor.h"
+#include "tqbitmap.h"
+#include "tqtooltip.h"
+#include "tqsimplerichtext.h"
+#include "tqstylesheet.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+#if defined(TQ_WS_WIN)
+#include "tqt_windows.h"
+#ifndef SPI_GETDROPSHADOW
+#define SPI_GETDROPSHADOW 0x1024
+#endif
+#endif
+
+/*!
+ \class TQWhatsThis tqwhatsthis.h
+ \brief The TQWhatsThis class provides a simple description of any
+ widget, i.e. answering the question "What's this?".
+
+ \ingroup helpsystem
+ \mainclass
+
+ "What's this?" help is part of an application's online help system
+ that provides users with information about functionality, usage,
+ background etc., in various levels of detail from short tool tips
+ to full text browsing help windows.
+
+ TQWhatsThis provides a single window with an explanatory text that
+ pops up when the user asks "What's this?". The default way to do
+ this is to focus the relevant widget and press Shift+F1. The help
+ text appears immediately; it goes away as soon as the user does
+ something else.
+
+ (Note that if there is an accelerator for Shift+F1, this mechanism
+ will not work.)
+
+ To add "What's this?" text to a widget you simply call
+ TQWhatsThis::add() for the widget. For example, to assign text to a
+ menu item, call TQMenuData::setWhatsThis(); for a global
+ accelerator key, call TQAccel::setWhatsThis() and If you're using
+ actions, use TQAction::setWhatsThis().
+
+ The text can be either rich text or plain text. If you specify a
+ rich text formatted string, it will be rendered using the default
+ stylesheet. This makes it possible to embed images. See
+ TQStyleSheet::defaultSheet() for details.
+
+ \quotefile action/application.cpp
+ \skipto fileOpenText
+ \printuntil setWhatsThis
+
+ An alternative way to enter "What's this?" mode is to use the
+ ready-made tool bar tool button from
+ TQWhatsThis::whatsThisButton(). By invoking this context help
+ button (in the picture below the first one from the right) the
+ user switches into "What's this?" mode. If they now click on a
+ widget the appropriate help text is shown. The mode is left when
+ help is given or when the user presses Esc.
+
+ \img whatsthis.png
+
+ If you are using TQMainWindow you can also use the
+ TQMainWindow::whatsThis() slot to invoke the mode from a menu item.
+
+ For more control you can create a dedicated TQWhatsThis object for
+ a special widget. By subclassing and reimplementing
+ TQWhatsThis::text() it is possible to have different help texts,
+ depending on the position of the mouse click. By reimplementing
+ TQWhatsThis::clicked() it is possible to have hyperlinks inside the
+ help texts.
+
+ If you wish to control the "What's this?" behavior of a widget
+ manually see TQWidget::customWhatsThis().
+
+ The What's This object can be removed using TQWhatsThis::remove(),
+ although this is rarely necessary because it is automatically
+ removed when the widget is destroyed.
+
+ \sa TQToolTip
+*/
+
+// a special button
+class TQWhatsThisButton: public TQToolButton
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQWhatsThisButton( TQWidget * tqparent, const char * name );
+ ~TQWhatsThisButton();
+
+public Q_SLOTS:
+ void mouseReleased();
+
+};
+
+
+class TQWhatsThat : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQWhatsThat( TQWidget* w, const TQString& txt, TQWidget* tqparent, const char* name );
+ ~TQWhatsThat() ;
+
+public Q_SLOTS:
+ void hide();
+ inline void widgetDestroyed() { widget = 0; }
+
+protected:
+ void mousePressEvent( TQMouseEvent* );
+ void mouseReleaseEvent( TQMouseEvent* );
+ void mouseMoveEvent( TQMouseEvent* );
+ void keyPressEvent( TQKeyEvent* );
+ void paintEvent( TQPaintEvent* );
+
+private:
+ TQString text;
+#ifndef TQT_NO_RICHTEXT
+ TQSimpleRichText* doc;
+#endif
+ TQString anchor;
+ bool pressed;
+ TQWidget* widget;
+};
+
+
+class TQWhatsThisPrivate: public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+
+ // an item for storing texts
+ struct WhatsThisItem: public TQShared
+ {
+ WhatsThisItem(): TQShared() { whatsthis = 0; }
+ ~WhatsThisItem();
+ TQString s;
+ TQWhatsThis* whatsthis;
+ };
+
+ // the (these days pretty small) state machine
+ enum State { Inactive, Waiting };
+
+ TQWhatsThisPrivate();
+ ~TQWhatsThisPrivate();
+
+ bool eventFilter( TQObject *, TQEvent * );
+
+ WhatsThisItem* newItem( TQWidget * widget );
+ void add( TQWidget * widget, TQWhatsThis* special );
+ void add( TQWidget * widget, const TQString& text );
+
+ // say it.
+ void say( TQWidget *, const TQString&, const TQPoint& );
+
+ // setup and teardown
+ static void setUpWhatsThis();
+
+ void enterWhatsThisMode();
+ void leaveWhatsThisMode();
+
+ // variables
+ TQWhatsThat * whatsThat;
+ TQPtrDict<WhatsThisItem> * dict;
+ TQPtrDict<TQWidget> * tlw;
+ TQPtrDict<TQWhatsThisButton> * buttons;
+ State state;
+
+private Q_SLOTS:
+ void cleanupWidget()
+ {
+ const TQObject* o = TQT_TQOBJECT(sender());
+ if ( o->isWidgetType() ) // sanity
+ TQWhatsThis::remove((TQWidget*)o);
+ }
+
+};
+
+// static, but static the less-typing way
+static TQWhatsThisPrivate * wt = 0;
+
+// shadowWidth not const, for XP drop-shadow-fu turns it to 0
+static int shadowWidth = 6; // also used as '5' and '6' and even '8' below
+const int vMargin = 8;
+const int hMargin = 12;
+
+// Lets TQPopupMenu destroy the TQWhatsThat.
+void qWhatsThisBDH()
+{
+ if ( wt && wt->whatsThat )
+ wt->whatsThat->hide();
+}
+
+
+TQWhatsThat::TQWhatsThat( TQWidget* w, const TQString& txt, TQWidget* tqparent, const char* name )
+ : TQWidget( tqparent, name, WType_Popup ), text( txt ), pressed( FALSE ), widget( w )
+{
+
+ setBackgroundMode( TQt::NoBackground );
+ setPalette( TQToolTip::palette() );
+ setMouseTracking( TRUE );
+#ifndef TQT_NO_CURSOR
+ setCursor( Qt::ArrowCursor );
+#endif
+
+ if ( widget )
+ connect( widget, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( widgetDestroyed() ) );
+
+
+ TQRect r;
+#ifndef TQT_NO_RICHTEXT
+ doc = 0;
+ if ( TQStyleSheet::mightBeRichText( text ) ) {
+ TQFont f = TQApplication::font( this );
+ doc = new TQSimpleRichText( text, f );
+ doc->adjustSize();
+ r.setRect( 0, 0, doc->width(), doc->height() );
+ }
+ else
+#endif
+ {
+ int sw = TQApplication::desktop()->width() / 3;
+ if ( sw < 200 )
+ sw = 200;
+ else if ( sw > 300 )
+ sw = 300;
+
+ r = fontMetrics().boundingRect( 0, 0, sw, 1000,
+ TQt::AlignAuto + TQt::AlignTop + TQt::WordBreak + TQt::ExpandTabs,
+ text );
+ }
+#if defined(TQ_WS_WIN)
+ if ( (qWinVersion()&WV_NT_based) > WV_2000 ) {
+ BOOL shadow;
+ SystemParametersInfo( SPI_GETDROPSHADOW, 0, &shadow, 0 );
+ shadowWidth = shadow ? 0 : 6;
+ }
+#endif
+ resize( r.width() + 2*hMargin + shadowWidth, r.height() + 2*vMargin + shadowWidth );
+}
+
+TQWhatsThat::~TQWhatsThat()
+{
+ if ( wt && wt->whatsThat == this )
+ wt->whatsThat = 0;
+#ifndef TQT_NO_RICHTEXT
+ if ( doc )
+ delete doc;
+#endif
+}
+
+void TQWhatsThat::hide()
+{
+ TQWidget::hide();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpEnd );
+#endif
+}
+
+void TQWhatsThat::mousePressEvent( TQMouseEvent* e )
+{
+ pressed = TRUE;
+ if ( e->button() == Qt::LeftButton && TQT_TQRECT_OBJECT(rect()).tqcontains( e->pos() ) ) {
+#ifndef TQT_NO_RICHTEXT
+ if ( doc )
+ anchor = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin) );
+#endif
+ return;
+ }
+ hide();
+}
+
+void TQWhatsThat::mouseReleaseEvent( TQMouseEvent* e )
+{
+ if ( !pressed )
+ return;
+#ifndef TQT_NO_RICHTEXT
+ if ( e->button() == Qt::LeftButton && doc && TQT_TQRECT_OBJECT(rect()).tqcontains( e->pos() ) ) {
+ TQString a = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin ) );
+ TQString href;
+ if ( anchor == a )
+ href = a;
+ anchor = TQString::null;
+ if ( widget && wt && wt->dict ) {
+ TQWhatsThisPrivate::WhatsThisItem * i = wt->dict->tqfind( widget );
+ if ( i && i->whatsthis && !i->whatsthis->clicked( href ) )
+ return;
+ }
+ }
+#endif
+ hide();
+}
+
+void TQWhatsThat::mouseMoveEvent( TQMouseEvent* e)
+{
+#ifndef TQT_NO_RICHTEXT
+#ifndef TQT_NO_CURSOR
+ if ( !doc )
+ return;
+ TQString a = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin ) );
+ if ( !a.isEmpty() )
+ setCursor( Qt::PointingHandCursor );
+ else
+ setCursor( Qt::ArrowCursor );
+#endif
+#endif
+}
+
+
+void TQWhatsThat::keyPressEvent( TQKeyEvent* )
+{
+ hide();
+}
+
+
+
+void TQWhatsThat::paintEvent( TQPaintEvent* )
+{
+ bool drawShadow = TRUE;
+#if defined(TQ_WS_WIN)
+ if ( (qWinVersion()&WV_NT_based) > WV_2000 ) {
+ BOOL shadow;
+ SystemParametersInfo( SPI_GETDROPSHADOW, 0, &shadow, 0 );
+ drawShadow = !shadow;
+ }
+#elif defined(TQ_WS_MACX)
+ drawShadow = FALSE; //never draw it on OS X we get it for free
+#endif
+
+ TQRect r = rect();
+ if ( drawShadow )
+ r.addCoords( 0, 0, -shadowWidth, -shadowWidth );
+ TQPainter p( this);
+ p.setPen( tqcolorGroup().foreground() );
+ p.drawRect( r );
+ p.setPen( tqcolorGroup().mid() );
+ p.setBrush( tqcolorGroup().brush( TQColorGroup::Background ) );
+ int w = r.width();
+ int h = r.height();
+ p.drawRect( 1, 1, w-2, h-2 );
+ if ( drawShadow ) {
+ p.setPen( tqcolorGroup().shadow() );
+ p.drawPoint( w + 5, 6 );
+ p.drawLine( w + 3, 6, w + 5, 8 );
+ p.drawLine( w + 1, 6, w + 5, 10 );
+ int i;
+ for( i=7; i < h; i += 2 )
+ p.drawLine( w, i, w + 5, i + 5 );
+ for( i = w - i + h; i > 6; i -= 2 )
+ p.drawLine( i, h, i + 5, h + 5 );
+ for( ; i > 0 ; i -= 2 )
+ p.drawLine( 6, h + 6 - i, i + 5, h + 5 );
+ }
+ p.setPen( tqcolorGroup().foreground() );
+ r.addCoords( hMargin, vMargin, -hMargin, -vMargin );
+
+#ifndef TQT_NO_RICHTEXT
+ if ( doc ) {
+ doc->draw( &p, r.x(), r.y(), r, tqcolorGroup(), 0 );
+ }
+ else
+#endif
+ {
+ p.drawText( r, TQt::AlignAuto + TQt::AlignTop + TQt::WordBreak + TQt::ExpandTabs, text );
+ }
+}
+
+// the item
+TQWhatsThisPrivate::WhatsThisItem::~WhatsThisItem()
+{
+ if ( count )
+ qFatal( "TQWhatsThis: Internal error (%d)", count );
+ delete whatsthis;
+}
+
+
+static const char * const button_image[] = {
+"16 16 3 1",
+" c None",
+"o c #000000",
+"a c #000080",
+"o aaaaa ",
+"oo aaa aaa ",
+"ooo aaa aaa",
+"oooo aa aa",
+"ooooo aa aa",
+"oooooo a aaa",
+"ooooooo aaa ",
+"oooooooo aaa ",
+"ooooooooo aaa ",
+"ooooo aaa ",
+"oo ooo ",
+"o ooo aaa ",
+" ooo aaa ",
+" ooo ",
+" ooo ",
+" ooo "};
+
+// the button class
+TQWhatsThisButton::TQWhatsThisButton( TQWidget * tqparent, const char * name )
+ : TQToolButton( tqparent, name )
+{
+ TQPixmap p( (const char**)button_image );
+ setPixmap( p );
+ setToggleButton( TRUE );
+ setAutoRaise( TRUE );
+ setFocusPolicy( Qt::NoFocus );
+ setTextLabel( tr( "What's this?" ) );
+ wt->buttons->insert( (void *)this, this );
+ connect( this, TQT_SIGNAL( released() ),
+ this, TQT_SLOT( mouseReleased() ) );
+}
+
+
+TQWhatsThisButton::~TQWhatsThisButton()
+{
+ if ( wt && wt->buttons )
+ wt->buttons->take( (void *)this );
+}
+
+
+void TQWhatsThisButton::mouseReleased()
+{
+ if ( wt->state == TQWhatsThisPrivate::Inactive && isOn() ) {
+ TQWhatsThisPrivate::setUpWhatsThis();
+#ifndef TQT_NO_CURSOR
+ TQApplication::setOverrideCursor( Qt::WhatsThisCursor, FALSE );
+#endif
+ wt->state = TQWhatsThisPrivate::Waiting;
+ tqApp->installEventFilter( wt );
+ }
+}
+
+static void qWhatsThisPrivateCleanup()
+{
+ if( wt ) {
+ delete wt;
+ wt = 0;
+ }
+}
+
+// the what's this manager class
+TQWhatsThisPrivate::TQWhatsThisPrivate()
+ : TQObject( 0, "global what's this object" )
+{
+ whatsThat = 0;
+ dict = new TQPtrDict<TQWhatsThisPrivate::WhatsThisItem>;
+ tlw = new TQPtrDict<TQWidget>;
+ wt = this;
+ buttons = new TQPtrDict<TQWhatsThisButton>;
+ state = Inactive;
+}
+
+TQWhatsThisPrivate::~TQWhatsThisPrivate()
+{
+#ifndef TQT_NO_CURSOR
+ if ( state == Waiting && tqApp )
+ TQApplication::restoreOverrideCursor();
+#endif
+ // the two straight-and-simple dicts
+ delete tlw;
+ delete buttons;
+
+ // then delete the complex one.
+ TQPtrDictIterator<WhatsThisItem> it( *dict );
+ WhatsThisItem * i;
+ TQWidget * w;
+ while( (i=it.current()) != 0 ) {
+ w = (TQWidget *)it.currentKey();
+ ++it;
+ dict->take( w );
+ if ( i->deref() )
+ delete i;
+ }
+ delete dict;
+ if ( whatsThat && !whatsThat->parentWidget() ) {
+ delete whatsThat;
+ }
+ // and finally lose wt
+ wt = 0;
+}
+
+bool TQWhatsThisPrivate::eventFilter( TQObject * o, TQEvent * e )
+{
+ switch( state ) {
+ case Waiting:
+ if ( e->type() == TQEvent::MouseButtonPress && o->isWidgetType() ) {
+ TQWidget * w = (TQWidget *) o;
+ if ( ( (TQMouseEvent*)e)->button() == Qt::RightButton )
+ return FALSE; // ignore RMB
+ if ( w->customWhatsThis() )
+ return FALSE;
+ TQWhatsThisPrivate::WhatsThisItem * i = 0;
+ TQMouseEvent* me = (TQMouseEvent*) e;
+ TQPoint p = me->pos();
+ while( w && !i ) {
+ i = dict->tqfind( w );
+ if ( !i ) {
+ p += w->pos();
+ w = w->parentWidget( TRUE );
+ }
+ }
+ leaveWhatsThisMode();
+ if (!i ) {
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpEnd );
+#endif
+ return TRUE;
+ }
+ if ( i->whatsthis )
+ say( w, i->whatsthis->text( p ), me->globalPos() );
+ else
+ say( w, i->s, me->globalPos() );
+ return TRUE;
+ } else if ( e->type() == TQEvent::MouseButtonRelease ) {
+ if ( ( (TQMouseEvent*)e)->button() == Qt::RightButton )
+ return FALSE; // ignore RMB
+ return !o->isWidgetType() || !((TQWidget*)o)->customWhatsThis();
+ } else if ( e->type() == TQEvent::MouseMove ) {
+ return !o->isWidgetType() || !((TQWidget*)o)->customWhatsThis();
+ } else if ( e->type() == TQEvent::KeyPress ) {
+ TQKeyEvent* kev = (TQKeyEvent*)e;
+
+ if ( kev->key() == Key_Escape ) {
+ leaveWhatsThisMode();
+ return TRUE;
+ } else if ( o->isWidgetType() && ((TQWidget*)o)->customWhatsThis() ) {
+ return FALSE;
+ } else if ( kev->key() == TQt::Key_Menu ||
+ ( kev->key() == TQt::Key_F10 &&
+ kev->state() == ShiftButton ) ) {
+ // we don't react to these keys, they are used for context menus
+ return FALSE;
+ } else if ( kev->state() == kev->stateAfter() &&
+ kev->key() != TQt::Key_Meta ) { // not a modifier key
+ leaveWhatsThisMode();
+ }
+ } else if ( e->type() == TQEvent::MouseButtonDblClick ) {
+ return TRUE;
+ }
+ break;
+ case Inactive:
+ if ( e->type() == TQEvent::Accel &&
+ ((TQKeyEvent *)e)->key() == TQt::Key_F1 &&
+ o->isWidgetType() &&
+ ((TQKeyEvent *)e)->state() == ShiftButton ) {
+ TQWidget * w = ((TQWidget *)o)->tqfocusWidget();
+ if ( !w )
+ break;
+ TQString s = TQWhatsThis::textFor( w, TQPoint(0,0), TRUE );
+ if ( !s.isNull() ) {
+ say ( w, s, w->mapToGlobal( w->rect().center() ) );
+ ((TQKeyEvent *)e)->accept();
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+
+
+void TQWhatsThisPrivate::setUpWhatsThis()
+{
+ if ( !wt ) {
+ wt = new TQWhatsThisPrivate();
+
+ // It is necessary to use a post routine, because
+ // the destructor deletes pixmaps and other stuff that
+ // needs a working X connection under X11.
+ qAddPostRoutine( qWhatsThisPrivateCleanup );
+ }
+}
+
+
+void TQWhatsThisPrivate::enterWhatsThisMode()
+{
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpStart );
+#endif
+}
+
+
+void TQWhatsThisPrivate::leaveWhatsThisMode()
+{
+ if ( state == Waiting ) {
+ TQPtrDictIterator<TQWhatsThisButton> it( *(wt->buttons) );
+ TQWhatsThisButton * b;
+ while( (b=it.current()) != 0 ) {
+ ++it;
+ b->setOn( FALSE );
+ }
+#ifndef TQT_NO_CURSOR
+ TQApplication::restoreOverrideCursor();
+#endif
+ state = Inactive;
+ tqApp->removeEventFilter( this );
+ }
+}
+
+
+
+void TQWhatsThisPrivate::say( TQWidget * widget, const TQString &text, const TQPoint& ppos)
+{
+ if ( text.isEmpty() )
+ return;
+ // make a fresh widget, and set it up
+ delete whatsThat;
+ whatsThat = new TQWhatsThat(
+ widget, text,
+#if defined(TQ_WS_X11)
+ TQT_TQWIDGET(TQApplication::desktop()->screen( widget ?
+ widget->x11Screen() :
+ TQCursor::x11Screen()) ),
+#else
+ 0,
+#endif
+ "automatic what's this? widget" );
+
+
+ // okay, now to tqfind a suitable location
+
+ int scr = ( widget ?
+ TQApplication::desktop()->screenNumber( widget ) :
+#if defined(TQ_WS_X11)
+ TQCursor::x11Screen()
+#else
+ TQApplication::desktop()->screenNumber( ppos )
+#endif // TQ_WS_X11
+ );
+ TQRect screen = TQApplication::desktop()->screenGeometry( scr );
+
+ int x;
+ int w = whatsThat->width();
+ int h = whatsThat->height();
+ int sx = screen.x();
+ int sy = screen.y();
+
+ // first try locating the widget immediately above/below,
+ // with nice tqalignment if possible.
+ TQPoint pos;
+ if ( widget )
+ pos = widget->mapToGlobal( TQPoint( 0,0 ) );
+
+ if ( widget && w > widget->width() + 16 )
+ x = pos.x() + widget->width()/2 - w/2;
+ else
+ x = ppos.x() - w/2;
+
+ // squeeze it in if that would result in part of what's this
+ // being only partially visible
+ if ( x + w + shadowWidth > sx+screen.width() )
+ x = (widget? (TQMIN(screen.width(),
+ pos.x() + widget->width())
+ ) : screen.width() )
+ - w;
+
+ if ( x < sx )
+ x = sx;
+
+ int y;
+ if ( widget && h > widget->height() + 16 ) {
+ y = pos.y() + widget->height() + 2; // below, two pixels spacing
+ // what's this is above or below, wherever there's most space
+ if ( y + h + 10 > sy+screen.height() )
+ y = pos.y() + 2 - shadowWidth - h; // above, overlap
+ }
+ y = ppos.y() + 2;
+
+ // squeeze it in if that would result in part of what's this
+ // being only partially visible
+ if ( y + h + shadowWidth > sy+screen.height() )
+ y = ( widget ? (TQMIN(screen.height(),
+ pos.y() + widget->height())
+ ) : screen.height() )
+ - h;
+ if ( y < sy )
+ y = sy;
+
+ whatsThat->move( x, y );
+ whatsThat->show();
+}
+
+TQWhatsThisPrivate::WhatsThisItem* TQWhatsThisPrivate::newItem( TQWidget * widget )
+{
+ WhatsThisItem * i = dict->tqfind( (void *)widget );
+ if ( i )
+ TQWhatsThis::remove( widget );
+ i = new WhatsThisItem;
+ dict->insert( (void *)widget, i );
+ TQWidget * t = widget->tqtopLevelWidget();
+ if ( !tlw->tqfind( (void *)t ) ) {
+ tlw->insert( (void *)t, t );
+ t->installEventFilter( this );
+ }
+ connect( widget, TQT_SIGNAL(destroyed()), this, TQT_SLOT(cleanupWidget()) );
+ return i;
+}
+
+void TQWhatsThisPrivate::add( TQWidget * widget, TQWhatsThis* special )
+{
+ newItem( widget )->whatsthis = special;
+}
+
+void TQWhatsThisPrivate::add( TQWidget * widget, const TQString &text )
+{
+ newItem( widget )->s = text;
+}
+
+
+// and finally the What's This class itself
+
+/*!
+ Adds \a text as "What's this" help for \a widget. If the text is
+ rich text formatted (i.e. it tqcontains markup) it will be rendered
+ with the default stylesheet TQStyleSheet::defaultSheet().
+
+ The text is destroyed if the widget is later destroyed, so it need
+ not be explicitly removed.
+
+ \sa remove()
+*/
+void TQWhatsThis::add( TQWidget * widget, const TQString &text )
+{
+ if ( text.isEmpty() )
+ return; // pointless
+ TQWhatsThisPrivate::setUpWhatsThis();
+ wt->add(widget,text);
+}
+
+
+/*!
+ Removes the "What's this?" help associated with the \a widget.
+ This happens automatically if the widget is destroyed.
+
+ \sa add()
+*/
+void TQWhatsThis::remove( TQWidget * widget )
+{
+ TQWhatsThisPrivate::setUpWhatsThis();
+ TQWhatsThisPrivate::WhatsThisItem * i = wt->dict->tqfind( (void *)widget );
+ if ( !i )
+ return;
+
+ wt->dict->take( (void *)widget );
+
+ i->deref();
+ if ( !i->count )
+ delete i;
+}
+
+
+/*!
+ Returns the what's this text for widget \a w or TQString::null if
+ there is no "What's this?" help for the widget. \a pos tqcontains
+ the mouse position; this is useful, for example, if you've
+ subclassed to make the text that is displayed position dependent.
+
+ If \a includeParents is TRUE, tqparent widgets are taken into
+ consideration as well when looking for what's this help text.
+
+ \sa add()
+*/
+TQString TQWhatsThis::textFor( TQWidget * w, const TQPoint& pos, bool includeParents )
+{
+ TQWhatsThisPrivate::setUpWhatsThis();
+ TQWhatsThisPrivate::WhatsThisItem * i = 0;
+ TQPoint p = pos;
+ while( w && !i ) {
+ i = wt->dict->tqfind( w );
+ if ( !includeParents )
+ break;
+ if ( !i ) {
+ p += w->pos();
+ w = w->parentWidget( TRUE );
+ }
+ }
+ if (!i)
+ return TQString::null;
+ if ( i->whatsthis )
+ return i->whatsthis->text( p );
+ return i->s;
+}
+
+
+/*!
+ Creates a TQToolButton preconfigured to enter "What's this?" mode
+ when clicked. You will often use this with a tool bar as \a
+ tqparent:
+ \code
+ (void) TQWhatsThis::whatsThisButton( my_help_tool_bar );
+ \endcode
+*/
+TQToolButton * TQWhatsThis::whatsThisButton( TQWidget * tqparent )
+{
+ TQWhatsThisPrivate::setUpWhatsThis();
+ return new TQWhatsThisButton( tqparent,
+ "automatic what's this? button" );
+}
+
+/*!
+ Constructs a dynamic "What's this?" object for \a widget. The
+ object is deleted when the \a widget is destroyed.
+
+ When the widget is queried by the user the text() function of this
+ TQWhatsThis will be called to provide the appropriate text, rather
+ than using the text assigned by add().
+*/
+TQWhatsThis::TQWhatsThis( TQWidget * widget)
+{
+ TQWhatsThisPrivate::setUpWhatsThis();
+ wt->add(widget,this);
+}
+
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+TQWhatsThis::~TQWhatsThis()
+{
+}
+
+
+/*!
+ This virtual function returns the text for position \e p in the
+ widget that this "What's this?" object documents. If there is no
+ "What's this?" text for the position, TQString::null is returned.
+
+ The default implementation returns TQString::null.
+*/
+TQString TQWhatsThis::text( const TQPoint & )
+{
+ return TQString::null;
+}
+
+/*!
+ \fn bool TQWhatsThis::clicked( const TQString& href )
+
+ This virtual function is called when the user clicks inside the
+ "What's this?" window. \a href is the link the user clicked on, or
+ TQString::null if there was no link.
+
+ If the function returns TRUE (the default), the "What's this?"
+ window is closed, otherwise it remains visible.
+
+ The default implementation ignores \a href and returns TRUE.
+*/
+bool TQWhatsThis::clicked( const TQString& )
+{
+ return TRUE;
+}
+
+
+/*!
+ Enters "What's this?" mode and returns immediately.
+
+ TQt will install a special cursor and take over mouse input until
+ the user clicks somewhere. It then shows any help available and
+ ends "What's this?" mode. Finally, TQt removes the special cursor
+ and help window and then restores ordinary event processing, at
+ which point the left mouse button is no longer pressed.
+
+ The user can also use the Esc key to leave "What's this?" mode.
+
+ \sa inWhatsThisMode(), leaveWhatsThisMode()
+*/
+
+void TQWhatsThis::enterWhatsThisMode()
+{
+ TQWhatsThisPrivate::setUpWhatsThis();
+ if ( wt->state == TQWhatsThisPrivate::Inactive ) {
+ wt->enterWhatsThisMode();
+#ifndef TQT_NO_CURSOR
+ TQApplication::setOverrideCursor( Qt::WhatsThisCursor, FALSE );
+#endif
+ wt->state = TQWhatsThisPrivate::Waiting;
+ tqApp->installEventFilter( wt );
+ }
+}
+
+
+/*!
+ Returns TRUE if the application is in "What's this?" mode;
+ otherwise returns FALSE.
+
+ \sa enterWhatsThisMode(), leaveWhatsThisMode()
+*/
+bool TQWhatsThis::inWhatsThisMode()
+{
+ if (!wt)
+ return FALSE;
+ return wt->state == TQWhatsThisPrivate::Waiting;
+}
+
+
+/*!
+ Leaves "What's this?" question mode.
+
+ This function is used internally by widgets that support
+ TQWidget::customWhatsThis(); applications do not usually call it.
+ An example of such a widget is TQPopupMenu: menus still work
+ normally in "What's this?" mode but also provide help texts for
+ individual menu items.
+
+ If \a text is not TQString::null, a "What's this?" help window is
+ displayed at the global screen position \a pos. If widget \a w is
+ not 0 and has its own dedicated TQWhatsThis object, this object
+ will receive clicked() messages when the user clicks on hyperlinks
+ inside the help text.
+
+ \sa inWhatsThisMode(), enterWhatsThisMode(), TQWhatsThis::clicked()
+*/
+void TQWhatsThis::leaveWhatsThisMode( const TQString& text, const TQPoint& pos, TQWidget* w )
+{
+ if ( !inWhatsThisMode() )
+ return;
+
+ wt->leaveWhatsThisMode();
+ if ( !text.isNull() )
+ wt->say( w, text, pos );
+}
+
+/*!
+ Display \a text in a help window at the global screen position \a
+ pos.
+
+ If widget \a w is not 0 and has its own dedicated TQWhatsThis
+ object, this object will receive clicked() messages when the user
+ clicks on hyperlinks inside the help text.
+
+ \sa TQWhatsThis::clicked()
+*/
+void TQWhatsThis::display( const TQString& text, const TQPoint& pos, TQWidget* w )
+{
+ if ( inWhatsThisMode() ) {
+ leaveWhatsThisMode( text, pos, w );
+ return;
+ }
+ TQWhatsThisPrivate::setUpWhatsThis();
+ wt->say( w, text, pos );
+}
+
+/*!
+ Sets the font for all "What's this?" helps to \a font.
+*/
+void TQWhatsThis::setFont( const TQFont &font )
+{
+ TQApplication::tqsetFont( font, TRUE, "TQWhatsThat" );
+}
+
+#include "tqwhatsthis.tqmoc"
+#endif