#include "e.h" #include "e_mod_main.h" typedef struct _Inst Inst; struct _Inst { Eina_Hash *added; Eina_List *apps; Evry_Item *candidate; }; static Evry_Plugin *_plug_new(); static Evry_Plugin *_plug_new2(); static void _plug_free(Evry_Plugin *p); static int _begin(Evry_Plugin *p, Evry_Item *item); static int _fetch(Evry_Plugin *p, const char *input); static int _action(Evry_Plugin *p, Evry_Item *item, const char *input); static void _cleanup(Evry_Plugin *p); static void _item_add(Evry_Plugin *p, Efreet_Desktop *desktop, char *file, int prio); static int _cb_sort(const void *data1, const void *data2); static void _item_icon_get(Evry_Plugin *p, Evry_Item *it, Evas *e); static Evry_Plugin_Class class; static Evry_Plugin_Class class2; EAPI int evry_plug_apps_init(void) { class.name = "Applications"; class.type_in = "NONE"; class.type_out = "APPLICATION"; class.need_query = 0; class.new = &_plug_new; class.free = &_plug_free; class.prio = 1; evry_plugin_register(&class); class2.name = "Open With.."; class2.type_in = "FILE"; class2.type_out = "APPLICATION"; class2.need_query = 0; class2.new = &_plug_new2; class2.free = &_plug_free; class2.prio = 3; evry_plugin_register(&class2); return 1; } EAPI int evry_plug_apps_shutdown(void) { evry_plugin_unregister(&class); evry_plugin_unregister(&class2); return 1; } static Evry_Plugin * _plug_new() { Evry_Plugin *p = E_NEW(Evry_Plugin, 1); p->class = &class; p->fetch = &_fetch; p->action = &_action; p->cleanup = &_cleanup; p->icon_get = &_item_icon_get; p->items = NULL; Inst *inst = E_NEW(Inst, 1); inst->added = NULL; p->priv = inst; return p; } static Evry_Plugin * _plug_new2() { Evry_Plugin *p = E_NEW(Evry_Plugin, 1); p->class = &class2; p->begin = &_begin; p->fetch = &_fetch; p->action = &_action; p->cleanup = &_cleanup; p->icon_get = &_item_icon_get; p->items = NULL; Inst *inst = E_NEW(Inst, 1); inst->added = NULL; p->priv = inst; return p; } static void _plug_free(Evry_Plugin *p) { Inst *inst = p->priv; _cleanup(p); if (inst->apps) eina_list_free(inst->apps); E_FREE(inst); E_FREE(p); } static int _begin(Evry_Plugin *p, Evry_Item *it) { Inst *inst; const char *mime; _cleanup(p); if (!it || !it->uri) return 0; inst = p->priv; inst->candidate = it; if (!it->mime) mime = efreet_mime_type_get(it->uri); else mime = it->mime; if (!mime) return 0; /* if (!strcmp(mime, "Folder")) * { * apps = * } * else */ inst->apps = efreet_util_desktop_mime_list(mime); return 1; } static int _action(Evry_Plugin *p, Evry_Item *it, const char *input) { E_Zone *zone; Evry_App *app = NULL; Efreet_Desktop *desktop = NULL; Eina_List *files = NULL; Inst *inst = p->priv; int ret = 0; if (it) app = it->data[0]; if (inst->candidate) files = eina_list_append(files, inst->candidate->uri); if (app && app->desktop) { desktop = app->desktop; } else { if (app && app->file) input = app->file; desktop = efreet_desktop_empty_new(""); if (strchr(input, '%')) { desktop->exec = strdup(input); } else { int len = strlen(input) + 4; desktop->exec = malloc(len); if (desktop->exec) snprintf(desktop->exec, len, "%s %%U", input); } } if (desktop) { zone = e_util_zone_current_get(e_manager_current_get()); e_exec(zone, desktop, NULL, files, NULL /*"everything"*/); if (!it) efreet_desktop_free(desktop); ret = 1; } eina_list_free(files); return ret; } static void _cleanup(Evry_Plugin *p) { Evry_Item *it; Evry_App *app; EINA_LIST_FREE(p->items, it) { if (it->label) eina_stringshare_del(it->label); if (it->o_icon) evas_object_del(it->o_icon); app = it->data[0]; free(app); free(it); } } static int _fetch(Evry_Plugin *p, const char *input) { Eina_List *l; Efreet_Desktop *desktop; char *file; char match1[4096]; char match2[4096]; Inst *inst = p->priv; _cleanup(p); if (inst->apps) { if (!input) { EINA_LIST_FOREACH(inst->apps, l, desktop) _item_add(p, desktop, NULL, 1); } else { snprintf(match1, sizeof(match1), "%s*", input); snprintf(match2, sizeof(match2), "*%s*", input); EINA_LIST_FOREACH(inst->apps, l, desktop) { if (desktop->name) { if (e_util_glob_case_match(desktop->name, match1)) _item_add(p, desktop, NULL, 1); else if (e_util_glob_case_match(desktop->name, match2)) _item_add(p, desktop, NULL, 2); else if (desktop->comment) { if (e_util_glob_case_match(desktop->comment, match1)) _item_add(p, desktop, NULL, 3); else if (e_util_glob_case_match(desktop->comment, match2)) _item_add(p, desktop, NULL, 4); } } } } } if (!p->items && input) { snprintf(match1, sizeof(match1), "%s*", input); l = efreet_util_desktop_exec_glob_list(match1); EINA_LIST_FREE(l, desktop) _item_add(p, desktop, NULL, 1); snprintf(match1, sizeof(match1), "*%s*", input); l = efreet_util_desktop_name_glob_list(match1); EINA_LIST_FREE(l, desktop) _item_add(p, desktop, NULL, 2); // TODO make these optional/configurable l = efreet_util_desktop_generic_name_glob_list(match1); EINA_LIST_FREE(l, desktop) _item_add(p, desktop, NULL, 3); l = efreet_util_desktop_comment_glob_list(match1); EINA_LIST_FREE(l, desktop) _item_add(p, desktop, NULL, 3); } else if (!p->items) { // TODO option for popular/recent l = e_exehist_list_get(); EINA_LIST_FREE(l, file) _item_add(p, NULL, file, 1); } if (inst->added) { eina_hash_free(inst->added); inst->added = NULL; } if (p->items) { if (input) p->items = eina_list_sort(p->items, eina_list_count(p->items), _cb_sort); return 1; } return 0; } static void _item_add(Evry_Plugin *p, Efreet_Desktop *desktop, char *file, int prio) { Evry_Item *it; Evry_App *app; Inst *inst = p->priv; Efreet_Desktop *desktop2; if (desktop) file = desktop->exec; if (!file) return; if (!inst->added) inst->added = eina_hash_string_superfast_new(NULL); if (!desktop) { char match[4096]; Eina_List *l; int len; char *tmp; int found = 0; if (eina_hash_find(inst->added, file)) return; len = strlen(file); tmp = ecore_file_app_exe_get(file); snprintf(match, sizeof(match), "%s*", tmp); l = efreet_util_desktop_exec_glob_list(match); EINA_LIST_FREE(l, desktop) { if (desktop->exec && !strncmp(file, desktop->exec, len)) { found = 1; break; } } eina_list_free(l); free(tmp); if (!found) eina_hash_add(inst->added, file, file); } if (desktop) { if ((desktop2 = eina_hash_find(inst->added, file))) if (desktop == desktop2) return; eina_hash_add(inst->added, file, desktop); file = NULL; } it = calloc(1, sizeof(Evry_Item)); app = calloc(1, sizeof(Evry_App)); app->desktop = desktop; app->file = file; it->data[0] = app; it->priority = prio; if (desktop) it->label = eina_stringshare_add(desktop->name); else it->label = eina_stringshare_add(file); it->o_icon = NULL; p->items = eina_list_append(p->items, it); } static void _item_icon_get(Evry_Plugin *p, Evry_Item *it, Evas *e) { Evry_App *app = it->data[0]; if (app->desktop) it->o_icon = e_util_desktop_icon_add(app->desktop, 24, e); if (!it->o_icon) { it->o_icon = edje_object_add(e); /* e_util_icon_theme_set(it->o_icon, "system-run") */ e_theme_edje_object_set(it->o_icon, "base/theme/fileman", "e/icons/system-run"); } } static int _cb_sort(const void *data1, const void *data2) { const Evry_Item *it1, *it2; Evry_App *app1, *app2; const char *e1, *e2; double t1, t2; it1 = data1; it2 = data2; app1 = it1->data[0]; app2 = it2->data[0]; e1 = efreet_util_path_to_file_id(app1->desktop->orig_path); e2 = efreet_util_path_to_file_id(app2->desktop->orig_path); t1 = e_exehist_newest_run_get(e1); t2 = e_exehist_newest_run_get(e2); if ((int)(t1 - t2)) return (int)(t1 - t2); else if (it1->priority - it2->priority) return (it1->priority - it2->priority); // TODO compare exe strings? else return 0; }