From 2538f6cf900b58ee75a745c2327e24df84c71414 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 28 Nov 2014 23:34:36 +0000 Subject: [PATCH] Refactor mime type lookup and UI creation code to use a content_provider registry. This is static at the moment but could be made dynamic to allow code to hook in new views --- src/bin/Makefile.am | 1 + src/bin/edi_content_provider.c | 89 +++++++++++++++++++++++++++ src/bin/edi_content_provider.h | 70 +++++++++++++++++++++ src/bin/mainview/edi_mainview.c | 78 +++++------------------ src/tests/Makefile.am | 7 ++- src/tests/edi_suite.c | 3 +- src/tests/edi_suite.h | 1 + src/tests/edi_test_content_provider.c | 36 +++++++++++ 8 files changed, 219 insertions(+), 66 deletions(-) create mode 100644 src/bin/edi_content_provider.c create mode 100644 src/bin/edi_content_provider.h create mode 100644 src/tests/edi_test_content_provider.c diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 35bc17f..043e645 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -14,6 +14,7 @@ AM_CPPFLAGS = -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ edi_SOURCES = \ editor/edi_editor_search.c \ editor/edi_editor.c \ +edi_content_provider.c \ welcome/edi_welcome.c \ edi_filepanel.c \ edi_logpanel.c \ diff --git a/src/bin/edi_content_provider.c b/src/bin/edi_content_provider.c new file mode 100644 index 0000000..80025ba --- /dev/null +++ b/src/bin/edi_content_provider.c @@ -0,0 +1,89 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "edi_content_provider.h" +#include "editor/edi_editor.h" + +#include "edi_private.h" + +// TODO move out to edi_content.c ot similar just like the editor type +// (and the Evas include) + +static Evas_Object * +_edi_content_provider_image_add(Evas_Object *parent, Edi_Mainview_Item *item) +{ + Evas_Object *img, *scroll; + + scroll = elm_scroller_add(parent); + evas_object_size_hint_weight_set(scroll, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(scroll, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(scroll); + img = elm_image_add(scroll); + elm_image_file_set(img, item->path, NULL); + elm_image_no_scale_set(img, EINA_TRUE); + elm_object_content_set(scroll, img); + evas_object_show(img); + + return scroll; +} + +static Evas_Object * +_edi_content_provider_diff_add(Evas_Object *parent, Edi_Mainview_Item *item) +{ + Elm_Code *code; + Evas_Object *diff; + + code = elm_code_create(); + elm_code_file_open(code, item->path); + diff = elm_code_diff_widget_add(parent, code); + elm_code_diff_widget_font_size_set(diff, 12); + + return diff; +} + +static Edi_Content_Provider _edi_content_provider_registry[] = +{ + {"text", EINA_TRUE, EINA_TRUE, edi_editor_add}, + {"image", EINA_FALSE, EINA_FALSE, _edi_content_provider_image_add}, + {"diff", EINA_TRUE, EINA_FALSE, _edi_content_provider_diff_add}, + + {NULL, EINA_FALSE, EINA_FALSE, NULL} +}; + +EAPI Edi_Content_Provider *edi_content_provider_for_mime_get(const char *mime) +{ + char *id; + + if (!strcasecmp(mime, "text/plain") || !strcasecmp(mime, "application/x-shellscript")) + id = "text"; + else if (!strcasecmp(mime, "text/x-chdr") || !strcasecmp(mime, "text/x-csrc")) + id = "text"; // TODO make a code view + else if (!strncasecmp(mime, "image/", 6)) + id = "image"; + else if (!strcasecmp(mime, "text/x-diff") || !strcasecmp(mime, "text/x-patch")) + id = "diff"; + else + return NULL; + + return edi_content_provider_for_id_get(id); +} + +EAPI Edi_Content_Provider *edi_content_provider_for_id_get(const char *id) +{ + Edi_Content_Provider *provider; + + provider = _edi_content_provider_registry; + while (provider != NULL && provider->id != NULL) + { + if (!strncmp(id, provider->id, strlen(provider->id))) + return provider; + + provider++; + } + + return NULL; +} diff --git a/src/bin/edi_content_provider.h b/src/bin/edi_content_provider.h new file mode 100644 index 0000000..4dbba7b --- /dev/null +++ b/src/bin/edi_content_provider.h @@ -0,0 +1,70 @@ +#ifndef EDI_CONTENT_PROVIDER_H_ +# define EDI_CONTENT_PROVIDER_H_ + +#include + +#include "mainview/edi_mainview_item.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * @brief These routines are used for managing information about supported content. + */ + +typedef struct _Edi_Content_Provider +{ + const char *id; + + Eina_Bool is_text; + Eina_Bool is_editable; + + Evas_Object *(*content_ui_add)(Evas_Object *parent, Edi_Mainview_Item *item); +} Edi_Content_Provider; + +/** + * @brief Lookup information in content provider registry. + * @defgroup Lookup + * + * @{ + * + * Looking up content providers based on mime or id etc. + * + */ + +/** + * Look up a content provider based on a mime type. + * + * @param mime the mime type of a file you wish to get a content provider for + * + * @return an Edi_Content_Provider if one is registered or NULL otherwise + * + * @ingroup Lookup + */ +EAPI Edi_Content_Provider *edi_content_provider_for_mime_get(const char *mime); + +/** + * Look up a content provider based on a provider id. + * This is useful for overriding mime-type based lookup. + * + * @param mime the id of a provider you wish to get a handle for. + * + * @return an Edi_Content_Provider if one is registered or NULL otherwise + * + * @ingroup Lookup + */ +EAPI Edi_Content_Provider *edi_content_provider_for_id_get(const char *id); + +/** + * @} + */ + + + +#ifdef __cplusplus +} +#endif + +#endif /* EDI_CONTENT_PROVIDER_H_ */ diff --git a/src/bin/mainview/edi_mainview.c b/src/bin/mainview/edi_mainview.c index 133d5be..789e33f 100644 --- a/src/bin/mainview/edi_mainview.c +++ b/src/bin/mainview/edi_mainview.c @@ -12,6 +12,7 @@ #include "mainview/edi_mainview.h" #include "editor/edi_editor.h" +#include "edi_content_provider.h" #include "edi_private.h" @@ -142,55 +143,16 @@ _edi_mainview_item_add(Edi_Path_Options *path, const char *mime, Elm_Object_Item return item; } -static Evas_Object * -_edi_mainview_content_image_create(Edi_Mainview_Item *item, Evas_Object *parent) -{ - Evas_Object *img, *scroll; - - scroll = elm_scroller_add(parent); - evas_object_size_hint_weight_set(scroll, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(scroll, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_show(scroll); - img = elm_image_add(scroll); - elm_image_file_set(img, item->path, NULL); - elm_image_no_scale_set(img, EINA_TRUE); - elm_object_content_set(scroll, img); - evas_object_show(img); - - return scroll; -} - -static Evas_Object * -_edi_mainview_content_diff_create(Edi_Mainview_Item *item, Evas_Object *parent) -{ - Elm_Code *code; - Evas_Object *diff; - - code = elm_code_create(); - elm_code_file_open(code, item->path); - diff = elm_code_diff_widget_add(parent, code); - elm_code_diff_widget_font_size_set(diff, 12); - - return diff; -} - static Evas_Object * _edi_mainview_content_create(Edi_Mainview_Item *item, Evas_Object *parent) { - if (!strcmp(item->editortype, "text")) - { - return edi_editor_add(parent, item); - } - else if (!strcmp(item->editortype, "image")) - { - return _edi_mainview_content_image_create(item, parent); - } - else if (!strcmp(item->editortype, "diff")) - { - return _edi_mainview_content_diff_create(item, parent); - } + Edi_Content_Provider *provider; - return NULL; + provider = edi_content_provider_for_id_get(item->editortype); + if (!provider) + return NULL; + + return provider->content_ui_add(parent, item); } static void @@ -326,6 +288,7 @@ static void _edi_mainview_tab_stat_done(void *data, Eio_File *handler EINA_UNUSED, const Eina_Stat *stat) { Edi_Path_Options *options; + Edi_Content_Provider *provider; const char *mime; options = data; @@ -333,20 +296,14 @@ _edi_mainview_tab_stat_done(void *data, Eio_File *handler EINA_UNUSED, const Ein return; mime = efreet_mime_type_get(options->path); - if (!strcasecmp(mime, "text/plain") || !strcasecmp(mime, "application/x-shellscript")) - options->type = "text"; - else if (!strcasecmp(mime, "text/x-chdr") || !strcasecmp(mime, "text/x-csrc")) - options->type = "text"; // TODO make a code view - else if (!strncasecmp(mime, "image/", 6)) - options->type = "image"; - else if (!strcasecmp(mime, "text/x-diff") || !strcasecmp(mime, "text/x-patch")) - options->type = "diff"; - else + provider = edi_content_provider_for_mime_get(mime); + if (!provider) { _edi_mainview_choose_type(nf, options, _edi_mainview_choose_type_tab_cb); return; } + options->type = provider->id; _edi_mainview_item_tab_add(options, mime); } @@ -354,6 +311,7 @@ static void _edi_mainview_win_stat_done(void *data, Eio_File *handler EINA_UNUSED, const Eina_Stat *stat) { Edi_Path_Options *options; + Edi_Content_Provider *provider; const char *mime; options = data; @@ -361,20 +319,14 @@ _edi_mainview_win_stat_done(void *data, Eio_File *handler EINA_UNUSED, const Ein return; mime = efreet_mime_type_get(options->path); - if (!strcasecmp(mime, "text/plain") || !strcasecmp(mime, "application/x-shellscript")) - options->type = "text"; - else if (!strcasecmp(mime, "text/x-chdr") || !strcasecmp(mime, "text/x-csrc")) - options->type = "text"; // TODO make a code view - else if (!strncasecmp(mime, "image/", 6)) - options->type = "image"; - else if (!strcasecmp(mime, "text/x-diff") || !strcasecmp(mime, "text/x-patch")) - options->type = "diff"; - else + provider = edi_content_provider_for_mime_get(mime); + if (!provider) { _edi_mainview_choose_type(nf, options, _edi_mainview_choose_type_win_cb); return; } + options->type = provider->id; _edi_mainview_item_win_add(options, mime); } diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 2b2a7f2..9743a94 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -5,16 +5,19 @@ check_PROGRAMS = edi_suite edi_suite_SOURCES = \ edi_test_path.c \ +edi_test_content_provider.c \ edi_suite.c edi_suite_CPPFLAGS = -I$(top_builddir)/src/lib/ -I$(top_builddir)/src/bin/ \ +-I$(top_srcdir)/elm_code/lib \ -DPACKAGE_TESTS_DIR=\"$(top_srcdir)/src/tests/\" \ -DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)/src/tests/\" \ +-DEFL_BETA_API_SUPPORT \ @EFL_CFLAGS@ \ @CHECK_CFLAGS@ -edi_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libedi.la -edi_suite_DEPENDENCIES = $(top_builddir)/src/lib/libedi.la +edi_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libedi.la $(top_builddir)/elm_code/lib/libelm_code.la +edi_suite_DEPENDENCIES = $(top_builddir)/src/lib/libedi.la $(top_builddir)/elm_code/lib/libelm_code.la endif diff --git a/src/tests/edi_suite.c b/src/tests/edi_suite.c index f57bf16..038cad7 100644 --- a/src/tests/edi_suite.c +++ b/src/tests/edi_suite.c @@ -14,7 +14,8 @@ static const struct { void (*build)(TCase *tc); } tests[] = { { "basic", edi_test_basic }, - { "path", edi_test_path } + { "path", edi_test_path }, + { "content_provider", edi_test_content_provider } }; START_TEST(edi_initialization) diff --git a/src/tests/edi_suite.h b/src/tests/edi_suite.h index bdc17f2..e5c6169 100644 --- a/src/tests/edi_suite.h +++ b/src/tests/edi_suite.h @@ -8,5 +8,6 @@ void edi_test_basic(TCase *tc); void edi_test_console(TCase *tc); void edi_test_path(TCase *tc); +void edi_test_content_provider(TCase *tc); #endif /* _EDI_SUITE_H */ diff --git a/src/tests/edi_test_content_provider.c b/src/tests/edi_test_content_provider.c new file mode 100644 index 0000000..5c912b8 --- /dev/null +++ b/src/tests/edi_test_content_provider.c @@ -0,0 +1,36 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "edi_content_provider.c" + +#include "edi_suite.h" + +START_TEST (edi_test_content_provider_id_lookup) +{ + Edi_Content_Provider *provider; + + provider = edi_content_provider_for_id_get("text"); + + ck_assert(provider); + ck_assert_str_eq(provider->id, "text"); +} +END_TEST + +START_TEST (edi_test_content_provider_mime_lookup) +{ + Edi_Content_Provider *provider; + + provider = edi_content_provider_for_mime_get("text/plain"); + + ck_assert(provider); + ck_assert_str_eq(provider->id, "text"); +} +END_TEST + +void edi_test_content_provider(TCase *tc) +{ + tcase_add_test(tc, edi_test_content_provider_id_lookup); + tcase_add_test(tc, edi_test_content_provider_mime_lookup); +} +