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;
674 len = 200 + strlen(n);
676 if ((rp->part->select_mode != EDJE_ENTRY_SELECTION_MODE_EXPLICIT) ||
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);
685 if ((rp->still_in) && (rp->clicked_button == ev->button) && (!ignored))
687 snprintf(buf, len, "anchor,mouse,clicked,%i,%s", ev->button, n);
688 _edje_emit(rp->edje, buf, rp->part->name);
693 _edje_anchor_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
696 Evas_Event_Mouse_Move *ev = event_info;
697 Edje_Real_Part *rp = an->en->rp;
704 if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) &&
707 ignored = rp->part->ignore_flags & ev->event_flags;
708 if ((!ev->event_flags) || (!ignored))
712 len = 200 + strlen(n);
714 snprintf(buf, len, "anchor,mouse,move,%s", n);
715 _edje_emit(rp->edje, buf, rp->part->name);
720 _edje_anchor_mouse_in_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
723 Evas_Event_Mouse_In *ev = event_info;
724 Edje_Real_Part *rp = an->en->rp;
729 ignored = rp->part->ignore_flags & ev->event_flags;
730 if ((!ev->event_flags) || (!ignored))
734 len = 200 + strlen(n);
736 snprintf(buf, len, "anchor,mouse,in,%s", n);
737 _edje_emit(rp->edje, buf, rp->part->name);
742 _edje_anchor_mouse_out_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
745 Evas_Event_Mouse_Out *ev = event_info;
746 Edje_Real_Part *rp = an->en->rp;
751 ignored = rp->part->ignore_flags & ev->event_flags;
752 if ((!ev->event_flags) || (!ignored))
756 len = 200 + strlen(n);
758 snprintf(buf, len, "anchor,mouse,out,%s", n);
759 _edje_emit(rp->edje, buf, rp->part->name);
764 _anchors_update(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o, Entry *en)
766 Eina_List *l, *ll, *range = NULL;
767 Evas_Coord x, y, w, h;
768 Evas_Object *smart, *clip;
772 smart = evas_object_smart_parent_get(o);
773 clip = evas_object_clip_get(o);
775 evas_object_geometry_get(o, &x, &y, &w, &h);
776 EINA_LIST_FOREACH(en->anchors, l, an)
788 if (sel->obj_bg) evas_object_del(sel->obj_bg);
789 if (sel->obj_fg) evas_object_del(sel->obj_fg);
790 if (sel->obj) evas_object_del(sel->obj);
792 an->sel = eina_list_remove_list(an->sel, an->sel);
795 sel = calloc(1, sizeof(Sel));
796 an->sel = eina_list_append(an->sel, sel);
798 if (en->rp->edje->item_provider.func)
800 ob = en->rp->edje->item_provider.func
801 (en->rp->edje->item_provider.data, smart,
802 en->rp->part->name, an->name);
803 evas_object_smart_member_add(ob, smart);
804 evas_object_stack_above(ob, o);
805 evas_object_clip_set(ob, clip);
806 evas_object_pass_events_set(ob, EINA_TRUE);
807 evas_object_show(ob);
816 evas_textblock_cursor_range_geometry_get(an->start, an->end);
817 if (eina_list_count(range) != eina_list_count(an->sel))
822 if (sel->obj_bg) evas_object_del(sel->obj_bg);
823 if (sel->obj_fg) evas_object_del(sel->obj_fg);
824 if (sel->obj) evas_object_del(sel->obj);
826 an->sel = eina_list_remove_list(an->sel, an->sel);
828 for (ll = range; ll; ll = eina_list_next(ll))
832 sel = calloc(1, sizeof(Sel));
833 an->sel = eina_list_append(an->sel, sel);
834 ob = edje_object_add(en->rp->edje->base.evas);
835 edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source5);
836 evas_object_smart_member_add(ob, smart);
837 evas_object_stack_below(ob, o);
838 evas_object_clip_set(ob, clip);
839 evas_object_pass_events_set(ob, EINA_TRUE);
840 evas_object_show(ob);
842 _edje_subobj_register(en->rp->edje, sel->obj_bg);
844 ob = edje_object_add(en->rp->edje->base.evas);
845 edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source6);
846 evas_object_smart_member_add(ob, smart);
847 evas_object_stack_above(ob, o);
848 evas_object_clip_set(ob, clip);
849 evas_object_pass_events_set(ob, EINA_TRUE);
850 evas_object_show(ob);
852 _edje_subobj_register(en->rp->edje, sel->obj_fg);
854 ob = evas_object_rectangle_add(en->rp->edje->base.evas);
855 evas_object_color_set(ob, 0, 0, 0, 0);
856 evas_object_smart_member_add(ob, smart);
857 evas_object_stack_above(ob, o);
858 evas_object_clip_set(ob, clip);
859 evas_object_repeat_events_set(ob, EINA_TRUE);
860 evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _edje_anchor_mouse_down_cb, an);
861 evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_UP, _edje_anchor_mouse_up_cb, an);
862 evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_MOVE, _edje_anchor_mouse_move_cb, an);
863 evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_IN, _edje_anchor_mouse_in_cb, an);
864 evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_OUT, _edje_anchor_mouse_out_cb, an);
865 evas_object_show(ob);
870 EINA_LIST_FOREACH(an->sel, ll, sel)
874 Evas_Coord cx, cy, cw, ch;
876 if (!evas_textblock_cursor_format_item_geometry_get
877 (an->start, &cx, &cy, &cw, &ch))
879 evas_object_move(sel->obj, x + cx, y + cy);
880 evas_object_resize(sel->obj, cw, ch);
884 Evas_Textblock_Rectangle *r;
887 *(&(sel->rect)) = *r;
890 evas_object_move(sel->obj_bg, x + r->x, y + r->y);
891 evas_object_resize(sel->obj_bg, r->w, r->h);
895 evas_object_move(sel->obj_fg, x + r->x, y + r->y);
896 evas_object_resize(sel->obj_fg, r->w, r->h);
900 evas_object_move(sel->obj, x + r->x, y + r->y);
901 evas_object_resize(sel->obj, r->w, r->h);
903 range = eina_list_remove_list(range, range);
911 _anchors_clear(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
913 while (en->anchorlist)
915 free(en->anchorlist->data);
916 en->anchorlist = eina_list_remove_list(en->anchorlist, en->anchorlist);
920 free(en->itemlist->data);
921 en->itemlist = eina_list_remove_list(en->itemlist, en->itemlist);
925 Anchor *an = en->anchors->data;
927 evas_textblock_cursor_free(an->start);
928 evas_textblock_cursor_free(an->end);
931 Sel *sel = an->sel->data;
932 if (sel->obj_bg) evas_object_del(sel->obj_bg);
933 if (sel->obj_fg) evas_object_del(sel->obj_fg);
934 if (sel->obj) evas_object_del(sel->obj);
936 an->sel = eina_list_remove_list(an->sel, an->sel);
940 en->anchors = eina_list_remove_list(en->anchors, en->anchors);
945 _anchors_get(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
947 const Eina_List *anchors_a, *anchors_item;
949 _anchors_clear(c, o, en);
951 anchors_a = evas_textblock_node_format_list_get(o, "a");
952 anchors_item = evas_textblock_node_format_list_get(o, "item");
956 const Evas_Object_Textblock_Node_Format *node;
957 const Eina_List *itr;
958 EINA_LIST_FOREACH(anchors_a, itr, node)
960 const char *s = evas_textblock_node_format_text_get(node);
962 an = calloc(1, sizeof(Anchor));
967 p = strstr(s, "href=");
970 an->name = strdup(p + 5);
972 en->anchors = eina_list_append(en->anchors, an);
973 an->start = evas_object_textblock_cursor_new(o);
974 an->end = evas_object_textblock_cursor_new(o);
975 evas_textblock_cursor_at_format_set(an->start, node);
976 evas_textblock_cursor_copy(an->start, an->end);
978 /* Close the anchor, if the anchor was without text,
980 node = evas_textblock_node_format_next_get(node);
981 for (; node; node = evas_textblock_node_format_next_get(node))
983 s = evas_textblock_node_format_text_get(node);
984 if ((!strcmp(s, "- a")) || (!strcmp(s, "-a")))
990 evas_textblock_cursor_at_format_set(an->end, node);
992 else if (!evas_textblock_cursor_compare(an->start, an->end))
994 if (an->name) free(an->name);
995 evas_textblock_cursor_free(an->start);
996 evas_textblock_cursor_free(an->end);
997 en->anchors = eina_list_remove(en->anchors, an);
1006 const Evas_Object_Textblock_Node_Format *node;
1007 const Eina_List *itr;
1008 EINA_LIST_FOREACH(anchors_item, itr, node)
1010 const char *s = evas_textblock_node_format_text_get(node);
1012 an = calloc(1, sizeof(Anchor));
1018 p = strstr(s, "href=");
1021 an->name = strdup(p + 5);
1023 en->anchors = eina_list_append(en->anchors, an);
1024 an->start = evas_object_textblock_cursor_new(o);
1025 an->end = evas_object_textblock_cursor_new(o);
1026 evas_textblock_cursor_at_format_set(an->start, node);
1027 evas_textblock_cursor_copy(an->start, an->end);
1028 /* Although needed in textblock, don't bother with finding the end
1029 * here cause it doesn't really matter. */
1035 _free_entry_change_info(void *_info)
1037 Edje_Entry_Change_Info *info = (Edje_Entry_Change_Info *) _info;
1040 eina_stringshare_del(info->change.insert.content);
1044 eina_stringshare_del(info->change.del.content);
1050 _range_del_emit(Edje *ed, Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
1054 Edje_Entry_Change_Info *info;
1056 start = evas_textblock_cursor_pos_get(en->sel_start);
1057 end = evas_textblock_cursor_pos_get(en->sel_end);
1061 info = calloc(1, sizeof(*info));
1062 info->insert = EINA_FALSE;
1063 info->change.del.start = start;
1064 info->change.del.end = end;
1066 tmp = evas_textblock_cursor_range_text_get(en->sel_start, en->sel_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
1067 info->change.del.content = eina_stringshare_add(tmp);
1069 evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
1070 _edje_emit(ed, "entry,changed", en->rp->part->name);
1071 _edje_emit_full(ed, "entry,changed,user", en->rp->part->name, info,
1072 _free_entry_change_info);
1074 _sel_clear(en->cursor, en->rp->object, en);
1078 _range_del(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
1080 evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
1081 _sel_clear(en->cursor, en->rp->object, en);
1085 _delete_emit(Edje *ed, Evas_Textblock_Cursor *c, Entry *en, size_t pos,
1086 Eina_Bool backspace)
1088 if (!evas_textblock_cursor_char_next(c))
1092 evas_textblock_cursor_char_prev(c);
1094 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1095 char *tmp = evas_textblock_cursor_content_get(c);
1097 info->insert = EINA_FALSE;
1100 info->change.del.start = pos - 1;
1101 info->change.del.end = pos;
1105 info->change.del.start = pos + 1;
1106 info->change.del.end = pos;
1109 info->change.del.content = eina_stringshare_add(tmp);
1112 evas_textblock_cursor_char_delete(c);
1113 _edje_emit(ed, "entry,changed", en->rp->part->name);
1114 _edje_emit_full(ed, "entry,changed,user", en->rp->part->name,
1115 info, _free_entry_change_info);
1119 _edje_entry_hide_visible_password(Edje_Real_Part *rp)
1121 const Evas_Object_Textblock_Node_Format *node;
1122 node = evas_textblock_node_format_first_get(rp->object);
1123 for (; node; node = evas_textblock_node_format_next_get(node))
1125 const char *text = evas_textblock_node_format_text_get(node);
1128 if (!strcmp(text, "+ password=off"))
1130 evas_textblock_node_format_remove_pair(rp->object,
1131 (Evas_Object_Textblock_Node_Format *) node);
1136 _edje_entry_real_part_configure(rp);
1137 _edje_emit(rp->edje, "entry,changed", rp->part->name);
1141 _password_timer_cb(void *data)
1143 Entry *en = (Entry *)data;
1144 _edje_entry_hide_visible_password(en->rp);
1145 en->pw_timer = NULL;
1146 return ECORE_CALLBACK_CANCEL;
1150 _is_modifier(const char *key)
1152 if ((!strncmp(key, "Shift", 5)) ||
1153 (!strncmp(key, "Control", 7)) ||
1154 (!strncmp(key, "Alt", 3)) ||
1155 (!strncmp(key, "Meta", 4)) ||
1156 (!strncmp(key, "Super", 5)) ||
1157 (!strncmp(key, "Hyper", 5)) ||
1158 (!strcmp(key, "Scroll_Lock")) ||
1159 (!strcmp(key, "Num_Lock")) ||
1160 (!strcmp(key, "Caps_Lock")))
1166 _compose_seq_reset(Entry *en)
1170 EINA_LIST_FREE(en->seq, str) eina_stringshare_del(str);
1171 en->composing = EINA_FALSE;
1175 _edje_key_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1178 Evas_Event_Key_Down *ev = event_info;
1179 Edje_Real_Part *rp = ed->focused_part;
1181 Eina_Bool control, alt, shift;
1182 Eina_Bool multiline;
1183 Eina_Bool cursor_changed;
1186 en = rp->entry_data;
1187 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1188 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
1190 if (!ev->keyname) return;
1192 #ifdef HAVE_ECORE_IMF
1193 if (en->imf_context)
1195 Ecore_IMF_Event_Key_Down ecore_ev;
1196 Eina_Bool filter_ret;
1197 ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev);
1200 filter_ret = ecore_imf_context_filter_event(en->imf_context,
1201 ECORE_IMF_EVENT_KEY_DOWN,
1202 (Ecore_IMF_Event *)&ecore_ev);
1204 if (!strcmp(ev->keyname, "Down") ||
1205 (!strcmp(ev->keyname, "KP_Down") && !ev->string) ||
1206 !strcmp(ev->keyname, "Up") ||
1207 (!strcmp(ev->keyname, "KP_Up") && !ev->string))
1209 if (en->have_preedit)
1210 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1219 if ((!strcmp(ev->keyname, "Escape")) ||
1220 (!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "KP_Enter")))
1221 _edje_entry_imf_context_reset(rp);
1223 old_cur_pos = evas_textblock_cursor_pos_get(en->cursor);
1225 control = evas_key_modifier_is_set(ev->modifiers, "Control");
1226 alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
1227 shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
1228 multiline = rp->part->multiline;
1229 cursor_changed = EINA_FALSE;
1230 if (!strcmp(ev->keyname, "Escape"))
1232 _compose_seq_reset(en);
1233 // dead keys here. Escape for now (should emit these)
1234 _edje_emit(ed, "entry,key,escape", rp->part->name);
1235 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1237 else if (!strcmp(ev->keyname, "Up") ||
1238 (!strcmp(ev->keyname, "KP_Up") && !ev->string))
1240 _compose_seq_reset(en);
1243 if (en->select_allow)
1245 if (shift) _sel_start(en->cursor, rp->object, en);
1246 else _sel_clear(en->cursor, rp->object, en);
1248 _curs_up(en->cursor, rp->object, en);
1249 if (en->select_allow)
1251 if (shift) _sel_extend(en->cursor, rp->object, en);
1252 else _sel_clear(en->cursor, rp->object, en);
1254 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1256 _edje_emit(ed, "entry,key,up", rp->part->name);
1257 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1259 else if (!strcmp(ev->keyname, "Down") ||
1260 (!strcmp(ev->keyname, "KP_Down") && !ev->string))
1262 _compose_seq_reset(en);
1265 if (en->select_allow)
1267 if (shift) _sel_start(en->cursor, rp->object, en);
1268 else _sel_clear(en->cursor, rp->object, en);
1270 _curs_down(en->cursor, rp->object, en);
1271 if (en->select_allow)
1273 if (shift) _sel_extend(en->cursor, rp->object, en);
1274 else _sel_clear(en->cursor, rp->object, en);
1276 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1278 _edje_emit(ed, "entry,key,down", rp->part->name);
1279 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1281 else if (!strcmp(ev->keyname, "Left") ||
1282 (!strcmp(ev->keyname, "KP_Left") && !ev->string))
1284 _compose_seq_reset(en);
1285 if (en->select_allow)
1287 if (shift) _sel_start(en->cursor, rp->object, en);
1288 else _sel_clear(en->cursor, rp->object, en);
1290 evas_textblock_cursor_char_prev(en->cursor);
1291 /* If control is pressed, go to the start of the word */
1292 if (control) evas_textblock_cursor_word_start(en->cursor);
1293 if (en->select_allow)
1295 if (shift) _sel_extend(en->cursor, rp->object, en);
1296 else _sel_clear(en->cursor, rp->object, en);
1298 _edje_emit(ed, "entry,key,left", rp->part->name);
1299 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1300 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1302 else if (!strcmp(ev->keyname, "Right") ||
1303 (!strcmp(ev->keyname, "KP_Right") && !ev->string))
1305 _compose_seq_reset(en);
1306 if (en->select_allow)
1308 if (shift) _sel_start(en->cursor, rp->object, en);
1309 else _sel_clear(en->cursor, rp->object, en);
1311 /* If control is pressed, go to the end of the word */
1312 if (control) evas_textblock_cursor_word_end(en->cursor);
1313 evas_textblock_cursor_char_next(en->cursor);
1314 if (en->select_allow)
1316 if (shift) _sel_extend(en->cursor, rp->object, en);
1317 else _sel_clear(en->cursor, rp->object, en);
1319 _edje_emit(ed, "entry,key,right", rp->part->name);
1320 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1321 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1323 else if (!strcmp(ev->keyname, "BackSpace"))
1325 _compose_seq_reset(en);
1326 if (control && !en->have_selection)
1328 // del to start of previous word
1329 _sel_start(en->cursor, rp->object, en);
1331 evas_textblock_cursor_char_prev(en->cursor);
1332 evas_textblock_cursor_word_start(en->cursor);
1334 _sel_preextend(en->cursor, rp->object, en);
1336 _range_del_emit(ed, en->cursor, rp->object, en);
1338 else if ((alt) && (shift))
1344 if (en->have_selection)
1346 _range_del_emit(ed, en->cursor, rp->object, en);
1350 if (evas_textblock_cursor_char_prev(en->cursor))
1352 _delete_emit(ed, en->cursor, en, old_cur_pos, EINA_TRUE);
1356 _sel_clear(en->cursor, rp->object, en);
1357 _anchors_get(en->cursor, rp->object, en);
1358 _edje_emit(ed, "entry,key,backspace", rp->part->name);
1359 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1361 else if (!strcmp(ev->keyname, "Delete") ||
1362 (!strcmp(ev->keyname, "KP_Delete") && !ev->string))
1364 _compose_seq_reset(en);
1367 // del to end of next word
1368 _sel_start(en->cursor, rp->object, en);
1370 evas_textblock_cursor_word_end(en->cursor);
1371 evas_textblock_cursor_char_next(en->cursor);
1373 _sel_extend(en->cursor, rp->object, en);
1375 _range_del_emit(ed, en->cursor, rp->object, en);
1383 if (en->have_selection)
1385 _range_del_emit(ed, en->cursor, rp->object, en);
1389 _delete_emit(ed, en->cursor, en, old_cur_pos, EINA_FALSE);
1392 _sel_clear(en->cursor, rp->object, en);
1393 _anchors_get(en->cursor, rp->object, en);
1394 _edje_emit(ed, "entry,key,delete", rp->part->name);
1395 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1397 else if (!strcmp(ev->keyname, "Home") ||
1398 ((!strcmp(ev->keyname, "KP_Home")) && !ev->string))
1400 _compose_seq_reset(en);
1401 if (en->select_allow)
1403 if (shift) _sel_start(en->cursor, rp->object, en);
1404 else _sel_clear(en->cursor, rp->object, en);
1406 if ((control) && (multiline))
1407 _curs_start(en->cursor, rp->object, en);
1409 _curs_lin_start(en->cursor, rp->object, en);
1410 if (en->select_allow)
1412 if (shift) _sel_extend(en->cursor, rp->object, en);
1414 _edje_emit(ed, "entry,key,home", rp->part->name);
1415 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1417 else if (!strcmp(ev->keyname, "End") ||
1418 ((!strcmp(ev->keyname, "KP_End")) && !ev->string))
1420 _compose_seq_reset(en);
1421 if (en->select_allow)
1423 if (shift) _sel_start(en->cursor, rp->object, en);
1424 else _sel_clear(en->cursor, rp->object, en);
1426 if ((control) && (multiline))
1427 _curs_end(en->cursor, rp->object, en);
1429 _curs_lin_end(en->cursor, rp->object, en);
1430 if (en->select_allow)
1432 if (shift) _sel_extend(en->cursor, rp->object, en);
1434 _edje_emit(ed, "entry,key,end", rp->part->name);
1435 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1437 else if ((control) && (!shift) && (!strcmp(ev->keyname, "v")))
1439 _compose_seq_reset(en);
1440 _edje_emit(ed, "entry,paste,request", rp->part->name);
1441 _edje_emit(ed, "entry,paste,request,3", rp->part->name);
1442 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1444 else if ((control) && (!strcmp(ev->keyname, "a")))
1446 _compose_seq_reset(en);
1449 _edje_emit(ed, "entry,selection,none,request", rp->part->name);
1450 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1454 _edje_emit(ed, "entry,selection,all,request", rp->part->name);
1455 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1458 else if ((control) && (((!shift) && !strcmp(ev->keyname, "c")) || !strcmp(ev->keyname, "Insert")))
1460 _compose_seq_reset(en);
1461 _edje_emit(ed, "entry,copy,notify", rp->part->name);
1462 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1464 else if ((control) && (!shift) && ((!strcmp(ev->keyname, "x") || (!strcmp(ev->keyname, "m")))))
1466 _compose_seq_reset(en);
1467 _edje_emit(ed, "entry,cut,notify", rp->part->name);
1468 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1470 else if ((control) && (!strcmp(ev->keyname, "z")))
1472 _compose_seq_reset(en);
1476 _edje_emit(ed, "entry,redo,request", rp->part->name);
1481 _edje_emit(ed, "entry,undo,request", rp->part->name);
1483 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1485 else if ((control) && (!shift) && (!strcmp(ev->keyname, "y")))
1487 _compose_seq_reset(en);
1489 _edje_emit(ed, "entry,redo,request", rp->part->name);
1490 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1492 else if ((control) && (!shift) && (!strcmp(ev->keyname, "w")))
1494 _compose_seq_reset(en);
1495 _sel_clear(en->cursor, rp->object, en);
1496 // select current word?
1497 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1499 else if (!strcmp(ev->keyname, "Tab"))
1501 _compose_seq_reset(en);
1510 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1511 info->insert = EINA_TRUE;
1512 info->change.insert.plain_length = 1;
1514 if (en->have_selection)
1516 _range_del_emit(ed, en->cursor, rp->object, en);
1517 info->merge = EINA_TRUE;
1519 info->change.insert.pos =
1520 evas_textblock_cursor_pos_get(en->cursor);
1521 info->change.insert.content = eina_stringshare_add("<tab/>");
1523 // evas_textblock_cursor_format_prepend(en->cursor, "tab");
1524 _text_filter_format_prepend(en, en->cursor, "tab");
1525 _anchors_get(en->cursor, rp->object, en);
1526 _edje_emit(ed, "entry,changed", rp->part->name);
1527 _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1528 info, _free_entry_change_info);
1530 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1532 _edje_emit(ed, "entry,key,tab", rp->part->name);
1534 else if ((!strcmp(ev->keyname, "ISO_Left_Tab")) && (multiline))
1536 _compose_seq_reset(en);
1538 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1540 else if (!strcmp(ev->keyname, "Prior") ||
1541 (!strcmp(ev->keyname, "KP_Prior") && !ev->string))
1543 _compose_seq_reset(en);
1544 if (en->select_allow)
1546 if (shift) _sel_start(en->cursor, rp->object, en);
1547 else _sel_clear(en->cursor, rp->object, en);
1549 _curs_jump_line_by(en->cursor, rp->object, en, -10);
1550 if (en->select_allow)
1552 if (shift) _sel_extend(en->cursor, rp->object, en);
1553 else _sel_clear(en->cursor, rp->object, en);
1555 _edje_emit(ed, "entry,key,pgup", rp->part->name);
1556 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1558 else if (!strcmp(ev->keyname, "Next") ||
1559 (!strcmp(ev->keyname, "KP_Next") && !ev->string))
1561 _compose_seq_reset(en);
1562 if (en->select_allow)
1564 if (shift) _sel_start(en->cursor, rp->object, en);
1565 else _sel_clear(en->cursor, rp->object, en);
1567 _curs_jump_line_by(en->cursor, rp->object, en, 10);
1568 if (en->select_allow)
1570 if (shift) _sel_extend(en->cursor, rp->object, en);
1571 else _sel_clear(en->cursor, rp->object, en);
1573 _edje_emit(ed, "entry,key,pgdn", rp->part->name);
1574 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1576 else if ((!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "KP_Enter")))
1578 _compose_seq_reset(en);
1581 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1582 info->insert = EINA_TRUE;
1583 info->change.insert.plain_length = 1;
1584 if (en->have_selection)
1586 _range_del_emit(ed, en->cursor, rp->object, en);
1587 info->merge = EINA_TRUE;
1590 info->change.insert.pos =
1591 evas_textblock_cursor_pos_get(en->cursor);
1593 evas_object_textblock_legacy_newline_get(rp->object))
1596 // evas_textblock_cursor_format_prepend(en->cursor, "br");
1597 _text_filter_format_prepend(en, en->cursor, "br");
1598 info->change.insert.content = eina_stringshare_add("<br/>");
1603 // evas_textblock_cursor_format_prepend(en->cursor, "ps");
1604 _text_filter_format_prepend(en, en->cursor, "ps");
1605 info->change.insert.content = eina_stringshare_add("<ps/>");
1607 _anchors_get(en->cursor, rp->object, en);
1608 _edje_emit(ed, "entry,changed", rp->part->name);
1609 _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1610 info, _free_entry_change_info);
1611 _edje_emit(ed, "cursor,changed", rp->part->name);
1612 cursor_changed = EINA_TRUE;
1613 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1615 _edje_emit(ed, "entry,key,enter", rp->part->name);
1619 char *compres = NULL, *string = (char *)ev->string;
1620 Eina_Bool free_string = EINA_FALSE;
1621 Ecore_Compose_State state;
1625 _compose_seq_reset(en);
1626 en->seq = eina_list_append(en->seq, eina_stringshare_add(ev->key));
1627 state = ecore_compose_get(en->seq, &compres);
1628 if (state == ECORE_COMPOSE_MIDDLE) en->composing = EINA_TRUE;
1629 else en->composing = EINA_FALSE;
1630 if (!en->composing) _compose_seq_reset(en);
1635 if (_is_modifier(ev->key)) goto end;
1636 en->seq = eina_list_append(en->seq, eina_stringshare_add(ev->key));
1637 state = ecore_compose_get(en->seq, &compres);
1638 if (state == ECORE_COMPOSE_NONE) _compose_seq_reset(en);
1639 else if (state == ECORE_COMPOSE_DONE)
1641 _compose_seq_reset(en);
1645 free_string = EINA_TRUE;
1652 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1653 info->insert = EINA_TRUE;
1654 info->change.insert.plain_length = 1;
1655 info->change.insert.content = eina_stringshare_add(string);
1657 if (en->have_selection)
1659 _range_del_emit(ed, en->cursor, rp->object, en);
1660 info->merge = EINA_TRUE;
1663 info->change.insert.pos =
1664 evas_textblock_cursor_pos_get(en->cursor);
1665 // if PASSWORD_SHOW_LAST mode, appending text with password=off tag
1666 if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
1667 _edje_password_show_last)
1669 _edje_entry_hide_visible_password(en->rp);
1670 _text_filter_format_prepend(en, en->cursor, "+ password=off");
1671 _text_filter_text_prepend(en, en->cursor, string);
1672 _text_filter_format_prepend(en, en->cursor, "- password");
1675 ecore_timer_del(en->pw_timer);
1676 en->pw_timer = NULL;
1678 en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout),
1679 _password_timer_cb, en);
1682 _text_filter_text_prepend(en, en->cursor, string);
1683 _anchors_get(en->cursor, rp->object, en);
1684 _edje_emit(ed, "entry,changed", rp->part->name);
1685 _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1686 info, _free_entry_change_info);
1687 _edje_emit(ed, "cursor,changed", rp->part->name);
1688 cursor_changed = EINA_TRUE;
1689 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1691 if (free_string) free(string);
1694 if (!cursor_changed && (old_cur_pos != evas_textblock_cursor_pos_get(en->cursor)))
1695 _edje_emit(ed, "cursor,changed", rp->part->name);
1697 _edje_entry_imf_cursor_info_set(en);
1698 _edje_entry_real_part_configure(rp);
1702 _edje_key_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1705 Edje_Real_Part *rp = ed->focused_part;
1709 en = rp->entry_data;
1710 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1711 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
1714 #ifdef HAVE_ECORE_IMF
1715 if (en->imf_context)
1717 Evas_Event_Key_Up *ev = event_info;
1718 Ecore_IMF_Event_Key_Up ecore_ev;
1720 ecore_imf_evas_event_key_up_wrap(ev, &ecore_ev);
1721 if (ecore_imf_context_filter_event(en->imf_context,
1722 ECORE_IMF_EVENT_KEY_UP,
1723 (Ecore_IMF_Event *)&ecore_ev))
1732 _edje_part_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1734 Edje_Real_Part *rp = data;
1737 en = rp->entry_data;
1739 _edje_entry_imf_cursor_info_set(en);
1743 _edje_part_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1746 Edje_Real_Part *rp = data;
1747 Evas_Event_Mouse_Down *ev = event_info;
1749 Evas_Coord x, y, w, h;
1750 // Eina_Bool multiline;
1751 Evas_Textblock_Cursor *tc = NULL;
1752 Eina_Bool dosel = EINA_FALSE;
1754 if ((!rp) || (!ev)) return;
1755 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1756 en = rp->entry_data;
1757 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1758 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
1760 if ((ev->button != 1) && (ev->button != 2)) return;
1762 #ifdef HAVE_ECORE_IMF
1763 if (en->imf_context)
1765 Ecore_IMF_Event_Mouse_Down ecore_ev;
1766 ecore_imf_evas_event_mouse_down_wrap(ev, &ecore_ev);
1767 if (ecore_imf_context_filter_event(en->imf_context,
1768 ECORE_IMF_EVENT_MOUSE_DOWN,
1769 (Ecore_IMF_Event *)&ecore_ev))
1774 _edje_entry_imf_context_reset(rp);
1776 shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
1777 en->select_mod_start = EINA_FALSE;
1778 en->select_mod_end = EINA_FALSE;
1779 if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
1781 else if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
1783 if (en->select_allow) dosel = EINA_TRUE;
1785 if (ev->button == 2) dosel = EINA_FALSE;
1788 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
1789 cx = ev->canvas.x - x;
1790 cy = ev->canvas.y - y;
1791 if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK)
1795 tc = evas_object_textblock_cursor_new(rp->object);
1796 evas_textblock_cursor_copy(en->cursor, tc);
1797 if (evas_textblock_cursor_compare(en->cursor, en->sel_start) < 0)
1798 evas_textblock_cursor_line_char_first(en->cursor);
1800 evas_textblock_cursor_line_char_last(en->cursor);
1801 _sel_extend(en->cursor, rp->object, en);
1805 en->have_selection = EINA_FALSE;
1806 en->selecting = EINA_FALSE;
1807 _sel_clear(en->cursor, rp->object, en);
1808 tc = evas_object_textblock_cursor_new(rp->object);
1809 evas_textblock_cursor_copy(en->cursor, tc);
1810 evas_textblock_cursor_line_char_first(en->cursor);
1811 _sel_start(en->cursor, rp->object, en);
1812 evas_textblock_cursor_line_char_last(en->cursor);
1813 _sel_extend(en->cursor, rp->object, en);
1817 else if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1821 tc = evas_object_textblock_cursor_new(rp->object);
1822 evas_textblock_cursor_copy(en->cursor, tc);
1823 if (evas_textblock_cursor_compare(en->cursor, en->sel_start) < 0)
1824 evas_textblock_cursor_word_start(en->cursor);
1827 evas_textblock_cursor_word_end(en->cursor);
1828 evas_textblock_cursor_char_next(en->cursor);
1830 _sel_extend(en->cursor, rp->object, en);
1834 en->have_selection = EINA_FALSE;
1835 en->selecting = EINA_FALSE;
1836 _sel_clear(en->cursor, rp->object, en);
1837 tc = evas_object_textblock_cursor_new(rp->object);
1838 evas_textblock_cursor_copy(en->cursor, tc);
1839 evas_textblock_cursor_word_start(en->cursor);
1840 _sel_start(en->cursor, rp->object, en);
1841 evas_textblock_cursor_word_end(en->cursor);
1842 evas_textblock_cursor_char_next(en->cursor);
1843 _sel_extend(en->cursor, rp->object, en);
1848 tc = evas_object_textblock_cursor_new(rp->object);
1849 evas_textblock_cursor_copy(en->cursor, tc);
1850 // multiline = rp->part->multiline;
1851 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
1852 cx = ev->canvas.x - x;
1853 cy = ev->canvas.y - y;
1854 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
1856 Evas_Coord lx, ly, lw, lh;
1859 line = evas_textblock_cursor_line_coord_set(en->cursor, cy);
1862 if (rp->part->multiline)
1863 _curs_end(en->cursor, rp->object, en);
1866 evas_textblock_cursor_paragraph_first(en->cursor);
1867 evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
1868 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
1869 _curs_end(en->cursor, rp->object, en);
1876 lnum = evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
1879 _curs_lin_start(en->cursor, rp->object, en);
1884 _curs_lin_start(en->cursor, rp->object, en);
1886 _curs_lin_end(en->cursor, rp->object, en);
1892 if ((en->have_selection) &&
1893 (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT))
1896 _sel_extend(en->cursor, rp->object, en);
1899 Eina_List *first, *last;
1903 last = eina_list_last(en->sel);
1906 Evas_Textblock_Rectangle *r1, *r2;
1907 Evas_Coord d, d1, d2;
1913 d = (r1->y + (r1->h / 2)) - cy;
1915 d = r2->x + r2->w - 1 - cx;
1917 d = (r2->y + (r2->h / 2)) - cy;
1919 sc = rp->edje->scale;
1920 if (sc == ZERO) sc = _edje_scale;
1921 d = (Evas_Coord)MUL(FROM_INT(20), sc); // FIXME: maxing number!
1927 en->select_mod_start = EINA_TRUE;
1928 en->selecting = EINA_TRUE;
1935 en->select_mod_end = EINA_TRUE;
1936 en->selecting = EINA_TRUE;
1944 if ((en->have_selection) && (shift))
1945 _sel_extend(en->cursor, rp->object, en);
1948 en->selecting = EINA_TRUE;
1949 _sel_clear(en->cursor, rp->object, en);
1950 if (en->select_allow)
1952 _sel_start(en->cursor, rp->object, en);
1958 if (evas_textblock_cursor_compare(tc, en->cursor))
1960 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
1961 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1963 evas_textblock_cursor_free(tc);
1965 _edje_entry_imf_cursor_info_set(en);
1967 _edje_entry_real_part_configure(rp);
1968 if (ev->button == 2)
1970 _edje_emit(rp->edje, "entry,paste,request", rp->part->name);
1971 _edje_emit(rp->edje, "entry,paste,request,1", rp->part->name);
1976 _edje_part_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1979 Edje_Real_Part *rp = data;
1980 Evas_Event_Mouse_Up *ev = event_info;
1982 Evas_Coord x, y, w, h;
1983 Evas_Textblock_Cursor *tc;
1984 if ((!ev) || (ev->button != 1)) return;
1986 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1987 if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK) return;
1988 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) return;
1989 en = rp->entry_data;
1990 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1991 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
1994 #ifdef HAVE_ECORE_IMF
1995 if (en->imf_context)
1997 Ecore_IMF_Event_Mouse_Up ecore_ev;
1998 ecore_imf_evas_event_mouse_up_wrap(ev, &ecore_ev);
1999 if (ecore_imf_context_filter_event(en->imf_context,
2000 ECORE_IMF_EVENT_MOUSE_UP,
2001 (Ecore_IMF_Event *)&ecore_ev))
2006 _edje_entry_imf_context_reset(rp);
2008 tc = evas_object_textblock_cursor_new(rp->object);
2009 evas_textblock_cursor_copy(en->cursor, tc);
2010 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2011 cx = ev->canvas.x - x;
2012 cy = ev->canvas.y - y;
2013 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
2015 Evas_Coord lx, ly, lw, lh;
2018 line = evas_textblock_cursor_line_coord_set(en->cursor, cy);
2021 if (rp->part->multiline)
2022 _curs_end(en->cursor, rp->object, en);
2025 evas_textblock_cursor_paragraph_first(en->cursor);
2026 evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2027 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
2028 _curs_end(en->cursor, rp->object, en);
2035 lnum = evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2038 _curs_lin_start(en->cursor, rp->object, en);
2043 _curs_lin_start(en->cursor, rp->object, en);
2045 _curs_lin_end(en->cursor, rp->object, en);
2049 if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
2051 if (en->select_allow)
2055 if (en->select_mod_end)
2056 _sel_extend(en->cursor, rp->object, en);
2057 else if (en->select_mod_start)
2058 _sel_preextend(en->cursor, rp->object, en);
2061 _sel_extend(en->cursor, rp->object, en);
2062 //evas_textblock_cursor_copy(en->cursor, en->sel_end);
2066 evas_textblock_cursor_copy(en->cursor, en->sel_end);
2069 if (en->have_selection)
2070 en->had_sel = EINA_TRUE;
2071 en->selecting = EINA_FALSE;
2073 if (evas_textblock_cursor_compare(tc, en->cursor))
2075 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2076 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
2078 evas_textblock_cursor_free(tc);
2080 _edje_entry_imf_cursor_info_set(en);
2081 _edje_entry_real_part_configure(rp);
2085 _edje_part_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2088 Edje_Real_Part *rp = data;
2089 Evas_Event_Mouse_Move *ev = event_info;
2091 Evas_Coord x, y, w, h;
2092 Evas_Textblock_Cursor *tc;
2093 if (!rp || (!ev)) return;
2094 en = rp->entry_data;
2095 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2096 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2099 #ifdef HAVE_ECORE_IMF
2100 if (en->imf_context)
2102 Ecore_IMF_Event_Mouse_Move ecore_ev;
2103 ecore_imf_evas_event_mouse_move_wrap(ev, &ecore_ev);
2104 if (ecore_imf_context_filter_event(en->imf_context,
2105 ECORE_IMF_EVENT_MOUSE_MOVE,
2106 (Ecore_IMF_Event *)&ecore_ev))
2113 tc = evas_object_textblock_cursor_new(rp->object);
2114 evas_textblock_cursor_copy(en->cursor, tc);
2115 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2116 cx = ev->cur.canvas.x - x;
2117 cy = ev->cur.canvas.y - y;
2118 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
2120 Evas_Coord lx, ly, lw, lh;
2122 if (evas_textblock_cursor_line_coord_set(en->cursor, cy) < 0)
2124 if (rp->part->multiline)
2125 _curs_end(en->cursor, rp->object, en);
2128 evas_textblock_cursor_paragraph_first(en->cursor);
2129 evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2130 if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
2131 _curs_end(en->cursor, rp->object, en);
2136 evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2138 _curs_lin_start(en->cursor, rp->object, en);
2140 _curs_lin_end(en->cursor, rp->object, en);
2143 if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
2145 if (en->select_allow)
2149 if (en->select_mod_end)
2150 _sel_extend(en->cursor, rp->object, en);
2151 else if (en->select_mod_start)
2152 _sel_preextend(en->cursor, rp->object, en);
2155 _sel_extend(en->cursor, rp->object, en);
2160 _sel_extend(en->cursor, rp->object, en);
2162 if (en->select_allow)
2164 if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) != 0)
2165 _sel_enable(en->cursor, rp->object, en);
2166 if (en->have_selection)
2167 _sel_update(en->cursor, rp->object, en);
2169 if (evas_textblock_cursor_compare(tc, en->cursor))
2171 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2172 _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
2174 evas_textblock_cursor_free(tc);
2176 _edje_entry_imf_context_reset(rp);
2177 _edje_entry_imf_cursor_info_set(en);
2179 _edje_entry_real_part_configure(rp);
2184 _evas_focus_in_cb(void *data, Evas *e, __UNUSED__ void *event_info)
2186 Edje *ed = (Edje *)data;
2189 if (evas_focus_get(e) == ed->obj)
2191 _edje_focus_in_cb(data, NULL, NULL, NULL);
2196 _evas_focus_out_cb(void *data, Evas *e, __UNUSED__ void *event_info)
2198 Edje *ed = (Edje *)data;
2201 if (evas_focus_get(e) == ed->obj)
2203 _edje_focus_out_cb(data, NULL, NULL, NULL);
2207 /***************************************************************/
2209 _edje_entry_init(Edje *ed)
2211 if (!ed->has_entries)
2213 if (ed->entries_inited)
2215 ed->entries_inited = EINA_TRUE;
2217 evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb, ed);
2218 evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb, ed);
2219 evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb, ed);
2220 evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_UP, _edje_key_up_cb, ed);
2221 evas_event_callback_add(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _evas_focus_in_cb, ed);
2222 evas_event_callback_add(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _evas_focus_out_cb, ed);
2226 _edje_entry_shutdown(Edje *ed)
2228 if ((!ed) || (!ed->has_entries))
2230 if (!ed->entries_inited)
2232 ed->entries_inited = EINA_FALSE;
2234 evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb);
2235 evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb);
2236 evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb);
2237 evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_UP, _edje_key_up_cb);
2238 if (evas_event_callback_del_full(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _evas_focus_in_cb, ed) != ed)
2239 ERR("could not unregister EVAS_CALLBACK_FOCUS_IN");
2240 if (evas_event_callback_del_full(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _evas_focus_out_cb, ed) != ed)
2241 ERR("could not unregister EVAS_CALLBACK_FOCUS_OUT");
2245 _edje_entry_real_part_init(Edje_Real_Part *rp)
2248 #ifdef HAVE_ECORE_IMF
2250 const Ecore_IMF_Context_Info *ctx_info;
2253 en = calloc(1, sizeof(Entry));
2255 rp->entry_data = en;
2258 evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOVE, _edje_part_move_cb, rp);
2260 evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_DOWN, _edje_part_mouse_down_cb, rp);
2261 evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_UP, _edje_part_mouse_up_cb, rp);
2262 evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_MOVE, _edje_part_mouse_move_cb, rp);
2264 if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
2265 en->select_allow = EINA_TRUE;
2267 if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
2269 Edje_Part_Description_Text *txt;
2271 txt = (Edje_Part_Description_Text *)rp->chosen_description;
2273 en->select_allow = EINA_FALSE;
2274 if (txt && edje_string_get(&txt->text.repch))
2275 evas_object_textblock_replace_char_set(rp->object, edje_string_get(&txt->text.repch));
2277 evas_object_textblock_replace_char_set(rp->object, "*");
2280 en->cursor_bg = edje_object_add(rp->edje->base.evas);
2281 edje_object_file_set(en->cursor_bg, rp->edje->path, rp->part->source3);
2282 evas_object_smart_member_add(en->cursor_bg, rp->edje->obj);
2283 evas_object_stack_below(en->cursor_bg, rp->object);
2284 evas_object_clip_set(en->cursor_bg, evas_object_clip_get(rp->object));
2285 evas_object_pass_events_set(en->cursor_bg, EINA_TRUE);
2286 _edje_subobj_register(en->rp->edje, en->cursor_bg);
2288 en->cursor_fg = edje_object_add(rp->edje->base.evas);
2289 edje_object_file_set(en->cursor_fg, rp->edje->path, rp->part->source4);
2290 evas_object_smart_member_add(en->cursor_fg, rp->edje->obj);
2291 evas_object_stack_above(en->cursor_fg, rp->object);
2292 evas_object_clip_set(en->cursor_fg, evas_object_clip_get(rp->object));
2293 evas_object_pass_events_set(en->cursor_fg, EINA_TRUE);
2294 _edje_subobj_register(en->rp->edje, en->cursor_fg);
2296 evas_object_textblock_legacy_newline_set(rp->object, EINA_TRUE);
2298 if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
2300 evas_object_show(en->cursor_bg);
2301 evas_object_show(en->cursor_fg);
2302 en->input_panel_enable = EINA_TRUE;
2304 #ifdef HAVE_ECORE_IMF
2307 edje_object_signal_callback_add(rp->edje->obj, "focus,part,in", rp->part->name, _edje_entry_focus_in_cb, rp);
2308 edje_object_signal_callback_add(rp->edje->obj, "focus,part,out", rp->part->name, _edje_entry_focus_out_cb, rp);
2310 ctx_id = ecore_imf_context_default_id_get();
2313 ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
2314 if (!ctx_info->canvas_type ||
2315 strcmp(ctx_info->canvas_type, "evas") == 0)
2317 en->imf_context = ecore_imf_context_add(ctx_id);
2321 ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
2324 en->imf_context = ecore_imf_context_add(ctx_id);
2329 en->imf_context = NULL;
2331 if (!en->imf_context) goto done;
2333 ecore_imf_context_client_window_set
2335 (void *)ecore_evas_window_get
2336 (ecore_evas_ecore_evas_get(rp->edje->base.evas)));
2337 ecore_imf_context_client_canvas_set(en->imf_context, rp->edje->base.evas);
2339 ecore_imf_context_retrieve_surrounding_callback_set(en->imf_context,
2340 _edje_entry_imf_retrieve_surrounding_cb, rp->edje);
2341 ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _edje_entry_imf_event_commit_cb, rp->edje);
2342 ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb, rp->edje);
2343 ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb, rp->edje);
2344 ecore_imf_context_input_mode_set(en->imf_context,
2345 rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD ?
2346 ECORE_IMF_INPUT_MODE_INVISIBLE : ECORE_IMF_INPUT_MODE_FULL);
2348 if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
2349 ecore_imf_context_input_panel_language_set(en->imf_context, ECORE_IMF_INPUT_PANEL_LANG_ALPHABET);
2352 #ifdef HAVE_ECORE_IMF
2355 en->cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(rp->object);
2359 _edje_entry_real_part_shutdown(Edje_Real_Part *rp)
2361 Entry *en = rp->entry_data;
2363 rp->entry_data = NULL;
2364 _sel_clear(en->cursor, rp->object, en);
2365 _anchors_clear(en->cursor, rp->object, en);
2366 #ifdef HAVE_ECORE_IMF
2369 evas_object_del(en->cursor_bg);
2370 evas_object_del(en->cursor_fg);
2374 ecore_timer_del(en->pw_timer);
2375 en->pw_timer = NULL;
2378 #ifdef HAVE_ECORE_IMF
2379 if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
2381 if (en->imf_context)
2383 ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _edje_entry_imf_event_commit_cb);
2384 ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb);
2385 ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb);
2387 ecore_imf_context_del(en->imf_context);
2388 en->imf_context = NULL;
2391 edje_object_signal_callback_del(rp->edje->obj, "focus,part,in", rp->part->name, _edje_entry_focus_in_cb);
2392 edje_object_signal_callback_del(rp->edje->obj, "focus,part,out", rp->part->name, _edje_entry_focus_out_cb);
2393 ecore_imf_shutdown();
2396 _compose_seq_reset(en);
2402 _edje_entry_real_part_configure(Edje_Real_Part *rp)
2404 Evas_Coord x, y, w, h, xx, yy, ww, hh;
2405 Entry *en = rp->entry_data;
2406 Evas_Textblock_Cursor_Type cur_type;
2408 switch (rp->part->cursor_mode)
2410 case EDJE_ENTRY_CURSOR_MODE_BEFORE:
2411 cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
2413 case EDJE_ENTRY_CURSOR_MODE_UNDER:
2414 /* no break for a resaon */
2416 cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
2419 _sel_update(en->cursor, rp->object, en);
2420 _anchors_update(en->cursor, rp->object, en);
2422 xx = yy = ww = hh = -1;
2423 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2424 evas_textblock_cursor_geometry_get(en->cursor, &xx, &yy, &ww, &hh, NULL, cur_type);
2429 evas_object_move(en->cursor_bg, x + xx, y + yy);
2430 evas_object_resize(en->cursor_bg, ww, hh);
2434 evas_object_move(en->cursor_fg, x + xx, y + yy);
2435 evas_object_resize(en->cursor_fg, ww, hh);
2440 _edje_entry_selection_get(Edje_Real_Part *rp)
2442 Entry *en = rp->entry_data;
2443 if (!en) return NULL;
2444 // get selection - convert to markup
2445 if ((!en->selection) && (en->have_selection))
2446 en->selection = evas_textblock_cursor_range_text_get
2447 (en->sel_start, en->sel_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
2448 return en->selection;
2452 _edje_entry_text_get(Edje_Real_Part *rp)
2454 Entry *en = rp->entry_data;
2455 if (!en) return NULL;
2456 // get text - convert to markup
2457 return evas_object_textblock_text_markup_get(rp->object);
2461 _edje_entry_text_markup_set(Edje_Real_Part *rp, const char *text)
2463 Entry *en = rp->entry_data;
2465 _edje_entry_imf_context_reset(rp);
2466 // set text as markup
2467 _sel_clear(en->cursor, rp->object, en);
2468 evas_object_textblock_text_markup_set(rp->object, text);
2469 _edje_entry_set_cursor_start(rp);
2471 _anchors_get(en->cursor, rp->object, en);
2472 _edje_emit(rp->edje, "entry,changed", rp->part->name);
2473 _edje_entry_imf_cursor_info_set(en);
2475 _edje_entry_real_part_configure(rp);
2477 /* Don't emit cursor changed cause it didn't. It's just init to 0. */
2478 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2483 _edje_entry_text_markup_append(Edje_Real_Part *rp, const char *text)
2485 Entry *en = rp->entry_data;
2486 Evas_Textblock_Cursor *end_cur;
2488 end_cur = evas_object_textblock_cursor_new(rp->object);
2489 evas_textblock_cursor_paragraph_last(end_cur);
2491 _text_filter_markup_prepend(en, end_cur, text);
2492 evas_textblock_cursor_free(end_cur);
2494 /* We are updating according to the real cursor on purpose */
2495 _anchors_get(en->cursor, rp->object, en);
2496 _edje_emit(rp->edje, "entry,changed", rp->part->name);
2498 _edje_entry_real_part_configure(rp);
2502 _edje_entry_text_markup_insert(Edje_Real_Part *rp, const char *text)
2504 Entry *en = rp->entry_data;
2506 _edje_entry_imf_context_reset(rp);
2508 // prepend markup @ cursor pos
2509 if (en->have_selection)
2510 _range_del(en->cursor, rp->object, en);
2512 // evas_object_textblock_text_markup_prepend(en->cursor, text);
2513 _text_filter_markup_prepend(en, en->cursor, text);
2514 _anchors_get(en->cursor, rp->object, en);
2515 _edje_emit(rp->edje, "entry,changed", rp->part->name);
2516 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2518 _edje_entry_imf_cursor_info_set(en);
2519 _edje_entry_real_part_configure(rp);
2523 _edje_entry_set_cursor_start(Edje_Real_Part *rp)
2525 Entry *en = rp->entry_data;
2527 _curs_start(en->cursor, rp->object, en);
2529 _edje_entry_imf_cursor_info_set(en);
2533 _edje_entry_set_cursor_end(Edje_Real_Part *rp)
2535 Entry *en = rp->entry_data;
2537 _curs_end(en->cursor, rp->object, en);
2539 _edje_entry_imf_cursor_info_set(en);
2543 _edje_entry_select_none(Edje_Real_Part *rp)
2545 Entry *en = rp->entry_data;
2547 _sel_clear(en->cursor, rp->object, en);
2551 _edje_entry_select_all(Edje_Real_Part *rp)
2553 Entry *en = rp->entry_data;
2556 _edje_entry_imf_context_reset(rp);
2558 _sel_clear(en->cursor, rp->object, en);
2559 _curs_start(en->cursor, rp->object, en);
2560 _sel_enable(en->cursor, rp->object, en);
2561 _sel_start(en->cursor, rp->object, en);
2562 _curs_end(en->cursor, rp->object, en);
2563 _sel_extend(en->cursor, rp->object, en);
2565 _edje_entry_imf_cursor_info_set(en);
2566 _edje_entry_real_part_configure(rp);
2570 _edje_entry_select_begin(Edje_Real_Part *rp)
2572 Entry *en = rp->entry_data;
2575 _edje_entry_imf_context_reset(rp);
2577 _sel_clear(en->cursor, rp->object, en);
2578 _sel_enable(en->cursor, rp->object, en);
2579 _sel_start(en->cursor, rp->object, en);
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_select_extend(Edje_Real_Part *rp)
2590 Entry *en = rp->entry_data;
2592 _edje_entry_imf_context_reset(rp);
2593 _sel_extend(en->cursor, rp->object, en);
2595 _edje_entry_imf_cursor_info_set(en);
2597 _edje_entry_real_part_configure(rp);
2601 _edje_entry_anchor_geometry_get(Edje_Real_Part *rp, const char *anchor)
2603 Entry *en = rp->entry_data;
2607 if (!en) return NULL;
2608 EINA_LIST_FOREACH(en->anchors, l, an)
2610 if (an->item) continue;
2611 if (!strcmp(anchor, an->name))
2618 _edje_entry_anchors_list(Edje_Real_Part *rp)
2620 Entry *en = rp->entry_data;
2621 Eina_List *l, *anchors = NULL;
2624 if (!en) return NULL;
2625 if (!en->anchorlist)
2627 EINA_LIST_FOREACH(en->anchors, l, an)
2629 const char *n = an->name;
2630 if (an->item) continue;
2632 anchors = eina_list_append(anchors, strdup(n));
2634 en->anchorlist = anchors;
2636 return en->anchorlist;
2640 _edje_entry_item_geometry_get(Edje_Real_Part *rp, const char *item, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
2642 Entry *en = rp->entry_data;
2646 if (!en) return EINA_FALSE;
2647 EINA_LIST_FOREACH(en->anchors, l, an)
2649 if (an->item) continue;
2650 if (!strcmp(item, an->name))
2652 evas_textblock_cursor_format_item_geometry_get(an->start, cx, cy, cw, ch);
2660 _edje_entry_items_list(Edje_Real_Part *rp)
2662 Entry *en = rp->entry_data;
2663 Eina_List *l, *items = NULL;
2666 if (!en) return NULL;
2669 EINA_LIST_FOREACH(en->anchors, l, an)
2671 const char *n = an->name;
2672 if (an->item) continue;
2674 items = eina_list_append(items, strdup(n));
2676 en->itemlist = items;
2678 return en->itemlist;
2682 _edje_entry_cursor_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
2684 Evas_Coord x, y, w, h, xx, yy, ww, hh;
2685 Entry *en = rp->entry_data;
2686 Evas_Textblock_Cursor_Type cur_type;
2688 switch (rp->part->cursor_mode)
2690 case EDJE_ENTRY_CURSOR_MODE_BEFORE:
2691 cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
2693 case EDJE_ENTRY_CURSOR_MODE_UNDER:
2694 /* no break for a resaon */
2696 cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
2700 xx = yy = ww = hh = -1;
2701 evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2702 evas_textblock_cursor_geometry_get(en->cursor, &xx, &yy, &ww, &hh, NULL, cur_type);
2704 if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
2705 edje_object_size_min_restricted_calc(en->cursor_fg, &ww, NULL, ww, 0);
2707 if (cx) *cx = x + xx;
2708 if (cy) *cy = y + yy;
2714 _edje_entry_user_insert(Edje_Real_Part *rp, const char *text)
2716 Entry *en = rp->entry_data;
2717 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
2718 info->insert = EINA_TRUE;
2719 info->change.insert.plain_length = 1;
2720 info->change.insert.content = eina_stringshare_add(text);
2723 tmp = evas_textblock_text_markup_to_utf8(rp->object,
2724 info->change.insert.content);
2725 info->change.insert.plain_length = eina_unicode_utf8_get_len(tmp);
2729 if (en->have_selection)
2731 _range_del_emit(rp->edje, en->cursor, rp->object, en);
2732 info->merge = EINA_TRUE;
2734 info->change.insert.pos = evas_textblock_cursor_pos_get(en->cursor);
2735 _text_filter_markup_prepend(en, en->cursor, text);
2736 _anchors_get(en->cursor, rp->object, en);
2737 _edje_emit(rp->edje, "entry,changed", rp->part->name);
2738 _edje_emit_full(rp->edje, "entry,changed,user", rp->part->name,
2739 info, _free_entry_change_info);
2740 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2742 _edje_entry_imf_cursor_info_set(en);
2743 _edje_entry_real_part_configure(rp);
2747 _edje_entry_select_allow_set(Edje_Real_Part *rp, Eina_Bool allow)
2749 Entry *en = rp->entry_data;
2750 if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
2752 en->select_allow = allow;
2756 _edje_entry_select_allow_get(const Edje_Real_Part *rp)
2758 const Entry *en = rp->entry_data;
2759 return en->select_allow;
2763 _edje_entry_select_abort(Edje_Real_Part *rp)
2765 Entry *en = rp->entry_data;
2768 en->selecting = EINA_FALSE;
2770 _edje_entry_imf_context_reset(rp);
2771 _edje_entry_imf_cursor_info_set(en);
2772 _edje_entry_real_part_configure(rp);
2777 _edje_entry_imf_context_get(Edje_Real_Part *rp)
2779 Entry *en = rp->entry_data;
2780 if (!en) return NULL;
2782 #ifdef HAVE_ECORE_IMF
2783 return en->imf_context;
2790 _edje_entry_autocapital_type_set(Edje_Real_Part *rp, Edje_Text_Autocapital_Type autocapital_type)
2792 Entry *en = rp->entry_data;
2795 if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
2796 autocapital_type = EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
2798 #ifdef HAVE_ECORE_IMF
2799 if (en->imf_context)
2800 ecore_imf_context_autocapital_type_set(en->imf_context, autocapital_type);
2804 Edje_Text_Autocapital_Type
2805 _edje_entry_autocapital_type_get(Edje_Real_Part *rp)
2807 Entry *en = rp->entry_data;
2808 if (!en) return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
2810 #ifdef HAVE_ECORE_IMF
2811 if (en->imf_context)
2812 return ecore_imf_context_autocapital_type_get(en->imf_context);
2815 return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
2819 _edje_entry_prediction_allow_set(Edje_Real_Part *rp, Eina_Bool prediction)
2821 Entry *en = rp->entry_data;
2824 en->prediction_allow = prediction;
2825 #ifdef HAVE_ECORE_IMF
2826 if (en->imf_context)
2827 ecore_imf_context_prediction_allow_set(en->imf_context, prediction);
2832 _edje_entry_prediction_allow_get(Edje_Real_Part *rp)
2834 Entry *en = rp->entry_data;
2835 if (!en) return EINA_FALSE;
2837 return en->prediction_allow;
2841 _edje_entry_input_panel_enabled_set(Edje_Real_Part *rp, Eina_Bool enabled)
2843 Entry *en = rp->entry_data;
2846 en->input_panel_enable = enabled;
2847 #ifdef HAVE_ECORE_IMF
2848 if (en->imf_context)
2849 ecore_imf_context_input_panel_enabled_set(en->imf_context, enabled);
2854 _edje_entry_input_panel_enabled_get(Edje_Real_Part *rp)
2856 Entry *en = rp->entry_data;
2857 if (!en) return EINA_FALSE;
2859 return en->input_panel_enable;
2863 _edje_entry_input_panel_show(Edje_Real_Part *rp)
2865 Entry *en = rp->entry_data;
2868 #ifdef HAVE_ECORE_IMF
2869 if (en->imf_context)
2870 ecore_imf_context_input_panel_show(en->imf_context);
2875 _edje_entry_input_panel_hide(Edje_Real_Part *rp)
2877 Entry *en = rp->entry_data;
2880 #ifdef HAVE_ECORE_IMF
2881 if (en->imf_context)
2882 ecore_imf_context_input_panel_hide(en->imf_context);
2887 _edje_entry_input_panel_language_set(Edje_Real_Part *rp, Edje_Input_Panel_Lang lang)
2889 Entry *en = rp->entry_data;
2892 en->input_panel_lang = lang;
2893 #ifdef HAVE_ECORE_IMF
2894 if (en->imf_context)
2895 ecore_imf_context_input_panel_language_set(en->imf_context, lang);
2899 Edje_Input_Panel_Lang
2900 _edje_entry_input_panel_language_get(Edje_Real_Part *rp)
2902 Entry *en = rp->entry_data;
2903 if (!en) return EDJE_INPUT_PANEL_LANG_AUTOMATIC;
2905 return en->input_panel_lang;
2908 #ifdef HAVE_ECORE_IMF
2910 _edje_entry_input_panel_imdata_set(Edje_Real_Part *rp, const void *data, int len)
2913 _edje_entry_input_panel_imdata_set(Edje_Real_Part *rp, const void *data __UNUSED__, int len __UNUSED__)
2916 Entry *en = rp->entry_data;
2918 #ifdef HAVE_ECORE_IMF
2919 if (en->imf_context)
2920 ecore_imf_context_input_panel_imdata_set(en->imf_context, data, len);
2924 #ifdef HAVE_ECORE_IMF
2926 _edje_entry_input_panel_imdata_get(Edje_Real_Part *rp, void *data, int *len)
2929 _edje_entry_input_panel_imdata_get(Edje_Real_Part *rp, void *data __UNUSED__, int *len __UNUSED__)
2932 Entry *en = rp->entry_data;
2934 #ifdef HAVE_ECORE_IMF
2935 if (en->imf_context)
2936 ecore_imf_context_input_panel_imdata_get(en->imf_context, data, len);
2940 #ifdef HAVE_ECORE_IMF
2942 _edje_entry_input_panel_return_key_type_set(Edje_Real_Part *rp, Edje_Input_Panel_Return_Key_Type return_key_type)
2945 _edje_entry_input_panel_return_key_type_set(Edje_Real_Part *rp, Edje_Input_Panel_Return_Key_Type return_key_type __UNUSED__)
2948 Entry *en = rp->entry_data;
2950 #ifdef HAVE_ECORE_IMF
2951 if (en->imf_context)
2952 ecore_imf_context_input_panel_return_key_type_set(en->imf_context, return_key_type);
2956 Edje_Input_Panel_Return_Key_Type
2957 _edje_entry_input_panel_return_key_type_get(Edje_Real_Part *rp)
2959 Entry *en = rp->entry_data;
2960 if (!en) return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
2961 #ifdef HAVE_ECORE_IMF
2962 if (en->imf_context)
2963 return ecore_imf_context_input_panel_return_key_type_get(en->imf_context);
2965 return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
2968 #ifdef HAVE_ECORE_IMF
2970 _edje_entry_input_panel_return_key_disabled_set(Edje_Real_Part *rp, Eina_Bool disabled)
2973 _edje_entry_input_panel_return_key_disabled_set(Edje_Real_Part *rp, Eina_Bool disabled __UNUSED__)
2976 Entry *en = rp->entry_data;
2978 #ifdef HAVE_ECORE_IMF
2979 if (en->imf_context)
2980 ecore_imf_context_input_panel_return_key_disabled_set(en->imf_context, disabled);
2985 _edje_entry_input_panel_return_key_disabled_get(Edje_Real_Part *rp)
2987 Entry *en = rp->entry_data;
2988 if (!en) return EINA_FALSE;
2989 #ifdef HAVE_ECORE_IMF
2990 if (en->imf_context)
2991 return ecore_imf_context_input_panel_return_key_disabled_get(en->imf_context);
2996 static Evas_Textblock_Cursor *
2997 _cursor_get(Edje_Real_Part *rp, Edje_Cursor cur)
2999 Entry *en = rp->entry_data;
3000 if (!en) return NULL;
3004 case EDJE_CURSOR_MAIN:
3006 case EDJE_CURSOR_SELECTION_BEGIN:
3007 return en->sel_start;
3008 case EDJE_CURSOR_SELECTION_END:
3010 case EDJE_CURSOR_PREEDIT_START:
3011 if (!en->preedit_start)
3012 en->preedit_start = evas_object_textblock_cursor_new(rp->object);
3013 return en->preedit_start;
3014 case EDJE_CURSOR_PREEDIT_END:
3015 if (!en->preedit_end)
3016 en->preedit_end = evas_object_textblock_cursor_new(rp->object);
3017 return en->preedit_end;
3018 case EDJE_CURSOR_USER:
3019 if (!en->cursor_user)
3020 en->cursor_user = evas_object_textblock_cursor_new(rp->object);
3021 return en->cursor_user;
3022 case EDJE_CURSOR_USER_EXTRA:
3023 if (!en->cursor_user_extra)
3024 en->cursor_user_extra = evas_object_textblock_cursor_new(rp->object);
3025 return en->cursor_user_extra;
3033 _edje_entry_cursor_next(Edje_Real_Part *rp, Edje_Cursor cur)
3035 Entry *en = rp->entry_data;
3036 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3037 if (!c) return EINA_FALSE;
3039 _edje_entry_imf_context_reset(rp);
3041 if (!evas_textblock_cursor_char_next(c))
3045 _sel_update(c, rp->object, rp->entry_data);
3046 _edje_entry_imf_cursor_info_set(en);
3048 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3049 _edje_entry_real_part_configure(rp);
3054 _edje_entry_cursor_prev(Edje_Real_Part *rp, Edje_Cursor cur)
3056 Entry *en = rp->entry_data;
3057 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3058 if (!c) return EINA_FALSE;
3060 _edje_entry_imf_context_reset(rp);
3062 if (!evas_textblock_cursor_char_prev(c))
3064 if (evas_textblock_cursor_paragraph_prev(c)) goto ok;
3065 else return EINA_FALSE;
3068 _sel_update(c, rp->object, rp->entry_data);
3070 _edje_entry_imf_cursor_info_set(en);
3072 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3073 _edje_entry_real_part_configure(rp);
3078 _edje_entry_cursor_up(Edje_Real_Part *rp, Edje_Cursor cur)
3080 Entry *en = rp->entry_data;
3081 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3082 Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
3084 if (!c) return EINA_FALSE;
3086 _edje_entry_imf_context_reset(rp);
3088 ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL);
3090 if (ln < 0) return EINA_FALSE;
3091 if (!evas_object_textblock_line_number_geometry_get(rp->object, ln,
3092 &lx, &ly, &lw, &lh))
3094 evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
3095 if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
3097 if (cx < (lx + (lw / 2)))
3098 evas_textblock_cursor_line_char_last(c);
3100 evas_textblock_cursor_line_char_last(c);
3102 _sel_update(c, rp->object, rp->entry_data);
3104 _edje_entry_imf_cursor_info_set(en);
3106 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3107 _edje_entry_real_part_configure(rp);
3112 _edje_entry_cursor_down(Edje_Real_Part *rp, Edje_Cursor cur)
3114 Entry *en = rp->entry_data;
3115 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3116 Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
3118 if (!c) return EINA_FALSE;
3120 _edje_entry_imf_context_reset(rp);
3122 ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL);
3124 if (!evas_object_textblock_line_number_geometry_get(rp->object, ln,
3125 &lx, &ly, &lw, &lh))
3127 evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
3128 if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
3130 if (cx < (lx + (lw / 2)))
3131 evas_textblock_cursor_line_char_last(c);
3133 evas_textblock_cursor_line_char_last(c);
3135 _sel_update(c, rp->object, rp->entry_data);
3137 _edje_entry_imf_cursor_info_set(en);
3138 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3139 _edje_entry_real_part_configure(rp);
3144 _edje_entry_cursor_begin(Edje_Real_Part *rp, Edje_Cursor cur)
3146 Entry *en = rp->entry_data;
3147 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3150 _edje_entry_imf_context_reset(rp);
3152 evas_textblock_cursor_paragraph_first(c);
3153 _sel_update(c, rp->object, rp->entry_data);
3155 _edje_entry_imf_cursor_info_set(en);
3156 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3157 _edje_entry_real_part_configure(rp);
3161 _edje_entry_cursor_end(Edje_Real_Part *rp, Edje_Cursor cur)
3163 Entry *en = rp->entry_data;
3164 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3167 _edje_entry_imf_context_reset(rp);
3169 _curs_end(c, rp->object, rp->entry_data);
3170 _sel_update(c, rp->object, rp->entry_data);
3172 _edje_entry_imf_cursor_info_set(en);
3174 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3175 _edje_entry_real_part_configure(rp);
3179 _edje_entry_cursor_copy(Edje_Real_Part *rp, Edje_Cursor cur, Edje_Cursor dst)
3181 Entry *en = rp->entry_data;
3182 Evas_Textblock_Cursor *c;
3183 Evas_Textblock_Cursor *d;
3185 c = _cursor_get(rp, cur);
3187 d = _cursor_get(rp, dst);
3189 evas_textblock_cursor_copy(c, d);
3190 _sel_update(c, rp->object, rp->entry_data);
3192 _edje_entry_imf_context_reset(rp);
3193 _edje_entry_imf_cursor_info_set(en);
3194 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3195 _edje_entry_real_part_configure(rp);
3199 _edje_entry_cursor_line_begin(Edje_Real_Part *rp, Edje_Cursor cur)
3201 Entry *en = rp->entry_data;
3202 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3204 _edje_entry_imf_context_reset(rp);
3206 evas_textblock_cursor_line_char_first(c);
3207 _sel_update(c, rp->object, rp->entry_data);
3209 _edje_entry_imf_cursor_info_set(en);
3211 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3212 _edje_entry_real_part_configure(rp);
3216 _edje_entry_cursor_line_end(Edje_Real_Part *rp, Edje_Cursor cur)
3218 Entry *en = rp->entry_data;
3219 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3221 _edje_entry_imf_context_reset(rp);
3222 evas_textblock_cursor_line_char_last(c);
3223 _sel_update(c, rp->object, rp->entry_data);
3225 _edje_entry_imf_cursor_info_set(en);
3226 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3227 _edje_entry_real_part_configure(rp);
3231 _edje_entry_cursor_coord_set(Edje_Real_Part *rp, Edje_Cursor cur,
3232 Evas_Coord x, Evas_Coord y)
3234 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3235 if (!c) return EINA_FALSE;
3236 return evas_textblock_cursor_char_coord_set(c, x, y);
3240 _edje_entry_cursor_is_format_get(Edje_Real_Part *rp, Edje_Cursor cur)
3242 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3243 if (!c) return EINA_FALSE;
3244 if (evas_textblock_cursor_is_format(c)) return EINA_TRUE;
3249 _edje_entry_cursor_is_visible_format_get(Edje_Real_Part *rp, Edje_Cursor cur)
3251 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3252 if (!c) return EINA_FALSE;
3253 return evas_textblock_cursor_format_is_visible_get(c);
3257 _edje_entry_cursor_content_get(Edje_Real_Part *rp, Edje_Cursor cur)
3259 static char *s = NULL;
3260 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3262 if (!c) return NULL;
3269 s = evas_textblock_cursor_content_get(c);
3274 _edje_entry_cursor_pos_set(Edje_Real_Part *rp, Edje_Cursor cur, int pos)
3276 Entry *en = rp->entry_data;
3277 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3279 /* Abort if cursor position didn't really change */
3280 if (evas_textblock_cursor_pos_get(c) == pos)
3283 _edje_entry_imf_context_reset(rp);
3284 evas_textblock_cursor_pos_set(c, pos);
3285 _sel_update(c, rp->object, rp->entry_data);
3287 _edje_entry_imf_cursor_info_set(en);
3288 _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3289 _edje_entry_real_part_configure(rp);
3293 _edje_entry_cursor_pos_get(Edje_Real_Part *rp, Edje_Cursor cur)
3295 Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
3297 return evas_textblock_cursor_pos_get(c);
3301 _edje_entry_input_panel_layout_set(Edje_Real_Part *rp, Edje_Input_Panel_Layout layout)
3303 Entry *en = rp->entry_data;
3305 #ifdef HAVE_ECORE_IMF
3306 if (en->imf_context)
3307 ecore_imf_context_input_panel_layout_set(en->imf_context, layout);
3313 Edje_Input_Panel_Layout
3314 _edje_entry_input_panel_layout_get(Edje_Real_Part *rp)
3316 Entry *en = rp->entry_data;
3317 if (!en) return EDJE_INPUT_PANEL_LAYOUT_INVALID;
3318 #ifdef HAVE_ECORE_IMF
3319 if (en->imf_context)
3320 return ecore_imf_context_input_panel_layout_get(en->imf_context);
3323 return EDJE_INPUT_PANEL_LAYOUT_INVALID;
3327 _edje_entry_imf_context_reset(Edje_Real_Part *rp)
3329 Entry *en = rp->entry_data;
3331 #ifdef HAVE_ECORE_IMF
3332 if (en->imf_context)
3333 ecore_imf_context_reset(en->imf_context);
3338 _edje_entry_imf_cursor_info_set(Entry *en)
3340 #ifdef HAVE_ECORE_IMF
3341 Evas_Coord cx, cy, cw, ch;
3342 if (!en || !en->rp || !en->imf_context) return;
3344 _edje_entry_cursor_geometry_get(en->rp, &cx, &cy, &cw, &ch);
3346 ecore_imf_context_cursor_position_set(en->imf_context,
3347 evas_textblock_cursor_pos_get(en->cursor));
3348 ecore_imf_context_cursor_location_set(en->imf_context, cx, cy, cw, ch);
3354 #ifdef HAVE_ECORE_IMF
3356 _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, char **text, int *cursor_pos)
3359 Edje_Real_Part *rp = ed->focused_part;
3363 if (!rp) return EINA_FALSE;
3364 en = rp->entry_data;
3365 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3366 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
3371 str = _edje_entry_text_get(rp);
3372 *text = str ? strdup(str) : strdup("");
3376 *cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
3382 _edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info)
3385 Edje_Real_Part *rp = ed->focused_part;
3387 char *commit_str = event_info;
3392 en = rp->entry_data;
3393 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3394 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
3397 if (en->have_selection)
3399 if (strcmp(commit_str, ""))
3401 /* delete selected characters */
3402 _range_del_emit(ed, en->cursor, rp->object, en);
3403 _sel_clear(en->cursor, rp->object, en);
3407 start_pos = evas_textblock_cursor_pos_get(en->cursor);
3409 #ifdef HAVE_ECORE_IMF
3410 /* delete preedit characters */
3415 if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
3416 _edje_password_show_last)
3417 _edje_entry_hide_visible_password(en->rp);
3418 if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
3419 _edje_password_show_last && (!en->preedit_start))
3421 _text_filter_format_prepend(en, en->cursor, "+ password=off");
3422 _text_filter_text_prepend(en, en->cursor, commit_str);
3423 _text_filter_format_prepend(en, en->cursor, "- password");
3427 ecore_timer_del(en->pw_timer);
3428 en->pw_timer = NULL;
3430 en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout),
3431 _password_timer_cb, en);
3434 _text_filter_text_prepend(en, en->cursor, commit_str);
3437 _edje_entry_imf_cursor_info_set(en);
3438 _anchors_get(en->cursor, rp->object, en);
3439 _edje_emit(rp->edje, "entry,changed", rp->part->name);
3442 Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
3443 info->insert = EINA_TRUE;
3444 info->change.insert.pos = start_pos;
3445 info->change.insert.content = eina_stringshare_add(commit_str);
3446 info->change.insert.plain_length =
3447 eina_unicode_utf8_get_len(info->change.insert.content);
3448 _edje_emit_full(ed, "entry,changed,user", rp->part->name,
3449 info, _free_entry_change_info);
3450 _edje_emit(ed, "cursor,changed", rp->part->name);
3453 _edje_entry_imf_cursor_info_set(en);
3454 _edje_entry_real_part_configure(rp);
3458 _edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info __UNUSED__)
3461 Edje_Real_Part *rp = ed->focused_part;
3464 int preedit_start_pos, preedit_end_pos;
3465 char *preedit_string;
3467 Eina_Bool preedit_end_state = EINA_FALSE;
3468 Eina_List *attrs = NULL, *l = NULL;
3469 Ecore_IMF_Preedit_Attr *attr;
3474 en = rp->entry_data;
3475 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3476 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
3479 if (!en->imf_context) return;
3481 ecore_imf_context_preedit_string_with_attributes_get(en->imf_context,
3483 &attrs, &cursor_pos);
3484 if (!preedit_string) return;
3486 if (!strcmp(preedit_string, ""))
3487 preedit_end_state = EINA_TRUE;
3489 if (en->have_selection && !preedit_end_state)
3491 /* delete selected characters */
3492 _range_del_emit(ed, en->cursor, rp->object, en);
3495 /* delete preedit characters */
3498 preedit_start_pos = evas_textblock_cursor_pos_get(en->cursor);
3500 /* insert preedit character(s) */
3501 if (strlen(preedit_string) > 0)
3503 buf = eina_strbuf_new();
3506 EINA_LIST_FOREACH(attrs, l, attr)
3508 if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1)
3510 eina_strbuf_append(buf, "<preedit>");
3511 eina_strbuf_append_n(buf, preedit_string + attr->start_index,
3512 attr->end_index - attr->start_index);
3513 eina_strbuf_append(buf, "</preedit>");
3516 else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2 ||
3517 attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3)
3519 eina_strbuf_append(buf, "<preedit_sel>");
3520 eina_strbuf_append_n(buf, preedit_string + attr->start_index,
3521 attr->end_index - attr->start_index);
3522 eina_strbuf_append(buf, "</preedit_sel>");
3528 eina_strbuf_append(buf, preedit_string);
3530 if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
3531 _edje_password_show_last)
3533 _edje_entry_hide_visible_password(en->rp);
3534 _text_filter_format_prepend(en, en->cursor, "+ password=off");
3535 _text_filter_markup_prepend(en, en->cursor, eina_strbuf_string_get(buf));
3536 _text_filter_format_prepend(en, en->cursor, "- password");
3539 ecore_timer_del(en->pw_timer);
3540 en->pw_timer = NULL;
3542 en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout),
3543 _password_timer_cb, en);
3547 _text_filter_markup_prepend(en, en->cursor, eina_strbuf_string_get(buf));
3549 eina_strbuf_free(buf);
3552 if (!preedit_end_state)
3554 /* set preedit start cursor */
3555 if (!en->preedit_start)
3556 en->preedit_start = evas_object_textblock_cursor_new(rp->object);
3557 evas_textblock_cursor_copy(en->cursor, en->preedit_start);
3559 /* set preedit end cursor */
3560 if (!en->preedit_end)
3561 en->preedit_end = evas_object_textblock_cursor_new(rp->object);
3562 evas_textblock_cursor_copy(en->cursor, en->preedit_end);
3564 preedit_end_pos = evas_textblock_cursor_pos_get(en->cursor);
3566 for (i = 0; i < (preedit_end_pos - preedit_start_pos); i++)
3568 evas_textblock_cursor_char_prev(en->preedit_start);
3571 en->have_preedit = EINA_TRUE;
3573 /* set cursor position */
3574 evas_textblock_cursor_pos_set(en->cursor, preedit_start_pos + cursor_pos);
3577 _edje_entry_imf_cursor_info_set(en);
3578 _anchors_get(en->cursor, rp->object, en);
3579 _edje_emit(rp->edje, "preedit,changed", rp->part->name);
3580 _edje_emit(ed, "cursor,changed", rp->part->name);
3582 /* delete attribute list */
3585 EINA_LIST_FREE(attrs, attr) free(attr);
3588 free(preedit_string);
3592 _edje_entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info)
3595 Edje_Real_Part *rp = ed->focused_part;
3597 Ecore_IMF_Event_Delete_Surrounding *ev = event_info;
3598 Evas_Textblock_Cursor *del_start, *del_end;
3601 if ((!rp) || (!ev)) return;
3602 en = rp->entry_data;
3603 if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3604 (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
3607 cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
3609 del_start = evas_object_textblock_cursor_new(en->rp->object);
3610 evas_textblock_cursor_pos_set(del_start, cursor_pos + ev->offset);
3612 del_end = evas_object_textblock_cursor_new(en->rp->object);
3613 evas_textblock_cursor_pos_set(del_end, cursor_pos + ev->offset + ev->n_chars);
3615 evas_textblock_cursor_range_delete(del_start, del_end);
3617 evas_textblock_cursor_free(del_start);
3618 evas_textblock_cursor_free(del_end);
3622 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/