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_P_H
9#define KTOOLTIPHELPER_P_H
10
11#include <qobject.h>
12
13#include <QPointer>
14#include <QRect>
15#include <QTimer>
16
17class KToolTipHelper;
18
19class QAction;
20class QHelpEvent;
21class QMenu;
22
23/*!
24 * \brief The private class of KToolTipHelper used for the PIMPL idiom.
25 * \inmodule KXmlGui
26 * \internal
27 */
28class KToolTipHelperPrivate : public QObject
29{
30 Q_OBJECT
31
32public:
33 /*!
34 * \brief Singleton implementation for KToolTipHelper and
35 * NOT of this class (KToolTipHelperPrivate).
36 */
37 static KToolTipHelper *instance();
38
39 explicit KToolTipHelperPrivate(KToolTipHelper *qq);
40
41 ~KToolTipHelperPrivate() override;
42
43 /*! \sa KToolTipHelper::eventFilter() */
44 bool eventFilter(QObject *watched, QEvent *event) override;
45
46 /*! \sa KToolTipHelper::whatsThisHintOnly() */
47 static const QString whatsThisHintOnly();
48
49 /*!
50 * \brief Makes sure submenus that show up do not mess with tooltips appearing in menus.
51 *
52 * This is somewhat of a workaround for Qt not posting QEvent::ToolTips when the
53 * cursor wasn't moved *after* a submenu hides.
54 *
55 * Returns false.
56 */
57 bool handleHideEvent(QObject *watched, QEvent *event);
58
59 /*!
60 * \brief Returns \c true if the key press is used to
61 * expand a tooltip, \c false otherwise.
62 */
63 bool handleKeyPressEvent(QEvent *event);
64
65 /*!
66 * Is called from handleToolTipEvent() to handle a QEvent::ToolTip in a menu.
67 * This method will show the tooltip of the action that is hovered at a nice
68 * position.
69 *
70 * \a menu The menu that a tooltip is requested for.
71 *
72 * \a helpEvent The QEvent::ToolTip that was cast to a QHelpEvent.
73 */
74 bool handleMenuToolTipEvent(QMenu *menu, QHelpEvent *helpEvent);
75
76 /*!
77 * \brief Returns \c false if no special handling of the tooltip event
78 * seems necessary, \c true otherwise.
79 *
80 * \a watched The object that is receiving the QHelpEvent.
81 *
82 * \a helpEvent The QEvent::ToolTip that was cast to a QHelpEvent.
83 */
84 bool handleToolTipEvent(QObject *watched, QHelpEvent *helpEvent);
85
86 /*!
87 * \brief Handles links being clicked in whatsThis.
88 *
89 * Returns true.
90 */
91 bool handleWhatsThisClickedEvent(QEvent *event);
92
93 /*!
94 * \brief The name is slightly misleading because it will only post events for QMenus.
95 * \sa handleHideEvent()
96 */
97 void postToolTipEventIfCursorDidntMove() const;
98
99 /*!
100 * \brief Shows a tooltip that contains a whatsThisHint
101 * at the location \a globalPos.
102 *
103 * If \a tooltip is empty, only a whatsThisHint is shown.
104 *
105 * The parameter usage is identical to that of QToolTip::showText. The only difference
106 * is that this method doesn't need a QWidget *w parameter because that one is already
107 * retrieved in handleToolTipEvent() prior to calling this method.
108 *
109 * \sa QToolTip::showText()
110 */
111 void showExpandableToolTip(const QPoint &globalPos, const QString &toolTip = QString(), const QRect &rect = QRect());
112
113public:
114 KToolTipHelper *const q;
115
116private:
117 /*! \brief An action in a menu a tooltip was requested for. */
118 QPointer<QAction> m_action;
119 /*!
120 * \brief The global position where the last tooltip
121 * that had a whatsThisHint was displayed.
122 */
123 QPoint m_lastExpandableToolTipGlobalPos;
124 /*! \brief The last widget a QEvent::tooltip was sent for. */
125 QPointer<QWidget> m_widget;
126 /*! \brief Whether or not the last tooltip was expandable. */
127 bool m_lastToolTipWasExpandable = false;
128
129 /*!
130 * \brief The global position of where the cursor was when the last
131 * QEvent::HideEvent for a menu occurred.
132 *
133 * \sa handleHideEvent() */
134 QPoint m_cursorGlobalPosWhenLastMenuHid;
135 /*!
136 * \brief Calls postToolTipEventIfCursorDidntMove().
137 * \sa handleHideEvent()
138 */
139 QTimer m_toolTipTimeout;
140
141 static KToolTipHelper *s_instance;
142};
143
144/*
145 * This method checks if string "a" is sufficiently different
146 * from string "b", barring characters like periods, ampersands
147 * and other characters.
148 *
149 * Used for determining if tooltips are different from their icon name counterparts.
150 *
151 * Returns true if the string "a" is similar to "b" and false otherwise.
152 */
153bool isTextSimilar(const QString &a, const QString &b);
154
155#endif // KTOOLTIPHELPER_P_H
156

source code of kxmlgui/src/ktooltiphelper_p.h