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