update for beta release
[framework/uifw/e17.git] / src / modules / everything / e_mod_main.c
1 #include "e_mod_main.h"
2
3 static void      _e_mod_action_cb(E_Object *obj, const char *params);
4 static void      _e_mod_action_cb_edge(E_Object *obj, const char *params, E_Event_Zone_Edge *ev);
5 static Eina_Bool _e_mod_run_defer_cb(void *data);
6 static void      _e_mod_run_cb(void *data, E_Menu *m, E_Menu_Item *mi);
7 static void      _e_mod_menu_add(void *data, E_Menu *m);
8 static void      _config_init(void);
9 static void      _config_free(void);
10 static Eina_Bool _cleanup_history(void *data);
11 static void      _evry_type_init(const char *type);
12 static Eina_List *_evry_types = NULL;
13 static E_Int_Menu_Augmentation *maug = NULL;
14 static E_Action *act = NULL;
15 static Ecore_Timer *cleanup_timer;
16 static const char *module_icon = NULL;
17 static E_Config_DD *conf_edd = NULL;
18 static E_Config_DD *plugin_conf_edd = NULL;
19 static E_Config_DD *gadget_conf_edd = NULL;
20 static int _e_module_evry_log_dom = -1;
21
22 Evry_API *evry = NULL;
23 Evry_Config *evry_conf = NULL;
24 int _evry_events[NUM_EVRY_EVENTS];
25 E_Module *_mod_evry = NULL;
26
27 /* module setup */
28 EAPI E_Module_Api e_modapi =
29 {
30    E_MODULE_API_VERSION,
31    "Everything"
32 };
33
34 EAPI void *
35 e_modapi_init(E_Module *m)
36 {
37    Eina_List *l;
38    Evry_Module *em;
39    char buf[4096];
40
41    _e_module_evry_log_dom = eina_log_domain_register
42        ("e_module_everything", EINA_LOG_DEFAULT_COLOR);
43
44    if (_e_module_evry_log_dom < 0)
45      {
46         EINA_LOG_ERR
47           ("impossible to create a log domain for everything module");
48         return NULL;
49      }
50
51    _mod_evry = m;
52
53    /* add module supplied action */
54    act = e_action_add("everything");
55    if (act)
56      {
57         act->func.go = _e_mod_action_cb;
58         act->func.go_edge = _e_mod_action_cb_edge;
59         e_action_predef_name_set
60           (_("Everything Launcher"),
61           _("Show Everything Launcher"),
62           "everything", "", NULL, 0);
63      }
64
65    maug = e_int_menus_menu_augmentation_add
66        ("main/1", _e_mod_menu_add, NULL, NULL, NULL);
67
68    e_configure_registry_category_add
69      ("launcher", 80, _("Launcher"), NULL, "modules-launcher");
70
71    snprintf(buf, sizeof(buf), "%s/e-module-everything.edj", e_module_dir_get(m));
72    module_icon = eina_stringshare_add(buf);
73
74    e_configure_registry_item_add
75      ("launcher/run_everything", 40, _("Everything Configuration"),
76      NULL, module_icon, evry_config_dialog);
77    evry_init();
78
79    _evry_type_init("NONE");
80    _evry_type_init("FILE");
81    _evry_type_init("DIRECTORY");
82    _evry_type_init("APPLICATION");
83    _evry_type_init("ACTION");
84    _evry_type_init("PLUGIN");
85    _evry_type_init("BORDER");
86    _evry_type_init("TEXT");
87
88    _config_init();
89
90    _evry_events[EVRY_EVENT_ITEMS_UPDATE] = ecore_event_type_new();
91    _evry_events[EVRY_EVENT_ITEM_SELECTED] = ecore_event_type_new();
92    _evry_events[EVRY_EVENT_ITEM_CHANGED] = ecore_event_type_new();
93    _evry_events[EVRY_EVENT_ACTION_PERFORMED] = ecore_event_type_new();
94    _evry_events[EVRY_EVENT_PLUGIN_SELECTED] = ecore_event_type_new();
95
96    evry = E_NEW(Evry_API, 1);
97    evry->log_dom = _e_module_evry_log_dom;
98 #define SET(func) (evry->func = &evry_##func);
99    SET(api_version_check);
100    SET(item_new);
101    SET(item_free);
102    SET(item_ref);
103    SET(plugin_new);
104    SET(plugin_free);
105    SET(plugin_register);
106    SET(plugin_unregister);
107    SET(plugin_update);
108    SET(plugin_find);
109    SET(action_new);
110    SET(action_free);
111    SET(action_register);
112    SET(action_unregister);
113    SET(action_find);
114    SET(api_version_check);
115    SET(type_register);
116    SET(icon_theme_get);
117    SET(fuzzy_match);
118    SET(util_exec_app);
119    SET(util_url_escape);
120    SET(util_url_unescape);
121    SET(util_file_detail_set);
122    SET(util_plugin_items_add);
123    SET(util_md5_sum);
124    SET(util_icon_get);
125    SET(item_changed);
126    SET(file_path_get);
127    SET(file_url_get);
128    SET(history_item_add);
129    SET(history_types_get);
130    SET(history_item_usage_set);
131    SET(event_handler_add);
132 #undef SET
133
134    evry_history_init();
135    evry_plug_actions_init();
136    evry_plug_apps_init(m);
137    evry_plug_files_init(m);
138    evry_plug_windows_init(m);
139    evry_plug_settings_init(m);
140    evry_plug_calc_init(m);
141    e_datastore_set("evry_api", evry);
142
143    EINA_LIST_FOREACH (e_datastore_get("evry_modules"), l, em)
144      em->active = em->init(evry);
145
146    evry_plug_collection_init();
147    evry_plug_clipboard_init();
148    evry_plug_text_init();
149    evry_view_init();
150    evry_view_help_init();
151    evry_gadget_init();
152
153    e_module_priority_set(m, -1000);
154    e_module_delayed_set(m, 1);
155
156    /* cleanup every hour :) */
157    cleanup_timer = ecore_timer_add(3600, _cleanup_history, NULL);
158
159    return m;
160 }
161
162 EAPI int
163 e_modapi_shutdown(E_Module *m __UNUSED__)
164 {
165    E_Config_Dialog *cfd;
166    const char *t;
167    Eina_List *l;
168    Evry_Module *em;
169
170    EINA_LIST_FOREACH (e_datastore_get("evry_modules"), l, em)
171      {
172         if (em->active)
173           em->shutdown();
174
175         em->active = EINA_FALSE;
176      }
177
178    evry_plug_apps_shutdown();
179    evry_plug_files_shutdown();
180    evry_plug_settings_shutdown();
181    evry_plug_windows_shutdown();
182    evry_plug_calc_shutdown();
183    evry_plug_clipboard_shutdown();
184    evry_plug_text_shutdown();
185    evry_plug_collection_shutdown();
186    evry_plug_actions_shutdown();
187    evry_view_shutdown();
188    evry_view_help_shutdown();
189    evry_gadget_shutdown();
190    evry_shutdown();
191
192    e_datastore_del("evry_api");
193    E_FREE(evry);
194    evry = NULL;
195
196    _config_free();
197    evry_history_free();
198
199    EINA_LIST_FREE (_evry_types, t)
200      eina_stringshare_del(t);
201
202    e_configure_registry_item_del("launcher/run_everything");
203    e_configure_registry_category_del("launcher");
204
205    while ((cfd = e_config_dialog_get("E", "_config_everything_dialog")))
206      e_object_del(E_OBJECT(cfd));
207
208    if (act)
209      {
210         e_action_predef_name_del(_("Everything Launcher"),
211                                  _("Show Everything Dialog"));
212         e_action_del("everything");
213      }
214
215    if (maug)
216      {
217         e_int_menus_menu_augmentation_del("main/1", maug);
218         maug = NULL;
219      }
220
221    if (module_icon)
222      eina_stringshare_del(module_icon);
223
224    /* Clean EET */
225    E_CONFIG_DD_FREE(conf_edd);
226    E_CONFIG_DD_FREE(plugin_conf_edd);
227    E_CONFIG_DD_FREE(gadget_conf_edd);
228
229    if (cleanup_timer)
230      ecore_timer_del(cleanup_timer);
231
232 #ifdef CHECK_REFS
233    Evry_Item *it;
234    EINA_LIST_FREE (_refd, it)
235      printf("%d %s\n", it->ref, it->label);
236 #endif
237
238    _mod_evry = NULL;
239
240    return 1;
241 }
242
243 EAPI int
244 e_modapi_save(E_Module *m __UNUSED__)
245 {
246    e_config_domain_save("module.everything", conf_edd, evry_conf);
247
248    evry_plug_apps_save();
249    evry_plug_files_save();
250    evry_plug_settings_save();
251    evry_plug_windows_save();
252    evry_plug_calc_save();
253
254    return 1;
255 }
256
257 /***************************************************************************/
258
259 Ecore_Event_Handler *
260 evry_event_handler_add(int type, Eina_Bool (*func)(void *data, int type, void *event), const void *data)
261 {
262    return ecore_event_handler_add(_evry_events[type], func, data);
263 }
264
265 Evry_Type
266 evry_type_register(const char *type)
267 {
268    const char *t = eina_stringshare_add(type);
269    Evry_Type ret = NUM_EVRY_TYPES;
270    const char *i;
271    Eina_List *l;
272
273    EINA_LIST_FOREACH (_evry_types, l, i)
274      {
275         if (i == t) break;
276         ret++;
277      }
278
279    if (!l)
280      {
281         _evry_types = eina_list_append(_evry_types, t);
282         return ret;
283      }
284    eina_stringshare_del(t);
285
286    return ret;
287 }
288
289 static void
290 _evry_type_init(const char *type)
291 {
292    const char *t = eina_stringshare_add(type);
293    _evry_types = eina_list_append(_evry_types, t);
294 }
295
296 const char *
297 evry_type_get(Evry_Type type)
298 {
299    const char *ret = eina_list_nth(_evry_types, type);
300    if (!ret)
301      return eina_stringshare_add("");
302
303    return ret;
304 }
305
306 int
307 evry_api_version_check(int version)
308 {
309    if (EVRY_API_VERSION == version)
310      return 1;
311
312    ERR("module API is %d, required is %d", version, EVRY_API_VERSION);
313
314    return 0;
315 }
316
317 static int
318 _evry_cb_view_sort(const void *data1, const void *data2)
319 {
320    const Evry_View *v1 = data1;
321    const Evry_View *v2 = data2;
322    return v1->priority - v2->priority;
323 }
324
325 void
326 evry_view_register(Evry_View *view, int priority)
327 {
328    view->priority = priority;
329
330    evry_conf->views = eina_list_append(evry_conf->views, view);
331
332    evry_conf->views = eina_list_sort(evry_conf->views,
333                                      eina_list_count(evry_conf->views),
334                                      _evry_cb_view_sort);
335 }
336
337 void
338 evry_view_unregister(Evry_View *view)
339 {
340    evry_conf->views = eina_list_remove(evry_conf->views, view);
341 }
342
343 /***************************************************************************/
344
345 static Eina_Bool
346 _cleanup_history(void *data __UNUSED__)
347 {
348    /* evrything is active */
349    if (evry_hist)
350      return ECORE_CALLBACK_RENEW;
351
352    /* cleanup old entries */
353    evry_history_free();
354    evry_history_init();
355
356    return ECORE_CALLBACK_RENEW;
357 }
358
359 static void
360 _config_init()
361 {
362    Plugin_Config *pc, *pcc;
363
364 #undef T
365 #undef D
366 #define T Plugin_Config
367 #define D plugin_conf_edd
368    plugin_conf_edd = E_CONFIG_DD_NEW("Plugin_Config", Plugin_Config);
369    E_CONFIG_VAL(D, T, name, STR);
370    E_CONFIG_VAL(D, T, enabled, INT);
371    E_CONFIG_VAL(D, T, priority, INT);
372    E_CONFIG_VAL(D, T, trigger, STR);
373    E_CONFIG_VAL(D, T, trigger_only, INT);
374    E_CONFIG_VAL(D, T, view_mode, INT);
375    E_CONFIG_VAL(D, T, aggregate, INT);
376    E_CONFIG_VAL(D, T, top_level, INT);
377    E_CONFIG_VAL(D, T, min_query, INT);
378    E_CONFIG_LIST(D, T, plugins, plugin_conf_edd);
379 #undef T
380 #undef D
381 #define T Gadget_Config
382 #define D gadget_conf_edd
383    gadget_conf_edd = E_CONFIG_DD_NEW("Gadget_Config", Gadget_Config);
384    E_CONFIG_VAL(D, T, id, STR);
385    E_CONFIG_VAL(D, T, plugin, STR);
386    E_CONFIG_VAL(D, T, hide_after_action, INT);
387    E_CONFIG_VAL(D, T, popup, INT);
388 #undef T
389 #undef D
390 #define T Evry_Config
391 #define D conf_edd
392    conf_edd = E_CONFIG_DD_NEW("Config", Evry_Config);
393    E_CONFIG_VAL(D, T, version, INT);
394    E_CONFIG_VAL(D, T, width, INT);
395    E_CONFIG_VAL(D, T, height, INT);
396    E_CONFIG_VAL(D, T, edge_width, INT);
397    E_CONFIG_VAL(D, T, edge_height, INT);
398    E_CONFIG_VAL(D, T, rel_x, DOUBLE);
399    E_CONFIG_VAL(D, T, rel_y, DOUBLE);
400    E_CONFIG_VAL(D, T, scroll_animate, INT);
401    E_CONFIG_VAL(D, T, scroll_speed, DOUBLE);
402    E_CONFIG_VAL(D, T, hide_input, INT);
403    E_CONFIG_VAL(D, T, hide_list, INT);
404    E_CONFIG_VAL(D, T, quick_nav, INT);
405    E_CONFIG_VAL(D, T, view_mode, INT);
406    E_CONFIG_VAL(D, T, view_zoom, INT);
407    E_CONFIG_VAL(D, T, cycle_mode, INT);
408    E_CONFIG_VAL(D, T, history_sort_mode, INT);
409    E_CONFIG_LIST(D, T, conf_subjects, plugin_conf_edd);
410    E_CONFIG_LIST(D, T, conf_actions, plugin_conf_edd);
411    E_CONFIG_LIST(D, T, conf_objects, plugin_conf_edd);
412    E_CONFIG_LIST(D, T, conf_views, plugin_conf_edd);
413    E_CONFIG_LIST(D, T, collections, plugin_conf_edd);
414    E_CONFIG_LIST(D, T, gadgets, gadget_conf_edd);
415    E_CONFIG_VAL(D, T, first_run, UCHAR);
416 #undef T
417 #undef D
418    evry_conf = e_config_domain_load("module.everything", conf_edd);
419
420    if (evry_conf && !e_util_module_config_check(_("Everything Module"),
421                                                 evry_conf->version,
422                                                 MOD_CONFIG_FILE_VERSION))
423      _config_free();
424
425    if (!evry_conf)
426      {
427         evry_conf = E_NEW(Evry_Config, 1);
428         evry_conf->version = (MOD_CONFIG_FILE_EPOCH << 16);
429      }
430
431 #define IFMODCFG(v) if ((evry_conf->version & 0xffff) < v) {
432 #define IFMODCFGEND }
433
434     /* setup defaults */
435     IFMODCFG(0x0001);
436     evry_conf->rel_x = 0.5;
437     evry_conf->rel_y = 0.43;
438     evry_conf->width = 455;
439     evry_conf->height = 430;
440     evry_conf->scroll_animate = 1;
441     evry_conf->scroll_speed = 10.0;
442     evry_conf->hide_input = 0;
443     evry_conf->hide_list = 0;
444     evry_conf->quick_nav = 1;
445     evry_conf->view_mode = VIEW_MODE_DETAIL;
446     evry_conf->view_zoom = 0;
447     evry_conf->cycle_mode = 0;
448     evry_conf->history_sort_mode = 0;
449     evry_conf->edge_width = 340;
450     evry_conf->edge_height = 385;
451     evry_conf->first_run = EINA_TRUE;
452
453     pcc = E_NEW(Plugin_Config, 1);
454     pcc->name = eina_stringshare_add("Start");
455     pcc->enabled = EINA_FALSE;
456     pcc->aggregate = EINA_FALSE;
457     pcc->top_level = EINA_TRUE;
458     pcc->view_mode = VIEW_MODE_THUMB;
459     evry_conf->collections = eina_list_append(evry_conf->collections, pcc);
460
461     pc = E_NEW(Plugin_Config, 1);
462     pc->name = eina_stringshare_add("Windows");
463     pc->enabled = EINA_TRUE;
464     pc->view_mode = VIEW_MODE_NONE;
465     pcc->plugins = eina_list_append(pcc->plugins, pc);
466
467     pc = E_NEW(Plugin_Config, 1);
468     pc->name = eina_stringshare_add("Settings");
469     pc->enabled = EINA_TRUE;
470     pc->view_mode = VIEW_MODE_NONE;
471     pcc->plugins = eina_list_append(pcc->plugins, pc);
472
473     pc = E_NEW(Plugin_Config, 1);
474     pc->name = eina_stringshare_add("Files");
475     pc->enabled = EINA_TRUE;
476     pc->view_mode = VIEW_MODE_NONE;
477     pcc->plugins = eina_list_append(pcc->plugins, pc);
478
479     pc = E_NEW(Plugin_Config, 1);
480     pc->name = eina_stringshare_add("Applications");
481     pc->enabled = EINA_TRUE;
482     pc->view_mode = VIEW_MODE_NONE;
483     pcc->plugins = eina_list_append(pcc->plugins, pc);
484     IFMODCFGEND;
485
486     IFMODCFG(0x0003);
487     evry_conf->width = 464;
488     evry_conf->height = 366;
489     IFMODCFGEND;
490
491     evry_conf->version = MOD_CONFIG_FILE_VERSION;
492 }
493
494 static void
495 _config_free(void)
496 {
497    Plugin_Config *pc, *pc2;
498    Gadget_Config *gc;
499
500    EINA_LIST_FREE (evry_conf->collections, pc)
501      EINA_LIST_FREE (pc->plugins, pc2)
502        {
503           IF_RELEASE(pc2->name);
504           IF_RELEASE(pc2->trigger);
505           E_FREE(pc2);
506        }
507    EINA_LIST_FREE (evry_conf->conf_subjects, pc)
508      {
509         IF_RELEASE(pc->name);
510         IF_RELEASE(pc->trigger);
511         E_FREE(pc);
512      }
513    EINA_LIST_FREE (evry_conf->conf_actions, pc)
514      {
515         IF_RELEASE(pc->name);
516         IF_RELEASE(pc->trigger);
517         E_FREE(pc);
518      }
519    EINA_LIST_FREE (evry_conf->conf_objects, pc)
520      {
521         IF_RELEASE(pc->name);
522         IF_RELEASE(pc->trigger);
523         E_FREE(pc);
524      }
525    EINA_LIST_FREE (evry_conf->gadgets, gc)
526      {
527         IF_RELEASE(gc->id);
528         IF_RELEASE(gc->plugin);
529         E_FREE(gc);
530      }
531
532    E_FREE(evry_conf);
533 }
534
535 /***************************************************************************/
536 /* action callback */
537
538 static Ecore_Idle_Enterer *_idler = NULL;
539 static const char *_params = NULL;
540
541 static Eina_Bool
542 _e_mod_run_defer_cb(void *data)
543 {
544    E_Zone *zone;
545
546    zone = data;
547    if (zone) evry_show(zone, E_ZONE_EDGE_NONE, _params, EINA_TRUE);
548
549    _idler = NULL;
550    return ECORE_CALLBACK_CANCEL;
551 }
552
553 static void
554 _e_mod_action_cb(E_Object *obj, const char *params)
555 {
556    E_Zone *zone = NULL;
557
558    if (obj)
559      {
560         if (obj->type == E_MANAGER_TYPE)
561           zone = e_util_zone_current_get((E_Manager *)obj);
562         else if (obj->type == E_CONTAINER_TYPE)
563           zone = e_util_zone_current_get(((E_Container *)obj)->manager);
564         else if (obj->type == E_ZONE_TYPE)
565           zone = e_util_zone_current_get(((E_Zone *)obj)->container->manager);
566         else
567           zone = e_util_zone_current_get(e_manager_current_get());
568      }
569    if (!zone) zone = e_util_zone_current_get(e_manager_current_get());
570
571    if (!zone) return;
572
573    IF_RELEASE(_params);
574    if (params && params[0])
575      _params = eina_stringshare_add(params);
576    /* if (zone) evry_show(zone, _params); */
577
578    if (_idler) ecore_idle_enterer_del(_idler);
579    _idler = ecore_idle_enterer_add(_e_mod_run_defer_cb, zone);
580 }
581
582 static void
583 _e_mod_action_cb_edge(E_Object *obj  __UNUSED__, const char *params, E_Event_Zone_Edge *ev)
584 {
585    IF_RELEASE(_params);
586    if (params && params[0])
587      _params = eina_stringshare_add(params);
588
589    if (_idler) ecore_idle_enterer_del(_idler);
590
591    evry_show(ev->zone, ev->edge, _params, EINA_TRUE);
592 }
593
594 /* menu item callback(s) */
595 static void
596 _e_mod_run_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
597 {
598    IF_RELEASE(_params);
599    ecore_idle_enterer_add(_e_mod_run_defer_cb, m->zone);
600 }
601
602 /* menu item add hook */
603 static void
604 _e_mod_menu_add(void *data __UNUSED__, E_Menu *m)
605 {
606    E_Menu_Item *mi;
607
608    mi = e_menu_item_new(m);
609    e_menu_item_label_set(mi, _("Run Everything"));
610    e_util_menu_item_theme_icon_set(mi, "system-run");
611    e_menu_item_callback_set(mi, _e_mod_run_cb, NULL);
612 }
613