diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 38f27b41d..e4383fa8e 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -166,7 +166,8 @@ e_entry_dialog.h \ e_fm.h \ e_widget_scrollframe.h \ e_sha1.h \ -e_widget_fsel.h +e_widget_fsel.h \ +e_fm_mime.h enlightenment_src = \ e_user.c \ @@ -309,6 +310,7 @@ e_fm.c \ e_widget_scrollframe.c \ e_sha1.c \ e_widget_fsel.c \ +e_fm_mime.c \ $(ENLIGHTENMENTHEADERS) enlightenment_SOURCES = \ diff --git a/src/bin/e_fm.c b/src/bin/e_fm.c index ac64d98a0..7b932dbcd 100644 --- a/src/bin/e_fm.c +++ b/src/bin/e_fm.c @@ -1107,6 +1107,7 @@ _e_fm2_icon_new(E_Fm2_Smart_Data *sd, char *file) Evas_Coord mw = 0, mh = 0; Evas_Object *obj, *obj2; char buf[4096], *lnk; + const char *mime; /* create icon */ ic = E_NEW(E_Fm2_Icon, 1); @@ -1124,10 +1125,17 @@ _e_fm2_icon_new(E_Fm2_Smart_Data *sd, char *file) ic->info.link = evas_stringshare_add(lnk); free(lnk); } - evas_event_freeze(evas_object_evas_get(sd->obj)); - edje_freeze(); + + if (!ic->info.mime) + { + mime = e_fm_mime_filename_get(ic->info.file); + if (mime) ic->info.mime = evas_stringshare_add(mime); + } + if (e_util_glob_case_match(ic->info.file, "*.desktop")) _e_fm2_icon_desktop_load(ic); + evas_event_freeze(evas_object_evas_get(sd->obj)); + edje_freeze(); switch (sd->config->view.mode) { case E_FM2_VIEW_MODE_ICONS: @@ -1360,7 +1368,7 @@ _e_fm2_icon_label_set(E_Fm2_Icon *ic, Evas_Object *obj) static void _e_fm2_icon_icon_set(E_Fm2_Icon *ic) { - char buf[4096]; + char buf[4096], *p; if (!ic->realized) return; if (ic->info.icon) @@ -1383,6 +1391,39 @@ _e_fm2_icon_icon_set(E_Fm2_Icon *ic) if (ic->info.mime) { /* use mime type to select icon */ + if ( + (!strcmp(ic->info.mime, "image/jpeg")) || + (!strcmp(ic->info.mime, "image/png")) || + (!strcmp(ic->info.mime, "image/gif")) || + (!strcmp(ic->info.mime, "image/tiff")) + ) + { + snprintf(buf, sizeof(buf), "%s/%s", ic->sd->realpath, ic->info.file); + ic->obj_icon = e_thumb_icon_add(evas_object_evas_get(ic->sd->obj)); + e_thumb_icon_file_set(ic->obj_icon, buf, NULL); + e_thumb_icon_size_set(ic->obj_icon, 64, 48); + evas_object_smart_callback_add(ic->obj_icon, "e_thumb_gen", _e_fm2_cb_icon_thumb_gen, ic); + _e_fm2_icon_thumb(ic); + edje_object_part_swallow(ic->obj, "icon_swallow", ic->obj_icon); + evas_object_show(ic->obj_icon); + } + else + { + /* fixme: quick hack to get some icons - need to have a proper + * mime -> icon mapping users can edit + */ + p = strchr(ic->info.mime, '/'); + if (p) p++; + else p = ic->info.mime; + snprintf(buf, sizeof(buf), "icons/fileman/%s", p); + ic->obj_icon = edje_object_add(evas_object_evas_get(ic->sd->obj)); + if (!e_theme_edje_object_set(ic->obj_icon, "base/theme/fileman", + buf)) + e_theme_edje_object_set(ic->obj_icon, "base/theme/fileman", + "icons/fileman/file"); + edje_object_part_swallow(ic->obj, "icon_swallow", ic->obj_icon); + evas_object_show(ic->obj_icon); + } return; } /* fallback */ @@ -1397,28 +1438,8 @@ _e_fm2_icon_icon_set(E_Fm2_Icon *ic) else { if ( - (e_util_glob_case_match(ic->info.file, "*.jpg")) || - (e_util_glob_case_match(ic->info.file, "*.jpeg")) || - (e_util_glob_case_match(ic->info.file, "*.jfif")) || - (e_util_glob_case_match(ic->info.file, "*.jpe")) || - (e_util_glob_case_match(ic->info.file, "*.png")) || - (e_util_glob_case_match(ic->info.file, "*.gif")) || - (e_util_glob_case_match(ic->info.file, "*.tif")) || - (e_util_glob_case_match(ic->info.file, "*.tiff")) + (e_util_glob_case_match(ic->info.file, "*.edj")) ) - { - snprintf(buf, sizeof(buf), "%s/%s", ic->sd->realpath, ic->info.file); - ic->obj_icon = e_thumb_icon_add(evas_object_evas_get(ic->sd->obj)); - e_thumb_icon_file_set(ic->obj_icon, buf, NULL); - e_thumb_icon_size_set(ic->obj_icon, 64, 64); - evas_object_smart_callback_add(ic->obj_icon, "e_thumb_gen", _e_fm2_cb_icon_thumb_gen, ic); - _e_fm2_icon_thumb(ic); - edje_object_part_swallow(ic->obj, "icon_swallow", ic->obj_icon); - evas_object_show(ic->obj_icon); - } - else if ( - (e_util_glob_case_match(ic->info.file, "*.edj")) - ) { snprintf(buf, sizeof(buf), "%s/%s", ic->sd->realpath, ic->info.file); ic->obj_icon = e_thumb_icon_add(evas_object_evas_get(ic->sd->obj)); diff --git a/src/bin/e_fm_mime.c b/src/bin/e_fm_mime.c new file mode 100644 index 000000000..64688ccb8 --- /dev/null +++ b/src/bin/e_fm_mime.c @@ -0,0 +1,292 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" + +typedef struct _E_Mime E_Mime; + +struct _E_Mime +{ + const char *glob; + const char *mime; +}; + +/* local subsystem functions */ +static void _e_fm_mime_all_free(void); +static void _e_fm_mime_update(void); +static int _e_fm_mime_glob_remove(const char *glob); +static void _e_fm_mime_mime_types_load(char *file); +static void _e_fm_mime_shared_mimeinfo_globs_load(char *file); + +static Evas_List *mimes = NULL; + +/* externally accessible functions */ +EAPI const char * +e_fm_mime_filename_get(const char *fname) +{ + Evas_List *l; + E_Mime *mime; + + _e_fm_mime_update(); + /* case senstive match first */ + for (l = mimes; l; l = l->next) + { + mime = l->data; + if (e_util_glob_match(fname, mime->glob)) + { + mimes = evas_list_remove_list(mimes, l); + mimes = evas_list_prepend(mimes, mime); + return mime->mime; + } + } + /* case insenstive match second */ + for (l = mimes; l; l = l->next) + { + mime = l->data; + if (e_util_glob_match(fname, mime->glob)) + { + mimes = evas_list_remove_list(mimes, l); + mimes = evas_list_prepend(mimes, mime); + return mime->mime; + } + } + return NULL; +} + +/* local subsystem functions */ +static void +_e_fm_mime_all_free(void) +{ + E_Mime *mime; + + while (mimes) + { + mime = mimes->data; + mimes = evas_list_remove_list(mimes, mimes); + evas_stringshare_del(mime->glob); + evas_stringshare_del(mime->mime); + free(mime); + } +} + +static void +_e_fm_mime_update(void) +{ + static double last_t = 0.0, t; + char buf[4096]; + char *homedir; + int reload = 0; + + /* load /etc/mime.types + * load /usr/share/mime/ + * + * load ~/.mime.types + * load ~/.local/share/mime/ + */ + t = ecore_time_get(); + if ((t - last_t) < 1.0) return; + + homedir = e_user_homedir_get(); + if (!homedir) return; + + { + static time_t last_changed = 0; + time_t ch; + + snprintf(buf, sizeof(buf), "/etc/mime.types"); + ch = ecore_file_mod_time(buf); + if ((ch != last_changed) || (reload)) + { + _e_fm_mime_all_free(); + last_changed = ch; + _e_fm_mime_mime_types_load(buf); + reload = 1; + } + } + + { + static time_t last_changed = 0; + time_t ch; + + snprintf(buf, sizeof(buf), "/usr/share/mime/globs"); + ch = ecore_file_mod_time(buf); + if ((ch != last_changed) || (reload)) + { + last_changed = ch; + _e_fm_mime_shared_mimeinfo_globs_load(buf); + } + } + + { + static time_t last_changed = 0; + time_t ch; + + snprintf(buf, sizeof(buf), "%s/.mime.types", homedir); + ch = ecore_file_mod_time(buf); + if ((ch != last_changed) || (reload)) + { + last_changed = ch; + _e_fm_mime_mime_types_load(buf); + } + } + + { + static time_t last_changed = 0; + time_t ch; + + snprintf(buf, sizeof(buf), "%s/.local/share/mime/globs", homedir); + ch = ecore_file_mod_time(buf); + if ((ch != last_changed) || (reload)) + { + last_changed = ch; + _e_fm_mime_shared_mimeinfo_globs_load(buf); + } + } + free(homedir); +} + +static int +_e_fm_mime_glob_remove(const char *glob) +{ + Evas_List *l; + E_Mime *mime; + + for (l = mimes; l; l = l->next) + { + mime = l->data; + if (!strcmp(glob, mime->glob)) + { + mimes = evas_list_remove_list(mimes, l); + evas_stringshare_del(mime->glob); + evas_stringshare_del(mime->mime); + free(mime); + return; + } + } +} + +static void +_e_fm_mime_mime_types_load(char *file) +{ + /* format: + + # type of encoding. + # + ############################################################################### + + application/msaccess mdb + application/msword doc dot + application/news-message-id + + */ + FILE *f; + char buf[4096], buf2[4096], mimetype[4096], ext[4096], *p, *pp; + E_Mime *mime; + + f = fopen(file, "rb"); + if (!f) return; + while (fgets(buf, sizeof(buf), f)) + { + p = buf; + while (isblank(*p) && (*p != 0) && (*p != '\n')) p++; + if (*p == '#') continue; + if ((*p == '\n') || (*p == 0)) continue; + pp = p; + while (!isblank(*p) && (*p != 0) && (*p != '\n')) p++; + if ((*p == '\n') || (*p == 0)) continue; + strncpy(mimetype, pp, (p - pp)); + mimetype[p - pp] = 0; + do + { + while (isblank(*p) && (*p != 0) && (*p != '\n')) p++; + if ((*p == '\n') || (*p == 0)) break; + pp = p; + while (!isblank(*p) && (*p != 0) && (*p != '\n')) p++; + strncpy(ext, pp, (p - pp)); + ext[p - pp] = 0; + + mime = E_NEW(E_Mime, 1); + if (mime) + { + mime->mime = evas_stringshare_add(mimetype); + snprintf(buf2, sizeof(buf2), "*.%s", ext); + mime->glob = evas_stringshare_add(buf2); + if ((!mime->mime) || (!mime->glob)) + { + if (mime->mime) evas_stringshare_del(mime->mime); + if (mime->glob) evas_stringshare_del(mime->glob); + free(mime); + } + else + { + _e_fm_mime_glob_remove(buf2); + mimes = evas_list_append(mimes, mime); + } + } + } + while ((*p != '\n') && (*p != 0)); + } + fclose(f); +} + +static void +_e_fm_mime_shared_mimeinfo_globs_load(char *file) +{ + /* format: + + # This file was automatically generated by the + # update-mime-database command. DO NOT EDIT! + text/vnd.wap.wml:*.wml + application/x-7z-compressed:*.7z + application/vnd.corel-draw:*.cdr + text/spreadsheet:*.sylk + + */ + FILE *f; + char buf[4096], buf2[4096], mimetype[4096], ext[4096], *p, *pp; + E_Mime *mime; + + f = fopen(file, "rb"); + if (!f) return; + while (fgets(buf, sizeof(buf), f)) + { + p = buf; + while (isblank(*p) && (*p != 0) && (*p != '\n')) p++; + if (*p == '#') continue; + if ((*p == '\n') || (*p == 0)) continue; + pp = p; + while ((*p != ':') && (*p != 0) && (*p != '\n')) p++; + if ((*p == '\n') || (*p == 0)) continue; + strncpy(mimetype, pp, (p - pp)); + mimetype[p - pp] = 0; + p++; + pp = ext; + while ((*p != 0) && (*p != '\n')) + { + *pp = *p; + *pp++; + p++; + } + *pp = 0; + + mime = E_NEW(E_Mime, 1); + if (mime) + { + mime->mime = evas_stringshare_add(mimetype); + snprintf(buf2, sizeof(buf2), "*.%s", ext); + mime->glob = evas_stringshare_add(buf2); + if ((!mime->mime) || (!mime->glob)) + { + if (mime->mime) evas_stringshare_del(mime->mime); + if (mime->glob) evas_stringshare_del(mime->glob); + free(mime); + } + else + { + _e_fm_mime_glob_remove(buf2); + mimes = evas_list_append(mimes, mime); + } + } + } + fclose(f); +} diff --git a/src/bin/e_fm_mime.h b/src/bin/e_fm_mime.h new file mode 100644 index 000000000..b9d547619 --- /dev/null +++ b/src/bin/e_fm_mime.h @@ -0,0 +1,13 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifdef E_TYPEDEFS + +#else +#ifndef E_FM_MIME_H +#define E_FM_MIME_H + +EAPI const char *e_fm_mime_filename_get(const char *fname); + +#endif +#endif diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 75db4e093..7862d3132 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -143,3 +143,4 @@ #include "e_sha1.h" #include "e_widget_framelist.h" #include "e_widget_fsel.h" +#include "e_fm_mime.h"