| 1 | /* |
| 2 | This file is part of the KDE project |
| 3 | SPDX-FileCopyrightText: 2021 Felix Ernst <fe.a.ernst@gmail.com> |
| 4 | |
| 5 | SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-2-Clause |
| 6 | */ |
| 7 | |
| 8 | #ifndef KTOOLTIPHELPER_H |
| 9 | #define KTOOLTIPHELPER_H |
| 10 | |
| 11 | #include <kxmlgui_export.h> |
| 12 | |
| 13 | #include <QObject> |
| 14 | |
| 15 | #include <memory> |
| 16 | |
| 17 | class KToolTipHelperPrivate; |
| 18 | |
| 19 | /*! |
| 20 | * \class KToolTipHelper |
| 21 | * \inmodule KXmlGui |
| 22 | * |
| 23 | * \brief An event filter used to enhance tooltips. |
| 24 | * |
| 25 | * Example: |
| 26 | * Without this class, a tooltip of a QToolButton of a "New" action will read something like |
| 27 | * "New File". Using this class, the tooltip can be enhanced to read something like |
| 28 | * "New File (Ctrl+N)" and in the next line smaller "Press Shift for help.". |
| 29 | * Pressing Shift will open the "What's This" context help for that widget. If a hyperlink in |
| 30 | * that help is clicked, the corresponding event will also be filtered by this class and open |
| 31 | * the linked location. |
| 32 | * |
| 33 | * The extra text added to tooltips is only shown when available and where it makes sense. If a |
| 34 | * QToolButton has no associated shortcut and an empty QWidget::whatsThis(), this class won't |
| 35 | * tamper with the requested tooltip at all. |
| 36 | * |
| 37 | * This class also activates tooltips for actions in QMenus but only when it makes sense like when |
| 38 | * the tooltip isn't equal to the already displayed text. |
| 39 | * |
| 40 | * If you want the "Press Shift for help." line to be displayed for a widget that has whatsThis() |
| 41 | * but no toolTip() take a look at KToolTipHelper::whatsThisHintOnly(). |
| 42 | * |
| 43 | * The enhanced tooltips can be enabled at any time after the QApplication was constructed with: |
| 44 | * |
| 45 | * \code |
| 46 | * qApp->installEventFilter(KToolTipHelper::instance()); |
| 47 | * \endcode |
| 48 | * |
| 49 | * Therefore, to de-activate them you can call the following any time later: |
| 50 | * |
| 51 | * \code |
| 52 | * qApp->removeEventFilter(KToolTipHelper::instance()); |
| 53 | * \endcode |
| 54 | * |
| 55 | * If you want KToolTipHelper to not tamper with certain QEvents, e.g. you want to handle some |
| 56 | * tooltips differently or you want to change what happens when a QWhatsThisClickedEvent is |
| 57 | * processed, first remove KToolTipHelper as an event filter just like in the line of code above. |
| 58 | * Then create your own custom EventFilter that handles those QEvents differently and, for all |
| 59 | * cases that you don't want to handle differently, call: |
| 60 | * \code |
| 61 | * return KToolTipHelper::instance()->eventFilter(watched, event); |
| 62 | * \endcode |
| 63 | * |
| 64 | * Since 5.84, KMainWindow installs this EventFilter by default. |
| 65 | * If you want to opt out of that, remove the EventFilter |
| 66 | * in the constructor of your MainWindow class inheriting from KMainWindow. |
| 67 | * |
| 68 | * \sa QToolTip |
| 69 | * \since 5.84 |
| 70 | */ |
| 71 | class KXMLGUI_EXPORT KToolTipHelper : public QObject |
| 72 | { |
| 73 | Q_OBJECT |
| 74 | Q_DISABLE_COPY(KToolTipHelper) |
| 75 | |
| 76 | public: |
| 77 | static KToolTipHelper *instance(); |
| 78 | |
| 79 | /*! |
| 80 | * \brief Filters the given \a event for a given \a watched object. |
| 81 | * |
| 82 | * Filters QEvent::ToolTip if an enhanced tooltip is available for the widget. |
| 83 | * Filters the QEvent::KeyPress that is used to expand an expandable tooltip. |
| 84 | * Filters QEvent::WhatsThisClicked so hyperlinks in whatsThis() texts work. |
| 85 | * |
| 86 | * \sa QObject::eventFilter() |
| 87 | * \sa QHelpEvent |
| 88 | */ |
| 89 | bool eventFilter(QObject *watched, QEvent *event) override; |
| 90 | |
| 91 | /*! |
| 92 | * \brief Use this to have a widget show "Press Shift for help." as its tooltip. |
| 93 | * |
| 94 | * Example usage: |
| 95 | * \code |
| 96 | * widget->setToolTip(KToolTipHelper::whatsThisHintOnly()); |
| 97 | * \endcode |
| 98 | * |
| 99 | * KToolTipHelper won't show that tooltip if the widget's whatsThis() is empty. |
| 100 | * |
| 101 | * Returns a QString that is interpreted by this class to show the expected tooltip. |
| 102 | */ |
| 103 | static const QString whatsThisHintOnly(); |
| 104 | |
| 105 | private: |
| 106 | KXMLGUI_NO_EXPORT explicit KToolTipHelper(QObject *parent); |
| 107 | |
| 108 | KXMLGUI_NO_EXPORT ~KToolTipHelper() override; |
| 109 | |
| 110 | private: |
| 111 | std::unique_ptr<KToolTipHelperPrivate> const d; |
| 112 | |
| 113 | friend class KToolTipHelperPrivate; |
| 114 | }; |
| 115 | |
| 116 | #endif // KTOOLTIPHELPER_H |
| 117 | |