4 EAPI int E_EVENT_EXEHIST_UPDATE = 0;
6 /* local subsystem functions */
7 typedef struct _E_Exehist E_Exehist;
8 typedef struct _E_Exehist_Item E_Exehist_Item;
16 struct _E_Exehist_Item
19 const char *normalized_exe;
20 const char *launch_method;
25 static void _e_exehist_unload_queue(void);
26 static void _e_exehist_load(void);
27 static void _e_exehist_clear(void);
28 static void _e_exehist_unload(void);
29 static void _e_exehist_limit(void);
30 static const char *_e_exehist_normalize_exe(const char *exe);
31 static void _e_exehist_cb_unload(void *data);
32 static int _e_exehist_sort_exe_cb(const void *d1, const void *d2);
33 static int _e_exehist_sort_pop_cb(const void *d1, const void *d2);
35 /* local subsystem globals */
36 static E_Config_DD *_e_exehist_config_edd = NULL;
37 static E_Config_DD *_e_exehist_config_item_edd = NULL;
38 static E_Exehist *_e_exehist = NULL;
39 static E_Powersave_Deferred_Action *_e_exehist_unload_defer = NULL;
40 static int _e_exehist_changes = 0;
42 /* externally accessible functions */
46 _e_exehist_config_item_edd = E_CONFIG_DD_NEW("E_Exehist_Item", E_Exehist_Item);
49 #define T E_Exehist_Item
50 #define D _e_exehist_config_item_edd
51 E_CONFIG_VAL(D, T, exe, STR);
52 E_CONFIG_VAL(D, T, normalized_exe, STR);
53 E_CONFIG_VAL(D, T, launch_method, STR);
54 E_CONFIG_VAL(D, T, exetime, DOUBLE);
56 _e_exehist_config_edd = E_CONFIG_DD_NEW("E_Exehist", E_Exehist);
60 #define D _e_exehist_config_edd
61 E_CONFIG_LIST(D, T, history, _e_exehist_config_item_edd);
62 E_CONFIG_LIST(D, T, mimes, _e_exehist_config_item_edd);
64 E_EVENT_EXEHIST_UPDATE = ecore_event_type_new();
70 e_exehist_shutdown(void)
72 if (_e_exehist_unload_defer)
74 e_powersave_deferred_action_del(_e_exehist_unload_defer);
75 _e_exehist_unload_defer = NULL;
77 _e_exehist_cb_unload(NULL);
78 E_CONFIG_DD_FREE(_e_exehist_config_item_edd);
79 E_CONFIG_DD_FREE(_e_exehist_config_edd);
84 e_exehist_add(const char *launch_method, const char *exe)
89 if (!_e_exehist) return;
90 ei = E_NEW(E_Exehist_Item, 1);
93 _e_exehist_unload_queue();
96 ei->launch_method = eina_stringshare_add(launch_method);
97 ei->exe = eina_stringshare_add(exe);
98 ei->normalized_exe = _e_exehist_normalize_exe(exe);
99 ei->exetime = ecore_time_unix_get();
100 _e_exehist->history = eina_list_append(_e_exehist->history, ei);
102 _e_exehist_changes++;
103 ecore_event_add(E_EVENT_EXEHIST_UPDATE, NULL, NULL, NULL);
104 _e_exehist_unload_queue();
108 e_exehist_del(const char *exe)
112 Eina_Bool ok = EINA_FALSE;
115 if (!_e_exehist) return;
116 EINA_LIST_FOREACH(_e_exehist->history, l, ei)
118 if ((ei->exe) && (!strcmp(exe, ei->exe)))
120 eina_stringshare_del(ei->exe);
121 eina_stringshare_del(ei->normalized_exe);
122 eina_stringshare_del(ei->launch_method);
124 _e_exehist->history = eina_list_remove_list(_e_exehist->history,
126 _e_exehist_changes++;
127 _e_exehist_unload_queue();
132 ecore_event_add(E_EVENT_EXEHIST_UPDATE, NULL, NULL, NULL);
136 e_exehist_clear(void)
139 if (!_e_exehist) return;
141 _e_exehist_changes++;
142 ecore_event_add(E_EVENT_EXEHIST_UPDATE, NULL, NULL, NULL);
143 _e_exehist_unload_queue();
147 e_exehist_popularity_get(const char *exe)
155 if (!_e_exehist) return 0;
156 normal = _e_exehist_normalize_exe(exe);
157 if (!normal) return 0;
158 EINA_LIST_FOREACH(_e_exehist->history, l, ei)
160 if ((ei->normalized_exe) && (!strcmp(normal, ei->normalized_exe)))
163 eina_stringshare_del(normal);
164 _e_exehist_unload_queue();
169 e_exehist_newest_run_get(const char *exe)
176 if (!_e_exehist) return 0.0;
177 normal = _e_exehist_normalize_exe(exe);
178 if (!normal) return 0.0;
179 EINA_LIST_REVERSE_FOREACH(_e_exehist->history, l, ei)
181 if ((ei->normalized_exe) && (!strcmp(normal, ei->normalized_exe)))
183 eina_stringshare_del(normal);
184 _e_exehist_unload_queue();
188 eina_stringshare_del(normal);
189 _e_exehist_unload_queue();
194 e_exehist_list_get(void)
196 return e_exehist_sorted_list_get(E_EXEHIST_SORT_BY_DATE, 0);
200 e_exehist_sorted_list_get(E_Exehist_Sort sort_type, int max)
202 Eina_List *list = NULL, *pop = NULL, *l = NULL, *m;
206 E_Exehist_Item *prev = NULL;
212 case E_EXEHIST_SORT_BY_EXE:
213 case E_EXEHIST_SORT_BY_POPULARITY:
214 l = eina_list_clone(_e_exehist->history);
215 l = eina_list_sort(l, 0, _e_exehist_sort_exe_cb);
216 iter = eina_list_iterator_new(l);
219 iter = eina_list_iterator_reversed_new(_e_exehist->history);
222 EINA_ITERATOR_FOREACH(iter, ei)
226 if (!(ei->normalized_exe)) continue;
227 if (sort_type == E_EXEHIST_SORT_BY_POPULARITY)
229 if (!prev || (strcmp(prev->normalized_exe, ei->normalized_exe)))
232 pop = eina_list_append(pop, ei);
240 EINA_LIST_FOREACH(list, m, exe)
243 if (!strcmp(exe, ei->exe))
251 list = eina_list_append(list, ei->exe);
255 if (count > max) break;
257 if (sort_type == E_EXEHIST_SORT_BY_POPULARITY)
260 pop = eina_list_sort(pop, 0, _e_exehist_sort_pop_cb);
261 EINA_LIST_FOREACH(pop, l, prev)
263 list = eina_list_append(list, prev->exe);
265 if (count > max) break;
270 eina_iterator_free(iter);
271 _e_exehist_unload_queue();
276 e_exehist_mime_desktop_add(const char *mime, Efreet_Desktop *desktop)
284 if ((!mime) || (!desktop)) return;
285 if (!desktop->orig_path) return;
287 if (!_e_exehist) return;
289 f = efreet_util_path_to_file_id(desktop->orig_path);
292 snprintf(buf, sizeof(buf), "%s/applications/defaults.list",
293 efreet_data_home_get());
294 ini = efreet_ini_new(buf);
295 fprintf(stderr, "try open %s = %p\n", buf, ini);
298 fprintf(stderr, "SAVE mime %s with %s\n", mime, desktop->orig_path);
299 if (!efreet_ini_section_set(ini, "Default Applications"))
301 efreet_ini_section_add(ini, "Default Applications");
302 efreet_ini_section_set(ini, "Default Applications");
304 if (desktop->orig_path)
305 efreet_ini_string_set(ini, mime, ecore_file_file_get(desktop->orig_path));
306 efreet_ini_save(ini, buf);
307 efreet_ini_free(ini);
310 EINA_LIST_FOREACH(_e_exehist->mimes, l, ei)
312 if ((ei->launch_method) && (!strcmp(mime, ei->launch_method)))
314 if ((ei->exe) && (!strcmp(f, ei->exe)))
316 _e_exehist_unload_queue();
319 if (ei->exe) eina_stringshare_del(ei->exe);
320 if (ei->launch_method) eina_stringshare_del(ei->launch_method);
322 _e_exehist->mimes = eina_list_remove_list(_e_exehist->mimes, l);
323 _e_exehist_changes++;
327 ei = E_NEW(E_Exehist_Item, 1);
330 _e_exehist_unload_queue();
333 ei->launch_method = eina_stringshare_add(mime);
334 ei->exe = eina_stringshare_add(f);
335 ei->exetime = ecore_time_unix_get();
336 _e_exehist->mimes = eina_list_append(_e_exehist->mimes, ei);
338 _e_exehist_changes++;
339 _e_exehist_unload_queue();
342 EAPI Efreet_Desktop *
343 e_exehist_mime_desktop_get(const char *mime)
345 Efreet_Desktop *desktop;
349 fprintf(stderr, "e_exehist_mime_desktop_get(%s)\n", mime);
350 if (!mime) return NULL;
352 fprintf(stderr, "x\n");
353 if (!_e_exehist) return NULL;
354 EINA_LIST_FOREACH(_e_exehist->mimes, l, ei)
356 fprintf(stderr, "look for %s == %s\n", mime, ei->launch_method);
357 if ((ei->launch_method) && (!strcmp(mime, ei->launch_method)))
360 if (ei->exe) desktop = efreet_util_desktop_file_id_find(ei->exe);
361 fprintf(stderr, " desk = %p\n", desktop);
364 _e_exehist_unload_queue();
369 _e_exehist_unload_queue();
373 /* local subsystem functions */
375 _e_exehist_unload_queue(void)
377 if (_e_exehist_unload_defer)
378 e_powersave_deferred_action_del(_e_exehist_unload_defer);
379 _e_exehist_unload_defer =
380 e_powersave_deferred_action_add(_e_exehist_cb_unload, NULL);
384 _e_exehist_load(void)
387 _e_exehist = e_config_domain_load("exehist", _e_exehist_config_edd);
389 _e_exehist = E_NEW(E_Exehist, 1);
393 _e_exehist_clear(void)
398 EINA_LIST_FREE(_e_exehist->history, ei)
400 eina_stringshare_del(ei->exe);
401 eina_stringshare_del(ei->normalized_exe);
402 eina_stringshare_del(ei->launch_method);
405 EINA_LIST_FREE(_e_exehist->mimes, ei)
407 eina_stringshare_del(ei->exe);
408 eina_stringshare_del(ei->launch_method);
415 _e_exehist_unload(void)
422 _e_exehist_limit(void)
424 /* go from first item in hist on and either delete all items before a
425 * specific timestamp, or if the list count > limit then delete items
427 * for now - limit to 500
431 while (eina_list_count(_e_exehist->history) > 500)
435 ei = eina_list_data_get(_e_exehist->history);
436 eina_stringshare_del(ei->exe);
437 eina_stringshare_del(ei->normalized_exe);
438 eina_stringshare_del(ei->launch_method);
440 _e_exehist->history = eina_list_remove_list(_e_exehist->history, _e_exehist->history);
442 while (eina_list_count(_e_exehist->mimes) > 500)
446 ei = eina_list_data_get(_e_exehist->mimes);
447 eina_stringshare_del(ei->exe);
448 eina_stringshare_del(ei->launch_method);
450 _e_exehist->mimes = eina_list_remove_list(_e_exehist->mimes, _e_exehist->mimes);
456 _e_exehist_normalize_exe(const char *exe)
458 char *base, *buf, *cp, *space = NULL;
460 Eina_Bool flag = EINA_FALSE;
463 base = basename(buf);
464 if ((base[0] == '.') && (base[1] == '\0'))
475 if (!space) space = cp;
476 if (flag) flag = EINA_FALSE;
480 /* usually a variable in the desktop exe field */
481 if (space && *cp == '%')
485 char lower = tolower(*cp);
488 if (lower != *cp) *cp = lower;
494 if (space) *space = '\0';
496 ret = eina_stringshare_add(base);
503 _e_exehist_cb_unload(void *data __UNUSED__)
505 if (_e_exehist_changes)
507 e_config_domain_save("exehist", _e_exehist_config_edd, _e_exehist);
508 _e_exehist_changes = 0;
511 _e_exehist_unload_defer = NULL;
515 _e_exehist_sort_exe_cb(const void *d1, const void *d2)
517 const E_Exehist_Item *ei1, *ei2;
522 if ((!ei1) || (!ei1->normalized_exe)) return 1;
523 if ((!ei2) || (!ei2->normalized_exe)) return -1;
525 return strcmp(ei1->normalized_exe, ei2->normalized_exe);
529 _e_exehist_sort_pop_cb(const void *d1, const void *d2)
531 const E_Exehist_Item *ei1, *ei2;
533 if (!(ei1 = d1)) return 1;
534 if (!(ei2 = d2)) return -1;
536 return ei2->count - ei1->count;