?? qwhatsthis.cpp
字號:
/****************************************************************************** $Id: qt/src/widgets/qwhatsthis.cpp 2.3.12 edited 2005-10-27 $**** Implementation of QWhatsThis class**** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.**** This file is part of the widgets module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses may use this file in accordance with the Qt Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qwhatsthis.h"#ifndef QT_NO_WHATSTHIS#include "qapplication.h"#include "qpaintdevicemetrics.h"#include "qpixmap.h"#include "qpainter.h"#include "qtimer.h"#include "qptrdict.h"#include "qtoolbutton.h"#include "qshared.h"#include "qcursor.h"#include "qbitmap.h"#include "qtooltip.h"#include "qsimplerichtext.h"#include "qstylesheet.h"// REVISED: warwick/*! \class QWhatsThis qwhatsthis.h \brief The QWhatsThis class provides a simple description of any widget, e.g. answering the question "what's this?" \ingroup helpsystem <i>What's This</i> help is part of an application's <a href=helpsystem.html>online help systems</a>, offering users a level of detail between tool tips and full text browsing windows. QWhatsThis provides a single window with a single explanatory text, which pops up quickly when the user asks "what's this?", and goes away as soon as the user does something else. To assign <i>What's This?</i> text to a widget, you simply call QWhatsThis::add() for the widget. To assign text to a menu item, call QMenuData::setWhatsThis(), and for a global accelerator key, call QAccel::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 also possible to embed images. See QStyleSheet::defaultSheet() for details. By default, the user will be able to view the text for a widget by pressing Shift-F1 while the widget has focus. On window systems where a context help button is provided in the window decorations, that button enters <i>What's This?</i> mode. In this mode, if the user clicks on a widget, help will be given for the widget. The mode is left when help is given or when the user presses the Escape key. An alternative way to enter <i>What's This?</i> mode is to use the ready-made toolbar tool button from QWhatsThis::whatsThisButton(). If you are using QMainWindow, you can also use the QMainWindow::whatsThis() slot to invoke the mode from a menu item. <img src="whatsthis.png" width="284" height="246"> For more control, you can create a dedicated QWhatsThis object for a special widget. By subclassing and reimplementing QWhatsThis::text() it is possible to have different explanatory texts depending on the position of the mouse click. If your widget needs even more control, see QWidget::customWhatsThis(). To remove added text, you can use QWhatsThis::remove(), but since the text is automatically removed when the widget is destroyed, this is rarely needed. \sa QToolTip*/// a special buttonclass QWhatsThisButton: public QToolButton{ Q_OBJECTpublic: QWhatsThisButton( QWidget * parent, const char * name ); ~QWhatsThisButton();public slots: void mouseReleased();};class QWhatsThisPrivate: public QObject{ Q_OBJECTpublic: // an item for storing texts struct WhatsThisItem: public QShared { WhatsThisItem(): QShared() { whatsthis = 0; } ~WhatsThisItem(); QString s; QWhatsThis* whatsthis; }; // the (these days pretty small) state machine enum State { Inactive, Waiting }; QWhatsThisPrivate(); ~QWhatsThisPrivate(); bool eventFilter( QObject *, QEvent * ); WhatsThisItem* newItem( QWidget * widget ); void add( QWidget * widget, QWhatsThis* special ); void add( QWidget * widget, const QString& text ); // say it. void say( QWidget *, const QString&, const QPoint& ); void say_helper(QWidget*,const QPoint& ppos,bool); // setup and teardown static void tearDownWhatsThis(); static void setUpWhatsThis(); void leaveWhatsThisMode(); // variables QWidget * whatsThat; QPtrDict<WhatsThisItem> * dict; QPtrDict<QWidget> * tlw; QPtrDict<QWhatsThisButton> * buttons; State state;#ifndef QT_NO_CURSOR QCursor * cursor;#endif QString currentText;private slots: void cleanupWidget() { const QObject* o = sender(); if ( o->isWidgetType() ) // sanity QWhatsThis::remove((QWidget*)o); }};// static, but static the less-typing waystatic QWhatsThisPrivate * wt = 0;// the itemQWhatsThisPrivate::WhatsThisItem::~WhatsThisItem(){ if ( count ) qFatal( "Internal error #10%d in What's This", count );}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 "};#ifndef QT_NO_CURSOR#define cursor_bits_width 32#define cursor_bits_height 32static unsigned char cursor_bits_bits[] = { 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00, 0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00, 0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00, 0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00, 0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00, 0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };#define cursor_mask_width 32#define cursor_mask_height 32static unsigned char cursor_mask_bits[] = { 0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00, 0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00, 0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00, 0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00, 0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00, 0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };#endif// the button classQWhatsThisButton::QWhatsThisButton( QWidget * parent, const char * name ) : QToolButton( parent, name ){ QPixmap p( (const char **)button_image ); setPixmap( p ); setToggleButton( TRUE ); setAutoRaise( TRUE ); setFocusPolicy( NoFocus ); setTextLabel( tr( "What's this?" ) ); wt->buttons->insert( (void *)this, this ); connect( this, SIGNAL( released() ), this, SLOT( mouseReleased() ) );}QWhatsThisButton::~QWhatsThisButton(){ if ( wt && wt->buttons ) wt->buttons->take( (void *)this );}void QWhatsThisButton::mouseReleased(){ if ( wt->state == QWhatsThisPrivate::Inactive && isOn() ) { QWhatsThisPrivate::setUpWhatsThis();#ifndef QT_NO_CURSOR QApplication::setOverrideCursor( *wt->cursor, FALSE );#endif wt->state = QWhatsThisPrivate::Waiting; qApp->installEventFilter( wt ); }}// the what's this manager classQWhatsThisPrivate::QWhatsThisPrivate() : QObject( 0, "global what's this object" ){ qAddPostRoutine( tearDownWhatsThis ); whatsThat = 0; dict = new QPtrDict<QWhatsThisPrivate::WhatsThisItem>; tlw = new QPtrDict<QWidget>; wt = this; buttons = new QPtrDict<QWhatsThisButton>; state = Inactive;#ifndef QT_NO_CURSOR cursor = new QCursor( QBitmap( cursor_bits_width, cursor_bits_height, cursor_bits_bits, TRUE ), QBitmap( cursor_mask_width, cursor_mask_height, cursor_mask_bits, TRUE ), 1, 1 );#endif}QWhatsThisPrivate::~QWhatsThisPrivate(){#ifndef QT_NO_CURSOR if ( state == Waiting ) QApplication::restoreOverrideCursor();#endif // the two straight-and-simple dicts delete tlw; delete buttons; // then delete the complex one. QPtrDictIterator<WhatsThisItem> it( *dict ); WhatsThisItem * i; QWidget * w; while( (i=it.current()) != 0 ) { w = (QWidget *)it.currentKey(); ++it; dict->take( w ); i->deref(); if ( !i->count ) delete i; } delete dict;#ifndef QT_NO_CURSOR delete cursor;#endif delete whatsThat; // and finally lose wt wt = 0;}bool QWhatsThisPrivate::eventFilter( QObject * o, QEvent * e ){ if ( !o || !e ) return FALSE; if ( o == whatsThat ) { if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::KeyPress ) { whatsThat->hide(); return TRUE; }#ifdef _WS_QWS_ else if ( e->type() == QEvent::Paint ) { wt->say_helper(0,QPoint(0,0),FALSE); }#endif return FALSE; } switch( state ) { case Waiting: if ( e->type() == QEvent::MouseButtonPress && o->isWidgetType() ) { QWidget * w = (QWidget *) o; if ( ( (QMouseEvent*)e)->button() == RightButton ) return FALSE; // ignore RMB if ( w->customWhatsThis() ) return FALSE; QWhatsThisPrivate::WhatsThisItem * i = 0; while( w && !i ) { i = dict->find( w ); if ( !i ) w = w->parentWidget(); } leaveWhatsThisMode(); if (!i ) return TRUE; QPoint pos = ((QMouseEvent*)e)->pos(); if ( i->whatsthis ) say( w, i->whatsthis->text( pos ), w->mapToGlobal(pos) ); else say( w, i->s, w->mapToGlobal(pos) ); return TRUE; } else if ( e->type() == QEvent::MouseButtonRelease ) { if ( ( (QMouseEvent*)e)->button() == RightButton ) return FALSE; // ignore RMB return !o->isWidgetType() || !((QWidget*)o)->customWhatsThis(); } else if ( e->type() == QEvent::MouseMove ) { return !o->isWidgetType() || !((QWidget*)o)->customWhatsThis(); } else if ( e->type() == QEvent::KeyPress ) { QKeyEvent* kev = (QKeyEvent*)e; if (kev->key() == Qt::Key_Escape) { leaveWhatsThisMode(); return TRUE; } else if ( o->isWidgetType() && ((QWidget*)o)->customWhatsThis() ) return FALSE; else if ( kev->key() == Key_Menu || ( kev->key() == Key_F10 && kev->state() == ShiftButton ) ) return FALSE; // ignore these keys, they are used for context menus else if ( kev->state() == kev->stateAfter() && kev->key() != Key_Meta ) // not a modifier key leaveWhatsThisMode(); } else if ( e->type() == QEvent::MouseButtonDblClick ) { return TRUE; } break; case Inactive: if ( e->type() == QEvent::Accel && ((QKeyEvent *)e)->key() == Key_F1 && o->isWidgetType() && ((QKeyEvent *)e)->state() == ShiftButton ) { QWidget * w = ((QWidget *)o)->focusWidget(); QWhatsThisPrivate::WhatsThisItem *i = w ? dict->find(w) : 0; if ( i && !i->s.isNull() ) { if ( i->whatsthis ) say( w, i->whatsthis->text( QPoint(0,0) ), w->mapToGlobal( w->rect().center() ) ); else say( w, i->s, w->mapToGlobal( w->rect().center() )); ((QKeyEvent *)e)->accept(); return TRUE; } } break; } return FALSE;}void QWhatsThisPrivate::setUpWhatsThis(){ if ( !wt ) wt = new QWhatsThisPrivate();}void QWhatsThisPrivate::tearDownWhatsThis(){ delete wt; wt = 0;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -