8#include <private/qguiapplication_p.h>
20#include <qpa/qplatformtheme.h>
21#include "private/qtextdocumentlayout_p.h"
23#if QT_CONFIG(accessibility)
24#include "qaccessible.h"
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
134 if (
const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
135 return theme->themeHint(QPlatformTheme::DropShadow).toBool();
140 : QWidget(parent, Qt::Popup),
141 widget(showTextFor), pressed(
false), text(txt)
145 setAttribute(Qt::WA_DeleteOnClose,
true);
146 setAttribute(Qt::WA_NoSystemBackground,
true);
148 setPalette(parent->palette());
149 setMouseTracking(
true);
150 setFocusPolicy(Qt::StrongFocus);
152 setCursor(Qt::ArrowCursor);
157 if (Qt::mightBeRichText(text)) {
158 doc =
new QTextDocument();
159 doc->setUndoRedoEnabled(
false);
160 doc->setDefaultFont(QApplication::font(
this));
161#ifdef QT_NO_TEXTHTMLPARSER
162 doc->setPlainText(text);
166 doc->setUndoRedoEnabled(
false);
170 r.setSize(doc->size().toSize());
174 int sw = QGuiApplication::primaryScreen()->virtualGeometry().width() / 3;
180 r = fontMetrics().boundingRect(0, 0, sw, 1000,
181 Qt::AlignLeft | Qt::AlignTop
182 | Qt::TextWordWrap | Qt::TextExpandTabs,
199 if (e->button() == Qt::LeftButton && rect().contains(e->position().toPoint())) {
201 anchor = doc->documentLayout()->anchorAt(e->position().toPoint() - QPoint(hMargin, vMargin));
211 if (widget && e->button() == Qt::LeftButton && doc && rect().contains(e->position().toPoint())) {
212 QString a = doc->documentLayout()->anchorAt(e->position().toPoint() - QPoint(hMargin, vMargin));
217 if (!href.isEmpty()) {
218 QWhatsThisClickedEvent e(href);
219 if (QCoreApplication::sendEvent(widget, &e))
233 QString a = doc->documentLayout()->anchorAt(e->position().toPoint() - QPoint(hMargin, vMargin));
235 setCursor(Qt::PointingHandCursor);
237 setCursor(Qt::ArrowCursor);
251 r.adjust(0, 0, -1, -1);
255 p.setPen(QPen(palette().toolTipText(), 0));
256 p.setBrush(palette().toolTipBase());
260 p.setPen(palette().brush(QPalette::Dark).color());
261 p.drawRect(1, 1, w-2, h-2);
263 p.setPen(palette().shadow().color());
264 p.drawPoint(w + 5, 6);
265 p.drawLine(w + 3, 6, w + 5, 8);
266 p.drawLine(w + 1, 6, w + 5, 10);
268 for(i=7; i < h; i += 2)
269 p.drawLine(w, i, w + 5, i + 5);
270 for(i = w - i + h; i > 6; i -= 2)
271 p.drawLine(i, h, i + 5, h + 5);
272 for(; i > 0 ; i -= 2)
273 p.drawLine(6, h + 6 - i, i + 5, h + 5);
275 r.adjust(0, 0, 1, 1);
276 p.setPen(palette().toolTipText().color());
280 p.translate(r.x(), r.y());
282 rect.translate(-r.x(), -r.y());
284 QAbstractTextDocumentLayout::PaintContext context;
285 context.palette.setBrush(QPalette::Text, context.palette.toolTipText());
286 doc->documentLayout()->draw(&p, context);
290 p.drawText(r, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap | Qt::TextExpandTabs, text);
326 static void say(
QWidget *,
const QString &,
int x = 0,
int y = 0);
333 const QWidgetList toplevels = QApplication::topLevelWidgets();
334 for (
auto *w : toplevels)
335 QCoreApplication::sendEvent(w, e);
344 qApp->installEventFilter(
this);
346 QPoint pos = QCursor::pos();
347 if (
QWidget *w = QApplication::widgetAt(pos)) {
348 QHelpEvent e(QEvent::QueryWhatsThis, w->mapFromGlobal(pos), pos);
349 const bool sentEvent = QCoreApplication::sendEvent(w, &e);
353 QGuiApplication::setOverrideCursor((!sentEvent || !e.isAccepted())?
354 Qt::ForbiddenCursor:Qt::WhatsThisCursor);
356 QGuiApplication::setOverrideCursor(
Qt::WhatsThisCursor);
359#if QT_CONFIG(accessibility)
360 QAccessibleEvent event(
this, QAccessible::ContextHelpStart);
361 QAccessible::updateAccessibility(&event);
369 action->setChecked(
false);
372 QGuiApplication::restoreOverrideCursor();
374#if QT_CONFIG(accessibility)
375 QAccessibleEvent event(
this, QAccessible::ContextHelpEnd);
376 QAccessible::updateAccessibility(&event);
383 if (!o->isWidgetType())
386 bool customWhatsThis = w->testAttribute(Qt::WA_CustomWhatsThis);
388 case QEvent::MouseButtonPress:
390 QMouseEvent *me =
static_cast<QMouseEvent*>(e);
391 if (me->button() == Qt::RightButton || customWhatsThis)
393 QHelpEvent e(QEvent::WhatsThis, me->position().toPoint(), me->globalPosition().toPoint());
394 if (!QCoreApplication::sendEvent(w, &e) || !e.isAccepted())
399 case QEvent::MouseMove:
401 QMouseEvent *me =
static_cast<QMouseEvent*>(e);
402 QHelpEvent e(QEvent::QueryWhatsThis, me->position().toPoint(), me->globalPosition().toPoint());
403 const bool sentEvent = QCoreApplication::sendEvent(w, &e);
407 QGuiApplication::changeOverrideCursor((!sentEvent || !e.isAccepted())?
408 Qt::ForbiddenCursor:Qt::WhatsThisCursor);
412 case QEvent::MouseButtonRelease:
413 case QEvent::MouseButtonDblClick:
414 if (leaveOnMouseRelease && e->type() == QEvent::MouseButtonRelease)
415 QWhatsThis::leaveWhatsThisMode();
416 if (
static_cast<QMouseEvent*>(e)->button() == Qt::RightButton || customWhatsThis)
419 case QEvent::KeyPress:
421 QKeyEvent *kev =
static_cast<QKeyEvent *>(e);
422#if QT_CONFIG(shortcut)
423 if (kev->matches(QKeySequence::Cancel)) {
424 QWhatsThis::leaveWhatsThisMode();
428 if (customWhatsThis) {
430 }
else if (kev->key() == Qt::Key_Menu ||
431 (kev->key() == Qt::Key_F10 &&
432 kev->modifiers() == Qt::ShiftModifier)) {
435 }
else if (kev->key() != Qt::Key_Shift && kev->key() != Qt::Key_Alt
436 && kev->key() != Qt::Key_Control && kev->key() != Qt::Key_Meta) {
437 QWhatsThis::leaveWhatsThisMode();
447class QWhatsThisAction:
public QAction
452 explicit QWhatsThisAction(QObject* parent =
nullptr);
455 void actionTriggered();
458QWhatsThisAction::QWhatsThisAction(QObject *parent) : QAction(tr(
"What's This?"), parent)
460#ifndef QT_NO_IMAGEFORMAT_XPM
461 QPixmap p(button_image);
465 connect(
this, &QWhatsThisAction::triggered,
this, &QWhatsThisAction::actionTriggered);
466#ifndef QT_NO_SHORTCUT
467 setShortcut(Qt::ShiftModifier | Qt::Key_F1);
471void QWhatsThisAction::actionTriggered()
474 QWhatsThis::enterWhatsThisMode();
475 QWhatsThisPrivate::instance->action =
this;
481
482
483
484
485
486
487
488
489
490
491void QWhatsThis::enterWhatsThisMode()
493 if (QWhatsThisPrivate::instance)
495 (
void)
new QWhatsThisPrivate;
496 QEvent e(QEvent::EnterWhatsThisMode);
497 QWhatsThisPrivate::notifyToplevels(&e);
501
502
503
504
505
506bool QWhatsThis::inWhatsThisMode()
508 return (QWhatsThisPrivate::instance !=
nullptr);
512
513
514
515
516
517
518
519
520void QWhatsThis::leaveWhatsThisMode()
522 delete QWhatsThisPrivate::instance;
523 QEvent e(QEvent::LeaveWhatsThisMode);
524 QWhatsThisPrivate::notifyToplevels(&e);
529 if (text.size() == 0)
535 QScreen *screen = widget ? widget->screen()
536 : QGuiApplication::screenAt(QPoint(x, y));
538 screen = QGuiApplication::primaryScreen();
539 QRect screenRect = screen->geometry();
541 int w = whatsThat->width();
542 int h = whatsThat->height();
543 int sx = screenRect.x();
544 int sy = screenRect.y();
550 pos = widget->mapToGlobal(QPoint(0,0));
552 if (widget && w > widget->width() + 16)
553 x = pos.x() + widget->width()/2 - w/2;
560 x = (widget ? qMin(screenRect.width(), pos.x() + widget->width())
561 : screenRect.width())
568 if (widget && h > widget->height() + 16) {
569 y = pos.y() + widget->height() + 2;
571 if (y + h + 10 > sy + screenRect.height())
578 if (y + h +
shadowWidth > sy + screenRect.height()) {
579 y = (widget ? qMin(screenRect.height(), pos.y() + widget->height())
580 : screenRect.height())
586 whatsThat->move(x, y);
588 whatsThat->grabKeyboard();
592
593
594
595
596
597
598void QWhatsThis::showText(
const QPoint &pos,
const QString &text, QWidget *w)
600 leaveWhatsThisMode();
601 QWhatsThisPrivate::say(w, text, pos.x(), pos.y());
605
606
607
608
609void QWhatsThis::hideText()
611 delete QWhatsThat::instance;
615
616
617
618
619
620
622QAction *QWhatsThis::createAction(QObject *parent)
624 return new QWhatsThisAction(parent);
630#include "qwhatsthis.moc"
The QHelpEvent class provides an event that is used to request helpful information about a particular...
\inmodule QtCore\reentrant
void keyPressEvent(QKeyEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive key press events f...
void mouseReleaseEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse release even...
void mouseMoveEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse move events ...
void mousePressEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
void paintEvent(QPaintEvent *) override
This event handler can be reimplemented in a subclass to receive paint events passed in event.
static QWhatsThat * instance
static void say(QWidget *, const QString &, int x=0, int y=0)
static QWhatsThisPrivate * instance
static void notifyToplevels(QEvent *e)
bool eventFilter(QObject *, QEvent *) override
Filters events if this object has been installed as an event filter for the watched object.
static const char *const button_image[]