enlightenment/src/modules/everything/evry_util.c

279 lines
5.5 KiB
C

#include "Evry.h"
#define MAX_FUZZ 100
#define MAX_WORDS 5
EAPI int
evry_fuzzy_match(const char *str, const char *match)
{
const char *p, *m, *next;
int sum = 0;
unsigned int last = 0;
unsigned int offset = 0;
unsigned int min = 0;
unsigned char first = 0;
/* ignore punctuation */
unsigned char ip = 1;
unsigned int cnt = 0;
/* words in match */
unsigned int m_num = 0;
unsigned int m_cnt = 0;
unsigned int m_min[MAX_WORDS];
unsigned int m_len = 0;
if (!match || !str) return 0;
/* remove white spaces at the beginning */
for (; (*match != 0) && isspace(*match); match++);
for (; (*str != 0) && isspace(*str); str++);
/* count words in match */
for (m = match; (*m != 0) && (m_num < MAX_WORDS);)
{
for (; (*m != 0) && !isspace(*m); m++);
for (; (*m != 0) && isspace(*m); m++);
m_min[m_num++] = MAX_FUZZ;
}
for (m = match; ip && (*m != 0); m++)
if (ip && ispunct(*m)) ip = 0;
m_len = strlen(match);
/* with less than 3 chars match must be a prefix */
if (m_len < 3) m_len = 0;
next = str;
m = match;
while((m_cnt < m_num) && (*next != 0))
{
/* reset match */
if (m_cnt == 0) m = match;
/* end of matching */
if (*m == 0) break;
offset = 0;
last = 0;
min = 1;
first = 0;
/* match current word of string against current match */
for (p = next; *next != 0; p++)
{
/* new word of string begins */
if ((*p == 0) || isspace(*p) || (ip && ispunct(*p)))
{
if (m_cnt < m_num - 1)
{
/* test next match */
for (; (*m != 0) && !isspace(*m); m++);
for (; (*m != 0) && isspace(*m); m++);
m_cnt++;
break;
}
else
{
/* go to next word */
for (; (*p != 0) && ((isspace(*p) || (ip && ispunct(*p)))); p++);
cnt++;
next = p;
m_cnt = 0;
break;
}
}
/* current char matches? */
if (tolower(*p) != tolower(*m))
{
if (!first)
offset += 1;
else
offset += 3;
if (offset <= m_len * 3)
continue;
}
if (min < MAX_FUZZ && offset <= m_len * 3)
{
/* first offset of match in word */
if (!first)
{
first = 1;
last = offset;
}
min += offset + (offset - last) * 5;
last = offset;
/* try next char of match */
if (*(++m) != 0 && !isspace(*m))
continue;
/* end of match: store min weight of match */
min += (cnt - m_cnt) > 0 ? (cnt - m_cnt) : 0;
if (min < m_min[m_cnt])
m_min[m_cnt] = min;
}
else
{
/* go to next match */
for (; (*m != 0) && !isspace(*m); m++);
}
if (m_cnt < m_num - 1)
{
/* test next match */
for (; (*m != 0) && isspace(*m); m++);
m_cnt++;
break;
}
else if(*p != 0)
{
/* go to next word */
for (; (*p != 0) && !((isspace(*p) || (ip && ispunct(*p)))); p++);
for (; (*p != 0) && ((isspace(*p) || (ip && ispunct(*p)))); p++);
cnt++;
next = p;
m_cnt = 0;
break;
}
else
{
next = p;
break;
}
}
}
for (m_cnt = 0; m_cnt < m_num; m_cnt++)
{
sum += m_min[m_cnt];
if (sum >= MAX_FUZZ)
{
sum = 0;
break;
}
}
return sum;
}
static int
_evry_fuzzy_match_sort_cb(const void *data1, const void *data2)
{
const Evry_Item *it1 = data1;
const Evry_Item *it2 = data2;
if (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);
}
return 0;
}
EAPI Eina_List *
evry_fuzzy_match_sort(Eina_List *items)
{
return eina_list_sort(items, eina_list_count(items), _evry_fuzzy_match_sort_cb);
}
/* taken from e_utils. just changed 48 to 72.. we need
evry_icon_theme_set(Evas_Object *obj, const char *icon,
size:small, mid, large) imo */
static int
_evry_icon_theme_set(Evas_Object *obj, const char *icon)
{
const char *file;
char buf[4096];
if ((!icon) || (!icon[0])) return 0;
snprintf(buf, sizeof(buf), "e/icons/%s", icon);
file = e_theme_edje_file_get("base/theme/icons", buf);
if (file[0])
{
e_icon_file_edje_set(obj, file, buf);
return 1;
}
return 0;
}
static int
_evry_icon_fdo_set(Evas_Object *obj, const char *icon)
{
char *path = NULL;
unsigned int size;
if ((!icon) || (!icon[0])) return 0;
size = e_util_icon_size_normalize(72 * e_scale);
path = efreet_icon_path_find(e_config->icon_theme, icon, size);
if (!path) return 0;
e_icon_file_set(obj, path);
E_FREE(path);
return 1;
}
EAPI Evas_Object *
evry_icon_theme_get(const char *icon, Evas *e)
{
Evas_Object *o = e_icon_add(e);
if (e_config->icon_theme_overrides)
{
if (_evry_icon_fdo_set(o, icon) ||
_evry_icon_theme_set(o, icon))
return o;
}
else
{
if (_evry_icon_theme_set(o, icon) ||
_evry_icon_fdo_set(o, icon))
return o;
}
evas_object_del(o);
return NULL;
}
EAPI Evas_Object *
evry_icon_mime_get(const char *mime, Evas *e)
{
Evas_Object *o = NULL;
char *icon;
icon = efreet_mime_type_icon_get(mime, e_config->icon_theme, 64);
if (icon)
{
o = e_util_icon_add(icon, e);
free(icon);
}
else
{
o = evry_icon_theme_get("none", e);
}
return o;
}