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