3 static Eina_Bool _e_fm2_custom_file_hash_foreach_list(const Eina_Hash *hash, const void *key, void *data, void *fdata);
4 static Eina_List *_e_fm2_custom_hash_key_base_list(Eina_Hash *hash, const char *str);
5 //static Eina_Bool _e_fm2_custom_file_hash_foreach_sub_list(Eina_Hash *hash, const char *key, void *data, void *fdata);
6 //static Eina_List *_e_fm2_custom_hash_key_sub_list(Eina_Hash *hash, const char *str);
7 static Eina_Bool _e_fm2_custom_file_hash_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
8 static Eina_Bool _e_fm2_custom_file_hash_foreach_save(const Eina_Hash *hash, const void *key, void *data, void *fdata);
9 static void _e_fm2_custom_file_info_load(void);
10 static void _e_fm2_custom_file_info_save(void);
11 static void _e_fm2_custom_file_info_free(void);
12 static void _e_fm2_custom_file_cb_defer_save(void *data);
14 static E_Powersave_Deferred_Action*_e_fm2_flush_defer = NULL;
15 static Eet_File *_e_fm2_custom_file = NULL;
16 static Eet_Data_Descriptor *_e_fm2_custom_file_edd = NULL;
17 static Eet_Data_Descriptor *_e_fm2_custom_dir_edd = NULL;
18 static Eina_Hash *_e_fm2_custom_hash = NULL;
19 static int _e_fm2_custom_writes = 0;
20 static int _e_fm2_custom_init = 0;
22 /* FIXME: this uses a flat path key for custom file info. this is fine as
23 * long as we only expect a limited number of custom info nodes. if we
24 * start to see whole dire trees stored this way things will suck. we need
25 * to use a tree struct to store this so deletes and renmes are sane.
28 /* externally accessible functions */
30 e_fm2_custom_file_init(void)
32 Eet_Data_Descriptor_Class eddc;
35 if (_e_fm2_custom_init > 1) return _e_fm2_custom_init;
37 if (!eet_eina_stream_data_descriptor_class_set(&eddc, sizeof (eddc), "e_fm2_custom_dir", sizeof (E_Fm2_Custom_Dir)))
43 _e_fm2_custom_hash = eina_hash_string_superfast_new(NULL);
45 _e_fm2_custom_dir_edd = eet_data_descriptor_stream_new(&eddc);
46 #define DAT(x, y, z) EET_DATA_DESCRIPTOR_ADD_BASIC(_e_fm2_custom_dir_edd, E_Fm2_Custom_Dir, x, y, z)
47 DAT("pos.x", pos.x, EET_T_DOUBLE);
48 DAT("pos.y", pos.y, EET_T_DOUBLE);
49 DAT("prop.icon_size", prop.icon_size, EET_T_SHORT);
50 DAT("prop.view_mode", prop.view_mode, EET_T_CHAR);
51 DAT("prop.order_file", prop.order_file, EET_T_UCHAR);
52 DAT("prop.show_hidden_files", prop.show_hidden_files, EET_T_UCHAR);
53 DAT("prop.in_use", prop.in_use, EET_T_UCHAR);
56 eddc.size = sizeof (E_Fm2_Custom_File);
57 eddc.name = "e_fm_custom_file";
59 _e_fm2_custom_file_edd = eet_data_descriptor_stream_new(&eddc);
60 #define DAT(x, y, z) EET_DATA_DESCRIPTOR_ADD_BASIC(_e_fm2_custom_file_edd, E_Fm2_Custom_File, x, y, z)
61 DAT("g.x", geom.x, EET_T_INT);
62 DAT("g.y", geom.y, EET_T_INT);
63 DAT("g.w", geom.w, EET_T_INT);
64 DAT("g.h", geom.h, EET_T_INT);
65 DAT("g.rw", geom.res_w, EET_T_INT);
66 DAT("g.rh", geom.res_h, EET_T_INT);
67 DAT("g.s", geom.scale, EET_T_DOUBLE);
68 DAT("g.v", geom.valid, EET_T_UCHAR);
70 DAT("i.t", icon.type, EET_T_INT);
71 DAT("i.i", icon.icon, EET_T_STRING);
72 DAT("i.v", icon.valid, EET_T_UCHAR);
74 DAT("l", label, EET_T_STRING);
78 EET_DATA_DESCRIPTOR_ADD_SUB(_e_fm2_custom_file_edd, E_Fm2_Custom_File, "dir",
79 dir, _e_fm2_custom_dir_edd);
85 e_fm2_custom_file_shutdown(void)
88 if (_e_fm2_custom_init != 0) return;
90 _e_fm2_custom_file_info_save();
91 _e_fm2_custom_file_info_free();
92 if (_e_fm2_flush_defer) e_powersave_deferred_action_del(_e_fm2_flush_defer);
93 _e_fm2_flush_defer = NULL;
94 eet_data_descriptor_free(_e_fm2_custom_file_edd);
95 _e_fm2_custom_file_edd = NULL;
96 eet_data_descriptor_free(_e_fm2_custom_dir_edd);
97 _e_fm2_custom_dir_edd = NULL;
100 EAPI E_Fm2_Custom_File *
101 e_fm2_custom_file_get(const char *path)
103 E_Fm2_Custom_File *cf;
105 _e_fm2_custom_file_info_load();
106 if (!_e_fm2_custom_file) return NULL;
107 if (_e_fm2_flush_defer) e_fm2_custom_file_flush();
108 cf = eina_hash_find(_e_fm2_custom_hash, path);
113 _e_fm2_custom_dir_del(E_Fm2_Custom_Dir *dir)
119 _e_fm2_custom_file_del(E_Fm2_Custom_File *cf)
123 eina_stringshare_del(cf->icon.icon);
124 eina_stringshare_del(cf->label);
125 _e_fm2_custom_dir_del(cf->dir);
129 static E_Fm2_Custom_Dir *
130 _e_fm2_custom_dir_dup(const E_Fm2_Custom_Dir *dir)
132 E_Fm2_Custom_Dir *copy;
134 if (!dir) return NULL;
136 copy = calloc(1, sizeof(*copy));
137 if (!copy) return NULL;
139 memcpy(copy, dir, sizeof(*copy));
143 EAPI E_Fm2_Custom_File *
144 e_fm2_custom_file_dup(const E_Fm2_Custom_File *cf)
146 E_Fm2_Custom_File *copy;
148 if (!cf) return NULL;
150 copy = calloc(1, sizeof(*copy));
151 if (!copy) return NULL;
153 memcpy(copy, cf, sizeof(*copy));
154 copy->icon.icon = eina_stringshare_add(cf->icon.icon);
155 copy->label = eina_stringshare_add(cf->label);
156 copy->dir = _e_fm2_custom_dir_dup(cf->dir);
161 e_fm2_custom_file_set(const char *path, const E_Fm2_Custom_File *cf)
163 E_Fm2_Custom_File *cf1;
164 _e_fm2_custom_file_info_load();
165 if (!_e_fm2_custom_file) return;
166 if (_e_fm2_flush_defer) e_fm2_custom_file_flush();
168 cf1 = eina_hash_find(_e_fm2_custom_hash, path);
169 if ((cf1 != cf) || ((cf1) && (cf) && (cf1->dir != cf->dir)))
171 E_Fm2_Custom_File *cf2 = e_fm2_custom_file_dup(cf);
176 eina_hash_modify(_e_fm2_custom_hash, path, cf2);
177 _e_fm2_custom_file_del(cf1);
180 eina_hash_add(_e_fm2_custom_hash, path, cf2);
183 _e_fm2_custom_writes = 1;
187 e_fm2_custom_file_del(const char *path)
190 E_Fm2_Custom_File *cf2;
193 _e_fm2_custom_file_info_load();
194 if (!_e_fm2_custom_file) return;
195 if (_e_fm2_flush_defer) e_fm2_custom_file_flush();
197 list = _e_fm2_custom_hash_key_base_list(_e_fm2_custom_hash, path);
200 EINA_LIST_FOREACH(list, l, key)
202 cf2 = eina_hash_find(_e_fm2_custom_hash, key);
205 eina_hash_del(_e_fm2_custom_hash, key, cf2);
206 _e_fm2_custom_file_del(cf2);
209 eina_list_free(list);
211 _e_fm2_custom_writes = 1;
215 e_fm2_custom_file_rename(const char *path, const char *new_path)
217 E_Fm2_Custom_File *cf, *cf2;
221 _e_fm2_custom_file_info_load();
222 if (!_e_fm2_custom_file) return;
223 if (_e_fm2_flush_defer) e_fm2_custom_file_flush();
224 cf2 = eina_hash_find(_e_fm2_custom_hash, path);
227 eina_hash_del(_e_fm2_custom_hash, path, cf2);
228 cf = eina_hash_find(_e_fm2_custom_hash, new_path);
230 _e_fm2_custom_file_del(cf);
231 eina_hash_add(_e_fm2_custom_hash, new_path, cf2);
233 list = _e_fm2_custom_hash_key_base_list(_e_fm2_custom_hash, path);
236 EINA_LIST_FOREACH(list, l, key)
238 cf2 = eina_hash_find(_e_fm2_custom_hash, key);
243 strcpy(buf, new_path);
244 strcat(buf, (char *)key + strlen(path));
245 eina_hash_del(_e_fm2_custom_hash, key, cf2);
246 cf = eina_hash_find(_e_fm2_custom_hash, buf);
248 _e_fm2_custom_file_del(cf);
249 eina_hash_add(_e_fm2_custom_hash, buf, cf2);
252 eina_list_free(list);
254 _e_fm2_custom_writes = 1;
258 e_fm2_custom_file_flush(void)
260 if (!_e_fm2_custom_file) return;
262 if (_e_fm2_flush_defer)
263 e_powersave_deferred_action_del(_e_fm2_flush_defer);
265 e_powersave_deferred_action_add(_e_fm2_custom_file_cb_defer_save, NULL);
270 struct _E_Custom_List
278 _e_fm2_custom_file_hash_foreach_list(const Eina_Hash *hash __UNUSED__, const void *key, void *data __UNUSED__, void *fdata)
280 struct _E_Custom_List *cl;
283 if (!strncmp(cl->base, key, cl->base_len))
284 cl->l = eina_list_append(cl->l, key);
289 _e_fm2_custom_hash_key_base_list(Eina_Hash *hash, const char *str)
291 struct _E_Custom_List cl;
295 cl.base_len = strlen(cl.base);
296 eina_hash_foreach(hash, _e_fm2_custom_file_hash_foreach_list, &cl);
302 _e_fm2_custom_file_hash_foreach_sub_list(const Eina_Hash *hash, const void *key, void *data, void *fdata)
304 struct _E_Custom_List *cl;
307 if (!strncmp(cl->base, key, strlen(key)))
308 cl->l = eina_list_append(cl->l, key);
315 _e_fm2_custom_hash_key_sub_list(const Eina_Hash *hash, const void *str)
317 struct _E_Custom_List cl;
321 eina_hash_foreach(hash,
322 _e_fm2_custom_file_hash_foreach_sub_list, &cl);
328 _e_fm2_custom_file_hash_foreach(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
330 _e_fm2_custom_file_del(data);
335 _e_fm2_custom_file_hash_foreach_save(const Eina_Hash *hash __UNUSED__, const void *key, void *data, void *fdata)
338 E_Fm2_Custom_File *cf;
342 eet_data_write(ef, _e_fm2_custom_file_edd, key, cf, 1);
347 _e_fm2_custom_file_info_load(void)
351 if (_e_fm2_custom_file) return;
352 _e_fm2_custom_writes = 0;
353 e_user_dir_concat_static(buf, "fileman/custom.cfg");
354 _e_fm2_custom_file = eet_open(buf, EET_FILE_MODE_READ);
355 if (!_e_fm2_custom_file)
356 _e_fm2_custom_file = eet_open(buf, EET_FILE_MODE_WRITE);
357 if (_e_fm2_custom_file)
359 E_Fm2_Custom_File *cf;
363 list = eet_list(_e_fm2_custom_file, "*", &num);
366 for (i = 0; i < num; i++)
368 cf = eet_data_read(_e_fm2_custom_file,
369 _e_fm2_custom_file_edd, list[i]);
371 eina_hash_add(_e_fm2_custom_hash, list[i], cf);
379 _e_fm2_custom_file_info_save(void)
382 char buf[PATH_MAX], buf2[PATH_MAX];
386 if (!_e_fm2_custom_file) return;
387 if (!_e_fm2_custom_writes) return;
389 len = e_user_dir_concat_static(buf, "fileman/custom.cfg.tmp");
390 if (len >= sizeof(buf)) return;
391 ef = eet_open(buf, EET_FILE_MODE_WRITE);
393 eina_hash_foreach(_e_fm2_custom_hash,
394 _e_fm2_custom_file_hash_foreach_save, ef);
397 memcpy(buf2, buf, len - (sizeof(".tmp") - 1));
398 buf2[len - (sizeof(".tmp") - 1)] = '\0';
399 eet_close(_e_fm2_custom_file);
400 _e_fm2_custom_file = NULL;
401 ret = rename(buf, buf2);
404 /* FIXME: do we want to trap individual errno
405 and provide a short blurp to the user? */
411 _e_fm2_custom_file_info_free(void)
413 _e_fm2_custom_writes = 0;
414 if (_e_fm2_custom_file)
416 eet_close(_e_fm2_custom_file);
417 _e_fm2_custom_file = NULL;
419 if (_e_fm2_custom_hash)
421 eina_hash_foreach(_e_fm2_custom_hash,
422 _e_fm2_custom_file_hash_foreach, NULL);
423 eina_hash_free(_e_fm2_custom_hash);
424 _e_fm2_custom_hash = eina_hash_string_superfast_new(NULL);
429 _e_fm2_custom_file_cb_defer_save(void *data __UNUSED__)
431 _e_fm2_custom_file_info_save();
432 _e_fm2_custom_file_info_free();
433 _e_fm2_flush_defer = NULL;