From 850f311d7494ae48616aaa95539d70b13fbcde36 Mon Sep 17 00:00:00 2001 From: woohyun Date: Tue, 7 Feb 2012 08:49:56 +0000 Subject: [PATCH] [edje/markup filter] Add new API, edje_object_markup_filter_callback_add. When using edje_object_text_insert_filter_callback_add, a filter function should check the type(format, text, or markup) of text for correct filtering. But in markup filter function(added by new API), text is always markup so no need to check the type of text. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/edje@67724 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/Edje.h | 81 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib/edje_entry.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++---- src/lib/edje_private.h | 9 ++++++ src/lib/edje_util.c | 65 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 235 insertions(+), 6 deletions(-) diff --git a/src/lib/Edje.h b/src/lib/Edje.h index e2b186c..b719d95 100644 --- a/src/lib/Edje.h +++ b/src/lib/Edje.h @@ -1054,6 +1054,7 @@ typedef void (*Edje_Signal_Cb) (void *data, Evas_Object *obj, c typedef void (*Edje_Text_Change_Cb) (void *data, Evas_Object *obj, const char *part); typedef void (*Edje_Message_Handler_Cb) (void *data, Evas_Object *obj, Edje_Message_Type type, int id, void *msg); /**< Edje message handler callback functions's prototype definition. @c data will have the auxiliary data pointer set at the time the callback registration. @c obj will be a pointer the Edje object where the message comes from. @c type will identify the type of the given message and @c msg will be a pointer the message's contents, de facto, which depend on @c type. */ typedef void (*Edje_Text_Filter_Cb) (void *data, Evas_Object *obj, const char *part, Edje_Text_Filter_Type type, char **text); +typedef void (*Edje_Markup_Filter_Cb) (void *data, Evas_Object *obj, const char *part, char **text); typedef Evas_Object *(*Edje_Item_Provider_Cb) (void *data, Evas_Object *obj, const char *part, const char *item); /** @@ -2924,8 +2925,20 @@ EAPI Eina_Bool edje_object_part_text_input_panel_enabled_get (const Evas_ * will make Edje break out of the filter cycle and reject the inserted * text. * + * @warning This function will be deprecated because of difficulty in use. + * The type(format, text, or makrup) of text should be always + * checked in the filter function for correct filtering. + * Please use edje_object_markup_filter_callback_add() instead. There + * is no need to check the type of text in the filter function + * because the text is always markup. + * @warning If you use this function with + * edje_object_markup_filter_callback_add() togehter, all + * Edje_Text_Filter_Cb functions and Edje_Markup_Filter_Cb functions + * will be executed, and then filtered text will be inserted. + * * @see edje_object_text_insert_filter_callback_del * @see edje_object_text_insert_filter_callback_del_full + * @see edje_object_markup_filter_callback_add * * @param obj A valid Evas_Object handle * @param part The part name @@ -2971,6 +2984,74 @@ EAPI void *edje_object_text_insert_filter_callback_del (Evas_Ob EAPI void *edje_object_text_insert_filter_callback_del_full (Evas_Object *obj, const char *part, Edje_Text_Filter_Cb func, void *data); /** + * Add a markup filter function for newly inserted text. + * + * Whenever text is inserted (not the same as set) into the given @p part, + * the list of markup filter functions will be called to decide if and how + * the new text will be accepted. + * The text parameter in the @p func filter is always markup. It can be + * modified by the user and it's up to him to free the one passed if he's to + * change the pointer. If doing so, the newly set text should be malloc'ed, + * as once all the filters are called Edje will free it. + * If the text is to be rejected, freeing it and setting the pointer to NULL + * will make Edje break out of the filter cycle and reject the inserted + * text. + * This function is different from edje_object_text_insert_filter_callback_add() + * in that the text parameter in the @p fucn filter is always markup. + * + * @warning If you use this function with + * edje_object_text_insert_filter_callback_add() togehter, all + * Edje_Text_Filter_Cb functions and Edje_Markup_Filter_Cb functions + * will be executed, and then filtered text will be inserted. + * + * @see edje_object_markup_filter_callback_del + * @see edje_object_markup_filter_callback_del_full + * @see edje_object_text_insert_filter_callback_add + * + * @param obj A valid Evas_Object handle + * @param part The part name + * @param func The callback function that will act as markup filter + * @param data User provided data to pass to the filter function + */ +EAPI void edje_object_markup_filter_callback_add(Evas_Object *obj, const char *part, Edje_Markup_Filter_Cb func, void *data); + +/** + * Delete a function from the markup filter list. + * + * Delete the given @p func filter from the list in @p part. Returns + * the user data pointer given when added. + * + * @see edje_object_markup_filter_callback_add + * @see edje_object_markup_filter_callback_del_full + * + * @param obj A valid Evas_Object handle + * @param part The part name + * @param func The function callback to remove + * + * @return The user data pointer if succesful, or NULL otherwise + */ +EAPI void *edje_object_markup_filter_callback_del(Evas_Object *obj, const char *part, Edje_Markup_Filter_Cb func); + +/** + * Delete a function and matching user data from the markup filter list. + * + * Delete the given @p func filter and @p data user data from the list + * in @p part. + * Returns the user data pointer given when added. + * + * @see edje_object_markup_filter_callback_add + * @see edje_object_markup_filter_callback_del + * + * @param obj A valid Evas_Object handle + * @param part The part name + * @param func The function callback to remove + * @param data The data passed to the callback function + * + * @return The same data pointer if succesful, or NULL otherwise + */ +EAPI void *edje_object_markup_filter_callback_del_full(Evas_Object *obj, const char *part, Edje_Markup_Filter_Cb func, void *data); + +/** * @brief Swallows an object into the edje. * * @param obj A valid Evas_Object handle diff --git a/src/lib/edje_entry.c b/src/lib/edje_entry.c index febbe2a..2effafd 100644 --- a/src/lib/edje_entry.c +++ b/src/lib/edje_entry.c @@ -180,6 +180,27 @@ _edje_focus_out_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, } static void +_text_filter_markup_prepend_internal(Entry *en, Evas_Textblock_Cursor *c, char *text) +{ + Edje_Markup_Filter_Callback *cb; + Eina_List *l; + + EINA_LIST_FOREACH(en->rp->edje->markup_filter_callbacks, l, cb) + { + if (!strcmp(cb->part, en->rp->part->name)) + { + cb->func(cb->data, en->rp->edje->obj, cb->part, &text); + if (!text) break; + } + } + if (text) + { + evas_object_textblock_text_markup_prepend(c, text); + free(text); + } +} + +static void _text_filter_text_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text) { char *text2; @@ -197,8 +218,11 @@ _text_filter_text_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text) } if (text2) { - evas_textblock_cursor_text_prepend(c, text2); + char *markup_text; + markup_text = evas_textblock_text_utf8_to_markup(NULL, text2); free(text2); + if (markup_text) + _text_filter_markup_prepend_internal(en, c, markup_text); } } @@ -220,8 +244,61 @@ _text_filter_format_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *tex } if (text2) { - evas_textblock_cursor_format_prepend(c, text2); + char *s, *markup_text; + + s = text2; + if (*s == '+') + { + s++; + while (*s == ' ') s++; + if (!s) + { + free(text2); + return; + } + markup_text = (char*) malloc(strlen(s) + 3); + if (markup_text) + { + *(markup_text) = '<'; + strncpy((markup_text + 1), s, strlen(s)); + *(markup_text + strlen(s) + 1) = '>'; + *(markup_text + strlen(s) + 2) = '\0'; + } + } + else if (s[0] == '-') + { + s++; + while (*s == ' ') s++; + if (!s) + { + free(text2); + return; + } + markup_text = (char*) malloc(strlen(s) + 4); + if (markup_text) + { + *(markup_text) = '<'; + *(markup_text + 1) = '/'; + strncpy((markup_text + 2), s, strlen(s)); + *(markup_text + strlen(s) + 2) = '>'; + *(markup_text + strlen(s) + 3) = '\0'; + } + } + else + { + markup_text = (char*) malloc(strlen(s) + 4); + if (markup_text) + { + *(markup_text) = '<'; + strncpy((markup_text + 1), s, strlen(s)); + *(markup_text + strlen(s) + 1) = '/'; + *(markup_text + strlen(s) + 2) = '>'; + *(markup_text + strlen(s) + 3) = '\0'; + } + } free(text2); + if (markup_text) + _text_filter_markup_prepend_internal(en, c, markup_text); } } @@ -242,10 +319,7 @@ _text_filter_markup_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *tex } } if (text2) - { - evas_object_textblock_text_markup_prepend(c, text2); - free(text2); - } + _text_filter_markup_prepend_internal(en, c, text2); } static void diff --git a/src/lib/edje_private.h b/src/lib/edje_private.h index ada8370..004538c 100644 --- a/src/lib/edje_private.h +++ b/src/lib/edje_private.h @@ -322,6 +322,7 @@ typedef struct _Edje_Var_Timer Edje_Var_Timer; typedef struct _Edje_Var_Pool Edje_Var_Pool; typedef struct _Edje_Signal_Source_Char Edje_Signal_Source_Char; typedef struct _Edje_Text_Insert_Filter_Callback Edje_Text_Insert_Filter_Callback; +typedef struct _Edje_Markup_Filter_Callback Edje_Markup_Filter_Callback; #define EDJE_INF_MAX_W 100000 #define EDJE_INF_MAX_H 100000 @@ -1077,6 +1078,7 @@ struct _Edje Edje_Real_Part *focused_part; Eina_List *subobjs; Eina_List *text_insert_filter_callbacks; + Eina_List *markup_filter_callbacks; void *script_only_data; int table_programs_size; @@ -1337,6 +1339,13 @@ struct _Edje_Text_Insert_Filter_Callback void *data; }; +struct _Edje_Markup_Filter_Callback +{ + const char *part; + Edje_Markup_Filter_Cb func; + void *data; +}; + struct _Edje_Pending_Program { Edje *edje; diff --git a/src/lib/edje_util.c b/src/lib/edje_util.c index 2211a3e..5271014 100644 --- a/src/lib/edje_util.c +++ b/src/lib/edje_util.c @@ -1941,6 +1941,71 @@ edje_object_text_insert_filter_callback_del_full(Evas_Object *obj, const char *p return NULL; } +EAPI void +edje_object_markup_filter_callback_add(Evas_Object *obj, const char *part, Edje_Markup_Filter_Cb func, void *data) +{ + Edje *ed; + Edje_Markup_Filter_Callback *cb; + + ed = _edje_fetch(obj); + if ((!ed) || (!part)) return; + cb = calloc(1, sizeof(Edje_Markup_Filter_Callback)); + cb->part = eina_stringshare_add(part); + cb->func = func; + cb->data = (void *)data; + ed->markup_filter_callbacks = + eina_list_append(ed->markup_filter_callbacks, cb); +} + +EAPI void * +edje_object_markup_filter_callback_del(Evas_Object *obj, const char *part, Edje_Markup_Filter_Cb func) +{ + Edje *ed; + Edje_Markup_Filter_Callback *cb; + Eina_List *l; + + ed = _edje_fetch(obj); + if ((!ed) || (!part)) return NULL; + EINA_LIST_FOREACH(ed->markup_filter_callbacks, l, cb) + { + if ((!strcmp(cb->part, part)) && (cb->func == func)) + { + void *data = cb->data; + ed->markup_filter_callbacks = + eina_list_remove_list(ed->markup_filter_callbacks, l); + eina_stringshare_del(cb->part); + free(cb); + return data; + } + } + return NULL; +} + +EAPI void * +edje_object_markup_filter_callback_del_full(Evas_Object *obj, const char *part, Edje_Markup_Filter_Cb func, void *data) +{ + Edje *ed; + Edje_Markup_Filter_Callback *cb; + Eina_List *l; + + ed = _edje_fetch(obj); + if ((!ed) || (!part)) return NULL; + EINA_LIST_FOREACH(ed->markup_filter_callbacks, l, cb) + { + if ((!strcmp(cb->part, part)) && (cb->func == func) && + (cb->data == data)) + { + void *tmp = cb->data; + ed->markup_filter_callbacks = + eina_list_remove_list(ed->markup_filter_callbacks, l); + eina_stringshare_del(cb->part); + free(cb); + return tmp; + } + } + return NULL; +} + EAPI Eina_Bool edje_object_part_swallow(Evas_Object *obj, const char *part, Evas_Object *obj_swallow) { -- 2.7.4