enlightenment/src/modules/everything/evry_plug_aggregator.c

350 lines
7.2 KiB
C

#include "e_mod_main.h"
//TODO min input for items not in history
#define MAX_ITEMS 50
typedef struct _Plugin Plugin;
struct _Plugin
{
Evry_Plugin base;
int type;
Evry_Window *win;
Evry_Item *warning;
};
static int
_fetch(Evry_Plugin *plugin, const char *input)
{
Plugin *p = (Plugin *) plugin;
Evry_Plugin *pp;
Evry_State *s;
Eina_List *l, *ll, *lp = NULL;
Evry_Item *it, *it2;
int i, top_level = 0, subj_sel = 0, inp_len = 0, cnt = 0;
Eina_List *items = NULL;
const char *context = NULL;
char buf[128];
Evry_Selector *sel = p->win->selectors[p->type];
if (input && input[0])
inp_len = strlen(input);
else
input = NULL;
EVRY_PLUGIN_ITEMS_FREE(p);
s = sel->state;
if (!s) return 0;
if (sel == p->win->selectors[0])
subj_sel = 1;
if (!sel->states->next)
top_level = 1;
/* get current items' context ... */
for (i = 1; i < 3; i++)
{
if (sel == p->win->selectors[i])
{
it = p->win->selectors[i-1]->state->cur_item;
if (it) context = it->context;
}
}
/* collect plugins to be shown in aggregator */
EINA_LIST_FOREACH(s->cur_plugins, l, pp)
{
if (!pp->config->aggregate)
continue;
if (pp == plugin)
continue;
if (top_level && !pp->config->top_level)
continue;
lp = eina_list_append(lp, pp);
}
if (top_level && (!s->trigger_active))
{
/* show non-top-level plugins as item */
EINA_LIST_FOREACH(s->plugins, l, pp)
{
int min_fuzz = 0;
double max_usage = 0.0;
if (pp->config->top_level)
continue;
if (pp == plugin)
continue;
if (!pp->items)
continue;
/* give plugin item the highest priority of its items */
EINA_LIST_FOREACH(pp->items, ll, it)
{
if (it->usage >= 0)
evry_history_item_usage_set(it, input, context);
if (it->usage && it->usage > max_usage)
{
max_usage = it->usage;
}
if (it->fuzzy_match == 0)
it->fuzzy_match = evry_fuzzy_match(it->label, input);
if ((!min_fuzz) || ((it->fuzzy_match > 0) &&
(it->fuzzy_match < min_fuzz)))
min_fuzz = it->fuzzy_match;
}
GET_ITEM(it, pp);
it->hi = NULL;
evry_history_item_usage_set(it, NULL, NULL);
it->usage /= 100.0;
if (it->usage && max_usage && (it->usage < max_usage))
it->usage = max_usage;
it->fuzzy_match = min_fuzz;
IF_RELEASE(it->detail);
snprintf(buf, sizeof(buf), "%d %s",
eina_list_count(pp->items), _("Items"));
it->detail = eina_stringshare_add(buf);
items = eina_list_append(items, it);
}
/* only one plugin: show items */
if ((eina_list_count(s->cur_plugins)) == 1 && items &&
(pp = eina_list_data_get(items)) && (pp->config->aggregate))
{
eina_list_free(items);
items = NULL;
EINA_LIST_FOREACH(pp->items, l, it)
{
if (it->usage >= 0)
evry_history_item_usage_set(it, input, context);
if (it->fuzzy_match == 0)
it->fuzzy_match = evry_fuzzy_match(it->label, input);
items = eina_list_append(items, it);
}
}
#if 0
/* append all plugins as items (which were not added above) */
if (inp_len >= plugin->config->min_query)
{
EINA_LIST_FOREACH(s->plugins, l, pp)
{
if (!strcmp(pp->name, "Actions"))
continue;
/* items MUST only conatin plugins here ! */
EINA_LIST_FOREACH(items, ll, pp2)
if (pp2->name == pp->name) break;
if (pp2)
continue;
GET_ITEM(it, pp);
if ((!input) ||
(it->fuzzy_match = evry_fuzzy_match(it->label, input)))
{
evry_history_item_usage_set(it, input, NULL);
it->usage /= 100.0;
EVRY_ITEM(pp)->plugin->state = s;
items = eina_list_append(items, pp);
}
}
}
#endif
if (!lp && (eina_list_count(items) < 2))
{
if (items) eina_list_free(items);
return 0;
}
}
if (!lp && !items)
return 0;
/* if there is only one plugin append all items */
if (lp && !lp->next)
{
pp = eina_list_data_get(lp);
EINA_LIST_FOREACH(pp->items, l, it)
{
if (it->usage >= 0)
evry_history_item_usage_set(it, input, context);
if (it->fuzzy_match == 0)
it->fuzzy_match = evry_fuzzy_match(it->label, input);
items = eina_list_append(items, it);
}
}
/* if there is input append all items that match */
else if (input)
{
EINA_LIST_FOREACH(lp, l, pp)
{
EINA_LIST_FOREACH(pp->items, ll, it)
{
if (it->fuzzy_match == 0)
it->fuzzy_match = evry_fuzzy_match(it->label, input);
if (it->usage >= 0)
evry_history_item_usage_set(it, input, context);
if ((subj_sel) && (top_level) &&
(!it->usage) && (inp_len < plugin->config->min_query))
continue;
items = eina_list_append(items, it);
}
}
}
/* no input: append all items that are in history */
else
{
EINA_LIST_FOREACH(lp, l, pp)
{
EINA_LIST_FOREACH(pp->items, ll, it)
{
if (((it->usage >= 0) &&
(evry_history_item_usage_set(it, input, context))) ||
(!subj_sel))
{
it->fuzzy_match = 0;
items = eina_list_append(items, it);
}
}
}
}
if ((!top_level) && (eina_list_count(items) < MAX_ITEMS))
{
EINA_LIST_FOREACH(lp, l, pp)
{
EINA_LIST_FOREACH(pp->items, ll, it)
{
if (eina_list_data_find_list(items, it))
continue;
items = eina_list_append(items, it);
}
}
}
items = eina_list_sort(items, -1, evry_items_sort_func);
EINA_LIST_FOREACH(items, l, it)
{
/* remove duplicates provided by different plugins */
if (it->id)
{
EINA_LIST_FOREACH(p->base.items, ll, it2)
{
if ((it->plugin->name != it2->plugin->name) &&
(it->type == it2->type) &&
(it->id == it2->id))
break;
}
}
if (!it->id || !it2)
{
evry_item_ref(it);
EVRY_PLUGIN_ITEM_APPEND(p, it);
}
if (cnt++ > MAX_ITEMS)
break;
}
if (lp) eina_list_free(lp);
if (items)
{
eina_list_free(items);
}
/* 'text' and 'actions' are always loaded */
else if ((subj_sel) && (eina_list_count(s->plugins) == 2))
{
evry_item_ref(p->warning);
EVRY_PLUGIN_ITEM_APPEND(p, p->warning);
}
return !!(p->base.items);
}
static void
_finish(Evry_Plugin *plugin)
{
GET_PLUGIN(p, plugin);
EVRY_PLUGIN_ITEMS_FREE(p);
E_FREE(p);
}
static Evry_Plugin *
_begin(Evry_Plugin *plugin, const Evry_Item *it __UNUSED__)
{
Plugin *p;
GET_PLUGIN(base, plugin);
EVRY_PLUGIN_INSTANCE(p, plugin);
p->type = base->type;
p->win = base->win;
p->warning = base->warning;
return EVRY_PLUGIN(p);
}
static void
_free(Evry_Plugin *plugin)
{
GET_PLUGIN(p, plugin);
evry_item_free(p->warning);
free(p);
}
Evry_Plugin *
evry_aggregator_new(Evry_Window *win, int type)
{
Evry_Plugin *p;
p = EVRY_PLUGIN_NEW(Plugin, N_("All"), NULL, 0, _begin, _finish, _fetch, _free);
if (evry_plugin_register(p, type, -1))
{
if (type == EVRY_PLUGIN_SUBJECT)
p->config->view_mode = VIEW_MODE_THUMB;
}
GET_PLUGIN(pa, p);
pa->win = win;
pa->type = type;
pa->warning = evry_item_new(NULL, p, N_("No plugins loaded"), NULL, NULL);
pa->warning->type = EVRY_TYPE_NONE;
return p;
}