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

source code of kwidgetsaddons/src/kacceleratormanager_p.h