From 74317f724a26d92d7fc6f3db1a90ed620e61425c Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Mon, 10 May 2010 22:35:13 +0000 Subject: [PATCH] added Evry_API struct to pass api as handle to modules so that they dont fail to load when everything is not loaded see everything-settings as example how to use. other modules need to be converted. SVN revision: 48740 --- src/modules/everything-aspell/e_mod_main.c | 2 +- src/modules/everything-files/e_mod_main.c | 8 +- src/modules/everything-settings/e_mod_main.c | 70 +++-- src/modules/everything-windows/e_mod_main.c | 2 +- src/modules/everything/Evry.h | 273 ++----------------- src/modules/everything/Makefile.am | 2 +- src/modules/everything/e_mod_main.c | 54 +++- src/modules/everything/evry.c | 6 +- src/modules/everything/evry_api.h | 190 +++++++++++++ src/modules/everything/evry_types.h | 240 ++++++++++++++++ src/modules/everything/evry_util.c | 6 +- 11 files changed, 561 insertions(+), 292 deletions(-) create mode 100644 src/modules/everything/evry_api.h create mode 100644 src/modules/everything/evry_types.h diff --git a/src/modules/everything-aspell/e_mod_main.c b/src/modules/everything-aspell/e_mod_main.c index 6b940a01b..5ec4e6200 100644 --- a/src/modules/everything-aspell/e_mod_main.c +++ b/src/modules/everything-aspell/e_mod_main.c @@ -241,7 +241,7 @@ _cb_data(void *data, int type __UNUSED__, void *event) } if (p->base.items) - evry_plugin_async_update(EVRY_PLUGIN(p), EVRY_ASYNC_UPDATE_ADD); + EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD); return 1; } diff --git a/src/modules/everything-files/e_mod_main.c b/src/modules/everything-files/e_mod_main.c index e4bcd7d5f..1af9fc649 100644 --- a/src/modules/everything-files/e_mod_main.c +++ b/src/modules/everything-files/e_mod_main.c @@ -482,7 +482,7 @@ _scan_end_func(void *data) _append_files(p); - evry_plugin_async_update(EVRY_PLUGIN(p), EVRY_ASYNC_UPDATE_ADD); + EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD); } static void @@ -541,7 +541,7 @@ _dir_watcher(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const c _append_files(p); - evry_plugin_async_update(EVRY_PLUGIN(p), EVRY_ASYNC_UPDATE_ADD); + EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD); } static void @@ -930,7 +930,7 @@ _recentf_end_func(void *data) _recentf_append_files(p); - evry_plugin_async_update(EVRY_PLUGIN(p), EVRY_ASYNC_UPDATE_ADD); + EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD); p->thread = NULL; E_FREE(d); @@ -1233,7 +1233,7 @@ _file_trash_action(Evry_Action *act) GET_FILE(file, act->it1.item); - if (!(evry_file_uri_get(file))) + if (!(evry_file_url_get(file))) return 0; euri = efreet_uri_decode(file->url); diff --git a/src/modules/everything-settings/e_mod_main.c b/src/modules/everything-settings/e_mod_main.c index 3cbb84cde..e668dffe0 100644 --- a/src/modules/everything-settings/e_mod_main.c +++ b/src/modules/everything-settings/e_mod_main.c @@ -2,8 +2,9 @@ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ -#include "Evry.h" +#include "e.h" #include "e_mod_main.h" +#include "evry_api.h" typedef struct _Settings_Item Settings_Item; @@ -15,11 +16,14 @@ struct _Settings_Item E_Configure_It *eci; }; + +static const Evry_API *evry = NULL; +static Evry_Module *evry_module = NULL; +static Eina_Bool active = EINA_FALSE; static Evry_Plugin *p; static Evry_Action *act; static Eina_List *items = NULL; - static void _finish(Evry_Plugin *p) { @@ -28,7 +32,7 @@ _finish(Evry_Plugin *p) EVRY_PLUGIN_ITEMS_CLEAR(p); EINA_LIST_FREE(items, it) - evry_item_free(it); + evry->item_free(it); } static Evas_Object * @@ -38,7 +42,7 @@ _icon_get(Evry_Item *item, Evas *e) Settings_Item *it = (Settings_Item *) item; if (it->eci->icon && - ((o = evry_icon_theme_get(it->eci->icon, e)) || + ((o = evry->icon_theme_get(it->eci->icon, e)) || (o = e_util_icon_add(it->eci->icon, e)))) return o; @@ -98,23 +102,30 @@ _action(Evry_Action *act) return EVRY_ACTION_FINISHED; } -static Eina_Bool -_plugins_init(void) -{ - if (!evry_api_version_check(EVRY_API_VERSION)) +static int +_plugins_init(const Evry_API *_api) +{ + if (active) + return EINA_TRUE; + + evry = _api; + + if (!evry->api_version_check(EVRY_API_VERSION)) return EINA_FALSE; p = EVRY_PLUGIN_NEW(Evry_Plugin, N_("Settings"), "preferences-desktop", - evry_type_register("E_SETTINGS"), + evry->type_register("E_SETTINGS"), _begin, _finish, _fetch, NULL); - evry_plugin_register(p, EVRY_PLUGIN_SUBJECT, 10); + evry->plugin_register(p, EVRY_PLUGIN_SUBJECT, 10); act = EVRY_ACTION_NEW(N_("Show Dialog"), - evry_type_register("E_SETTINGS"), 0, + evry->type_register("E_SETTINGS"), 0, "preferences-advanced", _action, NULL); - evry_action_register(act, 0); + evry->action_register(act, 0); + + active = EINA_TRUE; return EINA_TRUE; } @@ -122,17 +133,18 @@ _plugins_init(void) static void _plugins_shutdown(void) { + if (!active) return; + EVRY_PLUGIN_FREE(p); - evry_action_free(act); + evry->action_free(act); + + active = EINA_FALSE; } /***************************************************************************/ -static E_Module *module = NULL; -static Eina_Bool active = EINA_FALSE; - EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, @@ -142,24 +154,38 @@ EAPI E_Module_Api e_modapi = EAPI void * e_modapi_init(E_Module *m) { - module = m; + Eina_List *l; - if (e_datastore_get("everything_loaded")) - active = _plugins_init(); + if ((evry = e_datastore_get("everything_loaded"))) + _plugins_init(evry); + + evry_module = E_NEW(Evry_Module, 1); + evry_module->init = &_plugins_init; + evry_module->shutdown = &_plugins_shutdown; + + l = e_datastore_get("everything_modules"); + l = eina_list_append(l, evry_module); + e_datastore_set("everything_modules", l); e_module_delayed_set(m, 1); - + return m; } EAPI int e_modapi_shutdown(E_Module *m) { - if (active && e_datastore_get("everything_loaded")) + Eina_List *l; + + if (e_datastore_get("everything_loaded")) _plugins_shutdown(); - module = NULL; + l = e_datastore_get("everything_modules"); + l = eina_list_remove(l, evry_module); + e_datastore_set("everything_modules", l); + E_FREE(evry_module); + return 1; } diff --git a/src/modules/everything-windows/e_mod_main.c b/src/modules/everything-windows/e_mod_main.c index b58ea3cc1..e660fee31 100644 --- a/src/modules/everything-windows/e_mod_main.c +++ b/src/modules/everything-windows/e_mod_main.c @@ -32,7 +32,7 @@ _cb_border_remove(void *data, int type, void *event) p->items = eina_list_remove(p->items, it); eina_hash_del_by_key(border_hash, &(ev->border)); - evry_plugin_async_update(p, EVRY_ASYNC_UPDATE_ADD); + EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD); return 1; } diff --git a/src/modules/everything/Evry.h b/src/modules/everything/Evry.h index 8de963700..5220c5b13 100644 --- a/src/modules/everything/Evry.h +++ b/src/modules/everything/Evry.h @@ -2,29 +2,30 @@ #define EVRY_H #include "e.h" +#include "evry_types.h" -#define EVRY_API_VERSION 16 +#define EVRY_API_VERSION 17 -#define EVRY_ACTION_OTHER 0 +#define EVRY_ACTION_OTHER 0 #define EVRY_ACTION_FINISHED 1 #define EVRY_ACTION_CONTINUE 2 -#define EVRY_ASYNC_UPDATE_ADD 0 -#define EVRY_ASYNC_UPDATE_CLEAR 1 -#define EVRY_ASYNC_UPDATE_REFRESH 2 +#define EVRY_UPDATE_ADD 0 +#define EVRY_UPDATE_CLEAR 1 +#define EVRY_UPDATE_REFRESH 2 #define EVRY_COMPLETE_NONE 0 #define EVRY_COMPLETE_INPUT 1 #define EVRY_COMPLETE_BROWSE 2 -#define VIEW_MODE_NONE -1 -#define VIEW_MODE_LIST 0 -#define VIEW_MODE_DETAIL 1 -#define VIEW_MODE_THUMB 2 +#define VIEW_MODE_NONE -1 +#define VIEW_MODE_LIST 0 +#define VIEW_MODE_DETAIL 1 +#define VIEW_MODE_THUMB 2 -#define EVRY_PLUGIN_SUBJECT 0 -#define EVRY_PLUGIN_ACTION 1 -#define EVRY_PLUGIN_OBJECT 2 +#define EVRY_PLUGIN_SUBJECT 0 +#define EVRY_PLUGIN_ACTION 1 +#define EVRY_PLUGIN_OBJECT 2 extern int _e_module_evry_log_dom; @@ -43,24 +44,14 @@ extern int _e_module_evry_log_dom; #define WRN(...) EINA_LOG_DOM_WARN(_e_module_evry_log_dom , __VA_ARGS__) #define ERR(...) EINA_LOG_DOM_ERR(_e_module_evry_log_dom , __VA_ARGS__) -typedef struct _Evry_Plugin Evry_Plugin; -typedef struct _Evry_Item Evry_Item; -typedef struct _Evry_Item_App Evry_Item_App; -typedef struct _Evry_Item_File Evry_Item_File; -typedef struct _Evry_Action Evry_Action; typedef struct _Evry_State Evry_State; typedef struct _Evry_View Evry_View; typedef struct _History Evry_History; typedef struct _History_Entry History_Entry; typedef struct _History_Types History_Types; -typedef struct _History_Item History_Item; typedef struct _Config Evry_Config; -typedef struct _Plugin_Config Plugin_Config; -typedef struct _Plugin_Setting Plugin_Setting; typedef struct _Evry_Event_Item_Changed Evry_Event_Item_Changed; -typedef unsigned int Evry_Type; - #define EVRY_ITEM(_item) ((Evry_Item *)_item) #define EVRY_ACTN(_item) ((Evry_Action *) _item) #define EVRY_PLUGIN(_plugin) ((Evry_Plugin *) _plugin) @@ -118,6 +109,9 @@ typedef unsigned int Evry_Type; #define EVRY_PLUGIN_FREE(_p) \ if (_p) evry_plugin_free(EVRY_PLUGIN(_p)) +#define EVRY_PLUGIN_UPDATE(_p, _action) \ + if (_p) evry_plugin_update(EVRY_PLUGIN(_p), _action) + #define EVRY_PLUGIN_ITEMS_CLEAR(_p) { \ Evry_Item *it; \ @@ -147,183 +141,6 @@ typedef unsigned int Evry_Type; (x) = NULL; \ } while (0) -struct _Evry_Item -{ - /* label to show for this item */ - const char *label; - - /* optional: more information to be shown */ - const char *detail; - - /* optional: for 'static' fdo icon name, otherwise use _icon_get */ - const char *icon; - - /* item can be browsed, e.g. folders */ - Eina_Bool browseable; - - /* optional: for internally use by plugins */ - void *data; - - /* optional: priority hints for sorting */ - int priority; - - /* optional: store value of fuzzy match with input */ - int fuzzy_match; - - /* optional: plugin can set id to identify - * it in history otherwise label is used */ - const char *id; - - /* optional: context provided by item. e.g. to remember which action - * was performed on a file with a specific mimetype */ - const char *context; - - /* is set to type of Evry_Plugin by default */ - Evry_Type type; - - /* optional */ - Evry_Type subtype; - - /* do not set! */ - Eina_List *items; - - Evas_Object *(*icon_get) (Evry_Item *it, Evas *e); - void (*free) (Evry_Item *item); - - /* do not set by plugin! */ - Eina_Bool selected; - Eina_Bool marked; - Evry_Plugin *plugin; - int ref; - double usage; - History_Item *hi; -}; - -struct _Evry_Action -{ - Evry_Item base; - - /* identifier */ - const char *name; - - struct - { - /* requested type for action */ - Evry_Type type; - Evry_Type subtype; - /* handle multiple items */ - Eina_Bool accept_list; - - /* do not set ! */ - const Evry_Item *item; - Eina_List *items; - } it1; - - struct - { - Evry_Type type; - Evry_Type subtype; - Eina_Bool accept_list; - - /* do not set ! */ - const Evry_Item *item; - Eina_List *items; - } it2; - - - /* optional: this action is specific for a item 'context'. - e.g. 'copy' for file mime-type is not, 'image viewer' is. - default is FALSE */ - Eina_Bool remember_context; - - int (*action) (Evry_Action *act); - - /* optional: check whether action fits to chosen item */ - int (*check_item) (Evry_Action *act, const Evry_Item *it); - /* optional */ - void (*free) (Evry_Action *act); - /* optional: must be defined when action is browseable */ - Eina_List *(*fetch) (Evry_Action *act); -}; - -struct _Evry_Item_App -{ - Evry_Action base; - const char *file; - Efreet_Desktop *desktop; -}; - -struct _Evry_Item_File -{ - Evry_Item base; - const char *url; - const char *path; - const char *mime; -}; - -struct _Evry_Plugin -{ - Evry_Item base; - - /* identifier */ - const char *name; - - /* list of items visible for everything after fetch */ - Eina_List *items; - - /* required: get candidates matching string, fill 'items' list */ - int (*fetch) (Evry_Plugin *p, const char *input); - - /* required: run when state is removed in which this plugin is - active. free 'items' here */ - void (*finish) (Evry_Plugin *p); - - /* optional: plugin is added to the list of current plugins and - queried for results when not returning NULL. The previos - selectors item is passed, i.e. a plugin registered as action - receives the subject, a plugin registered as object receives the - action item. here you can check wheter the plugin can be queried, - for given context (provided by item) */ - Evry_Plugin *(*begin) (Evry_Plugin *p, const Evry_Item *item); - - /* optional: provide a list of subitems of 'item'. this function - must return a new instance which must be freed in 'finish' */ - Evry_Plugin *(*browse) (Evry_Plugin *p, const Evry_Item *item); - - /* optional: try to complete current item: - return: EVRY_COMPLETE_INPUT when input was changed - return: EVRY_COMPLETE_BROWSE to browse item */ - int (*complete) (Evry_Plugin *p, const Evry_Item *item, char **input); - - /* optional: handle key events: return positive when key was - handled */ - int (*cb_key_down) (Evry_Plugin *p, const Ecore_Event_Key *ev); - - /* optional: use this when begin returned a new instance or you - have extended plugin struct */ - void (*free) (Evry_Plugin *p); - - /* optional: whether the plugin uses evry_async_update to add new items */ - /* default FALSE */ - Eina_Bool async_fetch; - - /* optional: request items to be remembered for usage statistic */ - /* default TRUE */ - Eina_Bool history; - - /* optional: if transient, item is removed from history on cleanup */ - /* default FALSE */ - Eina_Bool transient; - - /* optional: config path registered for the module, to show - 'configure' button in everything config */ - const char *config_path; - - /* not to be set by plugin! */ - Plugin_Config *config; - unsigned int request; -}; - struct _Evry_State { @@ -430,47 +247,6 @@ struct _Config int min_w, min_h; }; -struct _Plugin_Config -{ - /* do not set! */ - const char *name; - int enabled; - - /* request initial sort order of this plugin */ - int priority; - - /* trigger to show plugin exclusively */ - const char *trigger; - - /* only show plugin when triggered */ - int trigger_only; - - /* preffered view mode */ - int view_mode; - - /* minimum input char to start query items, - this must be handled by plugin */ - int min_query; - - /* show items of plugin in aggregator */ - int aggregate; - - /* if not top-level the plugin is shown in aggregator - instead of the items */ - int top_level; - - /* Eina_Hash *settings; */ - - /* do not set! */ - Evry_Plugin *plugin; -}; - -/* struct _Plugin_Config_Setting - * { - * const char *str; - * double num; - * }; */ - struct _History_Entry { Eina_List *items; @@ -491,17 +267,6 @@ struct _History Eina_Bool changed; }; -struct _History_Item -{ - const char *plugin; - const char *context; - const char *input; - double last_used; - double usage; - int count; - int transient; - const char *data; -}; /* evry.c */ EAPI void evry_item_select(const Evry_State *s, Evry_Item *it); @@ -515,7 +280,7 @@ EAPI Evry_Item *evry_item_new(Evry_Item *base, Evry_Plugin *p, const char *label EAPI void evry_item_free(Evry_Item *it); EAPI void evry_item_ref(Evry_Item *it); -EAPI void evry_plugin_async_update(Evry_Plugin *plugin, int state); +EAPI void evry_plugin_update(Evry_Plugin *plugin, int state); EAPI void evry_clear_input(Evry_Plugin *p); /* evry_util.c */ @@ -525,7 +290,7 @@ EAPI int evry_fuzzy_match(const char *str, const char *match); EAPI Eina_List *evry_fuzzy_match_sort(Eina_List *items); EAPI int evry_util_exec_app(const Evry_Item *it_app, const Evry_Item *it_file); EAPI char *evry_util_url_escape(const char *string, int inlength); -EAPI char *evry_util_unescape(const char *string, int length); +EAPI char *evry_util_url_unescape(const char *string, int length); EAPI void evry_util_file_detail_set(Evry_Item_File *file); EAPI Eina_Bool evry_util_module_config_check(const char *module_name, int conf, int epoch, int version); EAPI Evas_Object *evry_util_icon_get(Evry_Item *it, Evas *e); @@ -535,7 +300,7 @@ EAPI void evry_event_item_changed(Evry_Item *it, int change_icon, int change_sel EAPI char *evry_util_md5_sum(const char *str); EAPI const char *evry_file_path_get(Evry_Item_File *file); -EAPI const char *evry_file_uri_get(Evry_Item_File *file); +EAPI const char *evry_file_url_get(Evry_Item_File *file); /* e_mod_main.c */ /* returns 1 when a new plugin config was created. in this case you can diff --git a/src/modules/everything/Makefile.am b/src/modules/everything/Makefile.am index c28c7bd7b..5d9700da5 100644 --- a/src/modules/everything/Makefile.am +++ b/src/modules/everything/Makefile.am @@ -21,7 +21,7 @@ pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH pkg_LTLIBRARIES = module.la # noinst_LTLIBRARIES = libfoo.la -EVRYHEADERS = Evry.h +EVRYHEADERS = Evry.h evry_api.h evry_types.h module_la_SOURCES = $(EVRYHEADERS) \ e_mod_main.c \ diff --git a/src/modules/everything/e_mod_main.c b/src/modules/everything/e_mod_main.c index 7a8ea44bf..e2d64c611 100644 --- a/src/modules/everything/e_mod_main.c +++ b/src/modules/everything/e_mod_main.c @@ -8,6 +8,7 @@ */ #include "e_mod_main.h" +#include "evry_api.h" /* #undef DBG * #define DBG(...) ERR(__VA_ARGS__) */ @@ -24,6 +25,8 @@ static void _config_free(void); static void _plugin_config_free(void); static int _cleanup_history(void *data); +static Evry_API *_api = NULL; + static E_Int_Menu_Augmentation *maug = NULL; static E_Action *act = NULL; @@ -33,7 +36,6 @@ static E_Config_DD *plugin_conf_edd = NULL; static E_Config_DD *plugin_setting_edd = NULL; static Ecore_Timer *cleanup_timer; - static int _update = 0; @@ -102,6 +104,9 @@ evry_type_get(Evry_Type type) EAPI void * e_modapi_init(E_Module *m) { + Eina_List *l; + Evry_Module *em; + _e_module_evry_log_dom = eina_log_domain_register ("e_module_everything", EINA_LOG_DEFAULT_COLOR); @@ -164,8 +169,44 @@ e_modapi_init(E_Module *m) /* make sure module is loaded before others */ e_module_priority_set(m, -1000); - e_datastore_set("everything_loaded", ""); + _api = E_NEW(Evry_API, 1); +#define SET(func) (_api->func = &evry_##func); + SET(api_version_check); + SET(item_new); + SET(item_free); + SET(item_ref); + SET(plugin_new); + SET(plugin_free); + SET(plugin_register); + SET(plugin_unregister); + SET(plugin_update); + SET(action_new); + SET(action_free); + SET(action_register); + SET(action_unregister); + SET(api_version_check); + SET(type_register); + SET(icon_mime_get); + SET(icon_theme_get); + SET(fuzzy_match); + SET(util_exec_app); + SET(util_url_escape); + SET(util_url_unescape); + SET(util_file_detail_set); + SET(util_plugin_items_add); + SET(util_md5_sum); + SET(util_icon_get); + SET(items_sort_func); + SET(event_item_changed); + SET(file_path_get); + SET(file_url_get); +#undef SET + + e_datastore_set("everything_loaded", _api); + EINA_LIST_FOREACH(e_datastore_get("everything_modules"), l, em) + em->init(_api); + /* cleanup every hour :) */ cleanup_timer = ecore_timer_add(3600, _cleanup_history, NULL); @@ -177,7 +218,15 @@ e_modapi_shutdown(E_Module *m __UNUSED__) { E_Config_Dialog *cfd; const char *t; + Eina_List *l; + Evry_Module *em; + + EINA_LIST_FOREACH(e_datastore_get("everything_modules"), l, em) + em->shutdown(); + e_datastore_del("everything_loaded"); + E_FREE(_api); + evry_shutdown(); view_thumb_shutdown(); @@ -215,7 +264,6 @@ e_modapi_shutdown(E_Module *m __UNUSED__) E_CONFIG_DD_FREE(conf_edd); E_CONFIG_DD_FREE(plugin_conf_edd); E_CONFIG_DD_FREE(plugin_setting_edd); - e_datastore_del("everything_loaded"); if (cleanup_timer) ecore_timer_del(cleanup_timer); diff --git a/src/modules/everything/evry.c b/src/modules/everything/evry.c index c2037c1c5..a7b6cc27b 100644 --- a/src/modules/everything/evry.c +++ b/src/modules/everything/evry.c @@ -535,7 +535,7 @@ evry_list_win_hide(void) } EAPI void -evry_plugin_async_update(Evry_Plugin *p, int action) +evry_plugin_update(Evry_Plugin *p, int action) { Evry_State *s; Evry_Plugin *agg; @@ -557,7 +557,7 @@ evry_plugin_async_update(Evry_Plugin *p, int action) agg = sel->aggregator; - if (action == EVRY_ASYNC_UPDATE_ADD) + if (action == EVRY_UPDATE_ADD) { if (!p->items && !s->trigger_active) { @@ -615,7 +615,7 @@ evry_plugin_async_update(Evry_Plugin *p, int action) _evry_view_update(s, NULL); } - else if (action == EVRY_ASYNC_UPDATE_REFRESH) + else if (action == EVRY_UPDATE_REFRESH) { _evry_view_clear(s); _evry_view_update(s, NULL); diff --git a/src/modules/everything/evry_api.h b/src/modules/everything/evry_api.h new file mode 100644 index 000000000..6323115d6 --- /dev/null +++ b/src/modules/everything/evry_api.h @@ -0,0 +1,190 @@ +#ifndef EVRY_API_H +#define EVRY_API_H + +#ifndef EVRY_H +#include "evry_types.h" + +#define EVRY_API_VERSION 17 + +#define EVRY_ACTION_OTHER 0 +#define EVRY_ACTION_FINISHED 1 +#define EVRY_ACTION_CONTINUE 2 + +#define EVRY_UPDATE_ADD 0 +#define EVRY_UPDATE_CLEAR 1 +#define EVRY_UPDATE_REFRESH 2 + +#define EVRY_COMPLETE_NONE 0 +#define EVRY_COMPLETE_INPUT 1 +#define EVRY_COMPLETE_BROWSE 2 + +#define VIEW_MODE_NONE -1 +#define VIEW_MODE_LIST 0 +#define VIEW_MODE_DETAIL 1 +#define VIEW_MODE_THUMB 2 + +#define EVRY_PLUGIN_SUBJECT 0 +#define EVRY_PLUGIN_ACTION 1 +#define EVRY_PLUGIN_OBJECT 2 +#endif + +typedef struct _Evry_API Evry_API; +typedef struct _Evry_Module Evry_Module; + +/*************************************************** + register module struct: + + Eina_List *l; + Evry_Module *em; + + em = E_NEW(Evry_Module, 1); + em->init = &_your_init_func; + em->shutdown = &_your_shutdown_func; + + l = e_datastore_get("everything_modules"); + l = eina_list_append(l, em); + e_datastore_set("everything_modules", l); +***************************************************/ + +struct _Evry_Module +{ + int (*init)(const Evry_API *api); + void (*shutdown)(void); +}; + +struct _Evry_API +{ + int (*api_version_check)(int version); + + Evry_Item *(*item_new)(Evry_Item *base, Evry_Plugin *p, const char *label, + Evas_Object *(*icon_get) (Evry_Item *it, Evas *e), + void (*cb_free) (Evry_Item *item)); + + void (*item_free)(Evry_Item *it); + void (*item_ref)(Evry_Item *it); + + Evry_Plugin *(*plugin_new)(Evry_Plugin *base, const char *name, + const char *label, const char *icon, + Evry_Type item_type, + Evry_Plugin *(*begin) (Evry_Plugin *p, const Evry_Item *item), + void (*cleanup) (Evry_Plugin *p), + int (*fetch) (Evry_Plugin *p, const char *input), + void (*free) (Evry_Plugin *p)); + + void (*plugin_free)(Evry_Plugin *p); + /* when a new plugin config was created return val is 1. in this + case you can set defaults of p->config otherwise zero */ + int (*plugin_register)(Evry_Plugin *p, int type, int priority); + void (*plugin_unregister)(Evry_Plugin *p); + void (*plugin_update)(Evry_Plugin *plugin, int state); + + Evry_Action *(*action_new)(const char *name, const char *label, + Evry_Type type1, Evry_Type type2, + const char *icon, + int (*action) (Evry_Action *act), + int (*check_item) (Evry_Action *act, const Evry_Item *it)); + + void (*action_free)(Evry_Action *act); + void (*action_register)(Evry_Action *act, int priority); + void (*action_unregister)(Evry_Action *act); + + Evry_Type (*type_register)(const char *type); + + /* evry_util.c */ + Evas_Object *(*icon_mime_get)(const char *mime, Evas *e); + Evas_Object *(*icon_theme_get)(const char *icon, Evas *e); + int (*fuzzy_match)(const char *str, const char *match); + int (*util_exec_app)(const Evry_Item *it_app, const Evry_Item *it_file); + char *(*util_url_escape)(const char *string, int inlength); + char *(*util_url_unescape)(const char *string, int length); + void (*util_file_detail_set)(Evry_Item_File *file); + int (*util_plugin_items_add)(Evry_Plugin *p, Eina_List *items, const char *input, int match_detail, int set_usage); + char *(*util_md5_sum)(const char *str); + Evas_Object *(*util_icon_get)(Evry_Item *it, Evas *e); + int (*items_sort_func)(const void *data1, const void *data2); + void (*event_item_changed)(Evry_Item *it, int change_icon, int change_selected); + + const char *(*file_path_get)(Evry_Item_File *file); + const char *(*file_url_get)(Evry_Item_File *file); +}; + +#ifndef EVRY_H +#define EVRY_ITEM(_item) ((Evry_Item *)_item) +#define EVRY_ACTN(_item) ((Evry_Action *) _item) +#define EVRY_PLUGIN(_plugin) ((Evry_Plugin *) _plugin) +#define EVRY_VIEW(_view) ((Evry_View *) _view) +#define EVRY_FILE(_it) ((Evry_Item_File *) _it) + +#define CHECK_TYPE(_item, _type) \ + (((Evry_Item *)_item)->type && ((Evry_Item *)_item)->type == _type) + +#define CHECK_SUBTYPE(_item, _type) \ + (((Evry_Item *)_item)->subtype && ((Evry_Item *)_item)->subtype == _type) + +#define IS_BROWSEABLE(_item) ((Evry_Item *)_item)->browseable + +#define GET_APP(_app, _item) Evry_Item_App *_app = (Evry_Item_App *) _item +#define GET_FILE(_file, _item) Evry_Item_File *_file = (Evry_Item_File *) _item +#define GET_EVRY_PLUGIN(_p, _plugin) Evry_Plugin *_p = (Evry_Plugin*) _plugin +#define GET_VIEW(_v, _view) View *_v = (View*) _view +#define GET_ACTION(_act, _item) Evry_Action *_act = (Evry_Action *) _item +#define GET_PLUGIN(_p, _plugin) Plugin *_p = (Plugin*) _plugin +#define GET_ITEM(_it, _any) Evry_Item *_it = (Evry_Item *) _any + +#define EVRY_ITEM_DATA_INT_SET(_item, _data) ((Evry_Item *)_item)->data = (void*)(long) _data +#define EVRY_ITEM_DATA_INT_GET(_item) (long) ((Evry_Item *)_item)->data +#define EVRY_ITEM_ICON_SET(_item, _icon) ((Evry_Item *)_item)->icon = _icon + +#define EVRY_ITEM_DETAIL_SET(_it, _detail) \ + if (EVRY_ITEM(_it)->detail) eina_stringshare_del(EVRY_ITEM(_it)->detail); \ + EVRY_ITEM(_it)->detail = eina_stringshare_add(_detail); + +#define EVRY_ITEM_LABEL_SET(_it, _label) \ + if (EVRY_ITEM(_it)->label) eina_stringshare_del(EVRY_ITEM(_it)->label); \ + EVRY_ITEM(_it)->label = eina_stringshare_add(_label); + +#define EVRY_ITEM_CONTEXT_SET(_it, _context) \ + if (EVRY_ITEM(_it)->context) eina_stringshare_del(EVRY_ITEM(_it)->context); \ + EVRY_ITEM(_it)->context = eina_stringshare_add(_context); + +#define EVRY_ITEM_NEW(_base, _plugin, _label, _icon_get, _free) \ + (_base *) evry->item_new(EVRY_ITEM(E_NEW(_base, 1)), EVRY_PLUGIN(_plugin), \ + _label, _icon_get, _free) + +#define EVRY_ITEM_FREE(_item) evry_item_free((Evry_Item *)_item) + +#define EVRY_PLUGIN_NEW(_base, _name, _icon, _item_type, _begin, _cleanup, _fetch, _free) \ + evry->plugin_new(EVRY_PLUGIN(E_NEW(_base, 1)), _name, _(_name), _icon, _item_type, \ + _begin, _cleanup, _fetch, _free) + + +#define EVRY_ACTION_NEW(_name, _in1, _in2, _icon, _action, _check) \ + evry->action_new(_name, _(_name), _in1, _in2, _icon, _action, _check) + + +#define EVRY_PLUGIN_FREE(_p) if (_p) evry->plugin_free(EVRY_PLUGIN(_p)) + + +#define EVRY_PLUGIN_ITEMS_CLEAR(_p) { \ + Evry_Item *it; \ + EINA_LIST_FREE(EVRY_PLUGIN(_p)->items, it) \ + it->fuzzy_match = 0; } + +#define EVRY_PLUGIN_ITEMS_FREE(_p) { \ + Evry_Item *it; \ + EINA_LIST_FREE(EVRY_PLUGIN(_p)->items, it) \ + evry->item_free(it); } + + +#define EVRY_PLUGIN_ITEMS_SORT(_p, _sortcb) \ + EVRY_PLUGIN(_p)->items = eina_list_sort \ + (EVRY_PLUGIN(_p)->items, eina_list_count(EVRY_PLUGIN(_p)->items), _sortcb) + +#define EVRY_PLUGIN_ITEM_APPEND(_p, _item) \ + EVRY_PLUGIN(_p)->items = eina_list_append(EVRY_PLUGIN(_p)->items, EVRY_ITEM(_item)) + +// should be renamed to ITEMS_FILTER +#define EVRY_PLUGIN_ITEMS_ADD(_plugin, _items, _input, _match_detail, _set_usage) \ + evry->util_plugin_items_add(EVRY_PLUGIN(_plugin), _items, _input, _match_detail, _set_usage) +#endif +#endif diff --git a/src/modules/everything/evry_types.h b/src/modules/everything/evry_types.h new file mode 100644 index 000000000..580c718db --- /dev/null +++ b/src/modules/everything/evry_types.h @@ -0,0 +1,240 @@ +#ifndef EVRY_TYPES_H +#define EVRY_TYPES_H + +typedef struct _Evry_Plugin Evry_Plugin; +typedef struct _Plugin_Config Plugin_Config; +typedef struct _Evry_Item Evry_Item; +typedef struct _Evry_Item_App Evry_Item_App; +typedef struct _Evry_Item_File Evry_Item_File; +typedef struct _Evry_Action Evry_Action; +typedef struct _History_Item History_Item; + +typedef unsigned int Evry_Type; + +struct _Evry_Item +{ + /* label to show for this item */ + const char *label; + + /* optional: more information to be shown */ + const char *detail; + + /* optional: for 'static' fdo icon name, otherwise use _icon_get */ + const char *icon; + + /* item can be browsed, e.g. folders */ + Eina_Bool browseable; + + /* optional: for internally use by plugins */ + void *data; + + /* optional: priority hints for sorting */ + int priority; + + /* optional: store value of fuzzy match with input */ + int fuzzy_match; + + /* optional: plugin can set id to identify + * it in history otherwise label is used */ + const char *id; + + /* optional: context provided by item. e.g. to remember which action + * was performed on a file with a specific mimetype */ + const char *context; + + /* is set to type of Evry_Plugin by default */ + Evry_Type type; + + /* optional */ + Evry_Type subtype; + + /* do not set! */ + Eina_List *items; + + Evas_Object *(*icon_get) (Evry_Item *it, Evas *e); + void (*free) (Evry_Item *item); + + /* do not set by plugin! */ + Eina_Bool selected; + Eina_Bool marked; + Evry_Plugin *plugin; + int ref; + double usage; + History_Item *hi; +}; + +struct _Evry_Action +{ + Evry_Item base; + + /* identifier */ + const char *name; + + struct + { + /* requested type for action */ + Evry_Type type; + Evry_Type subtype; + /* handle multiple items */ + Eina_Bool accept_list; + + /* do not set ! */ + const Evry_Item *item; + Eina_List *items; + } it1; + + struct + { + Evry_Type type; + Evry_Type subtype; + Eina_Bool accept_list; + + /* do not set ! */ + const Evry_Item *item; + Eina_List *items; + } it2; + + + /* optional: this action is specific for a item 'context'. + e.g. 'copy' for file mime-type is not, 'image viewer' is. + default is FALSE */ + Eina_Bool remember_context; + + int (*action) (Evry_Action *act); + + /* optional: check whether action fits to chosen item */ + int (*check_item) (Evry_Action *act, const Evry_Item *it); + /* optional */ + void (*free) (Evry_Action *act); + /* optional: must be defined when action is browseable */ + Eina_List *(*fetch) (Evry_Action *act); +}; + +struct _Evry_Item_App +{ + Evry_Action base; + const char *file; + Efreet_Desktop *desktop; +}; + +struct _Evry_Item_File +{ + Evry_Item base; + /* path and url must always be checked with + evry_file_path/uri_get before use !!! */ + const char *url; + const char *path; + const char *mime; +}; + +struct _Evry_Plugin +{ + Evry_Item base; + + /* identifier */ + const char *name; + + /* list of items visible for everything after fetch */ + Eina_List *items; + + /* required: get candidates matching string, fill 'items' list */ + int (*fetch) (Evry_Plugin *p, const char *input); + + /* required: run when state is removed in which this plugin is + active. free 'items' here */ + void (*finish) (Evry_Plugin *p); + + /* optional: plugin is added to the list of current plugins and + queried for results when not returning NULL. The previos + selectors item is passed, i.e. a plugin registered as action + receives the subject, a plugin registered as object receives the + action item. here you can check wheter the plugin can be queried, + for given context (provided by item) */ + Evry_Plugin *(*begin) (Evry_Plugin *p, const Evry_Item *item); + + /* optional: provide a list of subitems of 'item'. this function + must return a new instance which must be freed in 'finish' */ + Evry_Plugin *(*browse) (Evry_Plugin *p, const Evry_Item *item); + + /* optional: try to complete current item: + return: EVRY_COMPLETE_INPUT when input was changed + return: EVRY_COMPLETE_BROWSE to browse item */ + int (*complete) (Evry_Plugin *p, const Evry_Item *item, char **input); + + /* optional: handle key events: return positive when key was + handled */ + int (*cb_key_down) (Evry_Plugin *p, const Ecore_Event_Key *ev); + + /* optional: use this when begin returned a new instance or you + have extended plugin struct */ + void (*free) (Evry_Plugin *p); + + /* optional: whether the plugin uses evry_async_update to add new items */ + /* default FALSE */ + Eina_Bool async_fetch; + + /* optional: request items to be remembered for usage statistic */ + /* default TRUE */ + Eina_Bool history; + + /* optional: if transient, item is removed from history on cleanup */ + /* default FALSE */ + Eina_Bool transient; + + /* optional: config path registered for the module, to show + 'configure' button in everything config */ + const char *config_path; + + /* not to be set by plugin! */ + Plugin_Config *config; + unsigned int request; +}; + +struct _Plugin_Config +{ + /* do not set! */ + const char *name; + int enabled; + + /* request initial sort order of this plugin */ + int priority; + + /* trigger to show plugin exclusively */ + const char *trigger; + + /* only show plugin when triggered */ + int trigger_only; + + /* preffered view mode */ + int view_mode; + + /* minimum input char to start query items, + this must be handled by plugin */ + int min_query; + + /* show items of plugin in aggregator */ + int aggregate; + + /* if not top-level the plugin is shown in aggregator + instead of the items */ + int top_level; + + /* Eina_Hash *settings; */ + + /* do not set! */ + Evry_Plugin *plugin; +}; + +struct _History_Item +{ + const char *plugin; + const char *context; + const char *input; + double last_used; + double usage; + int count; + int transient; + const char *data; +}; + +#endif diff --git a/src/modules/everything/evry_util.c b/src/modules/everything/evry_util.c index 4e34a2c48..f985e3f47 100644 --- a/src/modules/everything/evry_util.c +++ b/src/modules/everything/evry_util.c @@ -685,7 +685,7 @@ evry_util_module_config_check(const char *module_name, int conf, int epoch, int #define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x))) EAPI char * -evry_util_unescape(const char *string, int length) +evry_util_url_unescape(const char *string, int length) { int alloc = (length?length:(int)strlen(string))+1; char *ns = malloc(alloc); @@ -812,7 +812,7 @@ evry_file_path_get(Evry_Item_File *file) tmp = file->url + 7; else return NULL; - if (!(path = evry_util_unescape(tmp, 0))) + if (!(path = evry_util_url_unescape(tmp, 0))) return NULL; file->path = eina_stringshare_add(path); @@ -823,7 +823,7 @@ evry_file_path_get(Evry_Item_File *file) } EAPI const char* -evry_file_uri_get(Evry_Item_File *file) +evry_file_url_get(Evry_Item_File *file) { char buf[PATH_MAX];