enlightenment/src/modules/everything/evry_plug_actions.c

233 lines
4.6 KiB
C

#include "e_mod_main.h"
/* action selector plugin: provides list of actions registered for
candidate types provided by current plugin */
typedef struct _Plugin Plugin;
struct _Plugin
{
Evry_Plugin base;
Evry_Selector *selector;
Eina_List *actions;
Eina_Bool parent;
Evry_Action *action;
};
static Evry_Plugin *_base_plug = NULL;
static void
_finish(Evry_Plugin *plugin)
{
GET_PLUGIN(p, plugin);
Evry_Action *act;
if (p->parent)
{
EINA_LIST_FREE(p->actions, act);
E_FREE(p);
}
else
{
EINA_LIST_FREE(p->actions, act);
}
}
static Evry_Plugin *
_begin(Evry_Plugin *plugin, const Evry_Item *it)
{
GET_PLUGIN(p, plugin);
Evry_Action *act;
Eina_List *l;
const char *type;
if (!it || !it->type) return NULL;
type = it->type;
if (it->browseable)
{
EINA_LIST_FOREACH(evry_conf->actions, l, act)
{
if (act == EVRY_ACTN(it))
{
p = E_NEW(Plugin, 1);
p->base = *plugin;
p->base.items = NULL;
p->actions = act->fetch(act);
p->parent = EINA_TRUE;
p->action = act;
return EVRY_PLUGIN(p);
}
}
}
EINA_LIST_FOREACH(evry_conf->actions, l, act)
{
if ((!act->it1.type) ||
((act->it1.type == type) &&
(!act->check_item || act->check_item(act, it))))
{
act->base.plugin = plugin;
if (!eina_list_data_find_list(p->actions, act))
{
p->actions = eina_list_append(p->actions, act);
}
continue;
}
p->actions = eina_list_remove(p->actions, act);
}
if (!p->actions) return NULL;
return plugin;
}
static int
_cb_sort(const void *data1, const void *data2)
{
const Evry_Item *it1 = data1;
const Evry_Item *it2 = data2;
if (it1->fuzzy_match || it2->fuzzy_match)
{
if (it1->fuzzy_match && !it2->fuzzy_match)
return -1;
if (!it1->fuzzy_match && it2->fuzzy_match)
return 1;
if (it1->fuzzy_match - it2->fuzzy_match)
return (it1->fuzzy_match - it2->fuzzy_match);
}
if (it1->priority - it2->priority)
return (it1->priority - it2->priority);
return 0;
}
static int
_fetch(Evry_Plugin *plugin, const char *input)
{
GET_PLUGIN(p, plugin);
Eina_List *l;
Evry_Item *it;
int match;
EVRY_PLUGIN_ITEMS_CLEAR(p);
EINA_LIST_FOREACH(p->actions, l, it)
{
match = evry_fuzzy_match(it->label, input);
if (!input || match)
{
it->fuzzy_match = match;
EVRY_PLUGIN_ITEM_APPEND(p, it);
}
}
if (!plugin->items) return 0;
EVRY_PLUGIN_ITEMS_SORT(p, _cb_sort);
return 1;
}
Evry_Plugin *
evry_plug_actions_new(Evry_Selector *sel, int type)
{
Evry_Plugin *plugin;
plugin = EVRY_PLUGIN_NEW(Plugin, N_("Actions"), NULL, NULL, _begin, _finish, _fetch, NULL);
GET_PLUGIN(p, plugin);
p->selector = sel;
evry_plugin_register(plugin, type, 2);
return plugin;
}
/***************************************************************************/
int evry_plug_actions_init()
{
_base_plug = evry_plugin_new(NULL, _("Actions"), NULL, NULL, NULL, NULL, NULL, NULL, NULL);
return 1;
}
void evry_plug_actions_shutdown()
{
Evry_Action *a;
evry_plugin_free(_base_plug);
EINA_LIST_FREE(evry_conf->actions, a)
evry_action_free(a);
}
EAPI void
evry_action_register(Evry_Action *act, int priority)
{
EVRY_ITEM(act)->priority = priority;
evry_conf->actions = eina_list_append(evry_conf->actions, act);
/* TODO sorting, initialization, etc */
}
EAPI void
evry_action_unregister(Evry_Action *act)
{
evry_conf->actions = eina_list_remove(evry_conf->actions, act);
/* finish */
}
static void
_action_free_cb(Evry_Item *it)
{
GET_ACTION(act, it);
if (act->name) eina_stringshare_del(act->name);
if (act->it1.type) eina_stringshare_del(act->it1.type);
if (act->it2.type) eina_stringshare_del(act->it2.type);
E_FREE(act);
}
EAPI Evry_Action *
evry_action_new(const char *name, const char *label,
const char *type_in1, const char *type_in2,
const char *icon,
int (*action) (Evry_Action *act),
int (*check_item) (Evry_Action *act, const Evry_Item *it))
{
Evry_Action *act = E_NEW(Evry_Action, 1);
evry_item_new(EVRY_ITEM(act), _base_plug, label, NULL, _action_free_cb);
act->base.icon = icon;
act->base.type = eina_stringshare_ref(EVRY_TYPE_ACTION);
act->name = eina_stringshare_add(name);
act->it1.type = (type_in1 ? eina_stringshare_add(type_in1) : NULL);
act->it2.type = (type_in2 ? eina_stringshare_add(type_in2) : NULL);
act->action = action;
act->check_item = check_item;
return act;
}
EAPI void
evry_action_free(Evry_Action *act)
{
evry_action_unregister(act);
evry_item_free(EVRY_ITEM(act));
}