diff options
Diffstat (limited to 'src/gui/kernel/qwhatsthis.cpp')
-rw-r--r-- | src/gui/kernel/qwhatsthis.cpp | 777 |
1 files changed, 0 insertions, 777 deletions
diff --git a/src/gui/kernel/qwhatsthis.cpp b/src/gui/kernel/qwhatsthis.cpp deleted file mode 100644 index 5e47ffa56b..0000000000 --- a/src/gui/kernel/qwhatsthis.cpp +++ /dev/null @@ -1,777 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwhatsthis.h" -#ifndef QT_NO_WHATSTHIS -#include "qpointer.h" -#include "qapplication.h" -#include "qdesktopwidget.h" -#include "qevent.h" -#include "qpixmap.h" -#include "qpainter.h" -#include "qtimer.h" -#include "qhash.h" -#include "qaction.h" -#include "qcursor.h" -#include "qbitmap.h" -#include "qtextdocument.h" -#include "../text/qtextdocumentlayout_p.h" -#include "qtoolbutton.h" -#include "qdebug.h" -#ifndef QT_NO_ACCESSIBILITY -#include "qaccessible.h" -#endif -#if defined(Q_WS_WIN) -#include "qt_windows.h" -#ifndef SPI_GETDROPSHADOW -#define SPI_GETDROPSHADOW 0x1024 -#endif -#endif -#if defined(Q_WS_X11) -#include "qx11info_x11.h" -#include <qwidget.h> -#endif - -QT_BEGIN_NAMESPACE - -/*! - \class QWhatsThis - \brief The QWhatsThis class provides a simple description of any - widget, i.e. answering the question "What's This?". - - \ingroup helpsystem - - - "What's This?" help is part of an application's online help - system, and provides users with information about the - functionality and usage of a particular widget. "What's This?" - help texts are typically longer and more detailed than \link - QToolTip tooltips\endlink, but generally provide less information - than that supplied by separate help windows. - - QWhatsThis provides a single window with an explanatory text that - pops up when the user asks "What's This?". The default way for - users to ask the question is to move the focus to 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 a shortcut for Shift+F1, this mechanism - will not work.) Some dialogs provide a "?" button that users can - click to enter "What's This?" mode; they then click the relevant - widget to pop up the "What's This?" window. It is also possible to - provide a a menu option or toolbar button to switch into "What's - This?" mode. - - To add "What's This?" text to a widget or an action, you simply - call QWidget::setWhatsThis() or QAction::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, making it possible to embed images in the displayed - text. To be as fast as possible, the default stylesheet uses a - simple method to determine whether the text can be rendered as - plain text. See Qt::mightBeRichText() for details. - - \snippet doc/src/snippets/whatsthis/whatsthis.cpp 0 - - An alternative way to enter "What's This?" mode is to call - createAction(), and add the returned QAction to either a menu or - a tool bar. By invoking this context help action (in the picture - below, the button with the arrow and question mark icon) 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 - - You can enter "What's This?" mode programmatically with - enterWhatsThisMode(), check the mode with inWhatsThisMode(), and - return to normal mode with leaveWhatsThisMode(). - - If you want to control the "What's This?" behavior of a widget - manually see Qt::WA_CustomWhatsThis. - - It is also possible to show different help texts for different - regions of a widget, by using a QHelpEvent of type - QEvent::WhatsThis. Intercept the help event in your widget's - QWidget::event() function and call QWhatsThis::showText() with the - text you want to display for the position specified in - QHelpEvent::pos(). If the text is rich text and the user clicks - on a link, the widget also receives a QWhatsThisClickedEvent with - the link's reference as QWhatsThisClickedEvent::href(). If a - QWhatsThisClickedEvent is handled (i.e. QWidget::event() returns - true), the help window remains visible. Call - QWhatsThis::hideText() to hide it explicitly. - - \sa QToolTip -*/ - -Q_CORE_EXPORT void qDeleteInEventHandler(QObject *o); - -class QWhatsThat : public QWidget -{ - Q_OBJECT - -public: - QWhatsThat(const QString& txt, QWidget* parent, QWidget *showTextFor); - ~QWhatsThat() ; - - static QWhatsThat *instance; - -protected: - void showEvent(QShowEvent *e); - void mousePressEvent(QMouseEvent*); - void mouseReleaseEvent(QMouseEvent*); - void mouseMoveEvent(QMouseEvent*); - void keyPressEvent(QKeyEvent*); - void paintEvent(QPaintEvent*); - -private: - QPointer<QWidget>widget; - bool pressed; - QString text; - QTextDocument* doc; - QString anchor; - QPixmap background; -}; - -QWhatsThat *QWhatsThat::instance = 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 -static const int vMargin = 8; -static const int hMargin = 12; - -QWhatsThat::QWhatsThat(const QString& txt, QWidget* parent, QWidget *showTextFor) - : QWidget(parent, Qt::Popup), - widget(showTextFor), pressed(false), text(txt) -{ - delete instance; - instance = this; - setAttribute(Qt::WA_DeleteOnClose, true); - setAttribute(Qt::WA_NoSystemBackground, true); - if (parent) - setPalette(parent->palette()); - setMouseTracking(true); - setFocusPolicy(Qt::StrongFocus); -#ifndef QT_NO_CURSOR - setCursor(Qt::ArrowCursor); -#endif - QRect r; - doc = 0; - ensurePolished(); // Ensures style sheet font before size calc - if (Qt::mightBeRichText(text)) { - doc = new QTextDocument(); - doc->setUndoRedoEnabled(false); - doc->setDefaultFont(QApplication::font(this)); -#ifdef QT_NO_TEXTHTMLPARSER - doc->setPlainText(text); -#else - doc->setHtml(text); -#endif - doc->setUndoRedoEnabled(false); - doc->adjustSize(); - r.setTop(0); - r.setLeft(0); - r.setSize(doc->size().toSize()); - } - else - { - int sw = QApplication::desktop()->width() / 3; - if (sw < 200) - sw = 200; - else if (sw > 300) - sw = 300; - - r = fontMetrics().boundingRect(0, 0, sw, 1000, - Qt::AlignLeft + Qt::AlignTop - + Qt::TextWordWrap + Qt::TextExpandTabs, - text); - } -#if defined(Q_WS_WIN) - if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) - { - BOOL shadow; - SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow, 0); - shadowWidth = shadow ? 0 : 6; - } -#endif - resize(r.width() + 2*hMargin + shadowWidth, r.height() + 2*vMargin + shadowWidth); -} - -QWhatsThat::~QWhatsThat() -{ - instance = 0; - if (doc) - delete doc; -} - -void QWhatsThat::showEvent(QShowEvent *) -{ - background = QPixmap::grabWindow(QApplication::desktop()->internalWinId(), - x(), y(), width(), height()); -} - -void QWhatsThat::mousePressEvent(QMouseEvent* e) -{ - pressed = true; - if (e->button() == Qt::LeftButton && rect().contains(e->pos())) { - if (doc) - anchor = doc->documentLayout()->anchorAt(e->pos() - QPoint(hMargin, vMargin)); - return; - } - close(); -} - -void QWhatsThat::mouseReleaseEvent(QMouseEvent* e) -{ - if (!pressed) - return; - if (widget && e->button() == Qt::LeftButton && doc && rect().contains(e->pos())) { - QString a = doc->documentLayout()->anchorAt(e->pos() - QPoint(hMargin, vMargin)); - QString href; - if (anchor == a) - href = a; - anchor.clear(); - if (!href.isEmpty()) { - QWhatsThisClickedEvent e(href); - if (QApplication::sendEvent(widget, &e)) - return; - } - } - close(); -} - -void QWhatsThat::mouseMoveEvent(QMouseEvent* e) -{ -#ifdef QT_NO_CURSOR - Q_UNUSED(e); -#else - if (!doc) - return; - QString a = doc->documentLayout()->anchorAt(e->pos() - QPoint(hMargin, vMargin)); - if (!a.isEmpty()) - setCursor(Qt::PointingHandCursor); - else - setCursor(Qt::ArrowCursor); -#endif -} - -void QWhatsThat::keyPressEvent(QKeyEvent*) -{ - close(); -} - -void QWhatsThat::paintEvent(QPaintEvent*) -{ - bool drawShadow = true; -#if defined(Q_WS_WIN) - if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) - { - BOOL shadow; - SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow, 0); - drawShadow = !shadow; - } -#elif defined(Q_WS_MAC) || defined(Q_WS_QWS) - drawShadow = false; // never draw it on OS X or QWS, as we get it for free -#endif - - QRect r = rect(); - r.adjust(0, 0, -1, -1); - if (drawShadow) - r.adjust(0, 0, -shadowWidth, -shadowWidth); - QPainter p(this); - p.drawPixmap(0, 0, background); - p.setPen(QPen(palette().toolTipText(), 0)); - p.setBrush(palette().toolTipBase()); - p.drawRect(r); - int w = r.width(); - int h = r.height(); - p.setPen(palette().brush(QPalette::Dark).color()); - p.drawRect(1, 1, w-2, h-2); - if (drawShadow) { - p.setPen(palette().shadow().color()); - 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); - } - r.adjust(0, 0, 1, 1); - p.setPen(palette().toolTipText().color()); - r.adjust(hMargin, vMargin, -hMargin, -vMargin); - - if (doc) { - p.translate(r.x(), r.y()); - QRect rect = r; - rect.translate(-r.x(), -r.y()); - p.setClipRect(rect); - QAbstractTextDocumentLayout::PaintContext context; - context.palette.setBrush(QPalette::Text, context.palette.toolTipText()); - doc->documentLayout()->draw(&p, context); - } - else - { - p.drawText(r, Qt::AlignLeft + Qt::AlignTop + Qt::TextWordWrap + Qt::TextExpandTabs, text); - } -} - -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 "}; - -class QWhatsThisPrivate : public QObject -{ - public: - QWhatsThisPrivate(); - ~QWhatsThisPrivate(); - static QWhatsThisPrivate *instance; - bool eventFilter(QObject *, QEvent *); - QPointer<QAction> action; -#ifdef QT3_SUPPORT - QPointer<QToolButton> button; -#endif - static void say(QWidget *, const QString &, int x = 0, int y = 0); - static void notifyToplevels(QEvent *e); - bool leaveOnMouseRelease; -}; - -void QWhatsThisPrivate::notifyToplevels(QEvent *e) -{ - QWidgetList toplevels = QApplication::topLevelWidgets(); - for (int i = 0; i < toplevels.count(); ++i) { - register QWidget *w = toplevels.at(i); - QApplication::sendEvent(w, e); - } -} - -QWhatsThisPrivate *QWhatsThisPrivate::instance = 0; - -QWhatsThisPrivate::QWhatsThisPrivate() - : leaveOnMouseRelease(false) -{ - instance = this; - qApp->installEventFilter(this); - - QPoint pos = QCursor::pos(); - if (QWidget *w = QApplication::widgetAt(pos)) { - QHelpEvent e(QEvent::QueryWhatsThis, w->mapFromGlobal(pos), pos); - bool sentEvent = QApplication::sendEvent(w, &e); -#ifdef QT_NO_CURSOR - Q_UNUSED(sentEvent); -#else - QApplication::setOverrideCursor((!sentEvent || !e.isAccepted())? - Qt::ForbiddenCursor:Qt::WhatsThisCursor); - } else { - QApplication::setOverrideCursor(Qt::WhatsThisCursor); -#endif - } -#ifndef QT_NO_ACCESSIBILITY - QAccessible::updateAccessibility(this, 0, QAccessible::ContextHelpStart); -#endif -} - -QWhatsThisPrivate::~QWhatsThisPrivate() -{ - if (action) - action->setChecked(false); -#ifdef QT3_SUPPORT - if (button) - button->setChecked(false); -#endif -#ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); -#endif -#ifndef QT_NO_ACCESSIBILITY - QAccessible::updateAccessibility(this, 0, QAccessible::ContextHelpEnd); -#endif - instance = 0; -} - -bool QWhatsThisPrivate::eventFilter(QObject *o, QEvent *e) -{ - if (!o->isWidgetType()) - return false; - QWidget * w = static_cast<QWidget *>(o); - bool customWhatsThis = w->testAttribute(Qt::WA_CustomWhatsThis); - switch (e->type()) { - case QEvent::MouseButtonPress: - { - QMouseEvent *me = static_cast<QMouseEvent*>(e); - if (me->button() == Qt::RightButton || customWhatsThis) - return false; - QHelpEvent e(QEvent::WhatsThis, me->pos(), me->globalPos()); - if (!QApplication::sendEvent(w, &e) || !e.isAccepted()) - leaveOnMouseRelease = true; - - } break; - - case QEvent::MouseMove: - { - QMouseEvent *me = static_cast<QMouseEvent*>(e); - QHelpEvent e(QEvent::QueryWhatsThis, me->pos(), me->globalPos()); - bool sentEvent = QApplication::sendEvent(w, &e); -#ifdef QT_NO_CURSOR - Q_UNUSED(sentEvent); -#else - QApplication::changeOverrideCursor((!sentEvent || !e.isAccepted())? - Qt::ForbiddenCursor:Qt::WhatsThisCursor); -#endif - } - // fall through - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - if (leaveOnMouseRelease && e->type() == QEvent::MouseButtonRelease) - QWhatsThis::leaveWhatsThisMode(); - if (static_cast<QMouseEvent*>(e)->button() == Qt::RightButton || customWhatsThis) - return false; // ignore RMB release - break; - case QEvent::KeyPress: - { - QKeyEvent* kev = (QKeyEvent*)e; - - if (kev->key() == Qt::Key_Escape) { - QWhatsThis::leaveWhatsThisMode(); - return true; - } else if (customWhatsThis) { - return false; - } else if (kev->key() == Qt::Key_Menu || - (kev->key() == Qt::Key_F10 && - kev->modifiers() == Qt::ShiftModifier)) { - // we don't react to these keys, they are used for context menus - return false; - } else if (kev->key() != Qt::Key_Shift && kev->key() != Qt::Key_Alt // not a modifier key - && kev->key() != Qt::Key_Control && kev->key() != Qt::Key_Meta) { - QWhatsThis::leaveWhatsThisMode(); - } - } break; - default: - return false; - } - return true; -} - -class QWhatsThisAction: public QAction -{ - Q_OBJECT - -public: - explicit QWhatsThisAction(QObject* parent = 0); - -private slots: - void actionTriggered(); -}; - -QWhatsThisAction::QWhatsThisAction(QObject *parent) : QAction(tr("What's This?"), parent) -{ -#ifndef QT_NO_IMAGEFORMAT_XPM - QPixmap p((const char**)button_image); - setIcon(p); -#endif - setCheckable(true); - connect(this, SIGNAL(triggered()), this, SLOT(actionTriggered())); -#ifndef QT_NO_SHORTCUT - setShortcut(Qt::ShiftModifier + Qt::Key_F1); -#endif -} - -void QWhatsThisAction::actionTriggered() -{ - if (isChecked()) { - QWhatsThis::enterWhatsThisMode(); - QWhatsThisPrivate::instance->action = this; - } -} - -QWhatsThis::QWhatsThis() -{ -} - -#ifdef QT3_SUPPORT -/*! - \obsolete - - Sets the What's This text \a s for the widget \a w. - - Use QWidget::setWhatsThis() or QAction::setWhatsThis() instead. -*/ -void QWhatsThis::add(QWidget *w, const QString &s) -{ - w->setWhatsThis(s); -} - -/*! - \obsolete - - Remove's the What's This text for the widget \a w. - - Use QWidget::setWhatsThis() or QAction::setWhatsThis() instead. -*/ -void QWhatsThis::remove(QWidget *w) -{ - w->setWhatsThis(QString()); -} - -class QWhatsThisButton : public QToolButton -{ - Q_OBJECT -public: - QWhatsThisButton(QWidget *p) : QToolButton(p) { - setCheckable(true); - QPixmap pix( const_cast<const char**>(button_image) ); - setIcon( pix ); - QObject::connect(this, SIGNAL(toggled(bool)), this, SLOT(whatToggled(bool))); - setAutoRaise(true); - setFocusPolicy(Qt::NoFocus); - } - -public slots: - void whatToggled(bool b) { - if (b) { - QWhatsThis::enterWhatsThisMode(); - QWhatsThisPrivate::instance->button = this; - } - } -}; - -/*! - Returns a new "What's This?" QToolButton with the given \a - parent. To do this now, create your own QToolButton and a - QWhatsThis object and call the QWhatsThis object's showText() - function when the QToolButton is invoked. - - Use createAction() instead. -*/ -QToolButton * QWhatsThis::whatsThisButton(QWidget * parent) -{ - return new QWhatsThisButton(parent); -} -#endif - -/*! - This function switches the user interface into "What's This?" - mode. The user interface can be switched back into normal mode by - the user (e.g. by them clicking or pressing Esc), or - programmatically by calling leaveWhatsThisMode(). - - When entering "What's This?" mode, a QEvent of type - Qt::EnterWhatsThisMode is sent to all toplevel widgets. - - \sa inWhatsThisMode() leaveWhatsThisMode() -*/ -void QWhatsThis::enterWhatsThisMode() -{ - if (QWhatsThisPrivate::instance) - return; - (void) new QWhatsThisPrivate; - QEvent e(QEvent::EnterWhatsThisMode); - QWhatsThisPrivate::notifyToplevels(&e); - } - -/*! - Returns true if the user interface is in "What's This?" mode; - otherwise returns false. - - \sa enterWhatsThisMode() -*/ -bool QWhatsThis::inWhatsThisMode() -{ - return (QWhatsThisPrivate::instance != 0); -} - -/*! - If the user interface is in "What's This?" mode, this function - switches back to normal mode; otherwise it does nothing. - - When leaving "What's This?" mode, a QEvent of type - Qt::LeaveWhatsThisMode is sent to all toplevel widgets. - - \sa enterWhatsThisMode() inWhatsThisMode() -*/ -void QWhatsThis::leaveWhatsThisMode() -{ - delete QWhatsThisPrivate::instance; - QEvent e(QEvent::LeaveWhatsThisMode); - QWhatsThisPrivate::notifyToplevels(&e); -} - -void QWhatsThisPrivate::say(QWidget * widget, const QString &text, int x, int y) -{ - if (text.size() == 0) - return; - // make a fresh widget, and set it up - QWhatsThat *whatsThat = new QWhatsThat( - text, -#if defined(Q_WS_X11) && !defined(QT_NO_CURSOR) - QApplication::desktop()->screen(widget ? widget->x11Info().screen() : QCursor::x11Screen()), -#else - 0, -#endif - widget - ); - - - // okay, now to find a suitable location - - int scr = (widget ? - QApplication::desktop()->screenNumber(widget) : -#if defined(Q_WS_X11) && !defined(QT_NO_CURSOR) - QCursor::x11Screen() -#else - QApplication::desktop()->screenNumber(QPoint(x,y)) -#endif // Q_WS_X11 - ); - QRect screen = QApplication::desktop()->screenGeometry(scr); - - 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 alignment if possible. - QPoint pos; - if (widget) - pos = widget->mapToGlobal(QPoint(0,0)); - - if (widget && w > widget->width() + 16) - x = pos.x() + widget->width()/2 - w/2; - else - x = 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? (qMin(screen.width(), - pos.x() + widget->width()) - ) : screen.width()) - - w; - - if (x < sx) - x = sx; - - 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 = 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 ? (qMin(screen.height(), - pos.y() + widget->height()) - ) : screen.height()) - - h; - if (y < sy) - y = sy; - - whatsThat->move(x, y); - whatsThat->show(); - whatsThat->grabKeyboard(); -} - -/*! - Shows \a text as a "What's This?" window, at global position \a - pos. The optional widget argument, \a w, is used to determine the - appropriate screen on multi-head systems. - - \sa hideText() -*/ -void QWhatsThis::showText(const QPoint &pos, const QString &text, QWidget *w) -{ - leaveWhatsThisMode(); - QWhatsThisPrivate::say(w, text, pos.x(), pos.y()); -} - -/*! - If a "What's This?" window is showing, this destroys it. - - \sa showText() -*/ -void QWhatsThis::hideText() -{ - qDeleteInEventHandler(QWhatsThat::instance); -} - -/*! - Returns a ready-made QAction, used to invoke "What's This?" context - help, with the given \a parent. - - The returned QAction provides a convenient way to let users enter - "What's This?" mode. -*/ -QAction *QWhatsThis::createAction(QObject *parent) -{ - return new QWhatsThisAction(parent); -} - -QT_END_NAMESPACE - -#include "qwhatsthis.moc" - -#endif // QT_NO_WHATSTHIS |