1 /*
2 * Copyright 2011 kubtek <kubtek@mail.com>
3 *
4 * This file is part of StarDict.
5 *
6 * StarDict is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * StarDict is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with StarDict. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <glib.h>
21 #include <glib/gi18n.h>
22 #include <glib/gstdio.h>
23 #include "dictmanage.h"
24 #include "lib/file-utils.h"
25 #include "conf.h"
26 #include "stardict.h"
27 #include "lib/pluginmanager.h"
28 #include "lib/verify_dict.h"
29
30 class GetAllDictList {
31 public:
GetAllDictList(std::list<DictItemId> & dict_all_list_)32 GetAllDictList(std::list<DictItemId> &dict_all_list_) :
33 dict_all_list(dict_all_list_) {}
operator ()(const std::string & url,bool disable)34 void operator()(const std::string& url, bool disable) {
35 dict_all_list.push_back(DictItemId(url));
36 }
37 private:
38 std::list<DictItemId> &dict_all_list;
39 };
40
41 class GetAllPluginList {
42 public:
GetAllPluginList(std::list<DictItemId> & plugin_all_list_)43 GetAllPluginList(std::list<DictItemId> &plugin_all_list_) :
44 plugin_all_list(plugin_all_list_) {}
operator ()(const std::string & url,bool disable)45 void operator()(const std::string& url, bool disable) {
46 plugin_all_list.push_back(DictItemId(url));
47 }
48 private:
49 std::list<DictItemId> &plugin_all_list;
50 };
51
52 /* List of dictionaries that are present on the hard disk in known directories. */
get_all_dict_list(std::list<DictItemId> & dict_all_list)53 static void get_all_dict_list(std::list<DictItemId> &dict_all_list)
54 {
55 std::list<std::string> dict_order_list;
56 std::list<std::string> dict_disable_list;
57 #ifdef _WIN32
58 std::list<std::string> dict_dirs_list;
59 {
60 const std::list<std::string>& dict_dirs_list_rel
61 = conf->get_strlist("/apps/stardict/manage_dictionaries/dict_dirs_list");
62 abs_path_to_data_dir(dict_dirs_list_rel, dict_dirs_list);
63 }
64 #else
65 const std::list<std::string>& dict_dirs_list
66 = conf->get_strlist("/apps/stardict/manage_dictionaries/dict_dirs_list");
67 #endif
68 for_each_file_restricted(
69 dict_dirs_list, ".ifo",
70 dict_order_list, dict_disable_list, GetAllDictList(dict_all_list));
71 }
72
73 /* List of plugins that are present on the hard disk in known directories. */
get_all_plugin_list(std::list<DictItemId> & plugin_all_list)74 static void get_all_plugin_list(std::list<DictItemId> &plugin_all_list)
75 {
76 std::list<std::string> plugin_order_list;
77 std::list<std::string> plugin_disable_list;
78 std::list<std::string> plugins_dirs;
79 plugins_dirs.push_back(conf_dirs->get_plugin_dir());
80 for_each_file(plugins_dirs, "." G_MODULE_SUFFIX, plugin_order_list,
81 plugin_disable_list, GetAllPluginList(plugin_all_list));
82 }
83
84 /* Remove all items of the var_list that are not in the all_list */
remove_list_items(std::list<DictItemId> & var_list,const std::list<DictItemId> & all_list)85 static void remove_list_items(std::list<DictItemId> &var_list,
86 const std::list<DictItemId> &all_list)
87 {
88 for(std::list<DictItemId>::iterator i = var_list.begin(); i != var_list.end();) {
89 if(all_list.end() == std::find(all_list.begin(), all_list.end(), *i))
90 i = var_list.erase(i);
91 else
92 ++i;
93 }
94 }
95
96 /* rename IDs in the var_list to match spelling in the all_list
97 On Windows DictItemId-s are compared case-insensitivly,
98 we may modify IDs so they'll be binary equal.
99 all_list - contains all possible IDs, it prescribe the preferrend spelling of them.
100 var_list - list of IDs that should be modified according to the all_list.
101 */
update_list_items(std::list<DictItemId> & var_list,const std::list<DictItemId> & all_list)102 static void update_list_items(std::list<DictItemId> &var_list,
103 const std::list<DictItemId> &all_list)
104 {
105 #ifdef _WIN32
106 for(std::list<DictItemId>::iterator i = var_list.begin(); i != var_list.end(); ++i) {
107 std::list<DictItemId>::const_iterator j = std::find(all_list.begin(), all_list.end(), *i);
108 g_assert(j != all_list.end());
109 *i = *j;
110 }
111 #endif
112 }
113
get_active_group(void)114 std::list<DictManageGroup>::iterator DictManageInfo::get_active_group(void)
115 {
116 std::list<DictManageGroup>::iterator i;
117 for (i = groups.begin(); i != groups.end(); ++i) {
118 if (i->name == active_group)
119 break;
120 }
121 if (i == groups.end()) {
122 i = groups.begin();
123 active_group = (i != groups.end()) ? i->name : "";
124 }
125 return i;
126 }
127
128 std::list<DictManageGroup>::iterator
set_active_group(const std::string & new_group)129 DictManageInfo::set_active_group(const std::string& new_group)
130 {
131 std::list<DictManageGroup>::iterator i;
132 for (i = groups.begin(); i != groups.end(); ++i) {
133 if (i->name == new_group)
134 break;
135 }
136 if (i == groups.end()) {
137 if (groups.empty()) {
138 DictManageGroup group;
139 group.name = _("Default Group");
140 groups.push_back(group);
141 }
142 i = groups.begin();
143 }
144 active_group = i->name;
145 return i;
146 }
147
148 struct config_ParseUserData {
149 DictManageInfo *info;
150 bool in_querydict;
151 bool in_scandict;
152 };
153
config_parse_start_element(GMarkupParseContext * context,const gchar * element_name,const gchar ** attribute_names,const gchar ** attribute_values,gpointer user_data,GError ** error)154 static void config_parse_start_element(GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error)
155 {
156 config_ParseUserData *Data = (config_ParseUserData *)user_data;
157 if (strcmp(element_name, "dictgroup")==0) {
158 const char *name = NULL;
159 size_t i = 0;
160 while (attribute_names[i]) {
161 if (strcmp(attribute_names[i], "name")==0) {
162 name = attribute_values[i];
163 break;
164 }
165 i++;
166 }
167 if (!name)
168 name = _("Default Group");
169 DictManageGroup group;
170 group.name = name;
171 Data->info->groups.push_back(group);
172 } else if (strcmp(element_name, "querydict")==0) {
173 Data->in_querydict = true;
174 } else if (strcmp(element_name, "scandict")==0) {
175 Data->in_scandict = true;
176 } else if (strcmp(element_name, "localdict")==0) {
177 bool enable = true;
178 const gchar *file = NULL;
179 size_t i = 0;
180 while (attribute_names[i]) {
181 if (strcmp(attribute_names[i], "enable")==0) {
182 if (strcmp(attribute_values[i], "false")==0) {
183 enable = false;
184 }
185 } else if (strcmp(attribute_names[i], "file")==0) {
186 file = attribute_values[i];
187 }
188 i++;
189 }
190 if (file) {
191 DictManageItem item;
192 item.type = LOCAL_DICT;
193 item.enable = enable;
194 #ifdef _WIN32
195 item.file_or_id = DictItemId(abs_path_to_data_dir(file));
196 #else
197 item.file_or_id = DictItemId(file);
198 #endif
199 if (Data->in_querydict) {
200 Data->info->groups.back().querydict.push_back(item);
201 } else if (Data->in_scandict) {
202 Data->info->groups.back().scandict.push_back(item);
203 }
204 }
205 } else if (strcmp(element_name, "virtualdict")==0) {
206 bool enable = true;
207 const gchar *id = NULL;
208 size_t i = 0;
209 while (attribute_names[i]) {
210 if (strcmp(attribute_names[i], "enable")==0) {
211 if (strcmp(attribute_values[i], "false")==0) {
212 enable = false;
213 }
214 } else if (strcmp(attribute_names[i], "id")==0) {
215 id = attribute_values[i];
216 }
217 i++;
218 }
219 if (id) {
220 DictManageItem item;
221 item.type = VIRTUAL_DICT;
222 item.enable = enable;
223 #ifdef _WIN32
224 item.file_or_id = DictItemId(abs_path_to_data_dir(id));
225 #else
226 item.file_or_id = DictItemId(id);
227 #endif
228 if (Data->in_querydict) {
229 Data->info->groups.back().querydict.push_back(item);
230 } else if (Data->in_scandict) {
231 Data->info->groups.back().scandict.push_back(item);
232 }
233 }
234 } else if (strcmp(element_name, "netdict")==0) {
235 bool enable = true;
236 const gchar *id = NULL;
237 size_t i = 0;
238 while (attribute_names[i]) {
239 if (strcmp(attribute_names[i], "enable")==0) {
240 if (strcmp(attribute_values[i], "false")==0) {
241 enable = false;
242 }
243 } else if (strcmp(attribute_names[i], "id")==0) {
244 id = attribute_values[i];
245 }
246 i++;
247 }
248 if (id) {
249 DictManageItem item;
250 item.type = NET_DICT;
251 item.enable = enable;
252 #ifdef _WIN32
253 item.file_or_id = DictItemId(abs_path_to_data_dir(id));
254 #else
255 item.file_or_id = DictItemId(id);
256 #endif
257 if (Data->in_querydict) {
258 Data->info->groups.back().querydict.push_back(item);
259 } else if (Data->in_scandict) {
260 Data->info->groups.back().scandict.push_back(item);
261 }
262 }
263 }
264 }
265
config_parse_end_element(GMarkupParseContext * context,const gchar * element_name,gpointer user_data,GError ** error)266 static void config_parse_end_element(GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error)
267 {
268 config_ParseUserData *Data = (config_ParseUserData *)user_data;
269 if (strcmp(element_name, "querydict")==0) {
270 Data->in_querydict = false;
271 } else if (strcmp(element_name, "scandict")==0) {
272 Data->in_scandict = false;
273 }
274 }
275
DictConfigXmlToInfo(const char * configxml,DictManageInfo & info)276 static void DictConfigXmlToInfo(const char *configxml, DictManageInfo &info)
277 {
278 info.groups.clear();
279 config_ParseUserData Data;
280 Data.info = &info;
281 Data.in_querydict = false;
282 Data.in_scandict = false;
283 GMarkupParser parser;
284 parser.start_element = config_parse_start_element;
285 parser.end_element = config_parse_end_element;
286 parser.text = NULL;
287 parser.passthrough = NULL;
288 parser.error = NULL;
289 GMarkupParseContext* context = g_markup_parse_context_new(&parser, (GMarkupParseFlags)0, &Data, NULL);
290 g_markup_parse_context_parse(context, configxml, -1, NULL);
291 g_markup_parse_context_end_parse(context, NULL);
292 g_markup_parse_context_free(context);
293 }
294
itemlist_to_xml(std::string & newxml,std::list<DictManageItem> & item_list,bool is_query)295 static void itemlist_to_xml(std::string &newxml, std::list<DictManageItem> &item_list, bool is_query)
296 {
297 if (is_query)
298 newxml += "<querydict>";
299 else
300 newxml += "<scandict>";
301 gchar *estr;
302 for (std::list<DictManageItem>::iterator j = item_list.begin(); j != item_list.end(); ++j) {
303 if (j->type == LOCAL_DICT)
304 newxml += "<localdict";
305 else if (j->type == VIRTUAL_DICT)
306 newxml += "<virtualdict";
307 else
308 newxml += "<netdict";
309 newxml += " enable=\"";
310 if (j->enable)
311 newxml += "true";
312 else
313 newxml += "false";
314 if (j->type == LOCAL_DICT)
315 newxml += "\" file=\"";
316 else
317 newxml += "\" id=\"";
318 #ifdef _WIN32
319 estr = g_markup_escape_text(rel_path_to_data_dir(j->file_or_id.str()).c_str(), -1);
320 #else
321 estr = g_markup_escape_text(j->file_or_id.c_str(), -1);
322 #endif
323 newxml += estr;
324 g_free(estr);
325 newxml += "\"/>";
326 }
327 if (is_query)
328 newxml += "</querydict>";
329 else
330 newxml += "</scandict>";
331 }
332
InfoToConfigXml(std::string & newxml,DictManageInfo & info)333 static void InfoToConfigXml(std::string &newxml, DictManageInfo &info)
334 {
335 newxml.clear();
336 gchar *estr;
337 for (std::list<DictManageGroup>::iterator i = info.groups.begin(); i != info.groups.end(); ++i) {
338 newxml += "<dictgroup name=\"";
339 estr = g_markup_escape_text(i->name.c_str(), -1);
340 newxml += estr;
341 g_free(estr);
342 newxml += "\">";
343 itemlist_to_xml(newxml, i->querydict, true);
344 itemlist_to_xml(newxml, i->scandict, false);
345 newxml += "</dictgroup>";
346 }
347 }
348
get_dictlist_from_itemlist(std::list<DictItemId> & dict_list,const std::list<DictManageItem> & itemlist)349 static void get_dictlist_from_itemlist(std::list<DictItemId> &dict_list,
350 const std::list<DictManageItem> &itemlist)
351 {
352 for (std::list<DictManageItem>::const_iterator i = itemlist.begin(); i != itemlist.end(); ++i) {
353 if (i->type == LOCAL_DICT && i->enable == true) {
354 if (std::find(dict_list.begin(), dict_list.end(), i->file_or_id) == dict_list.end()) {
355 dict_list.push_back(i->file_or_id);
356 }
357 }
358 }
359 }
360
361 /* remove unavailable dictionaries and plugins */
remove_unavailable_dicts_plugins(std::list<DictManageItem> & dict_list,const std::list<DictItemId> & dict_all_list,const std::list<DictItemId> & plugin_all_list)362 static void remove_unavailable_dicts_plugins(std::list<DictManageItem>& dict_list,
363 const std::list<DictItemId> &dict_all_list,
364 const std::list<DictItemId> &plugin_all_list)
365 {
366 for(std::list<DictManageItem>::iterator i=dict_list.begin();
367 i!=dict_list.end(); ) {
368 bool found=false;
369 switch(i->type) {
370 case LOCAL_DICT:
371 found = dict_all_list.end()
372 != std::find(dict_all_list.begin(), dict_all_list.end(), i->file_or_id);
373 break;
374 case VIRTUAL_DICT:
375 case NET_DICT:
376 found = plugin_all_list.end() != std::find(plugin_all_list.begin(),
377 plugin_all_list.end(), i->file_or_id);
378 break;
379 default:
380 g_error("Unknown plugin type %s\n", i->file_or_id.c_str());
381 found = false;
382 }
383 if(found)
384 ++i;
385 else
386 i = dict_list.erase(i);
387 }
388 }
389
390 /* update IDs of dictionaries and plugins in dict_list,
391 so they spell as in dict_all_list and plugin_all_list.
392 See update_list_items function. */
update_dicts_plugins(std::list<DictManageItem> & dict_list,const std::list<DictItemId> & dict_all_list,const std::list<DictItemId> & plugin_all_list)393 static void update_dicts_plugins(std::list<DictManageItem>& dict_list,
394 const std::list<DictItemId> &dict_all_list,
395 const std::list<DictItemId> &plugin_all_list)
396 {
397 #ifdef _WIN32
398 std::list<DictItemId>::const_iterator j;
399 for(std::list<DictManageItem>::iterator i=dict_list.begin();
400 i!=dict_list.end(); ++i) {
401 switch(i->type) {
402 case LOCAL_DICT:
403 j = std::find(dict_all_list.begin(), dict_all_list.end(), i->file_or_id);
404 g_assert(j != dict_all_list.end());
405 break;
406 case VIRTUAL_DICT:
407 case NET_DICT:
408 j = std::find(plugin_all_list.begin(), plugin_all_list.end(), i->file_or_id);
409 g_assert(j != plugin_all_list.end());
410 break;
411 default:
412 g_error("Unknown plugin type %s\n", i->file_or_id.c_str());
413 }
414 i->file_or_id = *j;
415 }
416 #endif
417 }
418
UpdateConfigXML(const std::list<DictItemId> & dict_new_install_list,const std::list<DictItemId> & plugin_new_install_list,const StarDictPlugins * oStarDictPlugins)419 void UpdateConfigXML(
420 const std::list<DictItemId> &dict_new_install_list,
421 const std::list<DictItemId> &plugin_new_install_list,
422 const StarDictPlugins* oStarDictPlugins)
423 {
424 std::list<DictItemId> dict_all_list;
425 std::list<DictItemId> plugin_all_list;
426 {
427 #ifdef _WIN32
428 std::list<std::string> s_dict_all_list;
429 std::list<std::string> s_plugin_all_list;
430 {
431 const std::list<std::string> &dict_all_list_rel
432 = conf->get_strlist("/apps/stardict/manage_dictionaries/dict_order_list");
433 const std::list<std::string> &plugin_all_list_rel
434 = conf->get_strlist("/apps/stardict/manage_plugins/plugin_order_list");
435 abs_path_to_data_dir(dict_all_list_rel, s_dict_all_list);
436 abs_path_to_data_dir(plugin_all_list_rel, s_plugin_all_list);
437 }
438 #else
439 const std::list<std::string> &s_dict_all_list
440 = conf->get_strlist("/apps/stardict/manage_dictionaries/dict_order_list");
441 const std::list<std::string> &s_plugin_all_list
442 = conf->get_strlist("/apps/stardict/manage_plugins/plugin_order_list");
443 #endif
444 DictItemId::convert(dict_all_list, s_dict_all_list);
445 DictItemId::convert(plugin_all_list, s_plugin_all_list);
446 }
447 const std::string &configxml
448 = conf->get_string("/apps/stardict/manage_dictionaries/dict_config_xml");
449 DictManageInfo dictinfo;
450 DictConfigXmlToInfo(configxml.c_str(), dictinfo);
451
452 // remove dictionaries and plugins that are not available now
453 for(std::list<DictManageGroup>::iterator igroup=dictinfo.groups.begin();
454 igroup!=dictinfo.groups.end(); ++igroup) {
455 remove_unavailable_dicts_plugins(igroup->querydict, dict_all_list, plugin_all_list);
456 remove_unavailable_dicts_plugins(igroup->scandict, dict_all_list, plugin_all_list);
457 update_dicts_plugins(igroup->querydict, dict_all_list, plugin_all_list);
458 update_dicts_plugins(igroup->scandict, dict_all_list, plugin_all_list);
459 }
460
461 std::list<DictManageGroup>::iterator iactivegroup
462 = dictinfo.set_active_group(
463 conf->get_string("/apps/stardict/manage_dictionaries/dict_default_group"));
464
465 if(conf->get_bool("/apps/stardict/preferences/dictionary/add_new_dict_in_active_group")) {
466 // add new dictionaries to the active group
467 for (std::list<DictItemId>::const_iterator j = dict_new_install_list.begin(); j != dict_new_install_list.end(); ++j) {
468 DictManageItem item;
469 item.type = LOCAL_DICT;
470 item.enable = true;
471 item.file_or_id = *j;
472 iactivegroup->querydict.push_back(item);
473 iactivegroup->scandict.push_back(item);
474 }
475 }
476 if(conf->get_bool("/apps/stardict/preferences/dictionary/add_new_plugin_in_active_group")) {
477 // add new plugins to the active group
478 for(std::list<DictItemId>::const_iterator j=plugin_new_install_list.begin(); j != plugin_new_install_list.end(); ++j) {
479 size_t iPlugin;
480 if(oStarDictPlugins->VirtualDictPlugins.find_dict_by_id(*j, iPlugin)) {
481 DictManageItem item;
482 item.type = VIRTUAL_DICT;
483 item.enable = true;
484 item.file_or_id = *j;
485 iactivegroup->querydict.push_back(item);
486 iactivegroup->scandict.push_back(item);
487 } else if(oStarDictPlugins->NetDictPlugins.find_dict_by_id(*j, iPlugin)) {
488 DictManageItem item;
489 item.type = NET_DICT;
490 item.enable = true;
491 item.file_or_id = *j;
492 iactivegroup->querydict.push_back(item);
493 iactivegroup->scandict.push_back(item);
494 }
495 }
496 }
497 std::string newxml;
498 InfoToConfigXml(newxml, dictinfo);
499 conf->set_string("/apps/stardict/manage_dictionaries/dict_config_xml", newxml);
500 }
501
502 /* get a list of all used dictionaries, those that are part of some dictionary group,
503 * not only the active dictionary group */
GetUsedDictList(std::list<DictItemId> & dict_list)504 void GetUsedDictList(std::list<DictItemId> &dict_list)
505 {
506 dict_list.clear();
507 for (std::list<DictManageGroup>::iterator i = gpAppFrame->dictinfo.groups.begin(); i != gpAppFrame->dictinfo.groups.end(); ++i) {
508 get_dictlist_from_itemlist(dict_list, i->querydict);
509 get_dictlist_from_itemlist(dict_list, i->scandict);
510 }
511 }
512
set_dictmask_by_itemlist(const std::list<DictManageItem> & itemlist,bool is_query)513 static void set_dictmask_by_itemlist(const std::list<DictManageItem> &itemlist, bool is_query)
514 {
515 if (is_query)
516 gpAppFrame->query_dictmask.clear();
517 else
518 gpAppFrame->scan_dictmask.clear();
519 for (std::list<DictManageItem>::const_iterator i = itemlist.begin(); i != itemlist.end(); ++i) {
520 if (i->enable) {
521 if (i->type == LOCAL_DICT) {
522 size_t iLib;
523 if (gpAppFrame->oLibs.find_lib_by_id(i->file_or_id, iLib)) {
524 InstantDictIndex instance_dict_index;
525 instance_dict_index.type = InstantDictType_LOCAL;
526 instance_dict_index.index = iLib;
527 if (is_query)
528 gpAppFrame->query_dictmask.push_back(instance_dict_index);
529 else
530 gpAppFrame->scan_dictmask.push_back(instance_dict_index);
531 }
532 } else if (i->type == VIRTUAL_DICT) {
533 size_t iPlugin;
534 if (gpAppFrame->oStarDictPlugins->VirtualDictPlugins.find_dict_by_id(i->file_or_id, iPlugin)) {
535 InstantDictIndex instance_dict_index;
536 instance_dict_index.type = InstantDictType_VIRTUAL;
537 instance_dict_index.index = iPlugin;
538 if (is_query)
539 gpAppFrame->query_dictmask.push_back(instance_dict_index);
540 else
541 gpAppFrame->scan_dictmask.push_back(instance_dict_index);
542 }
543 } else {
544 g_assert(i->type == NET_DICT);
545 size_t iPlugin;
546 if (gpAppFrame->oStarDictPlugins->NetDictPlugins.find_dict_by_id(i->file_or_id, iPlugin)) {
547 InstantDictIndex instance_dict_index;
548 instance_dict_index.type = InstantDictType_NET;
549 instance_dict_index.index = iPlugin;
550 if (is_query)
551 gpAppFrame->query_dictmask.push_back(instance_dict_index);
552 else
553 gpAppFrame->scan_dictmask.push_back(instance_dict_index);
554 }
555 }
556 }
557 }
558 }
559
UpdateDictMask()560 void UpdateDictMask()
561 {
562 std::list<DictManageGroup>::iterator i = gpAppFrame->dictinfo.get_active_group();
563 set_dictmask_by_itemlist(i->querydict, true);
564 set_dictmask_by_itemlist(i->scandict, false);
565 g_free(gpAppFrame->iCurrentIndex);
566 gpAppFrame->iCurrentIndex = (CurrentIndex*)g_malloc0(sizeof(CurrentIndex) * gpAppFrame->query_dictmask.size());
567 conf->set_string("/apps/stardict/manage_dictionaries/dict_default_group", gpAppFrame->dictinfo.active_group);
568 }
569
LoadDictInfo()570 void LoadDictInfo()
571 {
572 const std::string &configxml
573 = conf->get_string("/apps/stardict/manage_dictionaries/dict_config_xml");
574 DictConfigXmlToInfo(configxml.c_str(), gpAppFrame->dictinfo);
575 gpAppFrame->dictinfo.set_active_group(
576 conf->get_string("/apps/stardict/manage_dictionaries/dict_default_group"));
577 }
578
579 /* update manage_dictionaries/dict_order_list configuration option
580 * - add new dictionaries
581 * - remove dictionaries that are no longer available
582 * */
UpdateDictList(std::list<DictItemId> & dict_new_install_list,show_progress_t * sp,bool verify_dict)583 void UpdateDictList(std::list<DictItemId> &dict_new_install_list, show_progress_t *sp, bool verify_dict)
584 {
585 dict_new_install_list.clear();
586 std::list<DictItemId> dict_all_list;
587 get_all_dict_list(dict_all_list);
588 // verify dictionaries, remove invalid dictionaries from dict_all_list
589 if (verify_dict) {
590 std::list<std::string> s_dict_valid_list;
591 std::list<std::string> s_dict_all_list;
592 DictItemId::convert(s_dict_all_list, dict_all_list);
593 filter_verify_dicts(s_dict_all_list, s_dict_valid_list, sp);
594 DictItemId::convert(dict_all_list, s_dict_valid_list);
595 }
596 std::list<DictItemId> dict_order_list;
597 {
598 #ifdef _WIN32
599 std::list<std::string> s_dict_order_list;
600 {
601 const std::list<std::string>& dict_order_list_rel
602 = conf->get_strlist("/apps/stardict/manage_dictionaries/dict_order_list");
603 abs_path_to_data_dir(dict_order_list_rel, s_dict_order_list);
604 }
605 #else
606 std::list<std::string> s_dict_order_list(conf->get_strlist("/apps/stardict/manage_dictionaries/dict_order_list"));
607 #endif
608 DictItemId::convert(dict_order_list, s_dict_order_list);
609 }
610 // remove dictionaries that are not available
611 remove_list_items(dict_order_list, dict_all_list);
612 update_list_items(dict_order_list, dict_all_list);
613 // find new dictionaries
614 for (std::list<DictItemId>::iterator i = dict_all_list.begin(); i != dict_all_list.end(); ++i) {
615 if (dict_order_list.end() == std::find(dict_order_list.begin(), dict_order_list.end(), *i)) {
616 dict_new_install_list.push_back(*i);
617 }
618 }
619 dict_order_list.insert(dict_order_list.end(), dict_new_install_list.begin(), dict_new_install_list.end());
620 {
621 std::list<std::string> s_dict_order_list;
622 DictItemId::convert(s_dict_order_list, dict_order_list);
623 #ifdef _WIN32
624 {
625 std::list<std::string> dict_order_list_rel;
626 rel_path_to_data_dir(s_dict_order_list, dict_order_list_rel);
627 conf->set_strlist("/apps/stardict/manage_dictionaries/dict_order_list", dict_order_list_rel);
628 }
629 #else
630 conf->set_strlist("/apps/stardict/manage_dictionaries/dict_order_list", s_dict_order_list);
631 #endif
632 }
633 }
634
635 /* update manage_plugins/plugin_order_list configuration list
636 * - add new plug-ins,
637 * - remove plug-ins that are no longer available
638 * update manage_plugins/plugin_disable_list configuration list
639 * - remove plug-ins that are no longer available
640 * */
UpdatePluginList(std::list<DictItemId> & plugin_new_install_list)641 void UpdatePluginList(std::list<DictItemId> &plugin_new_install_list)
642 {
643 plugin_new_install_list.clear();
644 std::list<DictItemId> plugin_all_list;
645 std::list<DictItemId> plugin_order_list;
646
647 get_all_plugin_list(plugin_all_list);
648 {
649 std::list<std::string> s_plugin_order_list;
650 #ifdef _WIN32
651 {
652 const std::list<std::string>& plugin_order_list_rel
653 = conf->get_strlist("/apps/stardict/manage_plugins/plugin_order_list");
654 abs_path_to_data_dir(plugin_order_list_rel, s_plugin_order_list);
655 }
656 #else
657 s_plugin_order_list = conf->get_strlist("/apps/stardict/manage_plugins/plugin_order_list");
658 #endif
659 DictItemId::convert(plugin_order_list, s_plugin_order_list);
660 }
661 // remove plugins that are not available
662 remove_list_items(plugin_order_list, plugin_all_list);
663 update_list_items(plugin_order_list, plugin_all_list);
664 // find new plugins
665 for(std::list<DictItemId>::iterator it = plugin_all_list.begin(); it != plugin_all_list.end(); ++it) {
666 if(plugin_order_list.end() == std::find(plugin_order_list.begin(), plugin_order_list.end(), *it))
667 plugin_new_install_list.push_back(*it);
668 }
669 plugin_order_list.insert(plugin_order_list.end(), plugin_new_install_list.begin(), plugin_new_install_list.end());
670 {
671 std::list<std::string> s_plugin_order_list;
672 DictItemId::convert(s_plugin_order_list, plugin_order_list);
673 #ifdef _WIN32
674 {
675 std::list<std::string> plugin_order_list_rel;
676 rel_path_to_data_dir(s_plugin_order_list, plugin_order_list_rel);
677 conf->set_strlist("/apps/stardict/manage_plugins/plugin_order_list", plugin_order_list_rel);
678 }
679 #else
680 conf->set_strlist("/apps/stardict/manage_plugins/plugin_order_list", s_plugin_order_list);
681 #endif
682 }
683
684 std::list<DictItemId> plugin_disable_list;
685 {
686 #ifdef _WIN32
687 std::list<std::string> s_plugin_disable_list;
688 {
689 const std::list<std::string> &plugin_disable_list_rel
690 = conf->get_strlist("/apps/stardict/manage_plugins/plugin_disable_list");
691 abs_path_to_data_dir(plugin_disable_list_rel, s_plugin_disable_list);
692 }
693 #else
694 std::list<std::string> s_plugin_disable_list(
695 conf->get_strlist("/apps/stardict/manage_plugins/plugin_disable_list"));
696 #endif
697 DictItemId::convert(plugin_disable_list, s_plugin_disable_list);
698 }
699 remove_list_items(plugin_disable_list, plugin_all_list);
700 update_list_items(plugin_disable_list, plugin_all_list);
701 {
702 std::list<std::string> s_plugin_disable_list;
703 DictItemId::convert(s_plugin_disable_list, plugin_disable_list);
704 #ifdef _WIN32
705 {
706 std::list<std::string> plugin_disable_list_rel;
707 rel_path_to_data_dir(s_plugin_disable_list, plugin_disable_list_rel);
708 conf->set_strlist("/apps/stardict/manage_plugins/plugin_disable_list",
709 plugin_disable_list_rel);
710 }
711 #else
712 conf->set_strlist("/apps/stardict/manage_plugins/plugin_disable_list",
713 s_plugin_disable_list);
714 #endif
715 }
716 }
717
RemoveCacheFiles(void)718 void RemoveCacheFiles(void)
719 {
720 /* We may not simply remove all ".oft" and ".clt" files in all known
721 * directories, there are resource storage directories! */
722 #ifdef _WIN32
723 std::list<std::string> dict_list;
724 {
725 const std::list<std::string>& dict_list_rel = conf->get_strlist("/apps/stardict/manage_dictionaries/dict_order_list");
726 abs_path_to_data_dir(dict_list_rel, dict_list);
727 }
728 #else
729 const std::list<std::string>& dict_list = conf->get_strlist("/apps/stardict/manage_dictionaries/dict_order_list");
730 #endif
731 std::list<std::string> dir_list;
732 glib::CharStr gdir;
733 /* Collect a list of directories where to remove cache files. */
734 for(std::list<std::string>::const_iterator it = dict_list.begin(); it != dict_list.end(); ++it) {
735 gdir.reset(g_path_get_dirname(it->c_str()));
736 if(dir_list.end() == std::find_if(dir_list.begin(), dir_list.end(), PathComparePred(get_impl(gdir))))
737 dir_list.push_back(get_impl(gdir));
738 }
739 dir_list.push_back(conf_dirs->get_user_cache_dir());
740 // remove cache files
741 const gchar *filename;
742 GDir *dir;
743 for(std::list<std::string>::const_iterator it = dir_list.begin(); it != dir_list.end(); ++it) {
744 dir = g_dir_open(it->c_str(), 0, NULL);
745 if(!dir)
746 continue;
747 while ((filename = g_dir_read_name(dir))!=NULL) {
748 if(!is_path_end_with(filename, ".oft") && !is_path_end_with(filename, ".clt"))
749 continue;
750 std::string fullfilename(build_path(*it, filename));
751 if (!g_file_test(fullfilename.c_str(), G_FILE_TEST_IS_DIR)) {
752 if(g_unlink(fullfilename.c_str()))
753 g_warning(_("Unable to remove file: %s"), fullfilename.c_str());
754 }
755 }
756 g_dir_close(dir);
757 }
758 }
759