diff --git a/legacy/edje/src/lib/Edje.h b/legacy/edje/src/lib/Edje.h index e2b186c29e..b719d9569c 100644 --- a/legacy/edje/src/lib/Edje.h +++ b/legacy/edje/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 @@ -2970,6 +2983,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. * diff --git a/legacy/edje/src/lib/edje_entry.c b/legacy/edje/src/lib/edje_entry.c index febbe2a426..2effafdb1a 100644 --- a/legacy/edje/src/lib/edje_entry.c +++ b/legacy/edje/src/lib/edje_entry.c @@ -179,6 +179,27 @@ _edje_focus_out_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, #endif } +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) { @@ -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/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index ada8370ab1..004538c984 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/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/legacy/edje/src/lib/edje_util.c b/legacy/edje/src/lib/edje_util.c index 2211a3e225..527101414e 100644 --- a/legacy/edje/src/lib/edje_util.c +++ b/legacy/edje/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) {