1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
2 | // |
3 | // SPDX-License-Identifier: GPL-3.0-or-later |
4 | |
5 | #include "actionmanager.h" |
6 | #include "util/shortcututil.h" |
7 | #include "util/custompaths.h" |
8 | |
9 | #include <QAction> |
10 | #include <QDir> |
11 | |
12 | static ActionManager *kActionManagerInstance = nullptr; |
13 | |
14 | class ActionManagerPrivate final |
15 | { |
16 | public: |
17 | using IdCmdMap = QHash<QString, Action *>; |
18 | |
19 | ActionManagerPrivate(); |
20 | Action *addOverrideAction(QString id, QAction *action); |
21 | Action *removeOverrideAction(QString id); |
22 | Command *command(QString id); |
23 | QList<Command *> commands(); |
24 | |
25 | void addSetting(QString id, Action *action); |
26 | void removeSetting(QString id); |
27 | void saveAllSetting(); |
28 | void readUserSetting(); |
29 | |
30 | private: |
31 | IdCmdMap idCmdMap; |
32 | QString configFilePath; |
33 | }; |
34 | |
35 | ActionManagerPrivate::ActionManagerPrivate() |
36 | : configFilePath(CustomPaths::user(CustomPaths::Flags::Configures) + QDir::separator() + QString("shortcut.support" )) |
37 | { |
38 | |
39 | } |
40 | |
41 | Action *ActionManagerPrivate::addOverrideAction(QString id, QAction *action) |
42 | { |
43 | Action *a = idCmdMap.value(id, nullptr); |
44 | if (!a) { |
45 | a = new Action(id, action); |
46 | idCmdMap.insert(id, a); |
47 | } |
48 | |
49 | return a; |
50 | } |
51 | |
52 | Action *ActionManagerPrivate::removeOverrideAction(QString id) |
53 | { |
54 | Action *a = idCmdMap.value(id, nullptr); |
55 | if (a) { |
56 | idCmdMap.remove(id); |
57 | } |
58 | |
59 | return a; |
60 | } |
61 | |
62 | Command *ActionManagerPrivate::command(QString id) |
63 | { |
64 | return idCmdMap.value(id, nullptr); |
65 | } |
66 | |
67 | QList<Command *> ActionManagerPrivate::commands() |
68 | { |
69 | QList<Command *> result; |
70 | foreach (Command *cmd, idCmdMap) { |
71 | result << cmd; |
72 | } |
73 | |
74 | return result; |
75 | } |
76 | |
77 | void ActionManagerPrivate::addSetting(QString id, Action *action) |
78 | { |
79 | QString shortcut = action->keySequence().toString(); |
80 | QString description = action->description(); |
81 | |
82 | QMap<QString, QStringList> shortcutItemMap; |
83 | ShortcutUtil::readFromJson(configFilePath, shortcutItemMap); |
84 | QStringList valueList = {description, shortcut}; |
85 | shortcutItemMap[id] = valueList; |
86 | ShortcutUtil::writeToJson(configFilePath, shortcutItemMap); |
87 | } |
88 | |
89 | void ActionManagerPrivate::removeSetting(QString id) |
90 | { |
91 | QMap<QString, QStringList> shortcutItemMap; |
92 | ShortcutUtil::readFromJson(configFilePath, shortcutItemMap); |
93 | if (shortcutItemMap.contains(id)) { |
94 | shortcutItemMap.remove(id); |
95 | } |
96 | ShortcutUtil::writeToJson(configFilePath, shortcutItemMap); |
97 | } |
98 | |
99 | void ActionManagerPrivate::saveAllSetting() |
100 | { |
101 | QMap<QString, QStringList> shortcutItemMap; |
102 | IdCmdMap::const_iterator iter = idCmdMap.begin(); |
103 | for (; iter != idCmdMap.end(); ++iter) |
104 | { |
105 | QStringList valueList = {iter.value()->description(), iter.value()->keySequence().toString()}; |
106 | shortcutItemMap.insert(iter.key(), valueList); |
107 | } |
108 | |
109 | ShortcutUtil::writeToJson(configFilePath, shortcutItemMap); |
110 | } |
111 | |
112 | void ActionManagerPrivate::readUserSetting() |
113 | { |
114 | QMap<QString, QStringList> shortcutItemMap; |
115 | ShortcutUtil::readFromJson(configFilePath, shortcutItemMap); |
116 | |
117 | IdCmdMap::const_iterator iter = idCmdMap.begin(); |
118 | for (; iter != idCmdMap.end(); ++iter) |
119 | { |
120 | QString id = iter.key(); |
121 | if (shortcutItemMap.contains(id) && iter.value()->action()) { |
122 | QString shortcut = shortcutItemMap.value(id).last(); |
123 | iter.value()->action()->setShortcut(QKeySequence(shortcut)); |
124 | } |
125 | } |
126 | } |
127 | |
128 | ActionManager::ActionManager(QObject *parent) |
129 | : QObject(parent) |
130 | , d(new ActionManagerPrivate()) |
131 | { |
132 | |
133 | } |
134 | |
135 | ActionManager::~ActionManager() |
136 | { |
137 | if (d) { |
138 | delete d; |
139 | } |
140 | } |
141 | |
142 | ActionManager *ActionManager::getInstance() |
143 | { |
144 | if (!kActionManagerInstance) { |
145 | kActionManagerInstance = new ActionManager(); |
146 | } |
147 | return kActionManagerInstance; |
148 | } |
149 | |
150 | /*! |
151 | \fn Command *ActionManager::registerAction(QAction *action, const QString id, |
152 | const QString description, |
153 | const QKeySequence defaultShortcut) |
154 | |
155 | Makes an action known to the system under the specified action, id, description, default shortcut. |
156 | New a command and insert to map, set the keysequence and description to action, and save info to config file. |
157 | |
158 | Returns a Command instance that represents the action in the application |
159 | and is owned by the ActionManager. |
160 | |
161 | Usage: ActionManager::getInstance->registerAction(...); |
162 | */ |
163 | Command *ActionManager::registerAction(QAction *action, const QString &id, |
164 | const QString &description/* = nullptr*/, |
165 | const QKeySequence defaultShortcut/* = QKeySequence()*/, |
166 | const QString &iconFileName/* = nullptr*/) |
167 | { |
168 | if(!action || id.isEmpty()) |
169 | return nullptr; |
170 | |
171 | const QIcon icon = QIcon(iconFileName); |
172 | if (!icon.isNull()) |
173 | action->setIcon(icon); |
174 | |
175 | connect(action, &QAction::destroyed, [=] { |
176 | unregisterAction(id); |
177 | }); |
178 | |
179 | Action *a = d->addOverrideAction(id, action); |
180 | if (a) { |
181 | a->setKeySequence(defaultShortcut); |
182 | a->setDescription(description); |
183 | } |
184 | |
185 | return a; |
186 | } |
187 | |
188 | /*! |
189 | \fn void ActionManager::unregisterAction(QString id) |
190 | |
191 | Removes the knowledge about an action under the specified id. |
192 | Remove from map, set action shortcut to null, and save info to config file. |
193 | |
194 | Usage: ActionManager::getInstance->unregisterAction(...); |
195 | */ |
196 | void ActionManager::unregisterAction(QString id) |
197 | { |
198 | Action *a = d->removeOverrideAction(id); |
199 | if (a) { |
200 | a->setKeySequence(QKeySequence()); |
201 | } |
202 | } |
203 | |
204 | Command *ActionManager::command(QString id) |
205 | { |
206 | return d->command(id); |
207 | } |
208 | |
209 | QList<Command *> ActionManager::commands() |
210 | { |
211 | return d->commands(); |
212 | } |
213 | |
214 | void ActionManager::readUserSetting() |
215 | { |
216 | return d->readUserSetting(); |
217 | } |
218 | |
219 | void ActionManager::saveSetting() |
220 | { |
221 | return d->saveAllSetting(); |
222 | } |
223 | |
224 | |