1 //
2 // Copyright RIME Developers
3 // Distributed under the BSD License
4 //
5 // 2013-10-17 GONG Chen <chen.sst@gmail.com>
6 //
7 
8 #include <rime_api.h>
9 #include <rime_levers_api.h>
10 #include <rime/common.h>
11 #include <rime/registry.h>
12 #include <rime/service.h>
13 
14 #include <rime/lever/custom_settings.h>
15 #include <rime/lever/deployment_tasks.h>
16 #include <rime/lever/switcher_settings.h>
17 #include <rime/lever/user_dict_manager.h>
18 
19 using namespace rime;
20 
rime_levers_initialize()21 static void rime_levers_initialize() {
22 
23   LOG(INFO) << "registering components from module 'levers'.";
24   Registry& r = Registry::instance();
25 
26   // deployment tools
27   r.Register("detect_modifications", new Component<DetectModifications>);
28   r.Register("installation_update", new Component<InstallationUpdate>);
29   r.Register("workspace_update", new Component<WorkspaceUpdate>);
30   r.Register("schema_update", new Component<SchemaUpdate>);
31   r.Register("config_file_update", new Component<ConfigFileUpdate>);
32   r.Register("prebuild_all_schemas", new Component<PrebuildAllSchemas>);
33   r.Register("user_dict_upgrade", new Component<UserDictUpgrade>);
34   r.Register("cleanup_trash", new Component<CleanupTrash>);
35   r.Register("user_dict_sync", new Component<UserDictSync>);
36   r.Register("backup_config_files", new Component<BackupConfigFiles>);
37   r.Register("clean_old_log_files", new Component<CleanOldLogFiles>);
38 }
39 
rime_levers_finalize()40 static void rime_levers_finalize() {
41 }
42 
43 // implementation of levers api
44 
45 static RimeCustomSettings*
rime_levers_custom_settings_init(const char * config_id,const char * generator_id)46 rime_levers_custom_settings_init(const char* config_id,
47                                  const char* generator_id) {
48   return reinterpret_cast<RimeCustomSettings*>(
49       new CustomSettings(&Service::instance().deployer(),
50                          config_id, generator_id));
51 }
52 
rime_levers_custom_settings_destroy(RimeCustomSettings * settings)53 static void rime_levers_custom_settings_destroy(RimeCustomSettings* settings) {
54   delete reinterpret_cast<CustomSettings*>(settings);
55 }
56 
rime_levers_load_settings(RimeCustomSettings * settings)57 static Bool rime_levers_load_settings(RimeCustomSettings* settings) {
58   return Bool(reinterpret_cast<CustomSettings*>(settings)->Load());
59 }
60 
rime_levers_save_settings(RimeCustomSettings * settings)61 static Bool rime_levers_save_settings(RimeCustomSettings* settings) {
62   return Bool(reinterpret_cast<CustomSettings*>(settings)->Save());
63 }
64 
rime_levers_customize_bool(RimeCustomSettings * settings,const char * key,Bool value)65 static Bool rime_levers_customize_bool(RimeCustomSettings* settings,
66                                        const char* key, Bool value) {
67   an<ConfigItem> item = New<ConfigValue>(bool(value));
68   auto custom_settings = reinterpret_cast<CustomSettings*>(settings);
69   return custom_settings->Customize(key, item);
70 }
71 
rime_levers_customize_int(RimeCustomSettings * settings,const char * key,int value)72 static Bool rime_levers_customize_int(RimeCustomSettings* settings,
73                                       const char* key, int value) {
74   an<ConfigItem> item = New<ConfigValue>(value);
75   auto custom_settings = reinterpret_cast<CustomSettings*>(settings);
76   return custom_settings->Customize(key, item);
77 }
78 
rime_levers_customize_double(RimeCustomSettings * settings,const char * key,double value)79 static Bool rime_levers_customize_double(RimeCustomSettings* settings,
80                                          const char* key, double value) {
81   an<ConfigItem> item = New<ConfigValue>(value);
82   auto custom_settings = reinterpret_cast<CustomSettings*>(settings);
83   return custom_settings->Customize(key, item);
84 }
85 
rime_levers_customize_string(RimeCustomSettings * settings,const char * key,const char * value)86 static Bool rime_levers_customize_string(RimeCustomSettings* settings,
87                                          const char* key, const char* value) {
88   an<ConfigItem> item = New<ConfigValue>(value);
89   auto custom_settings = reinterpret_cast<CustomSettings*>(settings);
90   return custom_settings->Customize(key, item);
91 }
92 
rime_levers_customize_item(RimeCustomSettings * settings,const char * key,RimeConfig * value)93 static Bool rime_levers_customize_item(RimeCustomSettings* settings,
94                                        const char* key, RimeConfig* value) {
95   an<ConfigItem> item;
96   if (value) {
97     if (Config* v = reinterpret_cast<Config*>(value->ptr)) {
98       item = v->GetItem("");
99     }
100   }
101   auto custom_settings = reinterpret_cast<CustomSettings*>(settings);
102   return custom_settings->Customize(key, item);
103 }
104 
rime_levers_is_first_run(RimeCustomSettings * settings)105 static Bool rime_levers_is_first_run(RimeCustomSettings* settings) {
106   return reinterpret_cast<CustomSettings*>(settings)->IsFirstRun();
107 }
108 
rime_levers_settings_is_modified(RimeCustomSettings * settings)109 static Bool rime_levers_settings_is_modified(RimeCustomSettings* settings) {
110   return reinterpret_cast<CustomSettings*>(settings)->modified();
111 }
112 
rime_levers_settings_get_config(RimeCustomSettings * settings,RimeConfig * config)113 static Bool rime_levers_settings_get_config(RimeCustomSettings* settings,
114                                             RimeConfig* config) {
115   if (!config)
116     return False;
117   config->ptr = reinterpret_cast<CustomSettings*>(settings)->config();
118   return Bool(!!config->ptr);
119 }
120 
rime_levers_switcher_settings_init()121 static RimeSwitcherSettings* rime_levers_switcher_settings_init() {
122   return reinterpret_cast<RimeSwitcherSettings*>(
123       new SwitcherSettings(&Service::instance().deployer()));
124 }
125 
126 static Bool
rime_levers_get_available_schema_list(RimeSwitcherSettings * settings,RimeSchemaList * list)127 rime_levers_get_available_schema_list(RimeSwitcherSettings* settings,
128                                       RimeSchemaList* list) {
129   auto ss = reinterpret_cast<SwitcherSettings*>(settings);
130   list->size = 0;
131   list->list = NULL;
132   if (ss->available().empty()) {
133     return False;
134   }
135   list->list = new RimeSchemaListItem[ss->available().size()];
136   for (const auto& info : ss->available()) {
137     auto& item(list->list[list->size]);
138     item.schema_id = const_cast<char*>(info.schema_id.c_str());
139     item.name = const_cast<char*>(info.name.c_str());
140     item.reserved = const_cast<SchemaInfo*>(&info);
141     ++list->size;
142   }
143   return True;
144 }
145 
146 static Bool
rime_levers_get_selected_schema_list(RimeSwitcherSettings * settings,RimeSchemaList * list)147 rime_levers_get_selected_schema_list(RimeSwitcherSettings* settings,
148                                      RimeSchemaList* list) {
149   auto ss = reinterpret_cast<SwitcherSettings*>(settings);
150   list->size = 0;
151   list->list = NULL;
152   if (ss->selection().empty()) {
153     return False;
154   }
155   list->list = new RimeSchemaListItem[ss->selection().size()];
156   for (const string& schema_id : ss->selection()) {
157     auto& item(list->list[list->size]);
158     item.schema_id = const_cast<char*>(schema_id.c_str());
159     item.name = NULL;
160     item.reserved = NULL;
161     ++list->size;
162   }
163   return True;
164 }
165 
rime_levers_schema_list_destroy(RimeSchemaList * list)166 static void rime_levers_schema_list_destroy(RimeSchemaList* list) {
167   delete[] list->list;
168   list->size = 0;
169   list->list = NULL;
170 }
171 
rime_levers_get_schema_id(RimeSchemaInfo * info)172 static const char* rime_levers_get_schema_id(RimeSchemaInfo* info) {
173   auto si = reinterpret_cast<SchemaInfo*>(info);
174   return si && !si->schema_id.empty() ? si->schema_id.c_str() : NULL;
175 }
176 
rime_levers_get_schema_name(RimeSchemaInfo * info)177 static const char* rime_levers_get_schema_name(RimeSchemaInfo* info) {
178   auto si = reinterpret_cast<SchemaInfo*>(info);
179   return si && !si->name.empty() ? si->name.c_str() : NULL;
180 }
181 
rime_levers_get_schema_version(RimeSchemaInfo * info)182 static const char* rime_levers_get_schema_version(RimeSchemaInfo* info) {
183   auto si = reinterpret_cast<SchemaInfo*>(info);
184   return si && !si->version.empty() ? si->version.c_str() : NULL;
185 }
rime_levers_get_schema_author(RimeSchemaInfo * info)186 static const char* rime_levers_get_schema_author(RimeSchemaInfo* info) {
187   auto si = reinterpret_cast<SchemaInfo*>(info);
188   return si && !si->author.empty() ? si->author.c_str() : NULL;
189 }
190 
rime_levers_get_schema_description(RimeSchemaInfo * info)191 static const char* rime_levers_get_schema_description(RimeSchemaInfo* info) {
192   auto si = reinterpret_cast<SchemaInfo*>(info);
193   return si && !si->description.empty() ? si->description.c_str() : NULL;
194 }
195 
rime_levers_get_schema_file_path(RimeSchemaInfo * info)196 static const char* rime_levers_get_schema_file_path(RimeSchemaInfo* info) {
197   auto si = reinterpret_cast<SchemaInfo*>(info);
198   return si && !si->file_path.empty() ? si->file_path.c_str() : NULL;
199 }
200 
rime_levers_select_schemas(RimeSwitcherSettings * settings,const char * schema_id_list[],int count)201 static Bool rime_levers_select_schemas(RimeSwitcherSettings* settings,
202                                        const char* schema_id_list[],
203                                        int count) {
204   auto ss = reinterpret_cast<SwitcherSettings*>(settings);
205   SwitcherSettings::Selection selection;
206   for (int i = 0; i < count; ++i) {
207     selection.push_back(schema_id_list[i]);
208   }
209   return ss->Select(selection);
210 }
211 
rime_levers_get_hotkeys(RimeSwitcherSettings * settings)212 static const char* rime_levers_get_hotkeys(RimeSwitcherSettings* settings) {
213   auto ss = reinterpret_cast<SwitcherSettings*>(settings);
214   return !ss->hotkeys().empty() ? ss->hotkeys().c_str() : NULL;
215 }
216 
rime_levers_set_hotkeys(RimeSwitcherSettings * settings,const char * hotkeys)217 static Bool rime_levers_set_hotkeys(RimeSwitcherSettings* settings,
218                                     const char* hotkeys) {
219   auto ss = reinterpret_cast<SwitcherSettings*>(settings);
220   return Bool(ss->SetHotkeys(hotkeys));
221 }
222 
rime_levers_user_dict_iterator_init(RimeUserDictIterator * iter)223 static Bool rime_levers_user_dict_iterator_init(RimeUserDictIterator* iter) {
224   UserDictManager mgr(&Service::instance().deployer());
225   UserDictList* list = new UserDictList;
226   mgr.GetUserDictList(list);
227   if (list->empty()) {
228     delete list;
229     return False;
230   }
231   iter->ptr = list;
232   iter->i = 0;
233   return True;
234 }
235 
rime_levers_user_dict_iterator_destroy(RimeUserDictIterator * iter)236 static void rime_levers_user_dict_iterator_destroy(RimeUserDictIterator* iter) {
237   delete (UserDictList*)iter->ptr;
238   iter->ptr = NULL;
239   iter->i = 0;
240 }
241 
rime_levers_next_user_dict(RimeUserDictIterator * iter)242 static const char* rime_levers_next_user_dict(RimeUserDictIterator* iter) {
243   auto list = reinterpret_cast<UserDictList*>(iter->ptr);
244   if (!list || iter->i >= list->size()) {
245     return NULL;
246   }
247   return (*list)[iter->i++].c_str();
248 }
249 
rime_levers_backup_user_dict(const char * dict_name)250 static Bool rime_levers_backup_user_dict(const char* dict_name) {
251   UserDictManager mgr(&Service::instance().deployer());
252   return Bool(mgr.Backup(dict_name));
253 }
254 
rime_levers_restore_user_dict(const char * snapshot_file)255 static Bool rime_levers_restore_user_dict(const char* snapshot_file) {
256   UserDictManager mgr(&Service::instance().deployer());
257   return Bool(mgr.Restore(snapshot_file));
258 }
259 
rime_levers_export_user_dict(const char * dict_name,const char * text_file)260 static int rime_levers_export_user_dict(const char* dict_name,
261                                         const char* text_file) {
262   UserDictManager mgr(&Service::instance().deployer());
263   return mgr.Export(dict_name, text_file);
264 }
265 
rime_levers_import_user_dict(const char * dict_name,const char * text_file)266 static int rime_levers_import_user_dict(const char* dict_name,
267                                         const char* text_file) {
268   UserDictManager mgr(&Service::instance().deployer());
269   return mgr.Import(dict_name, text_file);
270 }
271 
272 //
273 
rime_levers_get_api()274 static RimeCustomApi* rime_levers_get_api() {
275   static RimeLeversApi s_api = {0};
276   if (!s_api.data_size) {
277     RIME_STRUCT_INIT(RimeLeversApi, s_api);
278     s_api.custom_settings_init = rime_levers_custom_settings_init;
279     s_api.custom_settings_destroy = rime_levers_custom_settings_destroy;
280     s_api.load_settings = rime_levers_load_settings;
281     s_api.save_settings = rime_levers_save_settings;
282     s_api.customize_bool = rime_levers_customize_bool;
283     s_api.customize_int = rime_levers_customize_int;
284     s_api.customize_double = rime_levers_customize_double;
285     s_api.customize_string = rime_levers_customize_string;
286     s_api.is_first_run = rime_levers_is_first_run;
287     s_api.settings_is_modified = rime_levers_settings_is_modified;
288     s_api.settings_get_config = rime_levers_settings_get_config;
289     s_api.switcher_settings_init = rime_levers_switcher_settings_init;
290     s_api.get_available_schema_list = rime_levers_get_available_schema_list;
291     s_api.get_selected_schema_list = rime_levers_get_selected_schema_list;
292     s_api.schema_list_destroy = rime_levers_schema_list_destroy;
293     s_api.get_schema_id = rime_levers_get_schema_id;
294     s_api.get_schema_name = rime_levers_get_schema_name;
295     s_api.get_schema_version = rime_levers_get_schema_version;
296     s_api.get_schema_author = rime_levers_get_schema_author;
297     s_api.get_schema_description = rime_levers_get_schema_description;
298     s_api.get_schema_file_path = rime_levers_get_schema_file_path;
299     s_api.select_schemas = rime_levers_select_schemas;
300     s_api.get_hotkeys = rime_levers_get_hotkeys;
301     s_api.set_hotkeys = rime_levers_set_hotkeys;
302     s_api.user_dict_iterator_init = rime_levers_user_dict_iterator_init;
303     s_api.user_dict_iterator_destroy = rime_levers_user_dict_iterator_destroy;
304     s_api.next_user_dict = rime_levers_next_user_dict;
305     s_api.backup_user_dict = rime_levers_backup_user_dict;
306     s_api.restore_user_dict = rime_levers_restore_user_dict;
307     s_api.export_user_dict = rime_levers_export_user_dict;
308     s_api.import_user_dict = rime_levers_import_user_dict;
309     s_api.customize_item = rime_levers_customize_item;
310   }
311   return (RimeCustomApi*)&s_api;
312 }
313 
RIME_REGISTER_CUSTOM_MODULE(levers)314 RIME_REGISTER_CUSTOM_MODULE(levers) {
315   module->get_api = rime_levers_get_api;
316 }
317