From 22bccb7e1e9ff94a9b911754401dffe4400ad2e4 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Fri, 29 Mar 2013 19:42:54 +0900 Subject: [PATCH] Fix edje entry to resepct filter callbacks and not clear selections if filters filter out all contents. --- ChangeLog | 5 + NEWS | 1 + src/lib/edje/edje_entry.c | 280 +++++++++++++++++++++----------------- 3 files changed, 161 insertions(+), 125 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ae8c55160..585c3061a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-03-29 Carsten Haitzler (The Rasterman) + + * Fix edje entry to resepct filter callbacks and not clear + selections if filters filter out all contents. + 2013-03-28 Cedric Bail * Ecore: automatically turn on Systemd watchdog in Ecore main loop. diff --git a/NEWS b/NEWS index 1eb636b1f1..e9589a3a06 100644 --- a/NEWS +++ b/NEWS @@ -216,3 +216,4 @@ Fixes: * Fix magic failure in eina_value_array_count when array has not been allocated * Ecore_x: fix alpha set function not clear sync counter * Fix evas word start/end find in textblock to be consistent with other toolkit logic on the matter + * Fix edje entry to respect filters and if input filtered out, don't clear selections diff --git a/src/lib/edje/edje_entry.c b/src/lib/edje/edje_entry.c index 4eaf0a79d9..75f37b1438 100644 --- a/src/lib/edje/edje_entry.c +++ b/src/lib/edje/edje_entry.c @@ -13,6 +13,8 @@ typedef struct _Anchor Anchor; static void _edje_entry_imf_cursor_location_set(Entry *en); static void _edje_entry_imf_cursor_info_set(Entry *en); +static void _range_del_emit(Edje *ed, Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o EINA_UNUSED, Entry *en); +static void _text_filter_format_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text); struct _Entry { @@ -189,8 +191,11 @@ _edje_focus_out_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED #endif } -static void -_text_filter_markup_prepend_internal(Entry *en, Evas_Textblock_Cursor *c, char *text) +static Edje_Entry_Change_Info * +_text_filter_markup_prepend_internal(Entry *en, Evas_Textblock_Cursor *c, + char *text, + const char *fmtpre, const char *fmtpost, + Eina_Bool clearsel, Eina_Bool changeinfo) { Edje_Markup_Filter_Callback *cb; Eina_List *l; @@ -210,19 +215,46 @@ _text_filter_markup_prepend_internal(Entry *en, Evas_Textblock_Cursor *c, char * #endif if (text) { + Edje_Entry_Change_Info *info = NULL; + + if (changeinfo) + { + info = calloc(1, sizeof(*info)); + if (info) + { + info->insert = EINA_TRUE; + info->change.insert.content = eina_stringshare_add(text); + info->change.insert.plain_length = + eina_unicode_utf8_get_len(info->change.insert.content); + } + } + if ((clearsel) && (en->have_selection)) + { + _range_del_emit(en->rp->edje, en->cursor, en->rp->object, en); + if (info) info->merge = EINA_TRUE; + } + if (info) info->change.insert.pos = + evas_textblock_cursor_pos_get(en->cursor); + if (fmtpre) _text_filter_format_prepend(en, en->cursor, fmtpre); evas_object_textblock_text_markup_prepend(c, text); free(text); + if (fmtpost) _text_filter_format_prepend(en, en->cursor, fmtpost); + return info; } + return NULL; } -static void -_text_filter_text_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text) +static Edje_Entry_Change_Info * +_text_filter_text_prepend(Entry *en, Evas_Textblock_Cursor *c, + const char *text, + const char *fmtpre, const char *fmtpost, + Eina_Bool clearsel, Eina_Bool changeinfo) { - char *text2; + char *text2 = NULL; Edje_Text_Insert_Filter_Callback *cb; Eina_List *l; - EINA_SAFETY_ON_NULL_RETURN(text); + EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL); text2 = strdup(text); EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb) { @@ -235,11 +267,17 @@ _text_filter_text_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text) if (text2) { char *markup_text; + Edje_Entry_Change_Info *info = NULL; + markup_text = evas_textblock_text_utf8_to_markup(NULL, text2); free(text2); if (markup_text) - _text_filter_markup_prepend_internal(en, c, markup_text); + info = _text_filter_markup_prepend_internal(en, c, markup_text, + fmtpre, fmtpost, + clearsel, changeinfo); + return info; } + return NULL; } static void @@ -315,18 +353,23 @@ _text_filter_format_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *tex } free(text2); if (markup_text) - _text_filter_markup_prepend_internal(en, c, markup_text); + _text_filter_markup_prepend_internal(en, c, markup_text, + NULL, NULL, + EINA_FALSE, EINA_FALSE); } } -static void -_text_filter_markup_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text) +static Edje_Entry_Change_Info * +_text_filter_markup_prepend(Entry *en, Evas_Textblock_Cursor *c, + const char *text, + const char *fmtpre, const char *fmtpost, + Eina_Bool clearsel, Eina_Bool changeinfo) { char *text2; Edje_Text_Insert_Filter_Callback *cb; Eina_List *l; - EINA_SAFETY_ON_NULL_RETURN(text); + EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL); text2 = strdup(text); EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb) { @@ -337,7 +380,15 @@ _text_filter_markup_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *tex } } if (text2) - _text_filter_markup_prepend_internal(en, c, text2); + { + Edje_Entry_Change_Info *info; + + info = _text_filter_markup_prepend_internal(en, c, text2, + fmtpre, fmtpost, + clearsel, changeinfo); + return info; + } + return NULL; } static void @@ -1101,12 +1152,12 @@ noop: _sel_clear(en->cursor, en->rp->object, en); } -static void -_range_del(Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o EINA_UNUSED, Entry *en) -{ - evas_textblock_cursor_range_delete(en->sel_start, en->sel_end); - _sel_clear(en->cursor, en->rp->object, en); -} +//static void +//_range_del(Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o EINA_UNUSED, Entry *en) +//{ +// evas_textblock_cursor_range_delete(en->sel_start, en->sel_end); +// _sel_clear(en->cursor, en->rp->object, en); +//} static void _delete_emit(Edje *ed, Evas_Textblock_Cursor *c, Entry *en, size_t pos, @@ -1558,8 +1609,6 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, info->change.insert.pos = evas_textblock_cursor_pos_get(en->cursor); info->change.insert.content = eina_stringshare_add(""); - //yy -// evas_textblock_cursor_format_prepend(en->cursor, "tab"); _text_filter_format_prepend(en, en->cursor, "tab"); _anchors_get(en->cursor, rp->object, en); _edje_emit(ed, "entry,changed", rp->part->name); @@ -1631,15 +1680,11 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, if (shift || evas_object_textblock_legacy_newline_get(rp->object)) { - //yy -// evas_textblock_cursor_format_prepend(en->cursor, "br"); _text_filter_format_prepend(en, en->cursor, "br"); info->change.insert.content = eina_stringshare_add("
"); } else { - //yy -// evas_textblock_cursor_format_prepend(en->cursor, "ps"); _text_filter_format_prepend(en, en->cursor, "ps"); info->change.insert.content = eina_stringshare_add(""); } @@ -1688,49 +1733,48 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, } if (string) { - Edje_Entry_Change_Info *info = calloc(1, sizeof(*info)); - info->insert = EINA_TRUE; - info->change.insert.plain_length = 1; - info->change.insert.content = eina_stringshare_add(string); - - if (en->have_selection) - { - _range_del_emit(ed, en->cursor, rp->object, en); - info->merge = EINA_TRUE; - } - - info->change.insert.pos = - evas_textblock_cursor_pos_get(en->cursor); - // if PASSWORD_SHOW_LAST mode, appending text with password=off tag + Edje_Entry_Change_Info *info = NULL; +// if PASSWORD_SHOW_LAST mode, appending text with password=off tag if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) && _edje_password_show_last) { _edje_entry_hide_visible_password(en->rp); - _text_filter_format_prepend(en, en->cursor, "+ password=off"); - _text_filter_text_prepend(en, en->cursor, string); - _text_filter_format_prepend(en, en->cursor, "- password"); - if (en->pw_timer) + info = _text_filter_text_prepend(en, en->cursor, string, + "+ password=off", + "- password", + EINA_TRUE, EINA_TRUE); + if (info) { - ecore_timer_del(en->pw_timer); - en->pw_timer = NULL; + if (en->pw_timer) + { + ecore_timer_del(en->pw_timer); + en->pw_timer = NULL; + } + en->pw_timer = ecore_timer_add + (TO_DOUBLE(_edje_password_show_last_timeout), + _password_timer_cb, en); } - en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout), - _password_timer_cb, en); } else - _text_filter_text_prepend(en, en->cursor, string); + info = _text_filter_text_prepend(en, en->cursor, string, + NULL, NULL, + EINA_TRUE, EINA_TRUE); _anchors_get(en->cursor, rp->object, en); - _edje_emit(ed, "entry,changed", rp->part->name); - _edje_emit_full(ed, "entry,changed,user", rp->part->name, - info, _free_entry_change_info); - _edje_emit(ed, "cursor,changed", rp->part->name); - cursor_changed = EINA_TRUE; - ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + if (info) + { + _edje_emit(ed, "entry,changed", rp->part->name); + _edje_emit_full(ed, "entry,changed,user", rp->part->name, + info, _free_entry_change_info); + _edje_emit(ed, "cursor,changed", rp->part->name); + cursor_changed = EINA_TRUE; + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + } } if (free_string) free(string); } end: - if (!cursor_changed && (old_cur_pos != evas_textblock_cursor_pos_get(en->cursor))) + if (!cursor_changed && + (old_cur_pos != evas_textblock_cursor_pos_get(en->cursor))) _edje_emit(ed, "cursor,changed", rp->part->name); _edje_entry_imf_cursor_info_set(en); @@ -2564,7 +2608,8 @@ _edje_entry_text_markup_append(Edje_Real_Part *rp, const char *text) end_cur = evas_object_textblock_cursor_new(rp->object); evas_textblock_cursor_paragraph_last(end_cur); - _text_filter_markup_prepend(en, end_cur, text); + _text_filter_markup_prepend(en, end_cur, text, NULL, NULL, + EINA_TRUE, EINA_FALSE); evas_textblock_cursor_free(end_cur); /* We are updating according to the real cursor on purpose */ @@ -2585,12 +2630,11 @@ _edje_entry_text_markup_insert(Edje_Real_Part *rp, const char *text) if (!en) return; _edje_entry_imf_context_reset(rp); - // prepend markup @ cursor pos - if (en->have_selection) - _range_del(en->cursor, rp->object, en); - //xx -// evas_object_textblock_text_markup_prepend(en->cursor, text); - _text_filter_markup_prepend(en, en->cursor, text); + // prepend markup @ cursor pos .. XXX: do we need to do this? maybe not? +// if (en->have_selection) +// _range_del(en->cursor, rp->object, en); + _text_filter_markup_prepend(en, en->cursor, text, NULL, NULL, + EINA_TRUE, EINA_FALSE); _anchors_get(en->cursor, rp->object, en); _edje_emit(rp->edje, "entry,changed", rp->part->name); _edje_emit(rp->edje, "cursor,changed", rp->part->name); @@ -2835,31 +2879,16 @@ _edje_entry_user_insert(Edje_Real_Part *rp, const char *text) (!rp->typedata.text)) return; en = rp->typedata.text->entry_data; if (!en) return; - info = calloc(1, sizeof(*info)); - if (!info) return; - info->insert = EINA_TRUE; - info->change.insert.plain_length = 1; - info->change.insert.content = eina_stringshare_add(text); - { - char *tmp; - tmp = evas_textblock_text_markup_to_utf8(rp->object, - info->change.insert.content); - info->change.insert.plain_length = eina_unicode_utf8_get_len(tmp); - free(tmp); - } - - if (en->have_selection) - { - _range_del_emit(rp->edje, en->cursor, rp->object, en); - info->merge = EINA_TRUE; - } - info->change.insert.pos = evas_textblock_cursor_pos_get(en->cursor); - _text_filter_markup_prepend(en, en->cursor, text); + info = _text_filter_markup_prepend(en, en->cursor, text, NULL, NULL, + EINA_TRUE, EINA_TRUE); _anchors_get(en->cursor, rp->object, en); - _edje_emit(rp->edje, "entry,changed", rp->part->name); - _edje_emit_full(rp->edje, "entry,changed,user", rp->part->name, - info, _free_entry_change_info); - _edje_emit(rp->edje, "cursor,changed", rp->part->name); + if (info) + { + _edje_emit(rp->edje, "entry,changed", rp->part->name); + _edje_emit_full(rp->edje, "entry,changed,user", rp->part->name, + info, _free_entry_change_info); + _edje_emit(rp->edje, "cursor,changed", rp->part->name); + } _edje_entry_imf_cursor_info_set(en); _edje_entry_real_part_configure(rp); @@ -3729,8 +3758,8 @@ _edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, Edje_Real_Part *rp = ed->focused_part; Entry *en = NULL; char *commit_str = event_info; - int start_pos; - + Edje_Entry_Change_Info *info = NULL; + if ((!rp)) return; if ((rp->type != EDJE_RP_TYPE_TEXT) || (!rp->typedata.text)) return; @@ -3750,8 +3779,6 @@ _edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, } } - start_pos = evas_textblock_cursor_pos_get(en->cursor); - /* delete preedit characters */ _preedit_del(en); _preedit_clear(en); @@ -3769,38 +3796,38 @@ _edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) && _edje_password_show_last && (!en->preedit_start)) { - _text_filter_format_prepend(en, en->cursor, "+ password=off"); - _text_filter_text_prepend(en, en->cursor, commit_str); - _text_filter_format_prepend(en, en->cursor, "- password"); - - if (en->pw_timer) + info = _text_filter_text_prepend(en, en->cursor, commit_str, + "+ password=off", "- password", + EINA_TRUE, EINA_TRUE); + if (info) { - ecore_timer_del(en->pw_timer); - en->pw_timer = NULL; + if (en->pw_timer) + { + ecore_timer_del(en->pw_timer); + en->pw_timer = NULL; + } + en->pw_timer = ecore_timer_add + (TO_DOUBLE(_edje_password_show_last_timeout), + _password_timer_cb, en); } - en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout), - _password_timer_cb, en); } else - _text_filter_text_prepend(en, en->cursor, commit_str); + { + info = _text_filter_text_prepend(en, en->cursor, commit_str, + NULL, NULL, + EINA_TRUE, EINA_TRUE); + } _edje_entry_imf_cursor_info_set(en); _anchors_get(en->cursor, rp->object, en); - _edje_emit(rp->edje, "entry,changed", rp->part->name); - + if (info) { - Edje_Entry_Change_Info *info = calloc(1, sizeof(*info)); - info->insert = EINA_TRUE; - info->change.insert.pos = start_pos; - info->change.insert.content = eina_stringshare_add(commit_str); - info->change.insert.plain_length = - eina_unicode_utf8_get_len(info->change.insert.content); + _edje_emit(rp->edje, "entry,changed", rp->part->name); _edje_emit_full(ed, "entry,changed,user", rp->part->name, info, _free_entry_change_info); _edje_emit(ed, "cursor,changed", rp->part->name); } - _edje_entry_imf_cursor_info_set(en); _edje_entry_real_part_configure(rp); } @@ -3845,12 +3872,6 @@ _edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx EINA if (!strcmp(preedit_string, "")) preedit_end_state = EINA_TRUE; - if (en->have_selection && !preedit_end_state) - { - /* delete selected characters */ - _range_del_emit(ed, en->cursor, rp->object, en); - } - /* delete preedit characters */ _preedit_del(en); @@ -3897,22 +3918,31 @@ _edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx EINA if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) && _edje_password_show_last) { + Edje_Entry_Change_Info *info; + _edje_entry_hide_visible_password(en->rp); - _text_filter_format_prepend(en, en->cursor, "+ password=off"); - _text_filter_markup_prepend(en, en->cursor, eina_strbuf_string_get(buf)); - _text_filter_format_prepend(en, en->cursor, "- password"); - if (en->pw_timer) + info = _text_filter_text_prepend(en, en->cursor, + eina_strbuf_string_get(buf), + "+ password=off", + "- password", + EINA_TRUE, EINA_TRUE); + if (info) { - ecore_timer_del(en->pw_timer); - en->pw_timer = NULL; + if (en->pw_timer) + { + ecore_timer_del(en->pw_timer); + en->pw_timer = NULL; + } + en->pw_timer = ecore_timer_add + (TO_DOUBLE(_edje_password_show_last_timeout), + _password_timer_cb, en); } - en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout), - _password_timer_cb, en); } else - { - _text_filter_markup_prepend(en, en->cursor, eina_strbuf_string_get(buf)); - } + _text_filter_markup_prepend(en, en->cursor, + eina_strbuf_string_get(buf), + NULL, NULL, + EINA_TRUE, EINA_FALSE); eina_strbuf_free(buf); }