1 /**
2 * SPDX-FileCopyrightText: 1999-2001 Lubos Lunak <l.lunak@kde.org>
3 * SPDX-FileCopyrightText: 2009 Michael Jansen <kde@michael-jansen.biz>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 **/
7
8 #include "settings_writer.h"
9
10 #include "action_data/action_data.h"
11 #include "action_data/action_data_group.h"
12 #include "action_data/generic_action_data.h"
13 #include "action_data/menuentry_shortcut_action_data.h"
14 #include "action_data/simple_action_data.h"
15
16 #include "conditions/conditions_list.h"
17
18 #include "windows_helper/window_selection_list.h"
19
20 #include <KConfig>
21 #include <KConfigGroup>
22 #include <QDebug>
23
24 namespace KHotKeys
25 {
26 const int CurrentFileVersion = 2;
27
SettingsWriter(const Settings * settings,ActionState state,const QString & id,bool allowMerging)28 SettingsWriter::SettingsWriter(const Settings *settings, ActionState state, const QString &id, bool allowMerging)
29 : _settings(settings)
30 , _state(state)
31 , _importId(id)
32 , _allowMerging(allowMerging)
33 , _export(false)
34 {
35 }
36
exportTo(const ActionDataBase * element,KConfigBase & config)37 void SettingsWriter::exportTo(const ActionDataBase *element, KConfigBase &config)
38 {
39 _export = true;
40
41 if (!element) {
42 Q_ASSERT(element);
43 return;
44 }
45
46 // Clean the file
47 QStringList groups = config.groupList();
48 Q_FOREACH (const QString &name, config.groupList()) {
49 config.deleteGroup(name);
50 }
51
52 KConfigGroup mainGroup(&config, "Main");
53 mainGroup.writeEntry("Version", CurrentFileVersion);
54 mainGroup.writeEntry("AllowMerge", _allowMerging);
55
56 if (!_importId.isEmpty())
57 mainGroup.writeEntry("ImportId", _importId);
58
59 // The root group contains nothing but the datacount!
60 KConfigGroup dataGroup(&config, "Data");
61 dataGroup.writeEntry("DataCount", 1);
62
63 // The group for the element to export
64 KConfigGroup data1Group(&config, "Data_1");
65 _stack.push(&data1Group);
66 element->accept(this);
67 _stack.pop();
68
69 _export = false;
70 }
71
visitActionData(const ActionData * data)72 void SettingsWriter::visitActionData(const ActionData *data)
73 {
74 visitActionDataBase(data);
75
76 KConfigGroup *config = _stack.top();
77
78 // Write triggers if available
79 if (data->triggers()) {
80 KConfigGroup triggersGroup(config->config(), config->name() + "Triggers");
81 data->triggers()->cfg_write(triggersGroup);
82 }
83
84 // Write actions if available
85 if (data->actions()) {
86 KConfigGroup actionsGroup(config->config(), config->name() + "Actions");
87 data->actions()->cfg_write(actionsGroup);
88 }
89 }
90
visitActionDataBase(const ActionDataBase * base)91 void SettingsWriter::visitActionDataBase(const ActionDataBase *base)
92 {
93 KConfigGroup *config = _stack.top();
94
95 config->writeEntry("Type", "ERROR"); // derived classes should call with their type
96 config->writeEntry("Name", base->name());
97 config->writeEntry("Comment", base->comment());
98
99 switch (_state) {
100 case KHotKeys::Retain:
101 config->writeEntry("Enabled", base->isEnabled(ActionDataBase::Ignore));
102 break;
103
104 case KHotKeys::Enabled:
105 config->writeEntry("Enabled", true);
106 break;
107
108 case KHotKeys::Disabled:
109 config->writeEntry("Enabled", false);
110 break;
111
112 default:
113 Q_ASSERT(false);
114 config->writeEntry("Enabled", false);
115 }
116
117 if (base->conditions()) {
118 KConfigGroup conditionsConfig(config->config(), config->name() + "Conditions");
119 base->conditions()->cfg_write(conditionsConfig);
120 } else {
121 qDebug() << "No conditions";
122 }
123 }
124
visitActionDataGroup(const ActionDataGroup * group)125 void SettingsWriter::visitActionDataGroup(const ActionDataGroup *group)
126 {
127 visitActionDataBase(group);
128
129 KConfigGroup *config = _stack.top();
130
131 config->writeEntry("SystemGroup", int(group->system_group()));
132 config->writeEntry("Type", "ACTION_DATA_GROUP");
133
134 int cnt = 0;
135 Q_FOREACH (ActionDataBase *child, group->children()) {
136 ++cnt;
137 KConfigGroup childConfig(config->config(), config->name() + QString("_") + QString::number(cnt));
138 _stack.push(&childConfig);
139 child->accept(this);
140 _stack.pop();
141 }
142 config->writeEntry("DataCount", cnt);
143
144 // We only write those two back if we do not export the settings
145 if (!_export) {
146 // ImportId only if set
147 if (!group->importId().isEmpty())
148 config->writeEntry("ImportId", group->importId());
149 if (group->allowMerging())
150 config->writeEntry("AllowMerge", group->allowMerging());
151 }
152 }
153
visitGenericActionData(const Generic_action_data * data)154 void SettingsWriter::visitGenericActionData(const Generic_action_data *data)
155 {
156 visitActionData(data);
157
158 KConfigGroup *config = _stack.top();
159 config->writeEntry("Type", "GENERIC_ACTION_DATA");
160 }
161
visitMenuentryShortcutActionData(const MenuEntryShortcutActionData * data)162 void SettingsWriter::visitMenuentryShortcutActionData(const MenuEntryShortcutActionData *data)
163 {
164 visitActionData(data);
165
166 KConfigGroup *config = _stack.top();
167 config->writeEntry("Type", "MENUENTRY_SHORTCUT_ACTION_DATA");
168 }
169
visitSimpleActionData(const SimpleActionData * data)170 void SettingsWriter::visitSimpleActionData(const SimpleActionData *data)
171 {
172 visitActionData(data);
173
174 KConfigGroup *config = _stack.top();
175 config->writeEntry("Type", "SIMPLE_ACTION_DATA");
176 }
177
writeTo(KConfigBase & config)178 void SettingsWriter::writeTo(KConfigBase &config)
179 {
180 QStringList groups = config.groupList();
181 for (QStringList::ConstIterator it = groups.constBegin(); it != groups.constEnd(); ++it)
182 config.deleteGroup(*it);
183
184 // Write the global settings
185 KConfigGroup mainGroup(&config, "Main");
186 mainGroup.writeEntry("Version", 2);
187 mainGroup.writeEntry("AlreadyImported", _settings->already_imported);
188 mainGroup.writeEntry("Disabled", _settings->isDaemonDisabled());
189
190 // Write the actions
191 KConfigGroup dataGroup(&config, "Data");
192 _stack.push(&dataGroup);
193
194 int cnt = 0;
195 if (_settings->actions()) {
196 Q_FOREACH (ActionDataBase *child, _settings->actions()->children()) {
197 ++cnt;
198 KConfigGroup childConfig(dataGroup.config(), QString("Data_") + QString::number(cnt));
199 _stack.push(&childConfig);
200 child->accept(this);
201 _stack.pop();
202 }
203 }
204 dataGroup.writeEntry("DataCount", cnt);
205 _stack.pop();
206
207 // CHECKME Count still needed????
208 // int cnt = write_actions( dataGroup, _settings->actions(), true );
209 // mainGroup.writeEntry( "Autostart", cnt != 0 && !_settings->isDaemonDisabled() );
210
211 // Write the gestures configuration
212 KConfigGroup gesturesConfig(&config, "Gestures");
213 gesturesConfig.writeEntry("Disabled", _settings->areGesturesDisabled());
214 gesturesConfig.writeEntry("MouseButton", _settings->gestureMouseButton());
215 gesturesConfig.writeEntry("Timeout", _settings->gestureTimeOut());
216 if (_settings->gesturesExclude() != nullptr) {
217 KConfigGroup gesturesExcludeConfig(&config, "GesturesExclude");
218 _settings->gesturesExclude()->cfg_write(gesturesExcludeConfig);
219 } else
220 config.deleteGroup("GesturesExclude");
221 KConfigGroup voiceConfig(&config, "Voice");
222 voiceConfig.writeEntry("Shortcut", _settings->voice_shortcut.toString());
223 }
224
225 } // namespace KHotKeys
226