File indexing completed on 2024-02-18 15:07:26

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2021 Felix Ernst <fe.a.ernst@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-2-Clause
0006 */
0007 
0008 #ifndef KTOOLTIPHELPER_H
0009 #define KTOOLTIPHELPER_H
0010 
0011 #include <kxmlgui_export.h>
0012 
0013 #include <QObject>
0014 
0015 #include <memory>
0016 
0017 class KToolTipHelperPrivate;
0018 
0019 /**
0020  * @class KToolTipHelper ktooltiphelper.h KToolTipHelper
0021  *
0022  * @short An event filter used to enhance tooltips
0023  *
0024  * Example:
0025  * Without this class, a tooltip of a QToolButton of a "New" action will read something like
0026  * "New File". Using this class, the tooltip can be enhanced to read something like
0027  * "New File (Ctrl+N)" and in the next line smaller "Press Shift for help.".
0028  * Pressing Shift will open the "What's This" context help for that widget. If a hyperlink in
0029  * that help is clicked, the corresponding event will also be filtered by this class and open
0030  * the linked location.
0031  *
0032  * The extra text added to tooltips is only shown when available and where it makes sense. If a
0033  * QToolButton has no associated shortcut and an empty QWidget::whatsThis(), this class won't
0034  * tamper with the requested tooltip at all.
0035  *
0036  * This class also activates tooltips for actions in QMenus but only when it makes sense like when
0037  * the tooltip isn't equal to the already displayed text.
0038  *
0039  * If you want the "Press Shift for help." line to be displayed for a widget that has whatsThis()
0040  * but no toolTip() take a look at KToolTipHelper::whatsThisHintOnly().
0041  *
0042  * The enhanced tooltips can be enabled at any time after the QApplication was constructed with
0043  * \code
0044  * qApp->installEventFilter(KToolTipHelper::instance());
0045  * \endcode
0046  * Therefore, to de-activate them you can call
0047  * \code
0048  * qApp->removeEventFilter(KToolTipHelper::instance());
0049  * \endcode
0050  * any time later.
0051  *
0052  * If you want KToolTipHelper to not tamper with certain QEvents, e.g. you want to handle some
0053  * tooltips differently or you want to change what happens when a QWhatsThisClickedEvent is
0054  * processed, first remove KToolTipHelper as an event filter just like in the line of code above.
0055  * Then create your own custom EventFilter that handles those QEvents differently and for all
0056  * cases that you don't want to handle differently call
0057  * \code
0058  * return KToolTipHelper::instance()->eventFilter(watched, event);
0059  * \endcode
0060  *
0061  * KMainWindow will have this EventFilter installed by default from framework version 5.84 onward
0062  * so if you want to opt out of that, remove the EventFilter in the constructor of your MainWindow
0063  * class inheriting from KMainWindow.
0064  *
0065  * @see QToolTip
0066  * @since 5.84
0067  */
0068 class KXMLGUI_EXPORT KToolTipHelper : public QObject
0069 {
0070     Q_OBJECT
0071     Q_DISABLE_COPY(KToolTipHelper)
0072 
0073 public:
0074     static KToolTipHelper *instance();
0075 
0076     /**
0077      * Filters QEvent::ToolTip if an enhanced tooltip is available for the widget.
0078      * Filters the QEvent::KeyPress that is used to expand an expandable tooltip.
0079      * Filters QEvent::WhatsThisClicked so hyperlinks in whatsThis() texts work.
0080      *
0081      * @see QObject::eventFilter()
0082      * @see QHelpEvent
0083      */
0084     virtual bool eventFilter(QObject *watched, QEvent *event) override;
0085 
0086     /**
0087      * Use this to have a widget show "Press Shift for help." as its tooltip.
0088      * \code
0089      * widget->setToolTip(KToolTipHelper::whatsThisHintOnly());
0090      * \endcode
0091      * KToolTipHelper won't show that tooltip if the widget's whatsThis() is empty.
0092      *
0093      * @return a QString that is interpreted by this class to show the expected tooltip.
0094      */
0095     static const QString whatsThisHintOnly();
0096 
0097 private:
0098     KXMLGUI_NO_EXPORT explicit KToolTipHelper(QObject *parent);
0099 
0100     KXMLGUI_NO_EXPORT ~KToolTipHelper() override;
0101 
0102 private:
0103     std::unique_ptr<KToolTipHelperPrivate> const d;
0104 
0105     friend class KToolTipHelperPrivate;
0106 };
0107 
0108 #endif // KTOOLTIPHELPER_H