1 #include "edje_private.h"
4 static Eina_Bool _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos);
5 static void _edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info);
6 static void _edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx, void *event_info);
7 static void _edje_entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx, void *event);
10 typedef struct _Entry Entry;
11 typedef struct _Sel Sel;
12 typedef struct _Anchor Anchor;
14 static void _edje_entry_imf_cursor_info_set(Entry *en);
19 Evas_Object *cursor_bg;
20 Evas_Object *cursor_fg;
21 Evas_Textblock_Cursor *cursor;
22 Evas_Textblock_Cursor *sel_start, *sel_end;
23 Evas_Textblock_Cursor *cursor_user, *cursor_user_extra;
24 Evas_Textblock_Cursor *preedit_start, *preedit_end;
25 Ecore_Timer *pw_timer;
28 Eina_List *anchorlist;
32 Edje_Input_Panel_Lang input_panel_lang;
33 Eina_Bool composing : 1;
34 Eina_Bool selecting : 1;
35 Eina_Bool have_selection : 1;
36 Eina_Bool select_allow : 1;
37 Eina_Bool select_mod_start : 1;
38 Eina_Bool select_mod_end : 1;
39 Eina_Bool had_sel : 1;
40 Eina_Bool input_panel_enable : 1;
41 Eina_Bool prediction_allow : 1;
44 Eina_Bool have_preedit : 1;
45 Ecore_IMF_Context *imf_context;
51 Evas_Textblock_Rectangle rect;
52 Evas_Object *obj_fg, *obj_bg, *obj, *sobj;
59 Evas_Textblock_Cursor *start, *end;
66 _preedit_clear(Entry *en)
68 if (en->preedit_start)
70 evas_textblock_cursor_free(en->preedit_start);
71 en->preedit_start = NULL;
76 evas_textblock_cursor_free(en->preedit_end);
77 en->preedit_end = NULL;
80 en->have_preedit = EINA_FALSE;
84 _preedit_del(Entry *en)
86 if (!en || !en->have_preedit) return;
87 if (!en->preedit_start || !en->preedit_end) return;
88 if (!evas_textblock_cursor_compare(en->preedit_start, en->preedit_end)) return;
90 /* delete the preedit characters */
91 evas_textblock_cursor_range_delete(en->preedit_start, en->preedit_end);
95 _edje_entry_focus_in_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
101 if (!rp || !rp->entry_data || !rp->edje || !rp->edje->obj) return;
104 if (!en || !en->imf_context) return;
106 if (evas_object_focus_get(rp->edje->obj))
108 ecore_imf_context_reset(en->imf_context);
109 ecore_imf_context_focus_in(en->imf_context);
110 _edje_entry_imf_cursor_info_set(en);
115 _edje_entry_focus_out_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
121 if (!rp || !rp->entry_data) return;
124 if (!en || !en->imf_context) return;
126 ecore_imf_context_reset(en->imf_context);
127 _edje_entry_imf_cursor_info_set(en);
128 ecore_imf_context_focus_out(en->imf_context);
133 _edje_focus_in_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
136 #ifdef HAVE_ECORE_IMF
141 _edje_emit(ed, "focus,in", "");
142 #ifdef HAVE_ECORE_IMF
143 rp = ed->focused_part;
147 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
148 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
151 if (!en->imf_context) return;
153 ecore_imf_context_reset(en->imf_context);
154 ecore_imf_context_focus_in(en->imf_context);
155 _edje_entry_imf_cursor_info_set(en);
160 _edje_focus_out_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
163 #ifdef HAVE_ECORE_IMF
164 Edje_Real_Part *rp = ed->focused_part;
168 _edje_emit(ed, "focus,out", "");
170 #ifdef HAVE_ECORE_IMF
173 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
174 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
177 if (!en->imf_context) return;
179 ecore_imf_context_reset(en->imf_context);
180 _edje_entry_imf_cursor_info_set(en);
181 ecore_imf_context_focus_out(en->imf_context);
186 _text_filter_markup_prepend_internal(Entry *en, Evas_Textblock_Cursor *c, char *text)
188 Edje_Markup_Filter_Callback *cb;
191 EINA_LIST_FOREACH(en->rp->edje->markup_filter_callbacks, l, cb)
193 if (!strcmp(cb->part, en->rp->part->name))
195 cb->func(cb->data, en->rp->edje->obj, cb->part, &text);
201 evas_object_textblock_text_markup_prepend(c, text);
207 _text_filter_text_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text)
210 Edje_Text_Insert_Filter_Callback *cb;
213 text2 = strdup(text);
214 EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb)
216 if (!strcmp(cb->part, en->rp->part->name))
218 cb->func(cb->data, en->rp->edje->obj, cb->part, EDJE_TEXT_FILTER_TEXT, &text2);
225 markup_text = evas_textblock_text_utf8_to_markup(NULL, text2);
228 _text_filter_markup_prepend_internal(en, c, markup_text);
233 _text_filter_format_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text)
236 Edje_Text_Insert_Filter_Callback *cb;
239 text2 = strdup(text);
240 EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb)
242 if (!strcmp(cb->part, en->rp->part->name))
244 cb->func(cb->data, en->rp->edje->obj, cb->part, EDJE_TEXT_FILTER_FORMAT, &text2);
250 char *s, *markup_text;
256 while (*s == ' ') s++;
262 markup_text = (char*) malloc(strlen(s) + 3);
265 *(markup_text) = '<';
266 strncpy((markup_text + 1), s, strlen(s));
267 *(markup_text + strlen(s) + 1) = '>';
268 *(markup_text + strlen(s) + 2) = '\0';
271 else if (s[0] == '-')
274 while (*s == ' ') s++;
280 markup_text = (char*) malloc(strlen(s) + 4);
283 *(markup_text) = '<';
284 *(markup_text + 1) = '/';
285 strncpy((markup_text + 2), s, strlen(s));
286 *(markup_text + strlen(s) + 2) = '>';
287 *(markup_text + strlen(s) + 3) = '\0';
292 markup_text = (char*) malloc(strlen(s) + 4);
295 *(markup_text) = '<';
296 strncpy((markup_text + 1), s, strlen(s));
297 *(markup_text + strlen(s) + 1) = '/';
298 *(markup_text + strlen(s) + 2) = '>';
299 *(markup_text + strlen(s) + 3) = '\0';
304 _text_filter_markup_prepend_internal(en, c, markup_text);
309 _text_filter_markup_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text)
312 Edje_Text_Insert_Filter_Callback *cb;
315 text2 = strdup(text);
316 EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb)
318 if (!strcmp(cb->part, en->rp->part->name))
320 cb->func(cb->data, en->rp->edje->obj, cb->part, EDJE_TEXT_FILTER_MARKUP, &text2);
325 _text_filter_markup_prepend_internal(en, c, text2);
329 _curs_update_from_curs(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__, Entry *en, Evas_Coord *cx, Evas_Coord *cy)
332 Evas_Textblock_Cursor_Type cur_type;
333 if (c != en->cursor) return;
334 switch (en->rp->part->cursor_mode)
336 case EDJE_ENTRY_CURSOR_MODE_BEFORE:
337 cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
339 case EDJE_ENTRY_CURSOR_MODE_UNDER:
340 /* no break for a resaon */
342 cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
344 evas_textblock_cursor_geometry_get(c, cx, cy, &cw, &ch, NULL, cur_type);
350 _curs_line_last_get(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o, Entry *en __UNUSED__)
352 Evas_Textblock_Cursor *cc;
355 cc = evas_object_textblock_cursor_new(o);
356 evas_textblock_cursor_paragraph_last(cc);
357 ln = evas_textblock_cursor_line_geometry_get(cc, NULL, NULL, NULL, NULL);
358 evas_textblock_cursor_free(cc);
363 _curs_lin_start(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__,
364 Entry *en __UNUSED__)
366 evas_textblock_cursor_line_char_first(c);
370 _curs_lin_end(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__,
371 Entry *en __UNUSED__)
373 evas_textblock_cursor_line_char_last(c);
377 _curs_start(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__,
378 Entry *en __UNUSED__)
380 evas_textblock_cursor_paragraph_first(c);
384 _curs_end(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__, Entry *en __UNUSED__)
386 evas_textblock_cursor_paragraph_last(c);
390 _curs_jump_line(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en, int ln)
393 Evas_Coord lx, ly, lw, lh;
394 int last = _curs_line_last_get(c, o, en);
399 if (ln > last) ln = last;
402 _curs_update_from_curs(c, o, en, &cx, &cy);
404 if (!evas_object_textblock_line_number_geometry_get(o, ln, &lx, &ly, &lw, &lh))
406 if (evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
408 evas_textblock_cursor_line_set(c, ln);
409 if (cx < (lx + (lw / 2)))
411 if (ln == last) _curs_end(c, o, en);
412 _curs_lin_start(c, o, en);
419 _curs_lin_end(c, o, en);
424 _curs_jump_line_by(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en, int by)
428 ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL) + by;
429 _curs_jump_line(c, o, en, ln);
433 _curs_up(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
435 _curs_jump_line_by(c, o, en, -1);
439 _curs_down(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
441 _curs_jump_line_by(c, o, en, 1);
445 _sel_start(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
447 if (en->sel_start) return;
448 en->sel_start = evas_object_textblock_cursor_new(o);
449 evas_textblock_cursor_copy(c, en->sel_start);
450 en->sel_end = evas_object_textblock_cursor_new(o);
451 evas_textblock_cursor_copy(c, en->sel_end);
453 en->have_selection = EINA_FALSE;
457 en->selection = NULL;
462 _sel_enable(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
464 if (en->have_selection) return;
465 en->have_selection = EINA_TRUE;
469 en->selection = NULL;
471 _edje_emit(en->rp->edje, "selection,start", en->rp->part->name);
475 _sel_extend(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
477 if (!en->sel_end) return;
478 _edje_entry_imf_context_reset(en->rp);
479 _sel_enable(c, o, en);
480 if (!evas_textblock_cursor_compare(c, en->sel_end)) return;
481 evas_textblock_cursor_copy(c, en->sel_end);
485 en->selection = NULL;
487 _edje_emit(en->rp->edje, "selection,changed", en->rp->part->name);
491 _sel_preextend(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
493 if (!en->sel_end) return;
494 _edje_entry_imf_context_reset(en->rp);
495 _sel_enable(c, o, en);
496 if (!evas_textblock_cursor_compare(c, en->sel_start)) return;
497 evas_textblock_cursor_copy(c, en->sel_start);
501 en->selection = NULL;
503 _edje_emit(en->rp->edje, "selection,changed", en->rp->part->name);
507 _sel_clear(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
509 en->had_sel = EINA_FALSE;
512 evas_textblock_cursor_free(en->sel_start);
513 evas_textblock_cursor_free(en->sel_end);
514 en->sel_start = NULL;
520 en->selection = NULL;
527 if (sel->obj_bg) evas_object_del(sel->obj_bg);
528 if (sel->obj_fg) evas_object_del(sel->obj_fg);
530 en->sel = eina_list_remove_list(en->sel, en->sel);
532 if (en->have_selection)
534 en->have_selection = EINA_FALSE;
535 _edje_emit(en->rp->edje, "selection,cleared", en->rp->part->name);
540 _sel_update(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o, Entry *en)
542 Eina_List *range = NULL, *l;
544 Evas_Coord x, y, w, h;
545 Evas_Object *smart, *clip;
547 smart = evas_object_smart_parent_get(o);
548 clip = evas_object_clip_get(o);
550 range = evas_textblock_cursor_range_geometry_get(en->sel_start, en->sel_end);
553 if (eina_list_count(range) != eina_list_count(en->sel))
558 if (sel->obj_bg) evas_object_del(sel->obj_bg);
559 if (sel->obj_fg) evas_object_del(sel->obj_fg);
561 en->sel = eina_list_remove_list(en->sel, en->sel);
563 if (en->have_selection)
565 for (l = range; l; l = eina_list_next(l))
569 sel = calloc(1, sizeof(Sel));
570 en->sel = eina_list_append(en->sel, sel);
571 ob = edje_object_add(en->rp->edje->base.evas);
572 edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source);
573 evas_object_smart_member_add(ob, smart);
574 evas_object_stack_below(ob, o);
575 evas_object_clip_set(ob, clip);
576 evas_object_pass_events_set(ob, EINA_TRUE);
577 evas_object_show(ob);
579 _edje_subobj_register(en->rp->edje, sel->obj_bg);
581 ob = edje_object_add(en->rp->edje->base.evas);
582 edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source2);
583 evas_object_smart_member_add(ob, smart);
584 evas_object_stack_above(ob, o);
585 evas_object_clip_set(ob, clip);
586 evas_object_pass_events_set(ob, EINA_TRUE);
587 evas_object_show(ob);
589 _edje_subobj_register(en->rp->edje, sel->obj_fg);
594 evas_object_geometry_get(o, &x, &y, &w, &h);
595 if (en->have_selection)
597 EINA_LIST_FOREACH(en->sel, l, sel)
599 Evas_Textblock_Rectangle *r;
604 evas_object_move(sel->obj_bg, x + r->x, y + r->y);
605 evas_object_resize(sel->obj_bg, r->w, r->h);
609 evas_object_move(sel->obj_fg, x + r->x, y + r->y);
610 evas_object_resize(sel->obj_fg, r->w, r->h);
612 *(&(sel->rect)) = *r;
613 range = eina_list_remove_list(range, range);
622 range = eina_list_remove_list(range, range);
628 _edje_anchor_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
631 Evas_Event_Mouse_Down *ev = event_info;
632 Edje_Real_Part *rp = an->en->rp;
639 if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) &&
642 ignored = rp->part->ignore_flags & ev->event_flags;
643 if ((!ev->event_flags) || (!ignored))
647 len = 200 + strlen(n);
649 if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK)
650 snprintf(buf, len, "anchor,mouse,down,%i,%s,triple", ev->button, n);
651 else if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
652 snprintf(buf, len, "anchor,mouse,down,%i,%s,double", ev->button, n);
654 snprintf(buf, len, "anchor,mouse,down,%i,%s", ev->button, n);
655 _edje_emit(rp->edje, buf, rp->part->name);
660 _edje_anchor_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
663 Evas_Event_Mouse_Up *ev = event_info;
664 Edje_Real_Part *rp = an->en->rp;
671 ignored = rp->part->ignore_flags & ev->event_flags;
672 if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) &&
677 len = 200 + strlen(n);
679 if ((!ev->event_flags) || (!ignored))
681 snprintf(buf, len, "anchor,mouse,up,%i,%s", ev->button, n);
682 _edje_emit(rp->edje, buf, rp->part->name);
684 if ((rp->still_in) && (rp->clicked_button == ev->button) && (!ignored))
686 snprintf(buf, len, "anchor,mouse,clicked,%i,%s", ev->button, n);
687 _edje_emit(rp->edje, buf, rp->part->name);
692 _edje_anchor_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
695 Evas_Event_Mouse_Move *ev = event_info;
696 Edje_Real_Part *rp = an->en->rp;
703 if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) &&
706 ignored = rp->part->ignore_flags & ev->event_flags;
707 if ((!ev->event_flags) || (!ignored))
711 len = 200 + strlen(n);
713 snprintf(buf, len, "anchor,mouse,move,%s", n);
714 _edje_emit(rp->edje, buf, rp->part->name);
719 _edje_anchor_mouse_in_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
722 Evas_Event_Mouse_In *ev = event_info;
723 Edje_Real_Part *rp = an->en->rp;
728 ignored = rp->part->ignore_flags & ev->event_flags;
729 if ((!ev->event_flags) || (!ignored))
733 len = 200 + strlen(n);
735 snprintf(buf, len, "anchor,mouse,in,%s", n);
736 _edje_emit(rp->edje, buf, rp->part->name);
741 _edje_anchor_mouse_out_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
744 Evas_Event_Mouse_Out *ev = event_info;
745 Edje_Real_Part *rp = an->en->rp;
750 ignored = rp->part->ignore_flags & ev->event_flags;
751 if ((!ev->event_flags) || (!ignored))
755 len = 200 + strlen(n);
757 snprintf(buf, len, "anchor,mouse,out,%s", n);
758 _edje_emit(rp->edje, buf, rp->part->name);
763 _anchors_update(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o, Entry *en)
765 Eina_List *l, *ll, *range = NULL;
766 Evas_Coord x, y, w, h;
767 Evas_Object *smart, *clip;
771 smart = evas_object_smart_parent_get(o);
772 clip = evas_object_clip_get(o);
774 evas_object_geometry_get(o, &x, &y, &w, &h);
775 EINA_LIST_FOREACH(en->anchors, l, an)
787 if (sel->obj_bg) evas_object_del(sel->obj_bg);
788 if (sel->obj_fg) evas_object_del(sel->obj_fg);
789 if (sel->obj) evas_object_del(sel->obj);
791 an->sel = eina_list_remove_list(an->sel, an->sel);
794 sel = calloc(1, sizeof(Sel));
795 an->sel = eina_list_append(an->sel, sel);
797 if (en->rp->edje->item_provider.func)
799 ob = en->rp->edje->item_provider.func
800 (en->rp->edje->item_provider.data, smart,
801 en->rp->part->name, an->name);
802 evas_object_smart_member_add(ob, smart);
803 evas_object_stack_above(ob, o);
804 evas_object_clip_set(ob, clip);
805 evas_object_pass_events_set(ob, EINA_TRUE);
806 evas_object_show(ob);
815 evas_textblock_cursor_range_geometry_get(an->start, an->end);
816 if (eina_list_count(range) != eina_list_count(an->sel))
821 if (sel->obj_bg) evas_object_del(sel->obj_bg);
822 if (sel->obj_fg) evas_object_del(sel->obj_fg);
823 if (sel->obj) evas_object_del(sel->obj);
825 an->sel = eina_list_remove_list(an->sel, an->sel);
827 for (ll = range; ll; ll = eina_list_next(ll))
831 sel = calloc(1, sizeof(Sel));
832 an->sel = eina_list_append(an->sel, sel);
833 ob = edje_object_add(en->rp->edje->base.evas);
834 edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source5);
835 evas_object_smart_member_add(ob, smart);
836 evas_object_stack_below(ob, o);
837 evas_object_clip_set(ob, clip);
838 evas_object_pass_events_set(ob, EINA_TRUE);
839 evas_object_show(ob);
841 _edje_subobj_register(en->rp->edje, sel->obj_bg);
843 ob = edje_object_add(en->rp->edje->base.evas);
844 edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source6);
845 evas_object_smart_member_add(ob, smart);
846 evas_object_stack_above(ob, o);
847 evas_object_clip_set(ob, clip);
848 evas_object_pass_events_set(ob, EINA_TRUE);
849 evas_object_show(ob);
851 _edje_subobj_register(en->rp->edje, sel->obj_fg);
853 ob = evas_object_rectangle_add(en->rp->edje->base.evas);
854 evas_object_color_set(ob, 0, 0, 0, 0);
855 evas_object_smart_member_add(ob, smart);
856 evas_object_stack_above(ob, o);
857 evas_object_clip_set(ob, clip);
858 evas_object_repeat_events_set(ob, EINA_TRUE);
859 evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _edje_anchor_mouse_down_cb, an);
860 evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_UP, _edje_anchor_mouse_up_cb, an);
861 evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_MOVE, _edje_anchor_mouse_move_cb, an);
862 evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_IN, _edje_anchor_mouse_in_cb, an);
863 evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_OUT, _edje_anchor_mouse_out_cb, an);
864 evas_object_show(ob);
869 EINA_LIST_FOREACH(an->sel, ll, sel)
873 Evas_Coord cx, cy, cw, ch;
875 if (!evas_textblock_cursor_format_item_geometry_get
876 (an->start, &cx, &cy, &cw, &ch))
878 evas_object_move(sel->obj, x + cx, y + cy);
879 evas_object_resize(sel->obj, cw, ch);
883 Evas_Textblock_Rectangle *r;
886 *(&(sel->rect)) = *r;
889 evas_object_move(sel->obj_bg, x + r->x, y + r->y);
890 evas_object_resize(sel->obj_bg, r->w, r->h);
894 evas_object_move(sel->obj_fg, x + r->x, y + r->y);
895 evas_object_resize(sel->obj_fg, r->w, r->h);
899 evas_object_move(sel->obj, x + r->x, y + r->y);
900 evas_object_resize(sel->obj, r->w, r->h);
902 range = eina_list_remove_list(range, range);
910 _anchors_clear(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
912 while (en->anchorlist)
914 free(en->anchorlist->data);
915 en->anchorlist = eina_list_remove_list(en->anchorlist, en->anchorlist);
919 free(en->itemlist->data);
920 en->itemlist = eina_list_remove_list(en->itemlist, en->itemlist);
924 Anchor *an = en->anchors->data;
926 evas_textblock_cursor_free(an->start);
927 evas_textblock_cursor_free(an->end);
930 Sel *sel = an->sel->data;
931 if (sel->obj_bg) evas_object_del(sel->obj_bg);
932 if (sel->obj_fg) evas_object_del(sel->obj_fg);
933 if (sel->obj) evas_object_del(sel->obj);
935 an->sel = eina_list_remove_list(an->sel, an->sel);
939 en->anchors = eina_list_remove_list(en->anchors, en->anchors);
944 _anchors_get(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
946 const Eina_List *anchors_a, *anchors_item;
948 _anchors_clear(c, o, en);
950 anchors_a = evas_textblock_node_format_list_get(o, "a");
951 anchors_item = evas_textblock_node_format_list_get(o, "item");
955 const Evas_Object_Textblock_Node_Format *node;
956 const Eina_List *itr;
957 EINA_LIST_FOREACH(anchors_a, itr, node)
959 const char *s = evas_textblock_node_format_text_get(node);
961 an = calloc(1, sizeof(Anchor));
966 p = strstr(s, "href=");
969 an->name = strdup(p + 5);
971 en->anchors = eina_list_append(en->anchors, an);
972 an->start = evas_object_textblock_cursor_new(o);
973 an->end = evas_object_textblock_cursor_new(o);
974 evas_textblock_cursor_at_format_set(an->start, node);
975 evas_textblock_cursor_copy(an->start, an->end);
977 /* Close the anchor, if the anchor was without text,
979 node = evas_textblock_node_format_next_get(node);
980 for (; node; node = evas_textblock_node_format_next_get(node))
982 s = evas_textblock_node_format_text_get(node);
983 if ((!strcmp(s, "- a")) || (!strcmp(s, "-a")))
989 evas_textblock_cursor_at_format_set(an->end, node);
991 else if (!evas_textblock_cursor_compare(an->start, an->end))
993 if (an->name) free(an->name);
994 evas_textblock_cursor_free(an->start);
995 evas_textblock_cursor_free(an->end);
996 en->anchors = eina_list_remove(en->anchors, an);
1005 const Evas_Object_Textblock_Node_Format *node;
1006 const Eina_List *itr;
1007 EINA_LIST_FOREACH(anchors_item, itr, node)
1009 const char *s = evas_textblock_node_format_text_get(node);
1011 an = calloc(1, sizeof(Anchor));
1017 p = strstr(s, "href=");
1020 an->name = strdup(p + 5);
1022 en->anchors = eina_list_append(en->anchors, an);
1023 an->start = evas_object_textblock_cursor_new(o);
1024 an->end = evas_object_textblock_cursor_new(o);
1025 evas_textblock_cursor_at_format_set(an->start, node);
1026 evas_textblock_cursor_copy(an->start, an->end);
1027 /* Although needed in textblock, don't bother with finding the end
1028 * here cause it doesn't really matter. */
1034 _free_entry_change_info(void *_info)
1036 Edje_Entry_Change_Info *info = (Edje_Entry_Change_Info *) _info;
1039 eina_stringshare_del(info->change.insert.content);
1043 eina_stringshare_del(info->change.del.content);
1049 _range_del_emit(Edje *ed, Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
1053 Edje_Entry_Change_Info *info;
1055 start = evas_textblock_cursor_pos_get(en->sel_start);
1056 end = evas_textblock_cursor_pos_get(en->sel_end);
1060 info = calloc(1, sizeof(*info));
1061 info->insert = EINA_FALSE;
1062 info->change.del.start = start;
1063 info->change.del.end = end;
1065 tmp = evas_textblock_cursor_range_text_get(en->sel_start, en->sel_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
1066 info->change.del.content = eina_stringshare_add(tmp);
1068 evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
1069 _edje_emit(ed, "entry,changed", en->rp->part->name);
1070 _edje_emit_full(ed, "entry,changed,user", en->rp->part->name, info,
1071 _free_entry_change_info);
1073 _sel_clear(en->cursor, en->rp->object, en);
1077 _range_del(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
1079 evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
1080 _sel_clear(en->cursor, en->rp->object, en);
1084 _delete_emit(Edje *ed, Evas_Textblock_Cursor *c, Entry *en, size_t pos,
1085 Eina_Bool backspace)
1087 if (!evas_textblock_cursor_char_next(c))
1091 evas_textblock_cursor_char_prev(c);
1093 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1094 char *tmp = evas_textblock_cursor_content_get(c);
1096 info->insert = EINA_FALSE;
1099 info->change.del.start = pos - 1;
1100 info->change.del.end = pos;
1104 info->change.del.start = pos + 1;
1105 info->change.del.end = pos;
1108 info->change.del.content = eina_stringshare_add(tmp);
1111 evas_textblock_cursor_char_delete(c);
1112 _edje_emit(ed, "entry,changed", en->rp->part->name);
1113 _edje_emit_full(ed, "entry,changed,user", en->rp->part->name,
1114 info, _free_entry_change_info);
1118 _edje_entry_hide_visible_password(Edje_Real_Part *rp)
1120 const Evas_Object_Textblock_Node_Format *node;
1121 node = evas_textblock_node_format_first_get(rp->object);
1122 for (; node; node = evas_textblock_node_format_next_get(node))
1124 const char *text = evas_textblock_node_format_text_get(node);
1127 if (!strcmp(text, "+ password=off"))
1129 evas_textblock_node_format_remove_pair(rp->object,
1130 (Evas_Object_Textblock_Node_Format *) node);
1135 _edje_entry_real_part_configure(rp);
1136 _edje_emit(rp->edje, "entry,changed", rp->part->name);
1140 _password_timer_cb(void *data)
1142 Entry *en = (Entry *)data;
1143 _edje_entry_hide_visible_password(en->rp);
1144 en->pw_timer = NULL;
1145 return ECORE_CALLBACK_CANCEL;
1149 _is_modifier(const char *key)
1151 if ((!strncmp(key, "Shift", 5)) ||
1152 (!strncmp(key, "Control", 7)) ||
1153 (!strncmp(key, "Alt", 3)) ||
1154 (!strncmp(key, "Meta", 4)) ||
1155 (!strncmp(key, "Super", 5)) ||
1156 (!strncmp(key, "Hyper", 5)) ||
1157 (!strcmp(key, "Scroll_Lock")) ||
1158 (!strcmp(key, "Num_Lock")) ||
1159 (!strcmp(key, "Caps_Lock")))
1165 _compose_seq_reset(Entry *en)
1169 EINA_LIST_FREE(en->seq, str) eina_stringshare_del(str);
1170 en->composing = EINA_FALSE;
1174 _edje_key_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1177 Evas_Event_Key_Down *ev = event_info;
1178 Edje_Real_Part *rp = ed->focused_part;
1180 Eina_Bool control, alt, shift;
1181 Eina_Bool multiline;
1182 Eina_Bool cursor_changed;
1185 en = rp->entry_data;
1186 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1187 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
1189 if (!ev->keyname) return;
1191 #ifdef HAVE_ECORE_IMF
1192 if (en->imf_context)
1194 Ecore_IMF_Event_Key_Down ecore_ev;
1195 ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev);
1198 if (ecore_imf_context_filter_event(en->imf_context,
1199 ECORE_IMF_EVENT_KEY_DOWN,
1200 (Ecore_IMF_Event *)&ecore_ev))
1206 if ((!strcmp(ev->keyname, "Escape")) ||
1207 (!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "KP_Enter")))
1208 _edje_entry_imf_context_reset(rp);
1210 old_cur_pos = evas_textblock_cursor_pos_get(en->cursor);
1212 control = evas_key_modifier_is_set(ev->modifiers, "Control");
1213 alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
1214 shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
1215 multiline = rp->part->multiline;
1216 cursor_changed = EINA_FALSE;
1217 if (!strcmp(ev->keyname, "Escape"))
1219 _compose_seq_reset(en);
1220 // dead keys here. Escape for now (should emit these)
1221 _edje_emit(ed, "entry,key,escape", rp->part->name);
1222 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1224 else if (!strcmp(ev->keyname, "Up") ||
1225 (!strcmp(ev->keyname, "KP_Up") && !ev->string))
1227 _compose_seq_reset(en);
1230 if (en->select_allow)
1232 if (shift) _sel_start(en->cursor, rp->object, en);
1233 else _sel_clear(en->cursor, rp->object, en);
1235 _curs_up(en->cursor, rp->object, en);
1236 if (en->select_allow)
1238 if (shift) _sel_extend(en->cursor, rp->object, en);
1239 else _sel_clear(en->cursor, rp->object, en);
1241 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1243 _edje_emit(ed, "entry,key,up", rp->part->name);
1244 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1246 else if (!strcmp(ev->keyname, "Down") ||
1247 (!strcmp(ev->keyname, "KP_Down") && !ev->string))
1249 _compose_seq_reset(en);
1252 if (en->select_allow)
1254 if (shift) _sel_start(en->cursor, rp->object, en);
1255 else _sel_clear(en->cursor, rp->object, en);
1257 _curs_down(en->cursor, rp->object, en);
1258 if (en->select_allow)
1260 if (shift) _sel_extend(en->cursor, rp->object, en);
1261 else _sel_clear(en->cursor, rp->object, en);
1263 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1265 _edje_emit(ed, "entry,key,down", rp->part->name);
1266 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1268 else if (!strcmp(ev->keyname, "Left") ||
1269 (!strcmp(ev->keyname, "KP_Left") && !ev->string))
1271 _compose_seq_reset(en);
1272 if (en->select_allow)
1274 if (shift) _sel_start(en->cursor, rp->object, en);
1275 else _sel_clear(en->cursor, rp->object, en);
1277 evas_textblock_cursor_char_prev(en->cursor);
1278 /* If control is pressed, go to the start of the word */
1279 if (control) evas_textblock_cursor_word_start(en->cursor);
1280 if (en->select_allow)
1282 if (shift) _sel_extend(en->cursor, rp->object, en);
1283 else _sel_clear(en->cursor, rp->object, en);
1285 _edje_emit(ed, "entry,key,left", rp->part->name);
1286 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1287 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1289 else if (!strcmp(ev->keyname, "Right") ||
1290 (!strcmp(ev->keyname, "KP_Right") && !ev->string))
1292 _compose_seq_reset(en);
1293 if (en->select_allow)
1295 if (shift) _sel_start(en->cursor, rp->object, en);
1296 else _sel_clear(en->cursor, rp->object, en);
1298 /* If control is pressed, go to the end of the word */
1299 if (control) evas_textblock_cursor_word_end(en->cursor);
1300 evas_textblock_cursor_char_next(en->cursor);
1301 if (en->select_allow)
1303 if (shift) _sel_extend(en->cursor, rp->object, en);
1304 else _sel_clear(en->cursor, rp->object, en);
1306 _edje_emit(ed, "entry,key,right", rp->part->name);
1307 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1308 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1310 else if (!strcmp(ev->keyname, "BackSpace"))
1312 _compose_seq_reset(en);
1313 if (control && !en->have_selection)
1315 // del to start of previous word
1316 _sel_start(en->cursor, rp->object, en);
1318 evas_textblock_cursor_char_prev(en->cursor);
1319 evas_textblock_cursor_word_start(en->cursor);
1321 _sel_preextend(en->cursor, rp->object, en);
1323 _range_del_emit(ed, en->cursor, rp->object, en);
1325 else if ((alt) && (shift))
1331 if (en->have_selection)
1333 _range_del_emit(ed, en->cursor, rp->object, en);
1337 if (evas_textblock_cursor_char_prev(en->cursor))
1339 _delete_emit(ed, en->cursor, en, old_cur_pos, EINA_TRUE);
1343 _sel_clear(en->cursor, rp->object, en);
1344 _anchors_get(en->cursor, rp->object, en);
1345 _edje_emit(ed, "entry,key,backspace", rp->part->name);
1346 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1348 else if (!strcmp(ev->keyname, "Delete") ||
1349 (!strcmp(ev->keyname, "KP_Delete") && !ev->string))
1351 _compose_seq_reset(en);
1354 // del to end of next word
1355 _sel_start(en->cursor, rp->object, en);
1357 evas_textblock_cursor_word_end(en->cursor);
1358 evas_textblock_cursor_char_next(en->cursor);
1360 _sel_extend(en->cursor, rp->object, en);
1362 _range_del_emit(ed, en->cursor, rp->object, en);
1370 if (en->have_selection)
1372 _range_del_emit(ed, en->cursor, rp->object, en);
1376 _delete_emit(ed, en->cursor, en, old_cur_pos, EINA_FALSE);
1379 _sel_clear(en->cursor, rp->object, en);
1380 _anchors_get(en->cursor, rp->object, en);
1381 _edje_emit(ed, "entry,key,delete", rp->part->name);
1382 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1384 else if (!strcmp(ev->keyname, "Home") ||
1385 ((!strcmp(ev->keyname, "KP_Home")) && !ev->string))
1387 _compose_seq_reset(en);
1388 if (en->select_allow)
1390 if (shift) _sel_start(en->cursor, rp->object, en);
1391 else _sel_clear(en->cursor, rp->object, en);
1393 if ((control) && (multiline))
1394 _curs_start(en->cursor, rp->object, en);
1396 _curs_lin_start(en->cursor, rp->object, en);
1397 if (en->select_allow)
1399 if (shift) _sel_extend(en->cursor, rp->object, en);
1401 _edje_emit(ed, "entry,key,home", rp->part->name);
1402 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1404 else if (!strcmp(ev->keyname, "End") ||
1405 ((!strcmp(ev->keyname, "KP_End")) && !ev->string))
1407 _compose_seq_reset(en);
1408 if (en->select_allow)
1410 if (shift) _sel_start(en->cursor, rp->object, en);
1411 else _sel_clear(en->cursor, rp->object, en);
1413 if ((control) && (multiline))
1414 _curs_end(en->cursor, rp->object, en);
1416 _curs_lin_end(en->cursor, rp->object, en);
1417 if (en->select_allow)
1419 if (shift) _sel_extend(en->cursor, rp->object, en);
1421 _edje_emit(ed, "entry,key,end", rp->part->name);
1422 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1424 else if ((control) && (!shift) && (!strcmp(ev->keyname, "v")))
1426 _compose_seq_reset(en);
1427 _edje_emit(ed, "entry,paste,request", rp->part->name);
1428 _edje_emit(ed, "entry,paste,request,3", rp->part->name);
1429 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1431 else if ((control) && (!strcmp(ev->keyname, "a")))
1433 _compose_seq_reset(en);
1436 _edje_emit(ed, "entry,selection,none,request", rp->part->name);
1437 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1441 _edje_emit(ed, "entry,selection,all,request", rp->part->name);
1442 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1445 else if ((control) && (((!shift) && !strcmp(ev->keyname, "c")) || !strcmp(ev->keyname, "Insert")))
1447 _compose_seq_reset(en);
1448 _edje_emit(ed, "entry,copy,notify", rp->part->name);
1449 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1451 else if ((control) && (!shift) && ((!strcmp(ev->keyname, "x") || (!strcmp(ev->keyname, "m")))))
1453 _compose_seq_reset(en);
1454 _edje_emit(ed, "entry,cut,notify", rp->part->name);
1455 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1457 else if ((control) && (!strcmp(ev->keyname, "z")))
1459 _compose_seq_reset(en);
1463 _edje_emit(ed, "entry,redo,request", rp->part->name);
1468 _edje_emit(ed, "entry,undo,request", rp->part->name);
1470 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1472 else if ((control) && (!shift) && (!strcmp(ev->keyname, "y")))
1474 _compose_seq_reset(en);
1476 _edje_emit(ed, "entry,redo,request", rp->part->name);
1477 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1479 else if ((control) && (!shift) && (!strcmp(ev->keyname, "w")))
1481 _compose_seq_reset(en);
1482 _sel_clear(en->cursor, rp->object, en);
1483 // select current word?
1484 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1486 else if (!strcmp(ev->keyname, "Tab"))
1488 _compose_seq_reset(en);
1497 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1498 info->insert = EINA_TRUE;
1499 info->change.insert.plain_length = 1;
1501 if (en->have_selection)
1503 _range_del_emit(ed, en->cursor, rp->object, en);
1504 info->merge = EINA_TRUE;
1506 info->change.insert.pos =
1507 evas_textblock_cursor_pos_get(en->cursor);
1508 info->change.insert.content = eina_stringshare_add("<tab/>");
1510 // evas_textblock_cursor_format_prepend(en->cursor, "tab");
1511 _text_filter_format_prepend(en, en->cursor, "tab");
1512 _anchors_get(en->cursor, rp->object, en);
1513 _edje_emit(ed, "entry,changed", rp->part->name);
1514 _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1515 info, _free_entry_change_info);
1517 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1519 _edje_emit(ed, "entry,key,tab", rp->part->name);
1521 else if ((!strcmp(ev->keyname, "ISO_Left_Tab")) && (multiline))
1523 _compose_seq_reset(en);
1525 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1527 else if (!strcmp(ev->keyname, "Prior") ||
1528 (!strcmp(ev->keyname, "KP_Prior") && !ev->string))
1530 _compose_seq_reset(en);
1531 if (en->select_allow)
1533 if (shift) _sel_start(en->cursor, rp->object, en);
1534 else _sel_clear(en->cursor, rp->object, en);
1536 _curs_jump_line_by(en->cursor, rp->object, en, -10);
1537 if (en->select_allow)
1539 if (shift) _sel_extend(en->cursor, rp->object, en);
1540 else _sel_clear(en->cursor, rp->object, en);
1542 _edje_emit(ed, "entry,key,pgup", rp->part->name);
1543 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1545 else if (!strcmp(ev->keyname, "Next") ||
1546 (!strcmp(ev->keyname, "KP_Next") && !ev->string))
1548 _compose_seq_reset(en);
1549 if (en->select_allow)
1551 if (shift) _sel_start(en->cursor, rp->object, en);
1552 else _sel_clear(en->cursor, rp->object, en);
1554 _curs_jump_line_by(en->cursor, rp->object, en, 10);
1555 if (en->select_allow)
1557 if (shift) _sel_extend(en->cursor, rp->object, en);
1558 else _sel_clear(en->cursor, rp->object, en);
1560 _edje_emit(ed, "entry,key,pgdn", rp->part->name);
1561 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1563 else if ((!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "KP_Enter")))
1565 _compose_seq_reset(en);
1568 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1569 info->insert = EINA_TRUE;
1570 info->change.insert.plain_length = 1;
1571 if (en->have_selection)
1573 _range_del_emit(ed, en->cursor, rp->object, en);
1574 info->merge = EINA_TRUE;
1577 info->change.insert.pos =
1578 evas_textblock_cursor_pos_get(en->cursor);
1580 evas_object_textblock_legacy_newline_get(rp->object))
1583 // evas_textblock_cursor_format_prepend(en->cursor, "br");
1584 _text_filter_format_prepend(en, en->cursor, "br");
1585 info->change.insert.content = eina_stringshare_add("<br/>");
1590 // evas_textblock_cursor_format_prepend(en->cursor, "ps");
1591 _text_filter_format_prepend(en, en->cursor, "ps");
1592 info->change.insert.content = eina_stringshare_add("<ps/>");
1594 _anchors_get(en->cursor, rp->object, en);
1595 _edje_emit(ed, "entry,changed", rp->part->name);
1596 _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1597 info, _free_entry_change_info);
1598 _edje_emit(ed, "cursor,changed", rp->part->name);
1599 cursor_changed = EINA_TRUE;
1600 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1602 _edje_emit(ed, "entry,key,enter", rp->part->name);
1606 char *compres = NULL, *string = (char *)ev->string;
1607 Eina_Bool free_string = EINA_FALSE;
1608 Ecore_Compose_State state;
1612 _compose_seq_reset(en);
1613 en->seq = eina_list_append(en->seq, eina_stringshare_add(ev->key));
1614 state = ecore_compose_get(en->seq, &compres);
1615 if (state == ECORE_COMPOSE_MIDDLE) en->composing = EINA_TRUE;
1616 else en->composing = EINA_FALSE;
1617 if (!en->composing) _compose_seq_reset(en);
1622 if (_is_modifier(ev->key)) goto end;
1623 en->seq = eina_list_append(en->seq, eina_stringshare_add(ev->key));
1624 state = ecore_compose_get(en->seq, &compres);
1625 if (state == ECORE_COMPOSE_NONE) _compose_seq_reset(en);
1626 else if (state == ECORE_COMPOSE_DONE)
1628 _compose_seq_reset(en);
1632 free_string = EINA_TRUE;
1639 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1640 info->insert = EINA_TRUE;
1641 info->change.insert.plain_length = 1;
1642 info->change.insert.content = eina_stringshare_add(string);
1644 if (en->have_selection)
1646 _range_del_emit(ed, en->cursor, rp->object, en);
1647 info->merge = EINA_TRUE;
1650 info->change.insert.pos =
1651 evas_textblock_cursor_pos_get(en->cursor);
1652 // if PASSWORD_SHOW_LAST mode, appending text with password=off tag
1653 if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
1654 _edje_password_show_last)
1656 _edje_entry_hide_visible_password(en->rp);
1657 _text_filter_format_prepend(en, en->cursor, "+ password=off");
1658 _text_filter_text_prepend(en, en->cursor, string);
1659 _text_filter_format_prepend(en, en->cursor, "- password");
1662 ecore_timer_del(en->pw_timer);
1663 en->pw_timer = NULL;
1665 en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout),
1666 _password_timer_cb, en);
1669 _text_filter_text_prepend(en, en->cursor, string);
1670 _anchors_get(en->cursor, rp->object, en);
1671 _edje_emit(ed, "entry,changed", rp->part->name);
1672 _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1673 info, _free_entry_change_info);
1674 _edje_emit(ed, "cursor,changed", rp->part->name);
1675 cursor_changed = EINA_TRUE;
1676 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1678 if (free_string) free(string);
1681 if (!cursor_changed && (old_cur_pos != evas_textblock_cursor_pos_get(en->cursor)))
1682 _edje_emit(ed, "cursor,changed", rp->part->name);
1684 _edje_entry_imf_cursor_info_set(en);
1685 _edje_entry_real_part_configure(rp);
1689 _edje_key_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1692 Edje_Real_Part *rp = ed->focused_part;
1696 en = rp->entry_data;
1697 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1698 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
1701 #ifdef HAVE_ECORE_IMF
1702 if (en->imf_context)
1704 Evas_Event_Key_Up *ev = event_info;
1705 Ecore_IMF_Event_Key_Up ecore_ev;
1707 ecore_imf_evas_event_key_up_wrap(ev, &ecore_ev);
1708 if (ecore_imf_context_filter_event(en->imf_context,
1709 ECORE_IMF_EVENT_KEY_UP,
1710 (Ecore_IMF_Event *)&ecore_ev))
1719 _edje_part_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1721 Edje_Real_Part *rp = data;
1724 en = rp->entry_data;
1726 _edje_entry_imf_cursor_info_set(en);
1730 _edje_part_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1733 Edje_Real_Part *rp = data;
1734 Evas_Event_Mouse_Down *ev = event_info;
1736 Evas_Coord x, y, w, h;
1737 // Eina_Bool multiline;
1738 Evas_Textblock_Cursor *tc = NULL;
1739 Eina_Bool dosel = EINA_FALSE;
1741 if ((!rp) || (!ev)) return;
1742 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1743 en = rp->entry_data;
1744 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1745 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
1747 if ((ev->button != 1) && (ev->button != 2)) return;
1749 #ifdef HAVE_ECORE_IMF
1750 if (en->imf_context)
1752 Ecore_IMF_Event_Mouse_Down ecore_ev;
1753 ecore_imf_evas_event_mouse_down_wrap(ev, &ecore_ev);
1754 if (ecore_imf_context_filter_event(en->imf_context,
1755 ECORE_IMF_EVENT_MOUSE_DOWN,
1756 (Ecore_IMF_Event *)&ecore_ev))
1761 _edje_entry_imf_context_reset(rp);
1763 shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
1764 en->select_mod_start = EINA_FALSE;
1765 en->select_mod_end = EINA_FALSE;
1766 if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
1768 else if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
1770 if (en->select_allow) dosel = EINA_TRUE;
1772 if (ev->button == 2) dosel = EINA_FALSE;
1775 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
1776 cx = ev->canvas.x - x;
1777 cy = ev->canvas.y - y;
1778 if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK)
1782 tc = evas_object_textblock_cursor_new(rp->object);
1783 evas_textblock_cursor_copy(en->cursor, tc);
1784 if (evas_textblock_cursor_compare(en->cursor, en->sel_start) < 0)
1785 evas_textblock_cursor_line_char_first(en->cursor);
1787 evas_textblock_cursor_line_char_last(en->cursor);
1788 _sel_extend(en->cursor, rp->object, en);
1792 en->have_selection = EINA_FALSE;
1793 en->selecting = EINA_FALSE;
1794 _sel_clear(en->cursor, rp->object, en);
1795 tc = evas_object_textblock_cursor_new(rp->object);
1796 evas_textblock_cursor_copy(en->cursor, tc);
1797 evas_textblock_cursor_line_char_first(en->cursor);
1798 _sel_start(en->cursor, rp->object, en);
1799 evas_textblock_cursor_line_char_last(en->cursor);
1800 _sel_extend(en->cursor, rp->object, en);
1804 else if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1808 tc = evas_object_textblock_cursor_new(rp->object);
1809 evas_textblock_cursor_copy(en->cursor, tc);
1810 if (evas_textblock_cursor_compare(en->cursor, en->sel_start) < 0)
1811 evas_textblock_cursor_word_start(en->cursor);
1814 evas_textblock_cursor_word_end(en->cursor);
1815 evas_textblock_cursor_char_next(en->cursor);
1817 _sel_extend(en->cursor, rp->object, en);
1821 en->have_selection = EINA_FALSE;
1822 en->selecting = EINA_FALSE;
1823 _sel_clear(en->cursor, rp->object, en);
1824 tc = evas_object_textblock_cursor_new(rp->object);
1825 evas_textblock_cursor_copy(en->cursor, tc);
1826 evas_textblock_cursor_word_start(en->cursor);
1827 _sel_start(en->cursor, rp->object, en);
1828 evas_textblock_cursor_word_end(en->cursor);
1829 evas_textblock_cursor_char_next(en->cursor);
1830 _sel_extend(en->cursor, rp->object, en);
1835 tc = evas_object_textblock_cursor_new(rp->object);
1836 evas_textblock_cursor_copy(en->cursor, tc);
1837 // multiline = rp->part->multiline;
1838 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
1839 cx = ev->canvas.x - x;
1840 cy = ev->canvas.y - y;
1841 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
1843 Evas_Coord lx, ly, lw, lh;
1846 line = evas_textblock_cursor_line_coord_set(en->cursor, cy);
1849 if (rp->part->multiline)
1850 _curs_end(en->cursor, rp->object, en);
1853 evas_textblock_cursor_paragraph_first(en->cursor);
1854 evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
1855 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
1856 _curs_end(en->cursor, rp->object, en);
1863 lnum = evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
1866 _curs_lin_start(en->cursor, rp->object, en);
1871 _curs_lin_start(en->cursor, rp->object, en);
1873 _curs_lin_end(en->cursor, rp->object, en);
1879 if ((en->have_selection) &&
1880 (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT))
1883 _sel_extend(en->cursor, rp->object, en);
1886 Eina_List *first, *last;
1890 last = eina_list_last(en->sel);
1893 Evas_Textblock_Rectangle *r1, *r2;
1894 Evas_Coord d, d1, d2;
1900 d = (r1->y + (r1->h / 2)) - cy;
1902 d = r2->x + r2->w - 1 - cx;
1904 d = (r2->y + (r2->h / 2)) - cy;
1906 sc = rp->edje->scale;
1907 if (sc == ZERO) sc = _edje_scale;
1908 d = (Evas_Coord)MUL(FROM_INT(20), sc); // FIXME: maxing number!
1914 en->select_mod_start = EINA_TRUE;
1915 en->selecting = EINA_TRUE;
1922 en->select_mod_end = EINA_TRUE;
1923 en->selecting = EINA_TRUE;
1931 if ((en->have_selection) && (shift))
1932 _sel_extend(en->cursor, rp->object, en);
1935 en->selecting = EINA_TRUE;
1936 _sel_clear(en->cursor, rp->object, en);
1937 if (en->select_allow)
1939 _sel_start(en->cursor, rp->object, en);
1945 if (evas_textblock_cursor_compare(tc, en->cursor))
1947 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
1948 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1950 evas_textblock_cursor_free(tc);
1952 _edje_entry_imf_cursor_info_set(en);
1954 _edje_entry_real_part_configure(rp);
1955 if (ev->button == 2)
1957 _edje_emit(rp->edje, "entry,paste,request", rp->part->name);
1958 _edje_emit(rp->edje, "entry,paste,request,1", rp->part->name);
1963 _edje_part_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1966 Edje_Real_Part *rp = data;
1967 Evas_Event_Mouse_Up *ev = event_info;
1969 Evas_Coord x, y, w, h;
1970 Evas_Textblock_Cursor *tc;
1971 if ((!ev) || (ev->button != 1)) return;
1973 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1974 if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK) return;
1975 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) return;
1976 en = rp->entry_data;
1977 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1978 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
1981 #ifdef HAVE_ECORE_IMF
1982 if (en->imf_context)
1984 Ecore_IMF_Event_Mouse_Up ecore_ev;
1985 ecore_imf_evas_event_mouse_up_wrap(ev, &ecore_ev);
1986 if (ecore_imf_context_filter_event(en->imf_context,
1987 ECORE_IMF_EVENT_MOUSE_UP,
1988 (Ecore_IMF_Event *)&ecore_ev))
1993 _edje_entry_imf_context_reset(rp);
1995 tc = evas_object_textblock_cursor_new(rp->object);
1996 evas_textblock_cursor_copy(en->cursor, tc);
1997 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
1998 cx = ev->canvas.x - x;
1999 cy = ev->canvas.y - y;
2000 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
2002 Evas_Coord lx, ly, lw, lh;
2005 line = evas_textblock_cursor_line_coord_set(en->cursor, cy);
2008 if (rp->part->multiline)
2009 _curs_end(en->cursor, rp->object, en);
2012 evas_textblock_cursor_paragraph_first(en->cursor);
2013 evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2014 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
2015 _curs_end(en->cursor, rp->object, en);
2022 lnum = evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2025 _curs_lin_start(en->cursor, rp->object, en);
2030 _curs_lin_start(en->cursor, rp->object, en);
2032 _curs_lin_end(en->cursor, rp->object, en);
2036 if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
2038 if (en->select_allow)
2042 if (en->select_mod_end)
2043 _sel_extend(en->cursor, rp->object, en);
2044 else if (en->select_mod_start)
2045 _sel_preextend(en->cursor, rp->object, en);
2048 _sel_extend(en->cursor, rp->object, en);
2049 //evas_textblock_cursor_copy(en->cursor, en->sel_end);
2053 evas_textblock_cursor_copy(en->cursor, en->sel_end);
2056 if (en->have_selection)
2057 en->had_sel = EINA_TRUE;
2058 en->selecting = EINA_FALSE;
2060 if (evas_textblock_cursor_compare(tc, en->cursor))
2062 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2063 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
2065 evas_textblock_cursor_free(tc);
2067 _edje_entry_imf_cursor_info_set(en);
2068 _edje_entry_real_part_configure(rp);
2072 _edje_part_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2075 Edje_Real_Part *rp = data;
2076 Evas_Event_Mouse_Move *ev = event_info;
2078 Evas_Coord x, y, w, h;
2079 Evas_Textblock_Cursor *tc;
2080 if (!rp || (!ev)) return;
2081 en = rp->entry_data;
2082 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2083 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2086 #ifdef HAVE_ECORE_IMF
2087 if (en->imf_context)
2089 Ecore_IMF_Event_Mouse_Move ecore_ev;
2090 ecore_imf_evas_event_mouse_move_wrap(ev, &ecore_ev);
2091 if (ecore_imf_context_filter_event(en->imf_context,
2092 ECORE_IMF_EVENT_MOUSE_MOVE,
2093 (Ecore_IMF_Event *)&ecore_ev))
2100 tc = evas_object_textblock_cursor_new(rp->object);
2101 evas_textblock_cursor_copy(en->cursor, tc);
2102 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2103 cx = ev->cur.canvas.x - x;
2104 cy = ev->cur.canvas.y - y;
2105 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
2107 Evas_Coord lx, ly, lw, lh;
2109 if (evas_textblock_cursor_line_coord_set(en->cursor, cy) < 0)
2111 if (rp->part->multiline)
2112 _curs_end(en->cursor, rp->object, en);
2115 evas_textblock_cursor_paragraph_first(en->cursor);
2116 evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2117 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
2118 _curs_end(en->cursor, rp->object, en);
2123 evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2125 _curs_lin_start(en->cursor, rp->object, en);
2127 _curs_lin_end(en->cursor, rp->object, en);
2130 if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
2132 if (en->select_allow)
2136 if (en->select_mod_end)
2137 _sel_extend(en->cursor, rp->object, en);
2138 else if (en->select_mod_start)
2139 _sel_preextend(en->cursor, rp->object, en);
2142 _sel_extend(en->cursor, rp->object, en);
2147 _sel_extend(en->cursor, rp->object, en);
2149 if (en->select_allow)
2151 if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) != 0)
2152 _sel_enable(en->cursor, rp->object, en);
2153 if (en->have_selection)
2154 _sel_update(en->cursor, rp->object, en);
2156 if (evas_textblock_cursor_compare(tc, en->cursor))
2158 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2159 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
2161 evas_textblock_cursor_free(tc);
2163 _edje_entry_imf_context_reset(rp);
2164 _edje_entry_imf_cursor_info_set(en);
2166 _edje_entry_real_part_configure(rp);
2171 _evas_focus_in_cb(void *data, Evas *e, __UNUSED__ void *event_info)
2173 Edje *ed = (Edje *)data;
2176 if (evas_focus_get(e) == ed->obj)
2178 _edje_focus_in_cb(data, NULL, NULL, NULL);
2183 _evas_focus_out_cb(void *data, Evas *e, __UNUSED__ void *event_info)
2185 Edje *ed = (Edje *)data;
2188 if (evas_focus_get(e) == ed->obj)
2190 _edje_focus_out_cb(data, NULL, NULL, NULL);
2194 /***************************************************************/
2196 _edje_entry_init(Edje *ed)
2198 if (!ed->has_entries)
2200 if (ed->entries_inited)
2202 ed->entries_inited = EINA_TRUE;
2204 evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb, ed);
2205 evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb, ed);
2206 evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb, ed);
2207 evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_UP, _edje_key_up_cb, ed);
2208 evas_event_callback_add(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _evas_focus_in_cb, ed);
2209 evas_event_callback_add(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _evas_focus_out_cb, ed);
2213 _edje_entry_shutdown(Edje *ed)
2215 if ((!ed) || (!ed->has_entries))
2217 if (!ed->entries_inited)
2219 ed->entries_inited = EINA_FALSE;
2221 evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb);
2222 evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb);
2223 evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb);
2224 evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_UP, _edje_key_up_cb);
2225 if (evas_event_callback_del_full(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _evas_focus_in_cb, ed) != ed)
2226 ERR("could not unregister EVAS_CALLBACK_FOCUS_IN");
2227 if (evas_event_callback_del_full(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _evas_focus_out_cb, ed) != ed)
2228 ERR("could not unregister EVAS_CALLBACK_FOCUS_OUT");
2232 _edje_entry_real_part_init(Edje_Real_Part *rp)
2235 #ifdef HAVE_ECORE_IMF
2237 const Ecore_IMF_Context_Info *ctx_info;
2240 en = calloc(1, sizeof(Entry));
2242 rp->entry_data = en;
2245 evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOVE, _edje_part_move_cb, rp);
2247 evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_DOWN, _edje_part_mouse_down_cb, rp);
2248 evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_UP, _edje_part_mouse_up_cb, rp);
2249 evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_MOVE, _edje_part_mouse_move_cb, rp);
2251 if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
2252 en->select_allow = EINA_TRUE;
2254 if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
2256 Edje_Part_Description_Text *txt;
2258 txt = (Edje_Part_Description_Text *)rp->chosen_description;
2260 en->select_allow = EINA_FALSE;
2261 if (txt && edje_string_get(&txt->text.repch))
2262 evas_object_textblock_replace_char_set(rp->object, edje_string_get(&txt->text.repch));
2264 evas_object_textblock_replace_char_set(rp->object, "*");
2267 en->cursor_bg = edje_object_add(rp->edje->base.evas);
2268 edje_object_file_set(en->cursor_bg, rp->edje->path, rp->part->source3);
2269 evas_object_smart_member_add(en->cursor_bg, rp->edje->obj);
2270 evas_object_stack_below(en->cursor_bg, rp->object);
2271 evas_object_clip_set(en->cursor_bg, evas_object_clip_get(rp->object));
2272 evas_object_pass_events_set(en->cursor_bg, EINA_TRUE);
2273 _edje_subobj_register(en->rp->edje, en->cursor_bg);
2275 en->cursor_fg = edje_object_add(rp->edje->base.evas);
2276 edje_object_file_set(en->cursor_fg, rp->edje->path, rp->part->source4);
2277 evas_object_smart_member_add(en->cursor_fg, rp->edje->obj);
2278 evas_object_stack_above(en->cursor_fg, rp->object);
2279 evas_object_clip_set(en->cursor_fg, evas_object_clip_get(rp->object));
2280 evas_object_pass_events_set(en->cursor_fg, EINA_TRUE);
2281 _edje_subobj_register(en->rp->edje, en->cursor_fg);
2283 evas_object_textblock_legacy_newline_set(rp->object, EINA_TRUE);
2285 if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
2287 evas_object_show(en->cursor_bg);
2288 evas_object_show(en->cursor_fg);
2289 en->input_panel_enable = EINA_TRUE;
2291 #ifdef HAVE_ECORE_IMF
2294 edje_object_signal_callback_add(rp->edje->obj, "focus,part,in", rp->part->name, _edje_entry_focus_in_cb, rp);
2295 edje_object_signal_callback_add(rp->edje->obj, "focus,part,out", rp->part->name, _edje_entry_focus_out_cb, rp);
2297 ctx_id = ecore_imf_context_default_id_get();
2300 ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
2301 if (!ctx_info->canvas_type ||
2302 strcmp(ctx_info->canvas_type, "evas") == 0)
2304 en->imf_context = ecore_imf_context_add(ctx_id);
2308 ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
2311 en->imf_context = ecore_imf_context_add(ctx_id);
2316 en->imf_context = NULL;
2318 if (!en->imf_context) goto done;
2320 ecore_imf_context_client_window_set
2322 (void *)ecore_evas_window_get
2323 (ecore_evas_ecore_evas_get(rp->edje->base.evas)));
2324 ecore_imf_context_client_canvas_set(en->imf_context, rp->edje->base.evas);
2326 ecore_imf_context_retrieve_surrounding_callback_set(en->imf_context,
2327 _edje_entry_imf_retrieve_surrounding_cb, rp->edje);
2328 ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _edje_entry_imf_event_commit_cb, rp->edje);
2329 ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb, rp->edje);
2330 ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb, rp->edje);
2331 ecore_imf_context_input_mode_set(en->imf_context,
2332 rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD ?
2333 ECORE_IMF_INPUT_MODE_INVISIBLE : ECORE_IMF_INPUT_MODE_FULL);
2335 if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
2336 ecore_imf_context_input_panel_language_set(en->imf_context, ECORE_IMF_INPUT_PANEL_LANG_ALPHABET);
2339 #ifdef HAVE_ECORE_IMF
2342 en->cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(rp->object);
2346 _edje_entry_real_part_shutdown(Edje_Real_Part *rp)
2348 Entry *en = rp->entry_data;
2350 rp->entry_data = NULL;
2351 _sel_clear(en->cursor, rp->object, en);
2352 _anchors_clear(en->cursor, rp->object, en);
2353 #ifdef HAVE_ECORE_IMF
2356 evas_object_del(en->cursor_bg);
2357 evas_object_del(en->cursor_fg);
2361 ecore_timer_del(en->pw_timer);
2362 en->pw_timer = NULL;
2365 #ifdef HAVE_ECORE_IMF
2366 if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
2368 if (en->imf_context)
2370 ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _edje_entry_imf_event_commit_cb);
2371 ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb);
2372 ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb);
2374 ecore_imf_context_del(en->imf_context);
2375 en->imf_context = NULL;
2378 edje_object_signal_callback_del(rp->edje->obj, "focus,part,in", rp->part->name, _edje_entry_focus_in_cb);
2379 edje_object_signal_callback_del(rp->edje->obj, "focus,part,out", rp->part->name, _edje_entry_focus_out_cb);
2380 ecore_imf_shutdown();
2383 _compose_seq_reset(en);
2389 _edje_entry_real_part_configure(Edje_Real_Part *rp)
2391 Evas_Coord x, y, w, h, xx, yy, ww, hh;
2392 Entry *en = rp->entry_data;
2393 Evas_Textblock_Cursor_Type cur_type;
2395 switch (rp->part->cursor_mode)
2397 case EDJE_ENTRY_CURSOR_MODE_BEFORE:
2398 cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
2400 case EDJE_ENTRY_CURSOR_MODE_UNDER:
2401 /* no break for a resaon */
2403 cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
2406 _sel_update(en->cursor, rp->object, en);
2407 _anchors_update(en->cursor, rp->object, en);
2409 xx = yy = ww = hh = -1;
2410 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2411 evas_textblock_cursor_geometry_get(en->cursor, &xx, &yy, &ww, &hh, NULL, cur_type);
2416 evas_object_move(en->cursor_bg, x + xx, y + yy);
2417 evas_object_resize(en->cursor_bg, ww, hh);
2421 evas_object_move(en->cursor_fg, x + xx, y + yy);
2422 evas_object_resize(en->cursor_fg, ww, hh);
2427 _edje_entry_selection_get(Edje_Real_Part *rp)
2429 Entry *en = rp->entry_data;
2430 if (!en) return NULL;
2431 // get selection - convert to markup
2432 if ((!en->selection) && (en->have_selection))
2433 en->selection = evas_textblock_cursor_range_text_get
2434 (en->sel_start, en->sel_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
2435 return en->selection;
2439 _edje_entry_text_get(Edje_Real_Part *rp)
2441 Entry *en = rp->entry_data;
2442 if (!en) return NULL;
2443 // get text - convert to markup
2444 return evas_object_textblock_text_markup_get(rp->object);
2448 _edje_entry_text_markup_set(Edje_Real_Part *rp, const char *text)
2450 Entry *en = rp->entry_data;
2452 _edje_entry_imf_context_reset(rp);
2453 // set text as markup
2454 _sel_clear(en->cursor, rp->object, en);
2455 evas_object_textblock_text_markup_set(rp->object, text);
2456 _edje_entry_set_cursor_start(rp);
2458 _anchors_get(en->cursor, rp->object, en);
2459 _edje_emit(rp->edje, "entry,changed", rp->part->name);
2460 _edje_entry_imf_cursor_info_set(en);
2462 _edje_entry_real_part_configure(rp);
2464 /* Don't emit cursor changed cause it didn't. It's just init to 0. */
2465 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2470 _edje_entry_text_markup_append(Edje_Real_Part *rp, const char *text)
2472 Entry *en = rp->entry_data;
2473 Evas_Textblock_Cursor *end_cur;
2475 end_cur = evas_object_textblock_cursor_new(rp->object);
2476 evas_textblock_cursor_paragraph_last(end_cur);
2478 _text_filter_markup_prepend(en, end_cur, text);
2479 evas_textblock_cursor_free(end_cur);
2481 /* We are updating according to the real cursor on purpose */
2482 _anchors_get(en->cursor, rp->object, en);
2483 _edje_emit(rp->edje, "entry,changed", rp->part->name);
2485 _edje_entry_real_part_configure(rp);
2489 _edje_entry_text_markup_insert(Edje_Real_Part *rp, const char *text)
2491 Entry *en = rp->entry_data;
2493 _edje_entry_imf_context_reset(rp);
2495 // prepend markup @ cursor pos
2496 if (en->have_selection)
2497 _range_del(en->cursor, rp->object, en);
2499 // evas_object_textblock_text_markup_prepend(en->cursor, text);
2500 _text_filter_markup_prepend(en, en->cursor, text);
2501 _anchors_get(en->cursor, rp->object, en);
2502 _edje_emit(rp->edje, "entry,changed", rp->part->name);
2503 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2505 _edje_entry_imf_cursor_info_set(en);
2506 _edje_entry_real_part_configure(rp);
2510 _edje_entry_set_cursor_start(Edje_Real_Part *rp)
2512 Entry *en = rp->entry_data;
2514 _curs_start(en->cursor, rp->object, en);
2516 _edje_entry_imf_cursor_info_set(en);
2520 _edje_entry_set_cursor_end(Edje_Real_Part *rp)
2522 Entry *en = rp->entry_data;
2524 _curs_end(en->cursor, rp->object, en);
2526 _edje_entry_imf_cursor_info_set(en);
2530 _edje_entry_select_none(Edje_Real_Part *rp)
2532 Entry *en = rp->entry_data;
2534 _sel_clear(en->cursor, rp->object, en);
2538 _edje_entry_select_all(Edje_Real_Part *rp)
2540 Entry *en = rp->entry_data;
2543 _edje_entry_imf_context_reset(rp);
2545 _sel_clear(en->cursor, rp->object, en);
2546 _curs_start(en->cursor, rp->object, en);
2547 _sel_enable(en->cursor, rp->object, en);
2548 _sel_start(en->cursor, rp->object, en);
2549 _curs_end(en->cursor, rp->object, en);
2550 _sel_extend(en->cursor, rp->object, en);
2552 _edje_entry_imf_cursor_info_set(en);
2553 _edje_entry_real_part_configure(rp);
2557 _edje_entry_select_begin(Edje_Real_Part *rp)
2559 Entry *en = rp->entry_data;
2562 _edje_entry_imf_context_reset(rp);
2564 _sel_clear(en->cursor, rp->object, en);
2565 _sel_enable(en->cursor, rp->object, en);
2566 _sel_start(en->cursor, rp->object, en);
2567 _sel_extend(en->cursor, rp->object, en);
2569 _edje_entry_imf_cursor_info_set(en);
2571 _edje_entry_real_part_configure(rp);
2575 _edje_entry_select_extend(Edje_Real_Part *rp)
2577 Entry *en = rp->entry_data;
2579 _edje_entry_imf_context_reset(rp);
2580 _sel_extend(en->cursor, rp->object, en);
2582 _edje_entry_imf_cursor_info_set(en);
2584 _edje_entry_real_part_configure(rp);
2588 _edje_entry_anchor_geometry_get(Edje_Real_Part *rp, const char *anchor)
2590 Entry *en = rp->entry_data;
2594 if (!en) return NULL;
2595 EINA_LIST_FOREACH(en->anchors, l, an)
2597 if (an->item) continue;
2598 if (!strcmp(anchor, an->name))
2605 _edje_entry_anchors_list(Edje_Real_Part *rp)
2607 Entry *en = rp->entry_data;
2608 Eina_List *l, *anchors = NULL;
2611 if (!en) return NULL;
2612 if (!en->anchorlist)
2614 EINA_LIST_FOREACH(en->anchors, l, an)
2616 const char *n = an->name;
2617 if (an->item) continue;
2619 anchors = eina_list_append(anchors, strdup(n));
2621 en->anchorlist = anchors;
2623 return en->anchorlist;
2627 _edje_entry_item_geometry_get(Edje_Real_Part *rp, const char *item, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
2629 Entry *en = rp->entry_data;
2633 if (!en) return EINA_FALSE;
2634 EINA_LIST_FOREACH(en->anchors, l, an)
2636 if (an->item) continue;
2637 if (!strcmp(item, an->name))
2639 evas_textblock_cursor_format_item_geometry_get(an->start, cx, cy, cw, ch);
2647 _edje_entry_items_list(Edje_Real_Part *rp)
2649 Entry *en = rp->entry_data;
2650 Eina_List *l, *items = NULL;
2653 if (!en) return NULL;
2656 EINA_LIST_FOREACH(en->anchors, l, an)
2658 const char *n = an->name;
2659 if (an->item) continue;
2661 items = eina_list_append(items, strdup(n));
2663 en->itemlist = items;
2665 return en->itemlist;
2669 _edje_entry_cursor_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
2671 Evas_Coord x, y, w, h, xx, yy, ww, hh;
2672 Entry *en = rp->entry_data;
2673 Evas_Textblock_Cursor_Type cur_type;
2675 switch (rp->part->cursor_mode)
2677 case EDJE_ENTRY_CURSOR_MODE_BEFORE:
2678 cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
2680 case EDJE_ENTRY_CURSOR_MODE_UNDER:
2681 /* no break for a resaon */
2683 cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
2687 xx = yy = ww = hh = -1;
2688 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2689 evas_textblock_cursor_geometry_get(en->cursor, &xx, &yy, &ww, &hh, NULL, cur_type);
2691 if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
2692 edje_object_size_min_restricted_calc(en->cursor_fg, &ww, NULL, ww, 0);
2694 if (cx) *cx = x + xx;
2695 if (cy) *cy = y + yy;
2701 _edje_entry_user_insert(Edje_Real_Part *rp, const char *text)
2703 Entry *en = rp->entry_data;
2704 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
2705 info->insert = EINA_TRUE;
2706 info->change.insert.plain_length = 1;
2707 info->change.insert.content = eina_stringshare_add(text);
2710 tmp = evas_textblock_text_markup_to_utf8(rp->object,
2711 info->change.insert.content);
2712 info->change.insert.plain_length = eina_unicode_utf8_get_len(tmp);
2716 if (en->have_selection)
2718 _range_del_emit(rp->edje, en->cursor, rp->object, en);
2719 info->merge = EINA_TRUE;
2721 info->change.insert.pos = evas_textblock_cursor_pos_get(en->cursor);
2722 _text_filter_markup_prepend(en, en->cursor, text);
2723 _anchors_get(en->cursor, rp->object, en);
2724 _edje_emit(rp->edje, "entry,changed", rp->part->name);
2725 _edje_emit_full(rp->edje, "entry,changed,user", rp->part->name,
2726 info, _free_entry_change_info);
2727 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2729 _edje_entry_imf_cursor_info_set(en);
2730 _edje_entry_real_part_configure(rp);
2734 _edje_entry_select_allow_set(Edje_Real_Part *rp, Eina_Bool allow)
2736 Entry *en = rp->entry_data;
2737 if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
2739 en->select_allow = allow;
2743 _edje_entry_select_allow_get(const Edje_Real_Part *rp)
2745 const Entry *en = rp->entry_data;
2746 return en->select_allow;
2750 _edje_entry_select_abort(Edje_Real_Part *rp)
2752 Entry *en = rp->entry_data;
2755 en->selecting = EINA_FALSE;
2757 _edje_entry_imf_context_reset(rp);
2758 _edje_entry_imf_cursor_info_set(en);
2759 _edje_entry_real_part_configure(rp);
2764 _edje_entry_imf_context_get(Edje_Real_Part *rp)
2766 Entry *en = rp->entry_data;
2767 if (!en) return NULL;
2769 #ifdef HAVE_ECORE_IMF
2770 return en->imf_context;
2777 _edje_entry_autocapital_type_set(Edje_Real_Part *rp, Edje_Text_Autocapital_Type autocapital_type)
2779 Entry *en = rp->entry_data;
2782 if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
2783 autocapital_type = EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
2785 #ifdef HAVE_ECORE_IMF
2786 if (en->imf_context)
2787 ecore_imf_context_autocapital_type_set(en->imf_context, autocapital_type);
2791 Edje_Text_Autocapital_Type
2792 _edje_entry_autocapital_type_get(Edje_Real_Part *rp)
2794 Entry *en = rp->entry_data;
2795 if (!en) return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
2797 #ifdef HAVE_ECORE_IMF
2798 if (en->imf_context)
2799 return ecore_imf_context_autocapital_type_get(en->imf_context);
2802 return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
2806 _edje_entry_prediction_allow_set(Edje_Real_Part *rp, Eina_Bool prediction)
2808 Entry *en = rp->entry_data;
2811 en->prediction_allow = prediction;
2812 #ifdef HAVE_ECORE_IMF
2813 if (en->imf_context)
2814 ecore_imf_context_prediction_allow_set(en->imf_context, prediction);
2819 _edje_entry_prediction_allow_get(Edje_Real_Part *rp)
2821 Entry *en = rp->entry_data;
2822 if (!en) return EINA_FALSE;
2824 return en->prediction_allow;
2828 _edje_entry_input_panel_enabled_set(Edje_Real_Part *rp, Eina_Bool enabled)
2830 Entry *en = rp->entry_data;
2833 en->input_panel_enable = enabled;
2834 #ifdef HAVE_ECORE_IMF
2835 if (en->imf_context)
2836 ecore_imf_context_input_panel_enabled_set(en->imf_context, enabled);
2841 _edje_entry_input_panel_enabled_get(Edje_Real_Part *rp)
2843 Entry *en = rp->entry_data;
2844 if (!en) return EINA_FALSE;
2846 return en->input_panel_enable;
2850 _edje_entry_input_panel_show(Edje_Real_Part *rp)
2852 Entry *en = rp->entry_data;
2855 #ifdef HAVE_ECORE_IMF
2856 if (en->imf_context)
2857 ecore_imf_context_input_panel_show(en->imf_context);
2862 _edje_entry_input_panel_hide(Edje_Real_Part *rp)
2864 Entry *en = rp->entry_data;
2867 #ifdef HAVE_ECORE_IMF
2868 if (en->imf_context)
2869 ecore_imf_context_input_panel_hide(en->imf_context);
2874 _edje_entry_input_panel_language_set(Edje_Real_Part *rp, Edje_Input_Panel_Lang lang)
2876 Entry *en = rp->entry_data;
2879 en->input_panel_lang = lang;
2880 #ifdef HAVE_ECORE_IMF
2881 if (en->imf_context)
2882 ecore_imf_context_input_panel_language_set(en->imf_context, lang);
2886 Edje_Input_Panel_Lang
2887 _edje_entry_input_panel_language_get(Edje_Real_Part *rp)
2889 Entry *en = rp->entry_data;
2890 if (!en) return EDJE_INPUT_PANEL_LANG_AUTOMATIC;
2892 return en->input_panel_lang;
2895 #ifdef HAVE_ECORE_IMF
2897 _edje_entry_input_panel_imdata_set(Edje_Real_Part *rp, const void *data, int len)
2900 _edje_entry_input_panel_imdata_set(Edje_Real_Part *rp, const void *data __UNUSED__, int len __UNUSED__)
2903 Entry *en = rp->entry_data;
2905 #ifdef HAVE_ECORE_IMF
2906 if (en->imf_context)
2907 ecore_imf_context_input_panel_imdata_set(en->imf_context, data, len);
2911 #ifdef HAVE_ECORE_IMF
2913 _edje_entry_input_panel_imdata_get(Edje_Real_Part *rp, void *data, int *len)
2916 _edje_entry_input_panel_imdata_get(Edje_Real_Part *rp, void *data __UNUSED__, int *len __UNUSED__)
2919 Entry *en = rp->entry_data;
2921 #ifdef HAVE_ECORE_IMF
2922 if (en->imf_context)
2923 ecore_imf_context_input_panel_imdata_get(en->imf_context, data, len);
2927 #ifdef HAVE_ECORE_IMF
2929 _edje_entry_input_panel_return_key_type_set(Edje_Real_Part *rp, Edje_Input_Panel_Return_Key_Type return_key_type)
2932 _edje_entry_input_panel_return_key_type_set(Edje_Real_Part *rp, Edje_Input_Panel_Return_Key_Type return_key_type __UNUSED__)
2935 Entry *en = rp->entry_data;
2937 #ifdef HAVE_ECORE_IMF
2938 if (en->imf_context)
2939 ecore_imf_context_input_panel_return_key_type_set(en->imf_context, return_key_type);
2943 Edje_Input_Panel_Return_Key_Type
2944 _edje_entry_input_panel_return_key_type_get(Edje_Real_Part *rp)
2946 Entry *en = rp->entry_data;
2947 if (!en) return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
2948 #ifdef HAVE_ECORE_IMF
2949 if (en->imf_context)
2950 return ecore_imf_context_input_panel_return_key_type_get(en->imf_context);
2952 return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
2955 #ifdef HAVE_ECORE_IMF
2957 _edje_entry_input_panel_return_key_disabled_set(Edje_Real_Part *rp, Eina_Bool disabled)
2960 _edje_entry_input_panel_return_key_disabled_set(Edje_Real_Part *rp, Eina_Bool disabled __UNUSED__)
2963 Entry *en = rp->entry_data;
2965 #ifdef HAVE_ECORE_IMF
2966 if (en->imf_context)
2967 ecore_imf_context_input_panel_return_key_disabled_set(en->imf_context, disabled);
2972 _edje_entry_input_panel_return_key_disabled_get(Edje_Real_Part *rp)
2974 Entry *en = rp->entry_data;
2975 if (!en) return EINA_FALSE;
2976 #ifdef HAVE_ECORE_IMF
2977 if (en->imf_context)
2978 return ecore_imf_context_input_panel_return_key_disabled_get(en->imf_context);
2983 static Evas_Textblock_Cursor *
2984 _cursor_get(Edje_Real_Part *rp, Edje_Cursor cur)
2986 Entry *en = rp->entry_data;
2987 if (!en) return NULL;
2991 case EDJE_CURSOR_MAIN:
2993 case EDJE_CURSOR_SELECTION_BEGIN:
2994 return en->sel_start;
2995 case EDJE_CURSOR_SELECTION_END:
2997 case EDJE_CURSOR_PREEDIT_START:
2998 if (!en->preedit_start)
2999 en->preedit_start = evas_object_textblock_cursor_new(rp->object);
3000 return en->preedit_start;
3001 case EDJE_CURSOR_PREEDIT_END:
3002 if (!en->preedit_end)
3003 en->preedit_end = evas_object_textblock_cursor_new(rp->object);
3004 return en->preedit_end;
3005 case EDJE_CURSOR_USER:
3006 if (!en->cursor_user)
3007 en->cursor_user = evas_object_textblock_cursor_new(rp->object);
3008 return en->cursor_user;
3009 case EDJE_CURSOR_USER_EXTRA:
3010 if (!en->cursor_user_extra)
3011 en->cursor_user_extra = evas_object_textblock_cursor_new(rp->object);
3012 return en->cursor_user_extra;
3020 _edje_entry_cursor_next(Edje_Real_Part *rp, Edje_Cursor cur)
3022 Entry *en = rp->entry_data;
3023 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3024 if (!c) return EINA_FALSE;
3026 _edje_entry_imf_context_reset(rp);
3028 if (!evas_textblock_cursor_char_next(c))
3032 _sel_update(c, rp->object, rp->entry_data);
3033 _edje_entry_imf_cursor_info_set(en);
3035 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3036 _edje_entry_real_part_configure(rp);
3041 _edje_entry_cursor_prev(Edje_Real_Part *rp, Edje_Cursor cur)
3043 Entry *en = rp->entry_data;
3044 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3045 if (!c) return EINA_FALSE;
3047 _edje_entry_imf_context_reset(rp);
3049 if (!evas_textblock_cursor_char_prev(c))
3051 if (evas_textblock_cursor_paragraph_prev(c)) goto ok;
3052 else return EINA_FALSE;
3055 _sel_update(c, rp->object, rp->entry_data);
3057 _edje_entry_imf_cursor_info_set(en);
3059 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3060 _edje_entry_real_part_configure(rp);
3065 _edje_entry_cursor_up(Edje_Real_Part *rp, Edje_Cursor cur)
3067 Entry *en = rp->entry_data;
3068 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3069 Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
3071 if (!c) return EINA_FALSE;
3073 _edje_entry_imf_context_reset(rp);
3075 ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL);
3077 if (ln < 0) return EINA_FALSE;
3078 if (!evas_object_textblock_line_number_geometry_get(rp->object, ln,
3079 &lx, &ly, &lw, &lh))
3081 evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
3082 if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
3084 if (cx < (lx + (lw / 2)))
3085 evas_textblock_cursor_line_char_last(c);
3087 evas_textblock_cursor_line_char_last(c);
3089 _sel_update(c, rp->object, rp->entry_data);
3091 _edje_entry_imf_cursor_info_set(en);
3093 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3094 _edje_entry_real_part_configure(rp);
3099 _edje_entry_cursor_down(Edje_Real_Part *rp, Edje_Cursor cur)
3101 Entry *en = rp->entry_data;
3102 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3103 Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
3105 if (!c) return EINA_FALSE;
3107 _edje_entry_imf_context_reset(rp);
3109 ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL);
3111 if (!evas_object_textblock_line_number_geometry_get(rp->object, ln,
3112 &lx, &ly, &lw, &lh))
3114 evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
3115 if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
3117 if (cx < (lx + (lw / 2)))
3118 evas_textblock_cursor_line_char_last(c);
3120 evas_textblock_cursor_line_char_last(c);
3122 _sel_update(c, rp->object, rp->entry_data);
3124 _edje_entry_imf_cursor_info_set(en);
3125 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3126 _edje_entry_real_part_configure(rp);
3131 _edje_entry_cursor_begin(Edje_Real_Part *rp, Edje_Cursor cur)
3133 Entry *en = rp->entry_data;
3134 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3137 _edje_entry_imf_context_reset(rp);
3139 evas_textblock_cursor_paragraph_first(c);
3140 _sel_update(c, rp->object, rp->entry_data);
3142 _edje_entry_imf_cursor_info_set(en);
3143 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3144 _edje_entry_real_part_configure(rp);
3148 _edje_entry_cursor_end(Edje_Real_Part *rp, Edje_Cursor cur)
3150 Entry *en = rp->entry_data;
3151 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3154 _edje_entry_imf_context_reset(rp);
3156 _curs_end(c, rp->object, rp->entry_data);
3157 _sel_update(c, rp->object, rp->entry_data);
3159 _edje_entry_imf_cursor_info_set(en);
3161 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3162 _edje_entry_real_part_configure(rp);
3166 _edje_entry_cursor_copy(Edje_Real_Part *rp, Edje_Cursor cur, Edje_Cursor dst)
3168 Entry *en = rp->entry_data;
3169 Evas_Textblock_Cursor *c;
3170 Evas_Textblock_Cursor *d;
3172 c = _cursor_get(rp, cur);
3174 d = _cursor_get(rp, dst);
3176 evas_textblock_cursor_copy(c, d);
3177 _sel_update(c, rp->object, rp->entry_data);
3179 _edje_entry_imf_context_reset(rp);
3180 _edje_entry_imf_cursor_info_set(en);
3181 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3182 _edje_entry_real_part_configure(rp);
3186 _edje_entry_cursor_line_begin(Edje_Real_Part *rp, Edje_Cursor cur)
3188 Entry *en = rp->entry_data;
3189 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3191 _edje_entry_imf_context_reset(rp);
3193 evas_textblock_cursor_line_char_first(c);
3194 _sel_update(c, rp->object, rp->entry_data);
3196 _edje_entry_imf_cursor_info_set(en);
3198 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3199 _edje_entry_real_part_configure(rp);
3203 _edje_entry_cursor_line_end(Edje_Real_Part *rp, Edje_Cursor cur)
3205 Entry *en = rp->entry_data;
3206 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3208 _edje_entry_imf_context_reset(rp);
3209 evas_textblock_cursor_line_char_last(c);
3210 _sel_update(c, rp->object, rp->entry_data);
3212 _edje_entry_imf_cursor_info_set(en);
3213 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3214 _edje_entry_real_part_configure(rp);
3218 _edje_entry_cursor_coord_set(Edje_Real_Part *rp, Edje_Cursor cur,
3219 Evas_Coord x, Evas_Coord y)
3221 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3222 if (!c) return EINA_FALSE;
3223 return evas_textblock_cursor_char_coord_set(c, x, y);
3227 _edje_entry_cursor_is_format_get(Edje_Real_Part *rp, Edje_Cursor cur)
3229 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3230 if (!c) return EINA_FALSE;
3231 if (evas_textblock_cursor_is_format(c)) return EINA_TRUE;
3236 _edje_entry_cursor_is_visible_format_get(Edje_Real_Part *rp, Edje_Cursor cur)
3238 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3239 if (!c) return EINA_FALSE;
3240 return evas_textblock_cursor_format_is_visible_get(c);
3244 _edje_entry_cursor_content_get(Edje_Real_Part *rp, Edje_Cursor cur)
3246 static char *s = NULL;
3247 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3249 if (!c) return NULL;
3256 s = evas_textblock_cursor_content_get(c);
3261 _edje_entry_cursor_pos_set(Edje_Real_Part *rp, Edje_Cursor cur, int pos)
3263 Entry *en = rp->entry_data;
3264 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3266 /* Abort if cursor position didn't really change */
3267 if (evas_textblock_cursor_pos_get(c) == pos)
3270 _edje_entry_imf_context_reset(rp);
3271 evas_textblock_cursor_pos_set(c, pos);
3272 _sel_update(c, rp->object, rp->entry_data);
3274 _edje_entry_imf_cursor_info_set(en);
3275 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3276 _edje_entry_real_part_configure(rp);
3280 _edje_entry_cursor_pos_get(Edje_Real_Part *rp, Edje_Cursor cur)
3282 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3284 return evas_textblock_cursor_pos_get(c);
3288 _edje_entry_input_panel_layout_set(Edje_Real_Part *rp, Edje_Input_Panel_Layout layout)
3290 Entry *en = rp->entry_data;
3292 #ifdef HAVE_ECORE_IMF
3293 if (en->imf_context)
3294 ecore_imf_context_input_panel_layout_set(en->imf_context, layout);
3300 Edje_Input_Panel_Layout
3301 _edje_entry_input_panel_layout_get(Edje_Real_Part *rp)
3303 Entry *en = rp->entry_data;
3304 if (!en) return EDJE_INPUT_PANEL_LAYOUT_INVALID;
3305 #ifdef HAVE_ECORE_IMF
3306 if (en->imf_context)
3307 return ecore_imf_context_input_panel_layout_get(en->imf_context);
3310 return EDJE_INPUT_PANEL_LAYOUT_INVALID;
3314 _edje_entry_imf_context_reset(Edje_Real_Part *rp)
3316 Entry *en = rp->entry_data;
3318 #ifdef HAVE_ECORE_IMF
3319 if (en->imf_context)
3320 ecore_imf_context_reset(en->imf_context);
3325 _edje_entry_imf_cursor_info_set(Entry *en)
3327 #ifdef HAVE_ECORE_IMF
3328 Evas_Coord cx, cy, cw, ch;
3329 if (!en || !en->rp || !en->imf_context) return;
3331 _edje_entry_cursor_geometry_get(en->rp, &cx, &cy, &cw, &ch);
3333 ecore_imf_context_cursor_position_set(en->imf_context,
3334 evas_textblock_cursor_pos_get(en->cursor));
3335 ecore_imf_context_cursor_location_set(en->imf_context, cx, cy, cw, ch);
3341 #ifdef HAVE_ECORE_IMF
3343 _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, char **text, int *cursor_pos)
3346 Edje_Real_Part *rp = ed->focused_part;
3350 if (!rp) return EINA_FALSE;
3351 en = rp->entry_data;
3352 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3353 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
3358 str = _edje_entry_text_get(rp);
3359 *text = str ? strdup(str) : strdup("");
3363 *cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
3369 _edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info)
3372 Edje_Real_Part *rp = ed->focused_part;
3374 char *commit_str = event_info;
3379 en = rp->entry_data;
3380 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3381 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
3384 if (en->have_selection)
3386 if (strcmp(commit_str, ""))
3388 /* delete selected characters */
3389 _range_del_emit(ed, en->cursor, rp->object, en);
3390 _sel_clear(en->cursor, rp->object, en);
3394 start_pos = evas_textblock_cursor_pos_get(en->cursor);
3396 #ifdef HAVE_ECORE_IMF
3397 /* delete preedit characters */
3402 if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
3403 _edje_password_show_last)
3404 _edje_entry_hide_visible_password(en->rp);
3405 if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
3406 _edje_password_show_last && (!en->preedit_start))
3408 _text_filter_format_prepend(en, en->cursor, "+ password=off");
3409 _text_filter_text_prepend(en, en->cursor, commit_str);
3410 _text_filter_format_prepend(en, en->cursor, "- password");
3414 ecore_timer_del(en->pw_timer);
3415 en->pw_timer = NULL;
3417 en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout),
3418 _password_timer_cb, en);
3421 _text_filter_text_prepend(en, en->cursor, commit_str);
3424 _edje_entry_imf_cursor_info_set(en);
3425 _anchors_get(en->cursor, rp->object, en);
3426 _edje_emit(rp->edje, "entry,changed", rp->part->name);
3429 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
3430 info->insert = EINA_TRUE;
3431 info->change.insert.pos = start_pos;
3432 info->change.insert.content = eina_stringshare_add(commit_str);
3433 info->change.insert.plain_length =
3434 eina_unicode_utf8_get_len(info->change.insert.content);
3435 _edje_emit_full(ed, "entry,changed,user", rp->part->name,
3436 info, _free_entry_change_info);
3437 _edje_emit(ed, "cursor,changed", rp->part->name);
3440 _edje_entry_imf_cursor_info_set(en);
3441 _edje_entry_real_part_configure(rp);
3445 _edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info __UNUSED__)
3448 Edje_Real_Part *rp = ed->focused_part;
3451 int preedit_start_pos, preedit_end_pos;
3452 char *preedit_string;
3454 Eina_Bool preedit_end_state = EINA_FALSE;
3455 Eina_List *attrs = NULL, *l = NULL;
3456 Ecore_IMF_Preedit_Attr *attr;
3461 en = rp->entry_data;
3462 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3463 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
3466 if (!en->imf_context) return;
3468 ecore_imf_context_preedit_string_with_attributes_get(en->imf_context,
3470 &attrs, &cursor_pos);
3471 if (!preedit_string) return;
3473 if (!strcmp(preedit_string, ""))
3474 preedit_end_state = EINA_TRUE;
3476 if (en->have_selection && !preedit_end_state)
3478 /* delete selected characters */
3479 _range_del_emit(ed, en->cursor, rp->object, en);
3482 /* delete preedit characters */
3485 preedit_start_pos = evas_textblock_cursor_pos_get(en->cursor);
3487 /* insert preedit character(s) */
3488 if (strlen(preedit_string) > 0)
3490 buf = eina_strbuf_new();
3493 EINA_LIST_FOREACH(attrs, l, attr)
3495 if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1)
3497 eina_strbuf_append(buf, "<preedit>");
3498 eina_strbuf_append_n(buf, preedit_string + attr->start_index,
3499 attr->end_index - attr->start_index);
3500 eina_strbuf_append(buf, "</preedit>");
3503 else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2 ||
3504 attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3)
3506 eina_strbuf_append(buf, "<preedit_sel>");
3507 eina_strbuf_append_n(buf, preedit_string + attr->start_index,
3508 attr->end_index - attr->start_index);
3509 eina_strbuf_append(buf, "</preedit_sel>");
3515 eina_strbuf_append(buf, preedit_string);
3517 if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
3518 _edje_password_show_last)
3520 _edje_entry_hide_visible_password(en->rp);
3521 _text_filter_format_prepend(en, en->cursor, "+ password=off");
3522 _text_filter_markup_prepend(en, en->cursor, eina_strbuf_string_get(buf));
3523 _text_filter_format_prepend(en, en->cursor, "- password");
3526 ecore_timer_del(en->pw_timer);
3527 en->pw_timer = NULL;
3529 en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout),
3530 _password_timer_cb, en);
3534 _text_filter_markup_prepend(en, en->cursor, eina_strbuf_string_get(buf));
3536 eina_strbuf_free(buf);
3539 if (!preedit_end_state)
3541 /* set preedit start cursor */
3542 if (!en->preedit_start)
3543 en->preedit_start = evas_object_textblock_cursor_new(rp->object);
3544 evas_textblock_cursor_copy(en->cursor, en->preedit_start);
3546 /* set preedit end cursor */
3547 if (!en->preedit_end)
3548 en->preedit_end = evas_object_textblock_cursor_new(rp->object);
3549 evas_textblock_cursor_copy(en->cursor, en->preedit_end);
3551 preedit_end_pos = evas_textblock_cursor_pos_get(en->cursor);
3553 for (i = 0; i < (preedit_end_pos - preedit_start_pos); i++)
3555 evas_textblock_cursor_char_prev(en->preedit_start);
3558 en->have_preedit = EINA_TRUE;
3560 /* set cursor position */
3561 evas_textblock_cursor_pos_set(en->cursor, preedit_start_pos + cursor_pos);
3564 _edje_entry_imf_cursor_info_set(en);
3565 _anchors_get(en->cursor, rp->object, en);
3566 _edje_emit(rp->edje, "preedit,changed", rp->part->name);
3567 _edje_emit(ed, "cursor,changed", rp->part->name);
3569 /* delete attribute list */
3572 EINA_LIST_FREE(attrs, attr) free(attr);
3575 free(preedit_string);
3579 _edje_entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info)
3582 Edje_Real_Part *rp = ed->focused_part;
3584 Ecore_IMF_Event_Delete_Surrounding *ev = event_info;
3585 Evas_Textblock_Cursor *del_start, *del_end;
3588 if ((!rp) || (!ev)) return;
3589 en = rp->entry_data;
3590 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3591 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
3594 cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
3596 del_start = evas_object_textblock_cursor_new(en->rp->object);
3597 evas_textblock_cursor_pos_set(del_start, cursor_pos + ev->offset);
3599 del_end = evas_object_textblock_cursor_new(en->rp->object);
3600 evas_textblock_cursor_pos_set(del_end, cursor_pos + ev->offset + ev->n_chars);
3602 evas_textblock_cursor_range_delete(del_start, del_end);
3604 evas_textblock_cursor_free(del_start);
3605 evas_textblock_cursor_free(del_end);
3609 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/