1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2002 Matthias Hölzer-Klüpfel <mhk@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#ifndef KACCELERATORMANAGER_PRIVATE_H
9#define KACCELERATORMANAGER_PRIVATE_H
10
11#include <QList>
12#include <QObject>
13#include <QString>
14
15class QStackedWidget;
16class QMenu;
17class QMenuBar;
18class QTabBar;
19class QDockWidget;
20
21/*!
22 * \internal
23 * A string class handling accelerators.
24 *
25 * This class contains a string and knowledge about accelerators.
26 * It keeps a list weights, telling how valuable each character
27 * would be as an accelerator.
28 */
29class KAccelString
30{
31public:
32 KAccelString()
33 : m_pureText()
34 , m_accel(-1)
35 , m_orig_accel(-1)
36 {
37 }
38 explicit KAccelString(const QString &input, int initalWeight = -1);
39
40 void calculateWeights(int initialWeight);
41
42 const QString &pure() const
43 {
44 return m_pureText;
45 }
46 QString accelerated() const;
47
48 int accel() const
49 {
50 return m_accel;
51 }
52 void setAccel(int accel)
53 {
54 m_accel = accel;
55 }
56
57 int originalAccel() const
58 {
59 return m_orig_accel;
60 }
61 QString originalText() const
62 {
63 return m_origText;
64 }
65
66 QChar accelerator() const;
67
68 int maxWeight(int &index, const QString &used) const;
69
70 bool operator==(const KAccelString &c) const
71 {
72 return m_pureText == c.m_pureText && m_accel == c.m_accel && m_orig_accel == c.m_orig_accel;
73 }
74
75private:
76 int stripAccelerator(QString &input);
77
78 void dump();
79
80 QString m_pureText;
81 QString m_origText;
82 int m_accel;
83 int m_orig_accel;
84 QList<int> m_weight;
85};
86
87Q_DECLARE_TYPEINFO(KAccelString, Q_RELOCATABLE_TYPE);
88
89typedef QList<KAccelString> KAccelStringList;
90
91/*!
92 * \internal
93 * This class encapsulates the algorithm finding the 'best'
94 * distribution of accelerators in a hierarchy of widgets.
95 */
96class KAccelManagerAlgorithm
97{
98public:
99 enum {
100 // Default control weight
101 DEFAULT_WEIGHT = 50,
102 // Additional weight for first character in string
103 FIRST_CHARACTER_EXTRA_WEIGHT = 50,
104 // Additional weight for the beginning of a word
105 WORD_BEGINNING_EXTRA_WEIGHT = 50,
106 // Additional weight for the dialog buttons (large, we basically never want these reassigned)
107 DIALOG_BUTTON_EXTRA_WEIGHT = 300,
108 // Additional weight for a 'wanted' accelerator
109 WANTED_ACCEL_EXTRA_WEIGHT = 150,
110 // Default weight for an 'action' widget (ie, pushbuttons)
111 ACTION_ELEMENT_WEIGHT = 50,
112 // Default weight for group boxes (lowest priority)
113 GROUP_BOX_WEIGHT = -2000,
114 // Default weight for checkable group boxes (low priority)
115 CHECKABLE_GROUP_BOX_WEIGHT = 20,
116 // Default weight for menu titles
117 MENU_TITLE_WEIGHT = 250,
118 // Additional weight for KDE standard accelerators
119 STANDARD_ACCEL = 300,
120 };
121
122 static void findAccelerators(KAccelStringList &result, QString &used);
123};
124
125/*!
126 * \internal
127 * This class manages a popup menu. It will notice if entries have been
128 * added or changed, and will recalculate the accelerators accordingly.
129 *
130 * This is necessary for dynamic menus like for example in kicker.
131 */
132class KPopupAccelManager : public QObject
133{
134 Q_OBJECT
135
136public:
137 static void manage(QMenu *popup);
138
139protected:
140 KPopupAccelManager(QMenu *popup);
141
142private Q_SLOTS:
143
144 void aboutToShow();
145
146private:
147 void calculateAccelerators();
148
149 void findMenuEntries(KAccelStringList &list);
150 void setMenuEntries(const KAccelStringList &list);
151
152 QMenu *m_popup;
153 KAccelStringList m_entries;
154 int m_count;
155};
156
157class QWidgetStackAccelManager : public QObject
158{
159 Q_OBJECT
160
161public:
162 static void manage(QStackedWidget *popup);
163
164protected:
165 QWidgetStackAccelManager(QStackedWidget *popup);
166
167private Q_SLOTS:
168
169 void currentChanged(int child);
170 bool eventFilter(QObject *watched, QEvent *e) override;
171
172private:
173 void calculateAccelerators();
174
175 QStackedWidget *m_stack;
176 KAccelStringList m_entries;
177};
178
179/*********************************************************************
180
181 class KAcceleratorManagerPrivate - internal helper class
182
183 This class does all the work to find accelerators for a hierarchy of
184 widgets.
185
186 *********************************************************************/
187
188class KAcceleratorManagerPrivate
189{
190public:
191 static void manage(QWidget *widget);
192 static bool programmers_mode;
193 static void addStandardActionNames(const QStringList &strList);
194 static bool standardName(const QString &str);
195
196 static bool checkChange(const KAccelString &as)
197 {
198 QString t2 = as.accelerated();
199 QString t1 = as.originalText();
200 if (t1 != t2) {
201 if (as.accel() == -1) {
202 removed_string += QLatin1String("<tr><td>") + t1.toHtmlEscaped() + QLatin1String("</td></tr>");
203 } else if (as.originalAccel() == -1) {
204 added_string += QLatin1String("<tr><td>") + t2.toHtmlEscaped() + QLatin1String("</td></tr>");
205 } else {
206 changed_string += QLatin1String("<tr><td>") + t1.toHtmlEscaped() + QLatin1String("</td>");
207 changed_string += QLatin1String("<td>") + t2.toHtmlEscaped() + QLatin1String("</td></tr>");
208 }
209 return true;
210 }
211 return false;
212 }
213 static QString changed_string;
214 static QString added_string;
215 static QString removed_string;
216 static QMap<QWidget *, int> ignored_widgets;
217 static QStringList standardNames;
218
219private:
220 class Item;
221
222public:
223 typedef QList<Item *> ItemList;
224
225private:
226 static void traverseChildren(QWidget *widget, Item *item, QString &used);
227
228 static void manageWidget(QWidget *widget, Item *item, QString &used);
229 static void manageMenuBar(QMenuBar *mbar, Item *item);
230 static void manageTabBar(QTabBar *bar, Item *item);
231 static void manageDockWidget(QDockWidget *dock, Item *item);
232
233 static void calculateAccelerators(Item *item, QString &used);
234
235 class Item
236 {
237 public:
238 Item()
239 : m_widget(nullptr)
240 , m_children(nullptr)
241 , m_index(-1)
242 {
243 }
244 ~Item();
245
246 Item(const Item &) = delete;
247 Item &operator=(const Item &) = delete;
248
249 void addChild(Item *item);
250
251 QWidget *m_widget;
252 KAccelString m_content;
253 ItemList *m_children;
254 int m_index;
255 };
256};
257
258#endif // KACCELERATORMANAGER_PRIVATE_H
259

source code of kwidgetsaddons/src/kacceleratormanager_p.h