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
This commit is contained in:
Andy Williams 2014-11-28 23:34:36 +00:00
parent 04dda232b6
commit 2538f6cf90
8 changed files with 219 additions and 66 deletions

View File

@ -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 \

View File

@ -0,0 +1,89 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Evas.h>
#include <Elm_Code.h>
#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;
}

View File

@ -0,0 +1,70 @@
#ifndef EDI_CONTENT_PROVIDER_H_
# define EDI_CONTENT_PROVIDER_H_
#include <Evas.h>
#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_ */

View File

@ -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);
}

View File

@ -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

View File

@ -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)

View File

@ -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 */

View File

@ -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);
}