2009-08-30 05:01:50 -07:00
|
|
|
#include "e_mod_main.h"
|
|
|
|
|
2009-09-24 16:08:59 -07:00
|
|
|
#define HISTORY_VERSION 8
|
2009-08-31 08:12:43 -07:00
|
|
|
|
2009-09-02 12:43:16 -07:00
|
|
|
#define SEVEN_DAYS 604800
|
|
|
|
|
|
|
|
#define TIME_FACTOR(_now) (1.0 - (evry_hist->begin / _now)) / 1000000000000000.0
|
2009-08-31 02:21:51 -07:00
|
|
|
|
|
|
|
typedef struct _Cleanup_Data Cleanup_Data;
|
|
|
|
|
|
|
|
struct _Cleanup_Data
|
|
|
|
{
|
|
|
|
double time;
|
|
|
|
Eina_List *keys;
|
2009-08-31 11:48:54 -07:00
|
|
|
Eina_Bool normalize;
|
2009-09-24 16:08:59 -07:00
|
|
|
const char *plugin;
|
2009-08-31 02:21:51 -07:00
|
|
|
};
|
2009-08-30 05:01:50 -07:00
|
|
|
|
|
|
|
static E_Config_DD *hist_entry_edd = NULL;
|
|
|
|
static E_Config_DD *hist_item_edd = NULL;
|
|
|
|
static E_Config_DD *hist_edd = NULL;
|
|
|
|
|
2010-04-10 13:05:57 -07:00
|
|
|
Evry_History *evry_hist = NULL;
|
2009-08-30 05:01:50 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
evry_history_init(void)
|
|
|
|
{
|
|
|
|
#undef T
|
|
|
|
#undef D
|
|
|
|
hist_item_edd = E_CONFIG_DD_NEW("History_Item", History_Item);
|
|
|
|
#define T History_Item
|
|
|
|
#define D hist_item_edd
|
2009-09-02 12:43:16 -07:00
|
|
|
E_CONFIG_VAL(D, T, plugin, STR);
|
|
|
|
E_CONFIG_VAL(D, T, context, STR);
|
|
|
|
E_CONFIG_VAL(D, T, input, STR);
|
2009-08-30 05:01:50 -07:00
|
|
|
E_CONFIG_VAL(D, T, last_used, DOUBLE);
|
2009-09-02 12:43:16 -07:00
|
|
|
E_CONFIG_VAL(D, T, usage, DOUBLE);
|
|
|
|
E_CONFIG_VAL(D, T, count, INT);
|
2009-08-31 08:12:43 -07:00
|
|
|
E_CONFIG_VAL(D, T, transient, INT);
|
2010-04-16 18:10:20 -07:00
|
|
|
E_CONFIG_VAL(D, T, type, STR);
|
2009-08-30 05:01:50 -07:00
|
|
|
#undef T
|
|
|
|
#undef D
|
|
|
|
hist_entry_edd = E_CONFIG_DD_NEW("History_Entry", History_Entry);
|
|
|
|
#define T History_Entry
|
|
|
|
#define D hist_entry_edd
|
|
|
|
E_CONFIG_LIST(D, T, items, hist_item_edd);
|
|
|
|
#undef T
|
|
|
|
#undef D
|
2010-04-10 13:05:57 -07:00
|
|
|
hist_edd = E_CONFIG_DD_NEW("History", Evry_History);
|
|
|
|
#define T Evry_History
|
2009-08-30 05:01:50 -07:00
|
|
|
#define D hist_edd
|
2009-09-02 12:43:16 -07:00
|
|
|
E_CONFIG_VAL(D, T, version, INT);
|
|
|
|
E_CONFIG_VAL(D, T, begin, DOUBLE);
|
2009-08-30 05:01:50 -07:00
|
|
|
E_CONFIG_HASH(D, T, subjects, hist_entry_edd);
|
|
|
|
E_CONFIG_HASH(D, T, actions, hist_entry_edd);
|
|
|
|
#undef T
|
2009-08-31 06:04:53 -07:00
|
|
|
#undef D
|
2009-08-30 05:01:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_hist_free_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata)
|
|
|
|
{
|
|
|
|
History_Entry *he = data;
|
|
|
|
History_Item *hi;
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
EINA_LIST_FREE(he->items, hi)
|
|
|
|
{
|
|
|
|
if (hi->input)
|
|
|
|
eina_stringshare_del(hi->input);
|
|
|
|
if (hi->plugin)
|
|
|
|
eina_stringshare_del(hi->plugin);
|
|
|
|
if (hi->context)
|
|
|
|
eina_stringshare_del(hi->context);
|
2010-04-16 18:10:20 -07:00
|
|
|
if (hi->type)
|
|
|
|
eina_stringshare_del(hi->type);
|
2009-08-30 05:01:50 -07:00
|
|
|
E_FREE(hi);
|
|
|
|
}
|
|
|
|
|
|
|
|
E_FREE(he);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-30 07:54:25 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_hist_cleanup_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata)
|
|
|
|
{
|
|
|
|
History_Entry *he = data;
|
2009-08-31 02:21:51 -07:00
|
|
|
Cleanup_Data *d = fdata;
|
2009-08-30 07:54:25 -07:00
|
|
|
History_Item *hi;
|
2009-08-31 02:21:51 -07:00
|
|
|
Eina_List *l, *ll;
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-30 07:54:25 -07:00
|
|
|
EINA_LIST_FOREACH_SAFE(he->items, l, ll, hi)
|
|
|
|
{
|
2009-09-24 16:08:59 -07:00
|
|
|
/* item for this plugi nneed to be removed, e.g. on updates */
|
|
|
|
if (d->plugin)
|
|
|
|
{
|
|
|
|
if (hi->plugin == d->plugin)
|
|
|
|
hi->transient = 1;
|
|
|
|
}
|
|
|
|
|
2009-09-02 12:43:16 -07:00
|
|
|
if (hi->last_used < d->time - SEVEN_DAYS)
|
|
|
|
{
|
|
|
|
hi->count--;
|
|
|
|
hi->last_used = d->time - SEVEN_DAYS/2;
|
|
|
|
}
|
|
|
|
|
2009-08-31 02:21:51 -07:00
|
|
|
/* item is transient or too old */
|
2009-08-31 08:12:43 -07:00
|
|
|
if (!hi->count || hi->transient)
|
2009-08-30 07:54:25 -07:00
|
|
|
{
|
|
|
|
if (hi->input)
|
|
|
|
eina_stringshare_del(hi->input);
|
|
|
|
if (hi->plugin)
|
|
|
|
eina_stringshare_del(hi->plugin);
|
|
|
|
if (hi->context)
|
|
|
|
eina_stringshare_del(hi->context);
|
2010-04-16 18:10:20 -07:00
|
|
|
if (hi->type)
|
|
|
|
eina_stringshare_del(hi->type);
|
2009-08-30 07:54:25 -07:00
|
|
|
E_FREE(hi);
|
|
|
|
|
|
|
|
he->items = eina_list_remove_list(he->items, l);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!he->items)
|
|
|
|
{
|
|
|
|
E_FREE(he);
|
2009-08-31 02:21:51 -07:00
|
|
|
d->keys = eina_list_append(d->keys, key);
|
2009-08-30 07:54:25 -07:00
|
|
|
}
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-30 07:54:25 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
void
|
|
|
|
evry_history_free(void)
|
|
|
|
{
|
2009-08-31 02:21:51 -07:00
|
|
|
Cleanup_Data *d;
|
2009-08-30 07:54:25 -07:00
|
|
|
char *key;
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-30 07:54:25 -07:00
|
|
|
evry_hist = e_config_domain_load("module.everything.history", hist_edd);
|
|
|
|
if (evry_hist)
|
|
|
|
{
|
2009-08-31 02:21:51 -07:00
|
|
|
d = E_NEW(Cleanup_Data, 1);
|
2009-09-02 12:43:16 -07:00
|
|
|
d->time = ecore_time_get();
|
2009-08-30 07:54:25 -07:00
|
|
|
|
2009-08-31 02:21:51 -07:00
|
|
|
if (evry_hist->subjects)
|
|
|
|
{
|
|
|
|
eina_hash_foreach(evry_hist->subjects, _hist_cleanup_cb, d);
|
|
|
|
EINA_LIST_FREE(d->keys, key)
|
|
|
|
eina_hash_del_by_key(evry_hist->subjects, key);
|
|
|
|
}
|
2009-08-30 07:54:25 -07:00
|
|
|
|
2009-09-24 16:08:59 -07:00
|
|
|
if (evry_hist->actions)
|
2009-08-31 02:21:51 -07:00
|
|
|
{
|
|
|
|
eina_hash_foreach(evry_hist->actions, _hist_cleanup_cb, d);
|
|
|
|
EINA_LIST_FREE(d->keys, key)
|
|
|
|
eina_hash_del_by_key(evry_hist->actions, key);
|
|
|
|
}
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-31 02:21:51 -07:00
|
|
|
E_FREE(d);
|
2009-08-30 07:54:25 -07:00
|
|
|
evry_history_unload();
|
|
|
|
}
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
E_CONFIG_DD_FREE(hist_item_edd);
|
|
|
|
E_CONFIG_DD_FREE(hist_entry_edd);
|
|
|
|
E_CONFIG_DD_FREE(hist_edd);
|
|
|
|
}
|
|
|
|
|
2009-10-01 17:13:36 -07:00
|
|
|
EAPI void
|
2009-08-30 05:01:50 -07:00
|
|
|
evry_history_load(void)
|
|
|
|
{
|
|
|
|
evry_hist = e_config_domain_load("module.everything.history", hist_edd);
|
2009-09-24 16:08:59 -07:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
if (evry_hist && evry_hist->version != HISTORY_VERSION)
|
|
|
|
{
|
|
|
|
eina_hash_foreach(evry_hist->subjects, _hist_free_cb, NULL);
|
|
|
|
eina_hash_foreach(evry_hist->actions, _hist_free_cb, NULL);
|
2009-08-30 07:54:25 -07:00
|
|
|
eina_hash_free(evry_hist->subjects);
|
|
|
|
eina_hash_free(evry_hist->actions);
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
E_FREE(evry_hist);
|
|
|
|
evry_hist = NULL;
|
|
|
|
}
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
if (!evry_hist)
|
|
|
|
{
|
2010-04-10 13:05:57 -07:00
|
|
|
evry_hist = E_NEW(Evry_History, 1);
|
2009-08-30 05:01:50 -07:00
|
|
|
evry_hist->version = HISTORY_VERSION;
|
2009-08-31 11:48:54 -07:00
|
|
|
evry_hist->begin = ecore_time_get();
|
2009-08-30 05:01:50 -07:00
|
|
|
}
|
|
|
|
if (!evry_hist->subjects)
|
|
|
|
evry_hist->subjects = eina_hash_string_superfast_new(NULL);
|
|
|
|
if (!evry_hist->actions)
|
|
|
|
evry_hist->actions = eina_hash_string_superfast_new(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-01 17:13:36 -07:00
|
|
|
EAPI void
|
2009-08-30 05:01:50 -07:00
|
|
|
evry_history_unload(void)
|
|
|
|
{
|
|
|
|
if (!evry_hist) return;
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
e_config_domain_save("module.everything.history", hist_edd, evry_hist);
|
|
|
|
|
2010-04-11 06:40:10 -07:00
|
|
|
eina_hash_foreach(evry_hist->subjects, _hist_free_cb, NULL);
|
|
|
|
eina_hash_foreach(evry_hist->actions, _hist_free_cb, NULL);
|
|
|
|
eina_hash_free(evry_hist->subjects);
|
|
|
|
eina_hash_free(evry_hist->actions);
|
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
E_FREE(evry_hist);
|
|
|
|
evry_hist = NULL;
|
|
|
|
}
|
|
|
|
|
2009-10-01 17:13:36 -07:00
|
|
|
EAPI void
|
2009-09-03 07:21:27 -07:00
|
|
|
evry_history_add(Eina_Hash *hist, Evry_State *s, const char *ctxt)
|
2009-08-30 05:01:50 -07:00
|
|
|
{
|
|
|
|
History_Entry *he;
|
2009-08-30 07:54:25 -07:00
|
|
|
History_Item *hi = NULL;
|
2009-08-30 05:01:50 -07:00
|
|
|
Evry_Item *it;
|
|
|
|
Eina_List *l;
|
|
|
|
const char *id;
|
2009-09-02 12:43:16 -07:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
if (!s) return;
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
it = s->cur_item;
|
2010-04-14 13:21:56 -07:00
|
|
|
if (!it || !it->plugin->history) return;
|
2009-08-30 05:01:50 -07:00
|
|
|
|
2009-09-02 12:43:16 -07:00
|
|
|
id = (it->id ? it->id : it->label);
|
2010-03-06 06:09:05 -08:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
he = eina_hash_find(hist, id);
|
2009-08-30 07:54:25 -07:00
|
|
|
if (!he)
|
|
|
|
{
|
|
|
|
he = E_NEW(History_Entry, 1);
|
|
|
|
eina_hash_add(hist, id, he);
|
|
|
|
}
|
|
|
|
else
|
2009-08-30 05:01:50 -07:00
|
|
|
{
|
|
|
|
EINA_LIST_FOREACH(he->items, l, hi)
|
2009-09-03 07:21:27 -07:00
|
|
|
if ((hi->plugin == it->plugin->name) &&
|
|
|
|
(ctxt == hi->context))
|
|
|
|
break;
|
2009-08-30 05:01:50 -07:00
|
|
|
}
|
2009-08-30 07:54:25 -07:00
|
|
|
|
|
|
|
if (!hi)
|
2009-08-31 06:04:53 -07:00
|
|
|
{
|
2009-08-30 05:01:50 -07:00
|
|
|
hi = E_NEW(History_Item, 1);
|
|
|
|
hi->plugin = eina_stringshare_ref(it->plugin->name);
|
2010-04-16 18:10:20 -07:00
|
|
|
if (it->plugin->type_out)
|
|
|
|
hi->type = eina_stringshare_ref(it->plugin->type_out);
|
2009-09-02 12:43:16 -07:00
|
|
|
he->items = eina_list_append(he->items, hi);
|
|
|
|
}
|
2009-08-31 02:21:51 -07:00
|
|
|
|
2009-09-02 12:43:16 -07:00
|
|
|
if (hi)
|
|
|
|
{
|
|
|
|
hi->last_used = ecore_time_get();
|
|
|
|
hi->usage /= 4.0;
|
|
|
|
hi->usage += TIME_FACTOR(hi->last_used);
|
2010-04-14 13:21:56 -07:00
|
|
|
hi->transient = it->plugin->transient;
|
2009-09-02 12:43:16 -07:00
|
|
|
hi->count += (hi->transient ? 2:1);
|
2010-04-16 18:10:20 -07:00
|
|
|
|
|
|
|
/* XXX can be remove just for update */
|
|
|
|
if (it->plugin->type_out && !hi->type)
|
|
|
|
hi->type = eina_stringshare_ref(it->plugin->type_out);
|
|
|
|
|
2009-09-03 07:21:27 -07:00
|
|
|
if (ctxt && !hi->context)
|
|
|
|
hi->context = eina_stringshare_ref(ctxt);
|
2010-04-08 21:14:09 -07:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
if (s->input)
|
2009-09-02 12:43:16 -07:00
|
|
|
{
|
2010-04-13 15:15:56 -07:00
|
|
|
|
2009-09-02 12:43:16 -07:00
|
|
|
if (hi->input)
|
|
|
|
eina_stringshare_del(hi->input);
|
2009-08-30 05:01:50 -07:00
|
|
|
|
2009-09-02 12:43:16 -07:00
|
|
|
hi->input = eina_stringshare_add(s->input);
|
|
|
|
}
|
|
|
|
}
|
2009-08-30 05:01:50 -07:00
|
|
|
}
|
|
|
|
|
2010-04-09 07:41:37 -07:00
|
|
|
EAPI int
|
2009-09-03 07:21:27 -07:00
|
|
|
evry_history_item_usage_set(Eina_Hash *hist, Evry_Item *it, const char *input, const char *ctxt)
|
2009-08-30 05:01:50 -07:00
|
|
|
{
|
|
|
|
History_Entry *he;
|
|
|
|
History_Item *hi;
|
|
|
|
Eina_List *l;
|
|
|
|
|
2010-04-14 13:21:56 -07:00
|
|
|
if (!it->plugin->history)
|
2010-04-13 15:15:56 -07:00
|
|
|
return 0;
|
|
|
|
|
2009-09-02 12:43:16 -07:00
|
|
|
it->usage = 0.0;
|
|
|
|
if (!(he = eina_hash_find(hist, (it->id ? it->id : it->label))))
|
2009-08-31 08:12:43 -07:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(he->items, l, hi)
|
2009-08-30 05:01:50 -07:00
|
|
|
{
|
2009-08-31 08:12:43 -07:00
|
|
|
if (hi->plugin != it->plugin->name)
|
|
|
|
continue;
|
2010-04-14 13:21:56 -07:00
|
|
|
|
2010-04-08 21:14:09 -07:00
|
|
|
if (ctxt != hi->context)
|
|
|
|
continue;
|
|
|
|
|
2010-04-13 15:15:56 -07:00
|
|
|
if (it->plugin->type == type_action)
|
|
|
|
{
|
|
|
|
if (hi->last_used > it->usage)
|
|
|
|
it->usage = hi->last_used;
|
|
|
|
}
|
|
|
|
|
2009-09-24 17:27:36 -07:00
|
|
|
if (evry_conf->history_sort_mode == 0)
|
|
|
|
{
|
|
|
|
|
2010-04-08 15:37:50 -07:00
|
|
|
if (!input || !hi->input)
|
2009-08-31 08:12:43 -07:00
|
|
|
{
|
2009-09-02 12:43:16 -07:00
|
|
|
it->usage += hi->usage * hi->count;
|
2009-08-31 08:12:43 -07:00
|
|
|
}
|
2010-04-08 15:37:50 -07:00
|
|
|
else
|
2009-08-31 08:12:43 -07:00
|
|
|
{
|
2010-04-08 15:37:50 -07:00
|
|
|
/* higher priority for exact matches */
|
|
|
|
if (!strncmp(input, hi->input, strlen(input)))
|
|
|
|
{
|
|
|
|
it->usage += hi->usage * hi->count;
|
|
|
|
}
|
|
|
|
if (!strncmp(input, hi->input, strlen(hi->input)))
|
|
|
|
{
|
|
|
|
it->usage += hi->usage * hi->count;
|
|
|
|
}
|
|
|
|
}
|
2010-04-08 21:14:09 -07:00
|
|
|
|
|
|
|
if (ctxt && hi->context &&
|
|
|
|
(hi->context == ctxt))
|
|
|
|
it->usage += hi->usage * hi->count * 10;
|
2009-09-24 17:27:36 -07:00
|
|
|
}
|
|
|
|
else if (evry_conf->history_sort_mode == 1)
|
|
|
|
{
|
|
|
|
it->usage = hi->count * (hi->last_used / 10000000000.0);
|
|
|
|
|
|
|
|
}
|
|
|
|
else if (evry_conf->history_sort_mode == 2)
|
|
|
|
{
|
2010-04-13 15:15:56 -07:00
|
|
|
if (hi->last_used > it->usage)
|
|
|
|
it->usage = hi->last_used;
|
2009-09-24 17:27:36 -07:00
|
|
|
}
|
2009-08-30 05:01:50 -07:00
|
|
|
}
|
2009-08-31 08:12:43 -07:00
|
|
|
|
2009-09-02 12:43:16 -07:00
|
|
|
if (it->usage > 0.0)
|
|
|
|
return 1;
|
2009-08-31 06:04:53 -07:00
|
|
|
|
2009-08-30 05:01:50 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|