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

source code of kxmlgui/src/ktooltiphelper_p.h