File indexing completed on 2025-02-16 13:11:35
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2002 Matthias Hölzer-Klüpfel <mhk@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef KACCELERATORMANAGER_PRIVATE_H 0009 #define KACCELERATORMANAGER_PRIVATE_H 0010 0011 #include <QObject> 0012 #include <QString> 0013 #include <QVector> 0014 0015 class QStackedWidget; 0016 class QMenu; 0017 class QMenuBar; 0018 class QTabBar; 0019 class QDockWidget; 0020 0021 /** 0022 * A string class handling accelerators. 0023 * 0024 * This class contains a string and knowledge about accelerators. 0025 * It keeps a list weights, telling how valuable each character 0026 * would be as an accelerator. 0027 * 0028 * @author Matthias Hölzer-Klüpfel <mhk@kde.org> 0029 */ 0030 0031 class KAccelString 0032 { 0033 public: 0034 KAccelString() 0035 : m_pureText() 0036 , m_accel(-1) 0037 , m_orig_accel(-1) 0038 { 0039 } 0040 explicit KAccelString(const QString &input, int initalWeight = -1); 0041 0042 void calculateWeights(int initialWeight); 0043 0044 const QString &pure() const 0045 { 0046 return m_pureText; 0047 } 0048 QString accelerated() const; 0049 0050 int accel() const 0051 { 0052 return m_accel; 0053 } 0054 void setAccel(int accel) 0055 { 0056 m_accel = accel; 0057 } 0058 0059 int originalAccel() const 0060 { 0061 return m_orig_accel; 0062 } 0063 QString originalText() const 0064 { 0065 return m_origText; 0066 } 0067 0068 QChar accelerator() const; 0069 0070 int maxWeight(int &index, const QString &used) const; 0071 0072 bool operator==(const KAccelString &c) const 0073 { 0074 return m_pureText == c.m_pureText && m_accel == c.m_accel && m_orig_accel == c.m_orig_accel; 0075 } 0076 0077 private: 0078 int stripAccelerator(QString &input); 0079 0080 void dump(); 0081 0082 QString m_pureText; 0083 QString m_origText; 0084 int m_accel; 0085 int m_orig_accel; 0086 QVector<int> m_weight; 0087 }; 0088 0089 Q_DECLARE_TYPEINFO(KAccelString, Q_MOVABLE_TYPE); 0090 0091 typedef QList<KAccelString> KAccelStringList; 0092 0093 /** 0094 * This class encapsulates the algorithm finding the 'best' 0095 * distribution of accelerators in a hierarchy of widgets. 0096 * 0097 * @author Matthias Hölzer-Klüpfel <mhk@kde.org> 0098 */ 0099 0100 class KAccelManagerAlgorithm 0101 { 0102 public: 0103 enum { 0104 // Default control weight 0105 DEFAULT_WEIGHT = 50, 0106 // Additional weight for first character in string 0107 FIRST_CHARACTER_EXTRA_WEIGHT = 50, 0108 // Additional weight for the beginning of a word 0109 WORD_BEGINNING_EXTRA_WEIGHT = 50, 0110 // Additional weight for the dialog buttons (large, we basically never want these reassigned) 0111 DIALOG_BUTTON_EXTRA_WEIGHT = 300, 0112 // Additional weight for a 'wanted' accelerator 0113 WANTED_ACCEL_EXTRA_WEIGHT = 150, 0114 // Default weight for an 'action' widget (ie, pushbuttons) 0115 ACTION_ELEMENT_WEIGHT = 50, 0116 // Default weight for group boxes (lowest priority) 0117 GROUP_BOX_WEIGHT = -2000, 0118 // Default weight for checkable group boxes (low priority) 0119 CHECKABLE_GROUP_BOX_WEIGHT = 20, 0120 // Default weight for menu titles 0121 MENU_TITLE_WEIGHT = 250, 0122 // Additional weight for KDE standard accelerators 0123 STANDARD_ACCEL = 300, 0124 }; 0125 0126 static void findAccelerators(KAccelStringList &result, QString &used); 0127 }; 0128 0129 /** 0130 * This class manages a popup menu. It will notice if entries have been 0131 * added or changed, and will recalculate the accelerators accordingly. 0132 * 0133 * This is necessary for dynamic menus like for example in kicker. 0134 * 0135 * @author Matthias Hölzer-Klüpfel <mhk@kde.org> 0136 */ 0137 0138 class KPopupAccelManager : public QObject 0139 { 0140 Q_OBJECT 0141 0142 public: 0143 static void manage(QMenu *popup); 0144 0145 protected: 0146 KPopupAccelManager(QMenu *popup); 0147 0148 private Q_SLOTS: 0149 0150 void aboutToShow(); 0151 0152 private: 0153 void calculateAccelerators(); 0154 0155 void findMenuEntries(KAccelStringList &list); 0156 void setMenuEntries(const KAccelStringList &list); 0157 0158 QMenu *m_popup; 0159 KAccelStringList m_entries; 0160 int m_count; 0161 }; 0162 0163 class QWidgetStackAccelManager : public QObject 0164 { 0165 Q_OBJECT 0166 0167 public: 0168 static void manage(QStackedWidget *popup); 0169 0170 protected: 0171 QWidgetStackAccelManager(QStackedWidget *popup); 0172 0173 private Q_SLOTS: 0174 0175 void currentChanged(int child); 0176 bool eventFilter(QObject *watched, QEvent *e) override; 0177 0178 private: 0179 void calculateAccelerators(); 0180 0181 QStackedWidget *m_stack; 0182 KAccelStringList m_entries; 0183 }; 0184 0185 /********************************************************************* 0186 0187 class KAcceleratorManagerPrivate - internal helper class 0188 0189 This class does all the work to find accelerators for a hierarchy of 0190 widgets. 0191 0192 *********************************************************************/ 0193 0194 class KAcceleratorManagerPrivate 0195 { 0196 public: 0197 static void manage(QWidget *widget); 0198 static bool programmers_mode; 0199 static void addStandardActionNames(const QStringList &strList); 0200 static bool standardName(const QString &str); 0201 0202 static bool checkChange(const KAccelString &as) 0203 { 0204 QString t2 = as.accelerated(); 0205 QString t1 = as.originalText(); 0206 if (t1 != t2) { 0207 if (as.accel() == -1) { 0208 removed_string += QLatin1String("<tr><td>") + t1.toHtmlEscaped() + QLatin1String("</td></tr>"); 0209 } else if (as.originalAccel() == -1) { 0210 added_string += QLatin1String("<tr><td>") + t2.toHtmlEscaped() + QLatin1String("</td></tr>"); 0211 } else { 0212 changed_string += QLatin1String("<tr><td>") + t1.toHtmlEscaped() + QLatin1String("</td>"); 0213 changed_string += QLatin1String("<td>") + t2.toHtmlEscaped() + QLatin1String("</td></tr>"); 0214 } 0215 return true; 0216 } 0217 return false; 0218 } 0219 static QString changed_string; 0220 static QString added_string; 0221 static QString removed_string; 0222 static QMap<QWidget *, int> ignored_widgets; 0223 static QStringList standardNames; 0224 0225 private: 0226 class Item; 0227 0228 public: 0229 typedef QList<Item *> ItemList; 0230 0231 private: 0232 static void traverseChildren(QWidget *widget, Item *item, QString &used); 0233 0234 static void manageWidget(QWidget *widget, Item *item, QString &used); 0235 static void manageMenuBar(QMenuBar *mbar, Item *item); 0236 static void manageTabBar(QTabBar *bar, Item *item); 0237 static void manageDockWidget(QDockWidget *dock, Item *item); 0238 0239 static void calculateAccelerators(Item *item, QString &used); 0240 0241 class Item 0242 { 0243 public: 0244 Item() 0245 : m_widget(nullptr) 0246 , m_children(nullptr) 0247 , m_index(-1) 0248 { 0249 } 0250 ~Item(); 0251 0252 Item(const Item &) = delete; 0253 Item &operator=(const Item &) = delete; 0254 0255 void addChild(Item *item); 0256 0257 QWidget *m_widget; 0258 KAccelString m_content; 0259 ItemList *m_children; 0260 int m_index; 0261 }; 0262 }; 0263 0264 #endif // KACCELERATORMANAGER_PRIVATE_H