enlightenment/src/modules/everything/evry_plug_aggregator.c

283 lines
6.2 KiB
C

#include "e_mod_main.h"
typedef struct _Plugin Plugin;
struct _Plugin
{
Evry_Plugin base;
Evry_Selector *selector;
};
static int
_cb_sort_recent(const void *data1, const void *data2)
{
const Evry_Item *it1 = data1;
const Evry_Item *it2 = data2;
if (it1->usage && it2->usage)
return (it2->usage - it1->usage);
if (it1->usage && !it2->usage)
return -1;
if (it2->usage && !it1->usage)
return 1;
if ((it1->plugin == action_selector) ||
(it2->plugin == action_selector))
{
if ((it1->plugin == action_selector) &&
(it2->plugin == action_selector))
return (it1->priority - it2->priority);
else if (it1->plugin == action_selector)
return ((it1->plugin->config->priority + it1->priority)
- it2->plugin->config->priority);
else
return (it1->plugin->config->priority -
(it2->plugin->config->priority + it2->priority));
}
return -1;
}
static int
_cb_sort(const void *data1, const void *data2)
{
const Evry_Item *it1 = data1;
const Evry_Item *it2 = data2;
if (it1->usage && it2->usage)
return (it2->usage - it1->usage);
if (it1->usage && !it2->usage)
return -1;
if (it2->usage && !it1->usage)
return 1;
if ((it1->plugin == action_selector) ||
(it2->plugin == action_selector))
{
if ((it1->plugin == action_selector) &&
(it2->plugin == action_selector))
return (it1->priority - it2->priority);
else if (it1->plugin == action_selector)
return ((it1->plugin->config->priority + it1->priority)
- it2->plugin->config->priority);
else
return (it1->plugin->config->priority -
(it1->plugin->config->priority + it2->priority));
}
if ((it1->plugin == it2->plugin) &&
(it1->priority - it2->priority))
return (it1->priority - it2->priority);
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->plugin->config->priority - it2->plugin->config->priority)
return (it1->plugin->config->priority - it2->plugin->config->priority);
if (it1->priority - it2->priority)
return (it1->priority - it2->priority);
return strcasecmp(it1->label, it2->label);
}
static int
_fetch(Evry_Plugin *plugin, const char *input)
{
Plugin *p = (Plugin *) plugin;
Evry_Plugin *pp;
Evry_State *s;
Eina_List *l, *ll, *lll, *lp;
Evry_Item *it;
int cnt = 0;
Eina_List *items = NULL;
History_Entry *he;
History_Item *hi;
const char *id;
EVRY_PLUGIN_ITEMS_FREE(p);
s = p->selector->state;
/* first is aggregator itself */
lp = s->cur_plugins->next;
if (input[0])
{
EINA_LIST_FOREACH(lp, l, pp)
{
EINA_LIST_FOREACH(pp->items, ll, it)
{
if (!it->fuzzy_match)
it->fuzzy_match = evry_fuzzy_match(it->label, input);
if (it->fuzzy_match || p->selector == selectors[2])
{
evry_item_ref(it);
items = eina_list_append(items, it);
EVRY_PLUGIN_ITEM_APPEND(p, it);
}
}
}
}
/* always append items of action selector */
if (!input[0] && (p->selector == selectors[1]))
{
EINA_LIST_FOREACH(lp, l, pp)
{
for (cnt = 0, ll = pp->items; ll && cnt < 50; ll = ll->next, cnt++)
{
if (!items || !eina_list_data_find_list(items, ll->data))
{
it = ll->data;
evry_item_ref(it);
it->fuzzy_match = 0;
EVRY_PLUGIN_ITEM_APPEND(p, it);
}
}
}
}
EINA_LIST_FOREACH(lp, l, pp)
{
EINA_LIST_FOREACH(pp->items, ll, it)
{
cnt = 1;
if (it->usage == 0)
continue;
if ((it->usage > 0) && (!eina_list_data_find_list(items, it)))
{
evry_item_ref(it);
it->fuzzy_match = 0;
items = eina_list_append(items, it);
EVRY_PLUGIN_ITEM_APPEND(p, it);
continue;
}
if (it->plugin->item_id)
id = it->plugin->item_id(it->plugin, it);
else
id = it->label;
if ((he = eina_hash_find(p->selector->history, id)))
{
EINA_LIST_FOREACH(he->items, lll, hi)
{
if ((hi->plugin == it->plugin->name) &&
((!input[0]) || (!input[0] && !hi->input) ||
(!strncmp(input, hi->input, strlen(input))) ||
(!strncmp(input, hi->input, strlen(hi->input)))))
{
cnt++;
it->usage += hi->last_used;
}
}
it->usage /= (double)cnt;
if (!eina_list_data_find_list(items, it))
{
evry_item_ref(it);
it->fuzzy_match = 0;
items = eina_list_append(items, it);
EVRY_PLUGIN_ITEM_APPEND(p, it);
}
}
else it->usage = 0;
}
}
/* NOTE this is kind of weird. list_count returns 2 even if there is
only one item in list */
if (eina_list_count(lp) == 2)
{
pp = lp->data;
EINA_LIST_FOREACH(pp->items, l, it)
{
if (!eina_list_data_find_list(items, it))
{
evry_item_ref(it);
it->fuzzy_match = 0;
EVRY_PLUGIN_ITEM_APPEND(p, it);
}
}
}
if (items) eina_list_free(items);
if (input[0])
{
EVRY_PLUGIN_ITEMS_SORT(p, _cb_sort);
}
else
{
EVRY_PLUGIN_ITEMS_SORT(p, _cb_sort_recent);
}
return 1;
}
static int
_action(Evry_Plugin *plugin, const Evry_Item *it)
{
if (it->plugin && it->plugin->action)
return it->plugin->action(it->plugin, it);
return 0;
}
static void
_cleanup(Evry_Plugin *plugin)
{
EVRY_PLUGIN_ITEMS_FREE(plugin);
}
static Evas_Object *
_icon_get(Evry_Plugin *plugin, const Evry_Item *it, Evas *e)
{
if (it->plugin && it->plugin->icon_get)
return it->plugin->icon_get(it->plugin, it, e);
return NULL;
}
Evry_Plugin *
evry_plug_aggregator_new(Evry_Selector *selector)
{
Plugin *p;
Plugin_Config *pc;
p = E_NEW(Plugin, 1);
evry_plugin_new(EVRY_PLUGIN(p), "All", 0, "", "", 0, NULL, NULL,
NULL, _cleanup, _fetch, _action, _icon_get,
NULL, NULL);
pc = E_NEW(Plugin_Config, 1);
pc->enabled = 1;
pc->priority = -1;
EVRY_PLUGIN(p)->config = pc;
p->selector = selector;
return EVRY_PLUGIN(p);
}
void
evry_plug_aggregator_free(Evry_Plugin *plugin)
{
PLUGIN(p, plugin);
EVRY_PLUGIN_FREE(p);
}