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);
8
static void _edje_entry_imf_event_selection_set_cb(void *data, Ecore_IMF_Context *ctx, void *event_info);
9
static Eina_Bool _edje_entry_imf_retrieve_selection_cb(void *data, Ecore_IMF_Context *ctx, char **text);
12
typedef struct _Entry Entry;
13
typedef struct _Sel Sel;
14
typedef struct _Anchor Anchor;
15
typedef struct _Item_Obj Item_Obj;
17
static void _edje_entry_imf_cursor_location_set(Entry *en);
18
static void _edje_entry_imf_cursor_info_set(Entry *en);
19
static void _range_del_emit(Edje *ed, Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o EINA_UNUSED, Entry *en);
20
static void _text_filter_format_prepend(Edje *ed, Entry *en, Evas_Textblock_Cursor *c, const char *text);
21
static void _free_entry_change_info(void *_info);
28
Evas_Object *cursor_bg;
29
Evas_Object *cursor_fg, *cursor_fg2;
30
/* CHANGE EDJE_ENTRY_NUM_CURSOR_OBJS IF YOU ADD MORE OBJECTS HERE */
31
Evas_Textblock_Cursor *cursor;
32
Evas_Textblock_Cursor *sel_start, *sel_end;
33
Evas_Textblock_Cursor *cursor_user, *cursor_user_extra;
34
Evas_Textblock_Cursor *preedit_start, *preedit_end;
35
Ecore_Timer *pw_timer;
38
Eina_List *anchorlist;
43
Edje_Input_Panel_Lang input_panel_lang;
44
Eina_Bool composing : 1;
45
Eina_Bool selecting : 1;
46
Eina_Bool have_selection : 1;
47
Eina_Bool select_allow : 1;
48
Eina_Bool select_mod_start : 1;
49
Eina_Bool select_mod_end : 1;
50
Eina_Bool had_sel : 1;
51
Eina_Bool input_panel_enable : 1;
52
Eina_Bool prediction_allow : 1;
53
Eina_Bool anchors_updated : 1;
54
Eina_Bool have_link_pressed : 1;
57
Eina_Bool have_preedit : 1;
58
Eina_Bool commit_cancel : 1; // For skipping useless commit
59
Ecore_IMF_Context *imf_context;
65
Evas_Textblock_Rectangle rect;
66
Evas_Object *obj_fg, *obj_bg, *obj, *sobj;
73
Evas_Textblock_Cursor *start, *end;
88
_preedit_clear(Entry *en)
90
if (en->preedit_start)
92
evas_textblock_cursor_free(en->preedit_start);
93
en->preedit_start = NULL;
98
evas_textblock_cursor_free(en->preedit_end);
99
en->preedit_end = NULL;
102
en->have_preedit = EINA_FALSE;
106
_preedit_del(Entry *en)
108
if (!en || !en->have_preedit) return;
109
if (!en->preedit_start || !en->preedit_end) return;
110
if (!evas_textblock_cursor_compare(en->preedit_start, en->preedit_end)) return;
112
/* delete the preedit characters */
113
evas_textblock_cursor_range_delete(en->preedit_start, en->preedit_end);
117
_edje_entry_focus_in_cb(void *data, Evas_Object *o, const char *emission, const char *source EINA_UNUSED)
119
Efl_Input_Device *seat;
120
const char *seat_name;
126
if ((!rp) || (rp->type != EDJE_RP_TYPE_TEXT) ||
127
(!rp->typedata.text)) return;
128
if (!rp->typedata.text->entry_data) return;
133
en = rp->typedata.text->entry_data;
134
if (!en || !en->imf_context) return;
136
seat_name = emission + sizeof("focus,part,in,") - 1;
137
seat = _edje_seat_get(ed, seat_name);
139
if (efl_canvas_object_seat_focus_check(ed->obj, seat))
141
ecore_imf_context_focus_in(en->imf_context);
142
_edje_entry_imf_cursor_info_set(en);
147
_edje_entry_focus_out_cb(void *data, Evas_Object *o EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
153
if ((!rp) || (rp->type != EDJE_RP_TYPE_TEXT) ||
154
(!rp->typedata.text)) return;
155
if (!rp->typedata.text->entry_data) return;
157
en = rp->typedata.text->entry_data;
158
if (!en || !en->imf_context) return;
160
ecore_imf_context_reset(en->imf_context);
161
ecore_imf_context_focus_out(en->imf_context);
167
_edje_focus_in(Edje *ed, Efl_Input_Device *seat)
174
_edje_seat_emit(ed, seat, "focus,in", "");
176
rp = _edje_focused_part_get(ed, _edje_seat_name_get(ed, seat));
178
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
179
(!rp->typedata.text)) return;
180
en = rp->typedata.text->entry_data;
181
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
182
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
185
if (!en->imf_context) return;
187
ecore_imf_context_focus_in(en->imf_context);
188
_edje_entry_imf_cursor_info_set(en);
193
_edje_focus_in_cb(void *data, const Efl_Event *event)
195
Efl_Input_Focus *ev = event->info;
197
_edje_focus_in(data, efl_input_device_get(ev));
201
_edje_focus_out(Edje *ed, Efl_Input_Device *seat)
208
_edje_seat_emit(ed, seat, "focus,out", "");
211
rp = _edje_focused_part_get(ed, _edje_seat_name_get(ed, seat));
213
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
214
(!rp->typedata.text)) return;
215
en = rp->typedata.text->entry_data;
216
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
217
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
220
if (!en->imf_context) return;
222
ecore_imf_context_reset(en->imf_context);
223
ecore_imf_context_focus_out(en->imf_context);
228
_edje_focus_out_cb(void *data, const Efl_Event *event)
230
Efl_Input_Focus *ev = event->info;
232
_edje_focus_out(data, efl_input_device_get(ev));
235
static Edje_Entry_Change_Info *
236
_text_filter_markup_prepend_internal(Edje *ed, Entry *en, Evas_Textblock_Cursor *c,
238
const char *fmtpre, const char *fmtpost,
239
Eina_Bool clearsel, Eina_Bool changeinfo)
241
Edje_Markup_Filter_Callback *cb;
243
Eina_Bool have_sel = EINA_FALSE;
245
if ((clearsel) && (en->have_selection))
247
_range_del_emit(ed, en->cursor, en->rp->object, en);
248
have_sel = EINA_TRUE;
251
EINA_LIST_FOREACH(ed->markup_filter_callbacks, l, cb)
253
if (!strcmp(cb->part, en->rp->part->name))
255
cb->func(cb->data, ed->obj, cb->part, &text);
260
// For skipping useless commit
261
if (en->have_preedit && (!text || !strcmp(text, "")))
262
en->commit_cancel = EINA_TRUE;
264
en->commit_cancel = EINA_FALSE;
268
Edje_Entry_Change_Info *info = NULL;
272
info = calloc(1, sizeof(*info));
275
ERR("Running very low on memory");
279
info->insert = EINA_TRUE;
280
info->change.insert.content = eina_stringshare_add(text);
281
info->change.insert.plain_length =
282
eina_unicode_utf8_get_len(info->change.insert.content);
289
info->merge = EINA_TRUE;
291
info->change.insert.pos =
292
evas_textblock_cursor_pos_get(en->cursor);
294
if (fmtpre) _text_filter_format_prepend(ed, en, en->cursor, fmtpre);
295
evas_object_textblock_text_markup_prepend(c, text);
297
if (fmtpost) _text_filter_format_prepend(ed, en, en->cursor, fmtpost);
303
static Edje_Entry_Change_Info *
304
_text_filter_text_prepend(Edje *ed, Entry *en, Evas_Textblock_Cursor *c,
306
const char *fmtpre, const char *fmtpost,
307
Eina_Bool clearsel, Eina_Bool changeinfo)
310
Edje_Text_Insert_Filter_Callback *cb;
313
EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL);
315
if ((clearsel) && (en->have_selection))
317
_range_del_emit(ed, en->cursor, en->rp->object, en);
320
text2 = strdup(text);
321
EINA_LIST_FOREACH(ed->text_insert_filter_callbacks, l, cb)
323
if (!strcmp(cb->part, en->rp->part->name))
325
cb->func(cb->data, ed->obj, cb->part, EDJE_TEXT_FILTER_TEXT, &text2);
332
Edje_Entry_Change_Info *info = NULL;
334
markup_text = evas_textblock_text_utf8_to_markup(NULL, text2);
337
info = _text_filter_markup_prepend_internal(ed, en, c, markup_text,
339
clearsel, changeinfo);
346
_text_filter_format_prepend(Edje *ed, Entry *en, Evas_Textblock_Cursor *c, const char *text)
349
Edje_Text_Insert_Filter_Callback *cb;
352
EINA_SAFETY_ON_NULL_RETURN(text);
353
text2 = strdup(text);
354
EINA_LIST_FOREACH(ed->text_insert_filter_callbacks, l, cb)
356
if (!strcmp(cb->part, en->rp->part->name))
358
cb->func(cb->data, ed->obj, cb->part, EDJE_TEXT_FILTER_FORMAT, &text2);
364
char *s, *markup_text;
379
markup_text = (char *)malloc(size + 3);
382
*(markup_text) = '<';
383
memcpy((markup_text + 1), s, size);
384
*(markup_text + size + 1) = '>';
385
*(markup_text + size + 2) = '\0';
388
else if (s[0] == '-')
399
markup_text = (char *)malloc(size + 4);
402
*(markup_text) = '<';
403
*(markup_text + 1) = '/';
404
memcpy((markup_text + 2), s, size);
405
*(markup_text + size + 2) = '>';
406
*(markup_text + size + 3) = '\0';
412
markup_text = (char *)malloc(size + 4);
415
*(markup_text) = '<';
416
memcpy((markup_text + 1), s, size);
417
*(markup_text + size + 1) = '/';
418
*(markup_text + size + 2) = '>';
419
*(markup_text + size + 3) = '\0';
424
_text_filter_markup_prepend_internal(ed, en, c, markup_text,
426
EINA_FALSE, EINA_FALSE);
430
static Edje_Entry_Change_Info *
431
_text_filter_markup_prepend(Edje *ed, Entry *en, Evas_Textblock_Cursor *c,
433
const char *fmtpre, const char *fmtpost,
434
Eina_Bool clearsel, Eina_Bool changeinfo)
437
Edje_Text_Insert_Filter_Callback *cb;
440
EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL);
442
if ((clearsel) && (en->have_selection))
444
_range_del_emit(ed, en->cursor, en->rp->object, en);
447
text2 = strdup(text);
448
EINA_LIST_FOREACH(ed->text_insert_filter_callbacks, l, cb)
450
if (!strcmp(cb->part, en->rp->part->name))
452
cb->func(cb->data, ed->obj, cb->part, EDJE_TEXT_FILTER_MARKUP, &text2);
458
Edje_Entry_Change_Info *info;
460
info = _text_filter_markup_prepend_internal(ed, en, c, text2,
462
clearsel, changeinfo);
469
_curs_update_from_curs(Evas_Textblock_Cursor *c, Evas_Object *o EINA_UNUSED, Entry *en, Evas_Coord *cx, Evas_Coord *cy)
472
Evas_Textblock_Cursor_Type cur_type;
473
if (c != en->cursor) return;
474
switch (en->rp->part->cursor_mode)
476
case EDJE_ENTRY_CURSOR_MODE_BEFORE:
477
cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
480
case EDJE_ENTRY_CURSOR_MODE_UNDER:
481
/* no break for a reason */
483
cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
485
evas_textblock_cursor_geometry_get(c, cx, cy, &cw, &ch, NULL, cur_type);
491
_curs_line_last_get(Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o, Entry *en EINA_UNUSED)
493
Evas_Textblock_Cursor *cc;
496
cc = evas_object_textblock_cursor_new(o);
497
evas_textblock_cursor_paragraph_last(cc);
498
ln = evas_textblock_cursor_line_geometry_get(cc, NULL, NULL, NULL, NULL);
499
evas_textblock_cursor_free(cc);
504
_curs_lin_start(Evas_Textblock_Cursor *c, Evas_Object *o EINA_UNUSED,
505
Entry *en EINA_UNUSED)
507
evas_textblock_cursor_line_char_first(c);
511
_curs_lin_end(Evas_Textblock_Cursor *c, Evas_Object *o EINA_UNUSED,
512
Entry *en EINA_UNUSED)
514
evas_textblock_cursor_line_char_last(c);
518
_curs_start(Evas_Textblock_Cursor *c, Evas_Object *o EINA_UNUSED,
519
Entry *en EINA_UNUSED)
521
evas_textblock_cursor_paragraph_first(c);
525
_curs_end(Evas_Textblock_Cursor *c, Evas_Object *o EINA_UNUSED, Entry *en EINA_UNUSED)
527
evas_textblock_cursor_paragraph_last(c);
531
_curs_jump_line(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en, int ln)
534
Evas_Coord lx, ly, lw, lh;
535
int last = _curs_line_last_get(c, o, en);
537
if (ln < 0) return EINA_FALSE;
538
if (ln > last) return EINA_FALSE;
540
_curs_update_from_curs(c, o, en, &cx, &cy);
542
if (!evas_object_textblock_line_number_geometry_get(o, ln, &lx, &ly, &lw, &lh))
544
if (evas_textblock_cursor_cluster_coord_set(c, cx, ly + (lh / 2)))
546
evas_textblock_cursor_line_set(c, ln);
547
if (cx < (lx + (lw / 2)))
549
if (ln == last) _curs_end(c, o, en);
550
_curs_lin_start(c, o, en);
557
_curs_lin_end(c, o, en);
563
_curs_jump_line_by(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en, int by)
567
ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL) + by;
568
return _curs_jump_line(c, o, en, ln);
572
_curs_up(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
574
return _curs_jump_line_by(c, o, en, -1);
578
_curs_down(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
580
return _curs_jump_line_by(c, o, en, 1);
584
_sel_start(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
586
if (en->sel_start) return;
587
en->sel_start = evas_object_textblock_cursor_new(o);
588
evas_textblock_cursor_copy(c, en->sel_start);
589
en->sel_end = evas_object_textblock_cursor_new(o);
590
evas_textblock_cursor_copy(c, en->sel_end);
592
en->have_selection = EINA_FALSE;
596
en->selection = NULL;
601
_sel_enable(Edje *ed, Evas_Textblock_Cursor *c EINA_UNUSED,
602
Evas_Object *o EINA_UNUSED, Entry *en)
604
if (en->have_selection) return;
605
en->have_selection = EINA_TRUE;
609
en->selection = NULL;
612
_edje_entry_imf_context_reset(en->rp);
613
_edje_emit(ed, "selection,start", en->rp->part->name);
617
_emit_sel_state(Edje *ed, Entry *en)
619
if (!evas_textblock_cursor_compare(en->sel_start, en->sel_end))
621
_edje_emit(ed, "selection,reset", en->rp->part->name);
625
_edje_emit(ed, "selection,changed", en->rp->part->name);
630
_sel_extend(Edje *ed, Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
632
if (!en->sel_end) return;
633
_sel_enable(ed, c, o, en);
634
if (!evas_textblock_cursor_compare(c, en->sel_end)) return;
636
evas_textblock_cursor_copy(c, en->sel_end);
638
_edje_entry_imf_cursor_info_set(en);
643
en->selection = NULL;
645
_emit_sel_state(ed, en);
649
_sel_preextend(Edje *ed, Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
651
if (!en->sel_end) return;
652
_sel_enable(ed, c, o, en);
653
if (!evas_textblock_cursor_compare(c, en->sel_start)) return;
655
evas_textblock_cursor_copy(c, en->sel_start);
657
_edje_entry_imf_cursor_info_set(en);
662
en->selection = NULL;
664
_emit_sel_state(ed, en);
668
_sel_clear(Edje *ed, Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o EINA_UNUSED, Entry *en)
670
en->had_sel = EINA_FALSE;
673
evas_textblock_cursor_free(en->sel_start);
674
evas_textblock_cursor_free(en->sel_end);
675
en->sel_start = NULL;
681
en->selection = NULL;
688
if (sel->obj_bg) evas_object_del(sel->obj_bg);
689
if (sel->obj_fg) evas_object_del(sel->obj_fg);
691
en->sel = eina_list_remove_list(en->sel, en->sel);
693
if (en->have_selection)
695
en->have_selection = EINA_FALSE;
696
_edje_emit(ed, "selection,cleared", en->rp->part->name);
701
_sel_update(Edje *ed, Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o, Entry *en)
704
Evas_Object *smart, *clip;
706
smart = evas_object_smart_parent_get(o);
707
clip = evas_object_clip_get(o);
711
evas_object_geometry_get(o, &x, &y, NULL, NULL);
712
if (en->have_selection)
714
Eina_Iterator *range = NULL;
717
Evas_Textblock_Rectangle *r;
719
range = evas_textblock_cursor_range_simple_geometry_get(en->sel_start,
723
EINA_ITERATOR_FOREACH(range, r)
729
sel = calloc(1, sizeof(Sel));
732
ERR("Running very low on memory");
735
en->sel = eina_list_append(en->sel, sel);
736
if (en->rp->part->source)
738
ob = edje_object_add(ed->base.evas);
739
edje_object_file_set(ob, ed->path, en->rp->part->source);
740
evas_object_smart_member_add(ob, smart);
741
evas_object_stack_below(ob, o);
742
evas_object_clip_set(ob, clip);
743
evas_object_pass_events_set(ob, EINA_TRUE);
744
evas_object_show(ob);
746
_edje_subobj_register(ed, sel->obj_bg);
749
if (en->rp->part->source2)
751
ob = edje_object_add(ed->base.evas);
752
edje_object_file_set(ob, ed->path, en->rp->part->source2);
753
evas_object_smart_member_add(ob, smart);
754
evas_object_stack_above(ob, o);
755
evas_object_clip_set(ob, clip);
756
evas_object_pass_events_set(ob, EINA_TRUE);
757
evas_object_show(ob);
759
_edje_subobj_register(ed, sel->obj_fg);
764
sel = eina_list_data_get(l);
767
*(&(sel->rect)) = *r;
771
evas_object_move(sel->obj_bg, x + r->x, y + r->y);
772
evas_object_resize(sel->obj_bg, r->w, r->h);
776
evas_object_move(sel->obj_fg, x + r->x, y + r->y);
777
evas_object_resize(sel->obj_fg, r->w, r->h);
780
eina_iterator_free(range);
782
/* delete redundant selection rects */
785
Eina_List *temp = l->next;
786
sel = eina_list_data_get(l);
789
if (sel->obj_bg) evas_object_del(sel->obj_bg);
790
if (sel->obj_fg) evas_object_del(sel->obj_fg);
793
en->sel = eina_list_remove_list(en->sel, l);
800
_edje_entry_style_tag_check(Edje_Real_Part *rp, const char *tag)
802
if (!tag) return EINA_FALSE;
803
const Evas_Textblock_Style *ts = NULL;
805
ts = evas_object_textblock_style_user_peek(rp->object);
806
if (!ts) ts = evas_object_textblock_style_get(rp->object);
809
const char *style_str = evas_textblock_style_get(ts);
810
if (!style_str) return EINA_FALSE;
811
if (strstr(style_str, tag)) return EINA_TRUE;
818
_edje_anchor_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
821
Evas_Event_Mouse_Down *ev = event_info;
822
Edje_Real_Part *rp = an->en->rp;
827
Edje *ed = an->en->ed;
829
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
830
(!rp->typedata.text)) return;
831
en = rp->typedata.text->entry_data;
832
if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) &&
836
ignored = rp->ignore_flags & ev->event_flags;
837
if ((!ev->event_flags) || (!ignored))
841
len = 200 + strlen(n);
843
if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK)
844
snprintf(buf, len, "anchor,mouse,down,%i,%s,triple", ev->button, n);
845
else if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
846
snprintf(buf, len, "anchor,mouse,down,%i,%s,double", ev->button, n);
848
snprintf(buf, len, "anchor,mouse,down,%i,%s", ev->button, n);
849
_edje_emit(ed, buf, rp->part->name);
851
/* Link Pressed effect */
852
if (_edje_entry_style_tag_check(rp, "link_pressed="))
854
an->en->have_link_pressed = EINA_TRUE;
855
evas_textblock_cursor_format_append(an->start, "<link_pressed>");
856
evas_textblock_cursor_format_prepend(an->end, "</link_pressed>");
859
ev->event_flags |= rp->mask_flags;
863
_edje_anchor_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
866
Evas_Event_Mouse_Up *ev = event_info;
867
Edje_Real_Part *rp = an->en->rp;
872
Edje *ed = an->en->ed;
874
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
875
(!rp->typedata.text)) return;
877
en = rp->typedata.text->entry_data;
878
ignored = rp->ignore_flags & ev->event_flags;
881
len = 200 + strlen(n);
883
if ((rp->part->select_mode != EDJE_ENTRY_SELECTION_MODE_EXPLICIT) ||
886
if ((!ev->event_flags) || (!ignored))
888
snprintf(buf, len, "anchor,mouse,up,%i,%s", ev->button, n);
889
_edje_emit(ed, buf, rp->part->name);
890
/* Link Pressed effect */
891
if (an->en->have_link_pressed)
893
const Evas_Object_Textblock_Node_Format *node;
894
node = evas_textblock_node_format_first_get(rp->object);
895
for (; node; node = evas_textblock_node_format_next_get(node))
897
const char *text = evas_textblock_node_format_text_get(node);
901
if (!strcmp(text, "+ link_pressed"))
903
evas_textblock_node_format_remove_pair(rp->object,
904
(Evas_Object_Textblock_Node_Format *)node);
913
if ((rp->still_in) && (rp->clicked_button == ev->button) && (!ignored))
915
snprintf(buf, len, "anchor,mouse,clicked,%i,%s", ev->button, n);
916
_edje_emit(ed, buf, rp->part->name);
918
ev->event_flags |= rp->mask_flags;
922
_edje_anchor_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
925
Evas_Event_Mouse_Move *ev = event_info;
926
Edje_Real_Part *rp = an->en->rp;
931
Edje *ed = an->en->ed;
933
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
934
(!rp->typedata.text)) return;
935
en = rp->typedata.text->entry_data;
936
if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) &&
940
ignored = rp->ignore_flags & ev->event_flags;
941
if ((!ev->event_flags) || (!ignored))
945
len = 200 + strlen(n);
947
snprintf(buf, len, "anchor,mouse,move,%s", n);
948
_edje_emit(ed, buf, rp->part->name);
950
ev->event_flags |= rp->mask_flags;
954
_edje_anchor_mouse_in_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
957
Evas_Event_Mouse_In *ev = event_info;
958
Edje_Real_Part *rp = an->en->rp;
959
Edje *ed = an->en->ed;
964
ignored = rp->ignore_flags & ev->event_flags;
965
if ((!ev->event_flags) || (!ignored))
967
/* set to allow handling in elementary, in case we have
968
* an unwanted event propagation */
969
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
973
len = 200 + strlen(n);
975
snprintf(buf, len, "anchor,mouse,in,%s", n);
976
_edje_emit(ed, buf, rp->part->name);
978
ev->event_flags |= rp->mask_flags;
982
_edje_anchor_mouse_out_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
985
Evas_Event_Mouse_Out *ev = event_info;
986
Edje_Real_Part *rp = an->en->rp;
990
Edje *ed = an->en->ed;
992
ignored = rp->ignore_flags & ev->event_flags;
993
if ((!ev->event_flags) || (!ignored))
995
/* set to allow handling in elementary, in case we have
996
* an unwanted event propagation */
997
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1001
len = 200 + strlen(n);
1003
snprintf(buf, len, "anchor,mouse,out,%s", n);
1004
_edje_emit(ed, buf, rp->part->name);
1006
ev->event_flags |= rp->mask_flags;
1010
_item_obj_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1012
Item_Obj *io = data;
1013
Anchor *an = io->an;
1018
ERR("Failed to free item object struct. Anchor is NULL!");
1023
en->item_objs = (Item_Obj *)eina_inlist_remove(EINA_INLIST_GET(en->item_objs),
1024
EINA_INLIST_GET(io));
1031
_item_obj_get(Anchor *an, Evas_Object *o, Evas_Object *smart, Evas_Object *clip)
1038
EINA_INLIST_FOREACH(en->item_objs, io)
1040
if (!io->an && io->name && !strcmp(an->name ? an->name : "", io->name))
1047
io = calloc(1, sizeof(Item_Obj));
1050
ERR("Running very low on memory");
1054
obj = ed->item_provider.func
1055
(ed->item_provider.data, smart,
1056
en->rp->part->name, an->name);
1057
evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _item_obj_del_cb, io);
1058
evas_object_smart_member_add(obj, smart);
1059
evas_object_stack_above(obj, o);
1060
evas_object_clip_set(obj, clip);
1061
evas_object_pass_events_set(obj, EINA_TRUE);
1064
io->name = strdup(an->name ? an->name : "");
1066
en->item_objs = (Item_Obj *)eina_inlist_append(EINA_INLIST_GET(en->item_objs),
1067
EINA_INLIST_GET(io));
1073
_unused_item_objs_free(Entry *en)
1078
EINA_INLIST_FOREACH_SAFE(en->item_objs, l, io)
1084
evas_object_event_callback_del_full(io->obj, EVAS_CALLBACK_DEL, _item_obj_del_cb, io);
1085
evas_object_del(io->obj);
1088
en->item_objs = (Item_Obj *)eina_inlist_remove(EINA_INLIST_GET(en->item_objs),
1089
EINA_INLIST_GET(io));
1097
_is_anchors_outside_viewport(Evas_Coord oxy, Evas_Coord axy, Evas_Coord awh,
1098
Evas_Coord vxy, Evas_Coord vwh)
1100
if (((oxy + axy + awh) < vxy) || ((oxy + axy) > vwh))
1109
_anchors_update(Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o, Entry *en)
1111
Eina_List *l, *ll, *range = NULL;
1112
Evas_Coord x, y, w, h;
1113
Evas_Coord vx, vy, vw, vh;
1114
Evas_Coord tvh, tvw;
1115
Evas_Object *smart, *clip;
1120
/* Better not to update anchors outside the view port. */
1121
if (en->anchors_updated) return;
1123
smart = evas_object_smart_parent_get(o);
1124
clip = evas_object_clip_get(o);
1126
evas_object_geometry_get(o, &x, &y, &w, &h);
1127
evas_output_viewport_get(en->ed->base.evas, &vx, &vy, &vw, &vh);
1131
EINA_LIST_FOREACH(en->anchors, l, an)
1136
Evas_Coord cx, cy, cw, ch;
1138
if (!evas_textblock_cursor_format_item_geometry_get
1139
(an->start, &cx, &cy, &cw, &ch))
1144
if (_is_anchors_outside_viewport(y, cy, ch, vy, tvh) ||
1145
_is_anchors_outside_viewport(x, cx, cw, vx, tvw))
1149
sel = an->sel->data;
1150
evas_object_hide(sel->obj);
1159
sel = calloc(1, sizeof(Sel));
1162
ERR("Running very low on memory");
1165
an->sel = eina_list_append(an->sel, sel);
1168
ERR("Running very low on memory");
1171
if (ed->item_provider.func)
1173
ob = _item_obj_get(an, o, smart, clip);
1177
/* We have only one sel per item */
1178
sel = an->sel->data;
1179
evas_object_move(sel->obj, x + cx, y + cy);
1180
evas_object_resize(sel->obj, cw, ch);
1181
evas_object_show(sel->obj);
1187
evas_textblock_cursor_range_geometry_get(an->start, an->end);
1188
if (eina_list_count(range) != eina_list_count(an->sel))
1192
sel = an->sel->data;
1193
if (sel->obj_bg) evas_object_del(sel->obj_bg);
1194
if (sel->obj_fg) evas_object_del(sel->obj_fg);
1195
if (sel->obj) evas_object_del(sel->obj);
1197
an->sel = eina_list_remove_list(an->sel, an->sel);
1201
Evas_Textblock_Rectangle *r, *r_last;
1204
r_last = eina_list_last_data_get(range);
1205
if (r->y != r_last->y)
1207
/* For multiple range */
1208
r->h = r->y + r_last->y + r_last->h;
1210
/* For vertically layout entry */
1211
if (_is_anchors_outside_viewport(y, r->y, r->h, vy, tvh))
1213
EINA_LIST_FREE(range, r)
1219
/* XXX: Should consider for horizontal entry but has
1220
* very minimal usage. Probably we should get the min x
1221
* and max w for range and then decide whether it is in
1222
* the viewport or not. Unnecessary calculation for this
1223
* minimal usage. Please test with large number of anchors
1224
* after implementing it, if its needed to be.
1227
for (ll = range; ll; ll = eina_list_next(ll))
1231
sel = calloc(1, sizeof(Sel));
1234
ERR("Running very low on memory");
1237
an->sel = eina_list_append(an->sel, sel);
1238
if (en->rp->part->source5)
1240
ob = edje_object_add(ed->base.evas);
1241
edje_object_file_set(ob, ed->path, en->rp->part->source5);
1242
evas_object_smart_member_add(ob, smart);
1243
evas_object_stack_below(ob, o);
1244
evas_object_clip_set(ob, clip);
1245
evas_object_pass_events_set(ob, EINA_TRUE);
1247
_edje_subobj_register(ed, sel->obj_bg);
1250
if (en->rp->part->source6)
1252
ob = edje_object_add(ed->base.evas);
1253
edje_object_file_set(ob, ed->path, en->rp->part->source6);
1254
evas_object_smart_member_add(ob, smart);
1255
evas_object_stack_above(ob, o);
1256
evas_object_clip_set(ob, clip);
1257
evas_object_pass_events_set(ob, EINA_TRUE);
1259
_edje_subobj_register(ed, sel->obj_fg);
1262
ob = evas_object_rectangle_add(ed->base.evas);
1263
evas_object_color_set(ob, 0, 0, 0, 0);
1264
evas_object_smart_member_add(ob, smart);
1265
evas_object_stack_above(ob, o);
1266
evas_object_clip_set(ob, clip);
1267
evas_object_repeat_events_set(ob, EINA_TRUE);
1268
evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _edje_anchor_mouse_down_cb, an);
1269
evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_UP, _edje_anchor_mouse_up_cb, an);
1270
evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_MOVE, _edje_anchor_mouse_move_cb, an);
1271
evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_IN, _edje_anchor_mouse_in_cb, an);
1272
evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_OUT, _edje_anchor_mouse_out_cb, an);
1278
EINA_LIST_FOREACH(an->sel, ll, sel)
1280
Evas_Textblock_Rectangle *r;
1285
*(&(sel->rect)) = *r;
1286
if (_is_anchors_outside_viewport(y, r->y, r->h, vy, tvh) ||
1287
_is_anchors_outside_viewport(x, r->x, r->w, vx, tvw))
1289
range = eina_list_remove_list(range, range);
1291
evas_object_hide(sel->obj_bg);
1292
evas_object_hide(sel->obj_fg);
1293
evas_object_hide(sel->obj);
1299
evas_object_move(sel->obj_bg, x + r->x, y + r->y);
1300
evas_object_resize(sel->obj_bg, r->w, r->h);
1301
evas_object_show(sel->obj_bg);
1305
evas_object_move(sel->obj_fg, x + r->x, y + r->y);
1306
evas_object_resize(sel->obj_fg, r->w, r->h);
1307
evas_object_show(sel->obj_fg);
1311
evas_object_move(sel->obj, x + r->x, y + r->y);
1312
evas_object_resize(sel->obj, r->w, r->h);
1313
evas_object_show(sel->obj);
1315
range = eina_list_remove_list(range, range);
1321
_unused_item_objs_free(en);
1325
_anchors_update_check(Edje *ed, Edje_Real_Part *rp)
1327
Evas_Coord x, y, w, h;
1328
Evas_Coord vx, vy, vw, vh;
1329
Eina_Bool anchors_updated = EINA_FALSE;
1332
en = rp->typedata.text->entry_data;
1334
vx = vy = vw = vh = -1;
1335
evas_object_geometry_get(rp->object, &x, &y, &w, &h);
1336
evas_output_viewport_get(ed->base.evas, &vx, &vy, &vw, &vh);
1337
if (((y + h) <= vy) || (y >= (vy + vh)))
1338
anchors_updated = EINA_TRUE;
1339
else if (((x + w) <= vx) || (x >= (vx + vw)))
1340
anchors_updated = EINA_TRUE;
1342
if (en->anchors_updated)
1343
en->anchors_updated = anchors_updated;
1344
_anchors_update(en->cursor, rp->object, en);
1345
en->anchors_updated = anchors_updated;
1349
_anchors_need_update(Edje_Real_Part *rp)
1352
Eina_Bool anchors_updated;
1354
en = rp->typedata.text->entry_data;
1355
anchors_updated = en->anchors_updated;
1356
en->anchors_updated = EINA_FALSE;
1357
_anchors_update(en->cursor, rp->object, en);
1358
en->anchors_updated = anchors_updated;
1362
_anchors_clear(Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o EINA_UNUSED, Entry *en)
1366
while (en->anchorlist)
1368
free(en->anchorlist->data);
1369
en->anchorlist = eina_list_remove_list(en->anchorlist, en->anchorlist);
1371
while (en->itemlist)
1373
free(en->itemlist->data);
1374
en->itemlist = eina_list_remove_list(en->itemlist, en->itemlist);
1378
Anchor *an = en->anchors->data;
1382
Sel *sel = an->sel->data;
1383
if (sel->obj_bg) evas_object_del(sel->obj_bg);
1384
if (sel->obj_fg) evas_object_del(sel->obj_fg);
1385
if (!an->item && sel->obj) evas_object_del(sel->obj);
1387
an->sel = eina_list_remove_list(an->sel, an->sel);
1389
evas_textblock_cursor_free(an->start);
1390
evas_textblock_cursor_free(an->end);
1393
en->anchors = eina_list_remove_list(en->anchors, en->anchors);
1396
EINA_INLIST_FOREACH(en->item_objs, io)
1400
/* FIXME: This is horrible. It's just a copy&paste (with some adjustments)
1401
* from textblock. I didn't want to introduce any non-API links between the
1402
* libs so I just copied it. Should have been handled differently. */
1404
_anchor_format_parse(const char *item)
1406
const char *start, *end;
1410
start = strchr(item, '=');
1411
if (!start) return NULL;
1413
start++; /* Advance after the '=' */
1414
/* If we can find a quote as the first non-space char,
1415
* our new delimiter is a quote, not a space. */
1416
while (*start == ' ')
1422
end = strchr(start, '\'');
1423
while ((end) && (end > start) && (end[-1] == '\\'))
1424
end = strchr(end + 1, '\'');
1428
end = strchr(start, ' ');
1429
while ((end) && (end > start) && (end[-1] == '\\'))
1430
end = strchr(end + 1, ' ');
1433
/* Null terminate before the spaces */
1434
if (end) len = end - start;
1435
else len = strlen(start);
1437
tmp = malloc(len + 1);
1440
ERR("Running out of memory when allocating %lu byte string", (unsigned long)len + 1);
1443
strncpy(tmp, start, len);
1450
_anchors_get(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
1452
const Eina_List *anchors_a, *anchors_item;
1454
_anchors_clear(c, o, en);
1456
anchors_a = evas_textblock_node_format_list_get(o, "a");
1457
anchors_item = evas_textblock_node_format_list_get(o, "item");
1461
const Evas_Object_Textblock_Node_Format *node;
1462
const Eina_List *itr;
1463
EINA_LIST_FOREACH(anchors_a, itr, node)
1465
const char *s = evas_textblock_node_format_text_get(node);
1467
an = calloc(1, sizeof(Anchor));
1470
ERR("Running very low on memory");
1475
p = strstr(s, "href=");
1478
an->name = _anchor_format_parse(p);
1480
en->anchors = eina_list_append(en->anchors, an);
1481
an->start = evas_object_textblock_cursor_new(o);
1482
an->end = evas_object_textblock_cursor_new(o);
1483
evas_textblock_cursor_at_format_set(an->start, node);
1484
evas_textblock_cursor_copy(an->start, an->end);
1486
/* Close the anchor, if the anchor was without text,
1487
* free it as well */
1488
node = evas_textblock_node_format_next_get(node);
1489
for (; node; node = evas_textblock_node_format_next_get(node))
1491
s = evas_textblock_node_format_text_get(node);
1492
if ((!strcmp(s, "- a")) || (!strcmp(s, "-a")))
1498
evas_textblock_cursor_at_format_set(an->end, node);
1500
else if (!evas_textblock_cursor_compare(an->start, an->end))
1503
evas_textblock_cursor_free(an->start);
1504
evas_textblock_cursor_free(an->end);
1505
en->anchors = eina_list_remove(en->anchors, an);
1514
const Evas_Object_Textblock_Node_Format *node;
1515
const Eina_List *itr;
1516
EINA_LIST_FOREACH(anchors_item, itr, node)
1518
const char *s = evas_textblock_node_format_text_get(node);
1520
an = calloc(1, sizeof(Anchor));
1523
ERR("Running very low on memory");
1529
p = strstr(s, "href=");
1532
an->name = _anchor_format_parse(p);
1534
en->anchors = eina_list_append(en->anchors, an);
1535
an->start = evas_object_textblock_cursor_new(o);
1536
an->end = evas_object_textblock_cursor_new(o);
1537
evas_textblock_cursor_at_format_set(an->start, node);
1538
evas_textblock_cursor_copy(an->start, an->end);
1539
/* Although needed in textblock, don't bother with finding the end
1540
* here cause it doesn't really matter. */
1546
_free_entry_change_info(void *_info)
1548
Edje_Entry_Change_Info *info = (Edje_Entry_Change_Info *)_info;
1551
eina_stringshare_del(info->change.insert.content);
1555
eina_stringshare_del(info->change.del.content);
1561
_range_del_emit(Edje *ed, Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o EINA_UNUSED, Entry *en)
1565
Edje_Entry_Change_Info *info;
1567
start = evas_textblock_cursor_pos_get(en->sel_start);
1568
end = evas_textblock_cursor_pos_get(en->sel_end);
1572
info = calloc(1, sizeof(*info));
1575
ERR("Running very low on memory");
1578
info->insert = EINA_FALSE;
1579
info->change.del.start = start;
1580
info->change.del.end = end;
1582
tmp = evas_textblock_cursor_range_text_get(en->sel_start, en->sel_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
1583
info->change.del.content = eina_stringshare_add(tmp);
1585
evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
1586
_edje_emit(ed, "entry,changed", en->rp->part->name);
1587
_edje_emit_full(ed, "entry,changed,user", en->rp->part->name, info,
1588
_free_entry_change_info);
1590
_sel_clear(ed, en->cursor, en->rp->object, en);
1594
//_range_del(Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o EINA_UNUSED, Entry *en)
1596
// evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
1597
// _sel_clear(ed, en->cursor, en->rp->object, en);
1601
_delete_emit(Edje *ed, Evas_Textblock_Cursor *c, Entry *en, size_t pos,
1602
Eina_Bool backspace)
1607
if (!evas_textblock_cursor_char_prev(c))
1611
evas_textblock_cursor_char_next(c);
1615
if (!evas_textblock_cursor_char_next(c))
1619
evas_textblock_cursor_char_prev(c);
1622
Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1625
ERR("Running very low on memory");
1630
info->insert = EINA_FALSE;
1634
Evas_Textblock_Cursor *cc = evas_object_textblock_cursor_new(en->rp->object);
1635
evas_textblock_cursor_copy(c, cc);
1636
Eina_Bool remove_cluster = evas_textblock_cursor_at_cluster_as_single_glyph(cc,EINA_FALSE);
1639
evas_textblock_cursor_cluster_prev(cc);
1643
evas_textblock_cursor_char_prev(cc);
1646
info->change.del.start = evas_textblock_cursor_pos_get(cc);
1647
info->change.del.end = pos;
1649
tmp = evas_textblock_cursor_range_text_get(c, cc, EVAS_TEXTBLOCK_TEXT_MARKUP);
1650
evas_textblock_cursor_range_delete(c, cc);
1651
evas_textblock_cursor_free(cc);
1655
Evas_Textblock_Cursor *cc = evas_object_textblock_cursor_new(en->rp->object);
1656
evas_textblock_cursor_copy(c, cc);
1658
Eina_Bool remove_cluster = evas_textblock_cursor_at_cluster_as_single_glyph(cc,EINA_TRUE);
1661
evas_textblock_cursor_cluster_next(cc);
1665
evas_textblock_cursor_char_next(cc);
1668
info->change.del.start = evas_textblock_cursor_pos_get(cc);
1669
info->change.del.end = pos;
1671
tmp = evas_textblock_cursor_range_text_get(c, cc, EVAS_TEXTBLOCK_TEXT_MARKUP);
1672
evas_textblock_cursor_range_delete(c, cc);
1673
evas_textblock_cursor_free(cc);
1676
info->change.del.content = eina_stringshare_add(tmp);
1679
_edje_emit(ed, "entry,changed", en->rp->part->name);
1680
_edje_emit_full(ed, "entry,changed,user", en->rp->part->name,
1681
info, _free_entry_change_info);
1685
_edje_entry_hide_visible_password(Edje *ed, Edje_Real_Part *rp)
1687
Eina_Bool int_ret = EINA_FALSE;
1688
const Evas_Object_Textblock_Node_Format *node;
1689
node = evas_textblock_node_format_first_get(rp->object);
1690
for (; node; node = evas_textblock_node_format_next_get(node))
1692
const char *text = evas_textblock_node_format_text_get(node);
1695
if (!strcmp(text, "+ password=off"))
1697
evas_textblock_node_format_remove_pair(rp->object,
1698
(Evas_Object_Textblock_Node_Format *)node);
1699
_edje_emit(ed, "entry,changed", rp->part->name);
1700
int_ret = EINA_TRUE;
1705
_edje_entry_real_part_configure(ed, rp);
1711
_password_timer_cb(void *data)
1713
Entry *en = (Entry *)data;
1714
_edje_entry_hide_visible_password(en->ed, en->rp);
1715
en->pw_timer = NULL;
1716
return ECORE_CALLBACK_CANCEL;
1720
_is_modifier(const char *key)
1722
if ((!strncmp(key, "Shift", 5)) ||
1723
(!strncmp(key, "Control", 7)) ||
1724
(!strncmp(key, "Alt", 3)) ||
1725
(!strncmp(key, "Meta", 4)) ||
1726
(!strncmp(key, "Super", 5)) ||
1727
(!strncmp(key, "Hyper", 5)) ||
1728
(!strcmp(key, "Scroll_Lock")) ||
1729
(!strcmp(key, "Num_Lock")) ||
1730
(!strcmp(key, "Caps_Lock")))
1736
_compose_seq_reset(Entry *en)
1740
EINA_LIST_FREE(en->seq, str)
1741
eina_stringshare_del(str);
1742
en->composing = EINA_FALSE;
1746
_edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1749
Evas_Event_Key_Down *ev = event_info;
1751
Efl_Input_Device *seat;
1754
Eina_Bool control, alt, shift;
1755
#if defined(__APPLE__) && defined(__MACH__)
1756
Eina_Bool super, altgr;
1758
Eina_Bool multiline;
1759
Eina_Bool cursor_changed;
1762
seat = efl_input_device_seat_get(ev->dev);
1763
rp = _edje_focused_part_get(ed, _edje_seat_name_get(ed, seat));
1766
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
1767
(!rp->typedata.text)) return;
1768
en = rp->typedata.text->entry_data;
1769
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1770
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
1772
if (!ev->key) return;
1774
_edje_emit(ed, "entry,keydown", rp->part->name);
1775
#ifdef HAVE_ECORE_IMF
1776
if (en->imf_context)
1778
Ecore_IMF_Event_Key_Down ecore_ev;
1779
ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev);
1782
if (ecore_imf_context_filter_event(en->imf_context,
1783
ECORE_IMF_EVENT_KEY_DOWN,
1784
(Ecore_IMF_Event *)&ecore_ev))
1786
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1793
old_cur_pos = evas_textblock_cursor_pos_get(en->cursor);
1795
#if defined(__APPLE__) && defined(__MACH__)
1796
super = evas_key_modifier_is_set(ev->modifiers, "Super");
1797
altgr = evas_key_modifier_is_set(ev->modifiers, "AltGr");
1799
control = evas_key_modifier_is_set(ev->modifiers, "Control");
1800
alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
1801
shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
1802
multiline = rp->part->multiline;
1803
cursor_changed = EINA_FALSE;
1804
if (!strcmp(ev->key, "Escape"))
1806
_compose_seq_reset(en);
1807
// dead keys here. Escape for now (should emit these)
1808
_edje_emit(ed, "entry,key,escape", rp->part->name);
1809
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1811
else if (!strcmp(ev->key, "Up") ||
1812
(!strcmp(ev->key, "KP_Up") && !ev->string))
1814
_compose_seq_reset(en);
1817
if (en->have_selection &&
1818
(evas_textblock_cursor_pos_get(en->sel_start) != evas_textblock_cursor_pos_get(en->sel_end)))
1819
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1820
if (en->select_allow)
1824
_sel_start(en->cursor, rp->object, en);
1825
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1827
else if (en->have_selection)
1829
if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) < 0)
1830
evas_textblock_cursor_copy(en->sel_start, en->cursor);
1832
evas_textblock_cursor_copy(en->sel_end, en->cursor);
1833
_sel_clear(ed, en->cursor, rp->object, en);
1836
if (_curs_up(en->cursor, rp->object, en))
1837
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1838
if (en->select_allow)
1840
if (shift) _sel_extend(ed, en->cursor, rp->object, en);
1841
else _sel_clear(ed, en->cursor, rp->object, en);
1844
_edje_emit(ed, "entry,key,up", rp->part->name);
1845
_edje_emit(ed, "cursor,changed,manual", rp->part->name);
1847
else if (!strcmp(ev->key, "Down") ||
1848
(!strcmp(ev->key, "KP_Down") && !ev->string))
1850
_compose_seq_reset(en);
1853
if (en->have_selection &&
1854
(evas_textblock_cursor_pos_get(en->sel_start) != evas_textblock_cursor_pos_get(en->sel_end)))
1855
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1856
if (en->select_allow)
1860
_sel_start(en->cursor, rp->object, en);
1861
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1863
else if (en->have_selection)
1865
if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) < 0)
1866
evas_textblock_cursor_copy(en->sel_end, en->cursor);
1868
evas_textblock_cursor_copy(en->sel_start, en->cursor);
1869
_sel_clear(ed, en->cursor, rp->object, en);
1872
if (_curs_down(en->cursor, rp->object, en))
1873
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1874
if (en->select_allow)
1876
if (shift) _sel_extend(ed, en->cursor, rp->object, en);
1877
else _sel_clear(ed, en->cursor, rp->object, en);
1880
_edje_emit(ed, "entry,key,down", rp->part->name);
1881
_edje_emit(ed, "cursor,changed,manual", rp->part->name);
1883
else if (!strcmp(ev->key, "Left") ||
1884
(!strcmp(ev->key, "KP_Left") && !ev->string))
1886
_compose_seq_reset(en);
1887
if (en->have_selection &&
1888
(evas_textblock_cursor_pos_get(en->sel_start) != evas_textblock_cursor_pos_get(en->sel_end)))
1889
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1890
if (en->select_allow)
1894
_sel_start(en->cursor, rp->object, en);
1895
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1899
if (en->have_selection)
1901
if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) < 0)
1902
evas_textblock_cursor_copy(en->sel_start, en->cursor);
1904
evas_textblock_cursor_copy(en->sel_end, en->cursor);
1905
_sel_clear(ed, en->cursor, rp->object, en);
1909
if (evas_textblock_cursor_cluster_prev(en->cursor))
1910
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1911
#if defined(__APPLE__) && defined(__MACH__)
1912
if (altgr) evas_textblock_cursor_word_start(en->cursor);
1914
/* If control is pressed, go to the start of the word */
1915
if (control) evas_textblock_cursor_word_start(en->cursor);
1917
if (en->select_allow)
1919
if (shift) _sel_extend(ed, en->cursor, rp->object, en);
1920
else _sel_clear(ed, en->cursor, rp->object, en);
1922
_edje_emit(ed, "entry,key,left", rp->part->name);
1923
_edje_emit(ed, "cursor,changed,manual", rp->part->name);
1925
else if (!strcmp(ev->key, "Right") ||
1926
(!strcmp(ev->key, "KP_Right") && !ev->string))
1928
_compose_seq_reset(en);
1929
if (en->have_selection &&
1930
(evas_textblock_cursor_pos_get(en->sel_start) != evas_textblock_cursor_pos_get(en->sel_end)))
1931
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1932
if (en->select_allow)
1936
_sel_start(en->cursor, rp->object, en);
1937
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1941
if (en->have_selection)
1943
if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) < 0)
1944
evas_textblock_cursor_copy(en->sel_end, en->cursor);
1946
evas_textblock_cursor_copy(en->sel_start, en->cursor);
1947
_sel_clear(ed, en->cursor, rp->object, en);
1951
/* If control is pressed, go to the end of the word */
1952
#if defined(__APPLE__) && defined(__MACH__)
1953
if (altgr) evas_textblock_cursor_word_end(en->cursor);
1955
if (control) evas_textblock_cursor_word_end(en->cursor);
1957
if (evas_textblock_cursor_cluster_next(en->cursor))
1958
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1959
if (en->select_allow)
1961
if (shift) _sel_extend(ed, en->cursor, rp->object, en);
1962
else _sel_clear(ed, en->cursor, rp->object, en);
1964
_edje_emit(ed, "entry,key,right", rp->part->name);
1965
_edje_emit(ed, "cursor,changed,manual", rp->part->name);
1967
else if (!strcmp(ev->key, "BackSpace"))
1969
_compose_seq_reset(en);
1970
if (control && !en->have_selection)
1972
// del to start of previous word
1973
_sel_start(en->cursor, rp->object, en);
1975
evas_textblock_cursor_cluster_prev(en->cursor);
1976
evas_textblock_cursor_word_start(en->cursor);
1978
_sel_preextend(ed, en->cursor, rp->object, en);
1980
_range_del_emit(ed, en->cursor, rp->object, en);
1982
else if ((alt) && (shift))
1988
if (en->have_selection)
1990
_range_del_emit(ed, en->cursor, rp->object, en);
1994
//if (evas_textblock_cursor_char_prev(en->cursor))
1996
_delete_emit(ed, en->cursor, en, old_cur_pos, EINA_TRUE);
2000
_sel_clear(ed, en->cursor, rp->object, en);
2001
_anchors_get(en->cursor, rp->object, en);
2002
_edje_emit(ed, "entry,key,backspace", rp->part->name);
2003
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2005
else if ((!strcmp(ev->key, "Delete") ||
2006
(!strcmp(ev->key, "KP_Delete") && !ev->string)) && (!shift))
2008
_compose_seq_reset(en);
2011
// del to end of next word
2012
_sel_start(en->cursor, rp->object, en);
2014
evas_textblock_cursor_word_end(en->cursor);
2015
evas_textblock_cursor_cluster_next(en->cursor);
2017
_sel_extend(ed, en->cursor, rp->object, en);
2019
_range_del_emit(ed, en->cursor, rp->object, en);
2027
if (en->have_selection)
2029
_range_del_emit(ed, en->cursor, rp->object, en);
2033
_delete_emit(ed, en->cursor, en, old_cur_pos, EINA_FALSE);
2036
_sel_clear(ed, en->cursor, rp->object, en);
2037
_anchors_get(en->cursor, rp->object, en);
2038
_edje_emit(ed, "entry,key,delete", rp->part->name);
2039
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2042
(!strcmp(ev->key, "Home") ||
2043
((!strcmp(ev->key, "KP_Home")) && !ev->string)))
2045
_compose_seq_reset(en);
2046
if (en->select_allow)
2048
if (shift) _sel_start(en->cursor, rp->object, en);
2049
else _sel_clear(ed, en->cursor, rp->object, en);
2051
if ((control) && (multiline))
2052
_curs_start(en->cursor, rp->object, en);
2054
_curs_lin_start(en->cursor, rp->object, en);
2055
if (en->select_allow)
2057
if (shift) _sel_extend(ed, en->cursor, rp->object, en);
2059
_edje_emit(ed, "entry,key,home", rp->part->name);
2060
_edje_emit(ed, "cursor,changed,manual", rp->part->name);
2061
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2064
(!strcmp(ev->key, "End") ||
2065
((!strcmp(ev->key, "KP_End")) && !ev->string)))
2067
_compose_seq_reset(en);
2068
if (en->select_allow)
2070
if (shift) _sel_start(en->cursor, rp->object, en);
2071
else _sel_clear(ed, en->cursor, rp->object, en);
2073
if ((control) && (multiline))
2074
_curs_end(en->cursor, rp->object, en);
2076
_curs_lin_end(en->cursor, rp->object, en);
2077
if (en->select_allow)
2079
if (shift) _sel_extend(ed, en->cursor, rp->object, en);
2081
_edje_emit(ed, "entry,key,end", rp->part->name);
2082
_edje_emit(ed, "cursor,changed,manual", rp->part->name);
2083
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2085
#if defined(__APPLE__) && defined(__MACH__)
2086
else if (((super) && (!shift) && (!strcmp(ev->key, "v"))) || ((shift) && (!super) && (!strcmp(ev->key, "Insert"))))
2088
else if (((control) && (!shift) && (!strcmp(ev->key, "v"))) || ((shift) && (!control) && (!strcmp(ev->key, "Insert"))))
2091
_compose_seq_reset(en);
2092
_edje_emit(ed, "entry,paste,request", rp->part->name);
2093
_edje_emit(ed, "entry,paste,request,3", rp->part->name);
2094
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2096
#if defined(__APPLE__) && defined(__MACH__)
2097
else if ((super) && (!strcmp(ev->key, "a")))
2099
else if ((control) && (!strcmp(ev->key, "a")))
2102
_compose_seq_reset(en);
2105
_edje_emit(ed, "entry,selection,none,request", rp->part->name);
2106
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2110
_edje_emit(ed, "entry,selection,all,request", rp->part->name);
2111
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2114
#if defined(__APPLE__) && defined(__MACH__)
2115
else if ((super) && (((!shift) && !strcmp(ev->key, "c")) || !strcmp(ev->key, "Insert")))
2117
else if ((control) && (((!shift) && !strcmp(ev->key, "c")) || !strcmp(ev->key, "Insert")))
2120
_compose_seq_reset(en);
2121
_edje_emit(ed, "entry,copy,notify", rp->part->name);
2122
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2124
#if defined(__APPLE__) && defined(__MACH__)
2125
else if ((super) && (!shift) && ((!strcmp(ev->key, "x") || (!strcmp(ev->key, "m")))))
2127
else if ((control) && (!shift) && ((!strcmp(ev->key, "x") || (!strcmp(ev->key, "m")))))
2130
_compose_seq_reset(en);
2131
_edje_emit(ed, "entry,cut,notify", rp->part->name);
2132
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2134
else if ((!strcmp(ev->key, "Delete") ||
2135
(!strcmp(ev->key, "KP_Delete") && !ev->string)) && (shift))
2137
_compose_seq_reset(en);
2138
_edje_emit(ed, "entry,cut,notify", rp->part->name);
2139
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2141
#if defined(__APPLE__) && defined(__MACH__)
2142
else if ((super) && (!strcmp(ev->key, "z")))
2144
else if ((control) && (!strcmp(ev->key, "z")))
2147
_compose_seq_reset(en);
2151
_edje_emit(ed, "entry,redo,request", rp->part->name);
2156
_edje_emit(ed, "entry,undo,request", rp->part->name);
2158
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2160
#if defined(__APPLE__) && defined(__MACH__)
2161
else if ((super) && (!shift) && (!strcmp(ev->key, "y")))
2163
else if ((control) && (!shift) && (!strcmp(ev->key, "y")))
2166
_compose_seq_reset(en);
2168
_edje_emit(ed, "entry,redo,request", rp->part->name);
2169
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2171
//else if ((control) && (!shift) && (!strcmp(ev->key, "w")))
2173
//_compose_seq_reset(en);
2174
//_sel_clear(ed, en->cursor, rp->object, en);
2175
//select current word?
2176
//ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2178
else if (!strcmp(ev->key, "Tab"))
2180
_compose_seq_reset(en);
2189
Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
2192
ERR("Running very low on memory");
2196
info->insert = EINA_TRUE;
2197
info->change.insert.plain_length = 1;
2199
if (en->have_selection)
2201
_range_del_emit(ed, en->cursor, rp->object, en);
2202
info->merge = EINA_TRUE;
2204
info->change.insert.pos =
2205
evas_textblock_cursor_pos_get(en->cursor);
2206
info->change.insert.content = eina_stringshare_add("<tab/>");
2207
_text_filter_format_prepend(ed, en, en->cursor, "tab");
2208
_anchors_get(en->cursor, rp->object, en);
2209
_edje_emit(ed, "entry,changed", rp->part->name);
2210
_edje_emit_full(ed, "entry,changed,user", rp->part->name,
2211
info, _free_entry_change_info);
2214
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2216
_edje_emit(ed, "entry,key,tab", rp->part->name);
2218
else if ((!strcmp(ev->key, "ISO_Left_Tab")) && (multiline))
2220
_compose_seq_reset(en);
2222
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2224
else if (!strcmp(ev->key, "Prior") ||
2225
(!strcmp(ev->key, "KP_Prior") && !ev->string))
2227
_compose_seq_reset(en);
2228
if (en->select_allow)
2230
if (shift) _sel_start(en->cursor, rp->object, en);
2231
else _sel_clear(ed, en->cursor, rp->object, en);
2233
if (!_curs_jump_line_by(en->cursor, rp->object, en, -10))
2235
evas_textblock_cursor_line_set(en->cursor, 0);
2236
_curs_lin_start(en->cursor, rp->object, en);
2238
if (en->select_allow)
2240
if (shift) _sel_extend(ed, en->cursor, rp->object, en);
2241
else _sel_clear(ed, en->cursor, rp->object, en);
2243
_edje_emit(ed, "entry,key,pgup", rp->part->name);
2244
_edje_emit(ed, "cursor,changed,manual", rp->part->name);
2245
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2247
else if (!strcmp(ev->key, "Next") ||
2248
(!strcmp(ev->key, "KP_Next") && !ev->string))
2250
_compose_seq_reset(en);
2251
if (en->select_allow)
2253
if (shift) _sel_start(en->cursor, rp->object, en);
2254
else _sel_clear(ed, en->cursor, rp->object, en);
2256
if (!_curs_jump_line_by(en->cursor, rp->object, en, 10))
2258
int last = _curs_line_last_get(en->cursor, rp->object, en);
2259
evas_textblock_cursor_line_set(en->cursor, last);
2260
_curs_lin_end(en->cursor, rp->object, en);
2262
if (en->select_allow)
2264
if (shift) _sel_extend(ed, en->cursor, rp->object, en);
2265
else _sel_clear(ed, en->cursor, rp->object, en);
2267
_edje_emit(ed, "entry,key,pgdn", rp->part->name);
2268
_edje_emit(ed, "cursor,changed,manual", rp->part->name);
2269
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2271
else if ((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter")))
2273
_compose_seq_reset(en);
2276
Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
2279
ERR("Running very low on memory");
2283
info->insert = EINA_TRUE;
2284
info->change.insert.plain_length = 1;
2285
if (en->have_selection)
2287
_range_del_emit(ed, en->cursor, rp->object, en);
2288
info->merge = EINA_TRUE;
2291
info->change.insert.pos =
2292
evas_textblock_cursor_pos_get(en->cursor);
2294
evas_object_textblock_legacy_newline_get(rp->object))
2296
_text_filter_format_prepend(ed, en, en->cursor, "br");
2297
info->change.insert.content = eina_stringshare_add("<br/>");
2301
_text_filter_format_prepend(ed, en, en->cursor, "ps");
2302
info->change.insert.content = eina_stringshare_add("<ps/>");
2304
_anchors_get(en->cursor, rp->object, en);
2305
_edje_emit(ed, "entry,changed", rp->part->name);
2306
_edje_emit_full(ed, "entry,changed,user", rp->part->name,
2307
info, _free_entry_change_info);
2308
_edje_emit(ed, "cursor,changed", rp->part->name);
2309
cursor_changed = EINA_TRUE;
2312
_edje_emit(ed, "entry,key,enter", rp->part->name);
2313
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2317
char *compres = NULL, *string = (char *)ev->string;
2318
Eina_Bool free_string = EINA_FALSE;
2319
Ecore_Compose_State state;
2321
if (control) goto end;
2324
_compose_seq_reset(en);
2325
en->seq = eina_list_append(en->seq, eina_stringshare_add(ev->key));
2326
state = ecore_compose_get(en->seq, &compres);
2327
if (state == ECORE_COMPOSE_MIDDLE) en->composing = EINA_TRUE;
2328
else en->composing = EINA_FALSE;
2333
_compose_seq_reset(en);
2334
if (ev->string && (!ev->string[1]) &&
2335
((ev->string[0] < 0x20) || (ev->string[0] == 0x7f)))
2347
if (_is_modifier(ev->key)) goto end;
2348
en->seq = eina_list_append(en->seq, eina_stringshare_add(ev->key));
2349
state = ecore_compose_get(en->seq, &compres);
2350
if (state == ECORE_COMPOSE_NONE)
2352
_compose_seq_reset(en);
2356
else if (state == ECORE_COMPOSE_DONE)
2358
_compose_seq_reset(en);
2362
free_string = EINA_TRUE;
2375
Edje_Entry_Change_Info *info = NULL;
2376
// if PASSWORD_SHOW_LAST mode, appending text with password=off tag
2377
if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
2378
_edje_password_show_last)
2380
_edje_entry_hide_visible_password(ed, en->rp);
2381
info = _text_filter_text_prepend(ed, en, en->cursor, string,
2384
EINA_TRUE, EINA_TRUE);
2389
ecore_timer_del(en->pw_timer);
2390
en->pw_timer = NULL;
2392
if (_edje_password_show_last_timeout >= 0)
2393
en->pw_timer = ecore_timer_add
2394
(_edje_password_show_last_timeout,
2395
_password_timer_cb, en);
2399
info = _text_filter_text_prepend(ed, en, en->cursor, string,
2401
EINA_TRUE, EINA_TRUE);
2402
_anchors_get(en->cursor, rp->object, en);
2405
_edje_emit(ed, "entry,changed", rp->part->name);
2406
_edje_emit_full(ed, "entry,changed,user", rp->part->name,
2407
info, _free_entry_change_info);
2408
_edje_emit(ed, "cursor,changed", rp->part->name);
2409
cursor_changed = EINA_TRUE;
2410
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2412
if (free_string) free(string);
2416
if (!cursor_changed &&
2417
(old_cur_pos != evas_textblock_cursor_pos_get(en->cursor)))
2418
_edje_emit(ed, "cursor,changed", rp->part->name);
2420
_edje_entry_imf_cursor_info_set(en);
2421
_edje_entry_real_part_configure(ed, rp);
2425
_edje_key_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
2427
Evas_Event_Key_Up *ev = event_info;
2428
Efl_Input_Device *seat;
2433
seat = efl_input_device_seat_get(ev->dev);
2434
rp = _edje_focused_part_get(ed, _edje_seat_name_get(ed, seat));
2436
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2437
(!rp->typedata.text)) return;
2438
en = rp->typedata.text->entry_data;
2439
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2440
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
2443
_edje_emit(ed, "entry,keyup", rp->part->name);
2444
#ifdef HAVE_ECORE_IMF
2445
if (en->imf_context)
2447
Ecore_IMF_Event_Key_Up ecore_ev;
2449
ecore_imf_evas_event_key_up_wrap(ev, &ecore_ev);
2450
if (ecore_imf_context_filter_event(en->imf_context,
2451
ECORE_IMF_EVENT_KEY_UP,
2452
(Ecore_IMF_Event *)&ecore_ev))
2460
static Evas_Textblock_Cursor *
2461
_edje_cursor_cluster_coord_set(Edje_Real_Part *rp, Evas_Coord canvasx, Evas_Coord canvasy, Evas_Coord *cx, Evas_Coord *cy)
2464
Evas_Coord x, y, lh = 0, cly = 0;
2465
Evas_Textblock_Cursor *line_cur;
2466
Evas_Textblock_Cursor *tc;
2468
en = rp->typedata.text->entry_data;
2469
tc = evas_object_textblock_cursor_new(rp->object);
2470
evas_textblock_cursor_copy(en->cursor, tc);
2471
evas_object_geometry_get(rp->object, &x, &y, NULL, NULL);
2475
line_cur = evas_object_textblock_cursor_new(rp->object);
2476
evas_textblock_cursor_paragraph_last(line_cur);
2477
evas_textblock_cursor_line_geometry_get(line_cur, NULL, &cly, NULL, &lh);
2478
/* Consider a threshold of half the line height */
2479
if (*cy > (cly + lh) && *cy < (cly + lh + lh / 2))
2481
*cy = cly + lh - 1; // Make it inside Textblock
2483
evas_textblock_cursor_paragraph_first(line_cur);
2484
evas_textblock_cursor_line_geometry_get(line_cur, NULL, &cly, NULL, NULL);
2486
if (*cy < cly && *cy > (cly - lh / 2))
2490
evas_textblock_cursor_free(line_cur);
2491
/* No need to check return value if not able to set the char coord Textblock
2493
evas_textblock_cursor_cluster_coord_set(en->cursor, *cx, *cy);
2499
_edje_part_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2501
Edje_Real_Part *rp = data;
2504
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2505
(!rp->typedata.text)) return;
2506
en = rp->typedata.text->entry_data;
2508
_edje_entry_imf_cursor_location_set(en);
2512
_edje_part_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
2515
Edje_Real_Part *rp = data;
2516
Evas_Event_Mouse_Down *ev = event_info;
2518
// Eina_Bool multiline;
2519
Evas_Textblock_Cursor *tc = NULL;
2520
Eina_Bool dosel = EINA_FALSE;
2523
if ((!rp) || (!ev)) return;
2524
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
2525
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2526
(!rp->typedata.text)) return;
2527
en = rp->typedata.text->entry_data;
2528
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2529
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2531
if ((ev->button != 1) && (ev->button != 2)) return;
2533
#ifdef HAVE_ECORE_IMF
2534
if (en->imf_context)
2536
Ecore_IMF_Event_Mouse_Down ecore_ev;
2537
ecore_imf_evas_event_mouse_down_wrap(ev, &ecore_ev);
2538
if (ecore_imf_context_filter_event(en->imf_context,
2539
ECORE_IMF_EVENT_MOUSE_DOWN,
2540
(Ecore_IMF_Event *)&ecore_ev))
2545
_edje_entry_imf_context_reset(rp);
2547
shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
2548
en->select_mod_start = EINA_FALSE;
2549
en->select_mod_end = EINA_FALSE;
2551
if (en->select_allow && ev->button != 2) dosel = EINA_TRUE;
2554
if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK)
2558
tc = evas_object_textblock_cursor_new(rp->object);
2559
evas_textblock_cursor_copy(en->cursor, tc);
2560
if (evas_textblock_cursor_compare(en->cursor, en->sel_start) < 0)
2561
evas_textblock_cursor_line_char_first(en->cursor);
2563
evas_textblock_cursor_line_char_last(en->cursor);
2564
_sel_extend(en->ed, en->cursor, rp->object, en);
2568
en->have_selection = EINA_FALSE;
2569
en->selecting = EINA_FALSE;
2570
_sel_clear(en->ed, en->cursor, rp->object, en);
2571
tc = evas_object_textblock_cursor_new(rp->object);
2572
evas_textblock_cursor_copy(en->cursor, tc);
2573
evas_textblock_cursor_line_char_first(en->cursor);
2574
_sel_start(en->cursor, rp->object, en);
2575
evas_textblock_cursor_line_char_last(en->cursor);
2576
_sel_extend(en->ed, en->cursor, rp->object, en);
2580
else if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
2584
tc = evas_object_textblock_cursor_new(rp->object);
2585
evas_textblock_cursor_copy(en->cursor, tc);
2586
if (evas_textblock_cursor_compare(en->cursor, en->sel_start) < 0)
2587
evas_textblock_cursor_word_start(en->cursor);
2590
evas_textblock_cursor_word_end(en->cursor);
2591
evas_textblock_cursor_cluster_next(en->cursor);
2593
_sel_extend(en->ed, en->cursor, rp->object, en);
2597
en->have_selection = EINA_FALSE;
2598
en->selecting = EINA_FALSE;
2599
_sel_clear(en->ed, en->cursor, rp->object, en);
2600
tc = evas_object_textblock_cursor_new(rp->object);
2601
evas_textblock_cursor_copy(en->cursor, tc);
2602
evas_textblock_cursor_word_start(en->cursor);
2603
_sel_start(en->cursor, rp->object, en);
2604
evas_textblock_cursor_word_end(en->cursor);
2605
evas_textblock_cursor_cluster_next(en->cursor);
2606
_sel_extend(en->ed, en->cursor, rp->object, en);
2611
tc = _edje_cursor_cluster_coord_set(rp, ev->canvas.x, ev->canvas.y, &cx, &cy);
2615
if ((en->have_selection) &&
2616
(rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT))
2619
_sel_extend(en->ed, en->cursor, rp->object, en);
2622
Eina_List *first, *last;
2626
last = eina_list_last(en->sel);
2629
Evas_Textblock_Rectangle *r1, *r2;
2630
Evas_Coord d, d1, d2;
2636
d = (r1->y + (r1->h / 2)) - cy;
2638
d = r2->x + r2->w - 1 - cx;
2640
d = (r2->y + (r2->h / 2)) - cy;
2642
sc = DIV(en->ed->scale, en->ed->file->base_scale);
2643
if (EQ(sc, ZERO)) sc = DIV(_edje_scale, en->ed->file->base_scale);
2644
d = (Evas_Coord)MUL(FROM_INT(20), sc); // FIXME: maxing number!
2650
en->select_mod_start = EINA_TRUE;
2651
en->selecting = EINA_TRUE;
2658
en->select_mod_end = EINA_TRUE;
2659
en->selecting = EINA_TRUE;
2669
_sel_extend(en->ed, en->cursor, rp->object, en);
2673
en->selecting = EINA_TRUE;
2674
_sel_clear(en->ed, en->cursor, rp->object, en);
2675
_sel_start(en->cursor, rp->object, en);
2680
if (evas_textblock_cursor_compare(tc, en->cursor))
2682
_edje_emit(en->ed, "cursor,changed", rp->part->name);
2683
_edje_emit(en->ed, "cursor,changed,manual", rp->part->name);
2685
evas_textblock_cursor_free(tc);
2687
_edje_entry_real_part_configure(en->ed, rp);
2688
if (ev->button == 2)
2690
_edje_emit(en->ed, "entry,paste,request", rp->part->name);
2691
_edje_emit(en->ed, "entry,paste,request,1", rp->part->name);
2696
_edje_part_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
2699
Edje_Real_Part *rp = data;
2700
Evas_Event_Mouse_Up *ev = event_info;
2702
Evas_Textblock_Cursor *tc;
2704
if ((!ev) || (ev->button != 1)) return;
2706
if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK) return;
2707
if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) return;
2708
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2709
(!rp->typedata.text)) return;
2710
en = rp->typedata.text->entry_data;
2711
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2712
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2715
/* We don't check for ON_HOLD because we'd like to end selection anyway when
2716
* mouse is up, even if it's held. */
2718
#ifdef HAVE_ECORE_IMF
2719
if (en->imf_context)
2721
Ecore_IMF_Event_Mouse_Up ecore_ev;
2722
ecore_imf_evas_event_mouse_up_wrap(ev, &ecore_ev);
2723
if (ecore_imf_context_filter_event(en->imf_context,
2724
ECORE_IMF_EVENT_MOUSE_UP,
2725
(Ecore_IMF_Event *)&ecore_ev))
2730
/* cx cy are unused but needed in mouse down, please bear with it */
2731
tc = _edje_cursor_cluster_coord_set(rp, ev->canvas.x, ev->canvas.y, &cx, &cy);
2733
if (en->select_allow)
2735
if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
2739
if (en->select_mod_end)
2740
_sel_extend(en->ed, en->cursor, rp->object, en);
2741
else if (en->select_mod_start)
2742
_sel_preextend(en->ed, en->cursor, rp->object, en);
2745
_sel_extend(en->ed, en->cursor, rp->object, en);
2746
//evas_textblock_cursor_copy(en->cursor, en->sel_end);
2750
evas_textblock_cursor_copy(en->cursor, en->sel_end);
2755
if (en->have_selection)
2756
en->had_sel = EINA_TRUE;
2757
en->selecting = EINA_FALSE;
2759
if (evas_textblock_cursor_compare(tc, en->cursor))
2761
_edje_emit(en->ed, "cursor,changed", rp->part->name);
2762
_edje_emit(en->ed, "cursor,changed,manual", rp->part->name);
2765
_edje_entry_imf_cursor_info_set(en);
2767
evas_textblock_cursor_free(tc);
2769
_edje_entry_real_part_configure(en->ed, rp);
2773
_edje_part_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
2776
Edje_Real_Part *rp = data;
2777
Evas_Event_Mouse_Move *ev = event_info;
2779
Evas_Coord x, y, w, h;
2780
Evas_Textblock_Cursor *tc;
2782
if ((!rp) || (!ev)) return;
2783
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2784
(!rp->typedata.text)) return;
2785
en = rp->typedata.text->entry_data;
2786
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2787
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2790
#ifdef HAVE_ECORE_IMF
2791
if (en->imf_context)
2793
Ecore_IMF_Event_Mouse_Move ecore_ev;
2794
ecore_imf_evas_event_mouse_move_wrap(ev, &ecore_ev);
2795
if (ecore_imf_context_filter_event(en->imf_context,
2796
ECORE_IMF_EVENT_MOUSE_MOVE,
2797
(Ecore_IMF_Event *)&ecore_ev))
2804
tc = evas_object_textblock_cursor_new(rp->object);
2805
evas_textblock_cursor_copy(en->cursor, tc);
2806
evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2807
cx = ev->cur.canvas.x - x;
2808
cy = ev->cur.canvas.y - y;
2809
if (!evas_textblock_cursor_cluster_coord_set(en->cursor, cx, cy))
2811
Evas_Coord lx, ly, lw, lh;
2813
if (evas_textblock_cursor_line_coord_set(en->cursor, cy) < 0)
2815
if (rp->part->multiline)
2816
_curs_end(en->cursor, rp->object, en);
2819
evas_textblock_cursor_paragraph_first(en->cursor);
2820
evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2821
if (!evas_textblock_cursor_cluster_coord_set(en->cursor, cx, ly + (lh / 2)))
2822
_curs_end(en->cursor, rp->object, en);
2827
evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2829
_curs_lin_start(en->cursor, rp->object, en);
2831
_curs_lin_end(en->cursor, rp->object, en);
2834
if (en->select_allow)
2836
if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
2840
if (en->select_mod_end)
2841
_sel_extend(en->ed, en->cursor, rp->object, en);
2842
else if (en->select_mod_start)
2843
_sel_preextend(en->ed, en->cursor, rp->object, en);
2846
_sel_extend(en->ed, en->cursor, rp->object, en);
2850
_sel_extend(en->ed, en->cursor, rp->object, en);
2853
if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) != 0)
2854
_sel_enable(en->ed, en->cursor, rp->object, en);
2855
if (en->have_selection)
2856
_sel_update(en->ed, en->cursor, rp->object, en);
2858
if (evas_textblock_cursor_compare(tc, en->cursor))
2860
_edje_emit(en->ed, "cursor,changed", rp->part->name);
2861
_edje_emit(en->ed, "cursor,changed,manual", rp->part->name);
2863
evas_textblock_cursor_free(tc);
2865
_edje_entry_real_part_configure(en->ed, rp);
2870
_canvas_viewport_resize_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
2872
Edje_Real_Part *rp = data;
2876
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2877
(!rp->typedata.text)) return;
2878
en = rp->typedata.text->entry_data;
2879
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2880
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2883
_anchors_need_update(rp);
2887
_evas_focus_in_cb(void *data, const Efl_Event *event)
2889
Efl_Input_Focus *ev = event->info;
2890
Evas *e = event->object;
2891
Efl_Input_Device *seat;
2896
seat = efl_input_device_get(ev);
2897
if (evas_canvas_seat_focus_get(e, seat) == ed->obj)
2899
_edje_focus_in(data, seat);
2904
_evas_focus_out_cb(void *data, const Efl_Event *event)
2906
Efl_Input_Focus *ev = event->info;
2907
Evas *e = event->object;
2908
Efl_Input_Device *seat;
2913
seat = efl_input_device_get(ev);
2914
if (evas_canvas_seat_focus_get(e, seat) == ed->obj)
2916
_edje_focus_out(data, seat);
2920
/***************************************************************/
2922
_edje_entry_init(Edje *ed)
2924
if (!ed->has_entries)
2926
if (ed->entries_inited)
2928
ed->entries_inited = EINA_TRUE;
2930
efl_event_callback_add(ed->obj, EFL_EVENT_FOCUS_IN, _edje_focus_in_cb, ed);
2931
efl_event_callback_add(ed->obj, EFL_EVENT_FOCUS_OUT, _edje_focus_out_cb, ed);
2932
evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_DOWN,
2933
_edje_key_down_cb, ed);
2934
evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_UP,
2935
_edje_key_up_cb, ed);
2936
efl_event_callback_add(ed->base.evas, EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN,
2937
_evas_focus_in_cb, ed);
2938
efl_event_callback_add(ed->base.evas, EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT,
2939
_evas_focus_out_cb, ed);
2943
_edje_entry_shutdown(Edje *ed)
2945
if ((!ed) || (!ed->has_entries))
2947
if (!ed->entries_inited)
2949
ed->entries_inited = EINA_FALSE;
2951
efl_event_callback_del(ed->obj, EFL_EVENT_FOCUS_IN, _edje_focus_in_cb, ed);
2952
efl_event_callback_del(ed->obj, EFL_EVENT_FOCUS_OUT, _edje_focus_out_cb, ed);
2953
evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_DOWN,
2955
evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_UP,
2957
efl_event_callback_del(ed->base.evas, EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN,
2958
_evas_focus_in_cb, ed);
2959
efl_event_callback_del(ed->base.evas, EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT,
2960
_evas_focus_out_cb, ed);
2964
_edje_entry_real_part_cursor_objs_get(Edje_Real_Part *rp, Evas_Object **cursor_objs)
2969
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2970
(!rp->typedata.text) || (!rp->typedata.text->entry_data)) return -1;
2972
en = rp->typedata.text->entry_data;
2974
if (en->cursor_bg) cursor_objs[ret++] = en->cursor_bg;
2975
if (en->cursor_fg) cursor_objs[ret++] = en->cursor_fg;
2976
if (en->cursor_fg2) cursor_objs[ret++] = en->cursor_fg2;
2981
_edje_entry_real_part_init(Edje *ed, Edje_Real_Part *rp)
2984
#ifdef HAVE_ECORE_IMF
2986
const Ecore_IMF_Context_Info *ctx_info;
2989
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2990
(!rp->typedata.text)) return;
2991
en = calloc(1, sizeof(Entry));
2994
ERR("Running very low on memory");
2997
rp->typedata.text->entry_data = en;
3001
evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOVE, _edje_part_move_cb, rp);
3003
evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_DOWN, _edje_part_mouse_down_cb, rp);
3004
evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_UP, _edje_part_mouse_up_cb, rp);
3005
evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_MOVE, _edje_part_mouse_move_cb, rp);
3006
evas_event_callback_add(ed->base.evas, EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE, _canvas_viewport_resize_cb, rp);
3008
if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
3009
en->select_allow = EINA_TRUE;
3011
if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
3013
Edje_Part_Description_Text *txt;
3015
txt = (Edje_Part_Description_Text *)rp->chosen_description;
3017
en->select_allow = EINA_FALSE;
3018
if (txt && edje_string_get(&txt->text.repch))
3019
evas_object_textblock_replace_char_set(rp->object, edje_string_get(&txt->text.repch));
3021
evas_object_textblock_replace_char_set(rp->object, "*");
3024
if (rp->part->source3)
3026
en->cursor_bg = edje_object_add(ed->base.evas);
3027
edje_object_file_set(en->cursor_bg, ed->path, rp->part->source3);
3028
evas_object_smart_member_add(en->cursor_bg, ed->obj);
3029
evas_object_stack_below(en->cursor_bg, rp->object);
3030
evas_object_clip_set(en->cursor_bg, evas_object_clip_get(rp->object));
3031
evas_object_pass_events_set(en->cursor_bg, EINA_TRUE);
3032
_edje_subobj_register(ed, en->cursor_bg);
3034
if (rp->part->source4)
3036
en->cursor_fg = edje_object_add(ed->base.evas);
3037
edje_object_file_set(en->cursor_fg, ed->path, rp->part->source4);
3038
evas_object_smart_member_add(en->cursor_fg, ed->obj);
3039
evas_object_stack_above(en->cursor_fg, rp->object);
3040
evas_object_clip_set(en->cursor_fg, evas_object_clip_get(rp->object));
3041
evas_object_pass_events_set(en->cursor_fg, EINA_TRUE);
3042
_edje_subobj_register(ed, en->cursor_fg);
3044
/* A proxy to the main cursor. */
3045
if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
3047
en->cursor_fg2 = edje_object_add(ed->base.evas);
3048
edje_object_file_set(en->cursor_fg2, ed->path, rp->part->source4);
3049
evas_object_smart_member_add(en->cursor_fg2, ed->obj);
3050
evas_object_stack_above(en->cursor_fg2, rp->object);
3051
evas_object_clip_set(en->cursor_fg2, evas_object_clip_get(rp->object));
3052
evas_object_pass_events_set(en->cursor_fg2, EINA_TRUE);
3053
_edje_subobj_register(ed, en->cursor_fg2);
3057
evas_object_textblock_legacy_newline_set(rp->object, EINA_TRUE);
3059
if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
3061
if (en->cursor_bg) evas_object_show(en->cursor_bg);
3062
if (en->cursor_fg) evas_object_show(en->cursor_fg);
3063
if (en->cursor_fg2) evas_object_show(en->cursor_fg2);
3064
en->input_panel_enable = EINA_TRUE;
3066
#ifdef HAVE_ECORE_IMF
3069
en->commit_cancel = EINA_FALSE;
3071
edje_object_signal_callback_add(ed->obj, "focus,part,in,*",
3073
_edje_entry_focus_in_cb, rp);
3074
edje_object_signal_callback_add(ed->obj, "focus,part,out,*",
3076
_edje_entry_focus_out_cb, rp);
3078
ctx_id = ecore_imf_context_default_id_get();
3081
ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
3082
if (!ctx_info->canvas_type ||
3083
strcmp(ctx_info->canvas_type, "evas") == 0)
3085
en->imf_context = ecore_imf_context_add(ctx_id);
3089
ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
3092
en->imf_context = ecore_imf_context_add(ctx_id);
3097
en->imf_context = NULL;
3099
if (!en->imf_context) goto done;
3101
ecore_imf_context_client_window_set
3103
(void *)ecore_evas_window_get
3104
(ecore_evas_ecore_evas_get(ed->base.evas)));
3105
ecore_imf_context_client_canvas_set(en->imf_context, ed->base.evas);
3107
ecore_imf_context_retrieve_surrounding_callback_set(en->imf_context,
3108
_edje_entry_imf_retrieve_surrounding_cb, ed);
3109
ecore_imf_context_retrieve_selection_callback_set(en->imf_context, _edje_entry_imf_retrieve_selection_cb, ed);
3110
ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _edje_entry_imf_event_commit_cb, ed);
3111
ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb, ed);
3112
ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb, ed);
3113
ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_SELECTION_SET, _edje_entry_imf_event_selection_set_cb, ed);
3114
ecore_imf_context_input_mode_set(en->imf_context,
3115
rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD ?
3116
ECORE_IMF_INPUT_MODE_INVISIBLE : ECORE_IMF_INPUT_MODE_FULL);
3118
if (rp->part->multiline)
3119
ecore_imf_context_input_hint_set(en->imf_context,
3120
ecore_imf_context_input_hint_get(en->imf_context) | ECORE_IMF_INPUT_HINT_MULTILINE);
3122
if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
3123
ecore_imf_context_input_panel_language_set(en->imf_context, ECORE_IMF_INPUT_PANEL_LANG_ALPHABET);
3126
#ifdef HAVE_ECORE_IMF
3129
en->cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(rp->object);
3133
_edje_entry_real_part_shutdown(Edje *ed, Edje_Real_Part *rp)
3137
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3138
(!rp->typedata.text)) return;
3139
en = rp->typedata.text->entry_data;
3141
rp->typedata.text->entry_data = NULL;
3142
_sel_clear(ed, en->cursor, rp->object, en);
3143
_anchors_clear(en->cursor, rp->object, en);
3144
_unused_item_objs_free(en);
3145
#ifdef HAVE_ECORE_IMF
3148
evas_object_del(en->cursor_bg);
3149
evas_object_del(en->cursor_fg);
3150
evas_object_del(en->cursor_fg2);
3152
if (en->cursor_user)
3153
evas_textblock_cursor_free(en->cursor_user);
3155
if (en->cursor_user_extra)
3156
evas_textblock_cursor_free(en->cursor_user_extra);
3160
ecore_timer_del(en->pw_timer);
3161
en->pw_timer = NULL;
3164
evas_event_callback_del_full(ed->base.evas, EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE, _canvas_viewport_resize_cb, rp);
3166
#ifdef HAVE_ECORE_IMF
3167
if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
3169
if (en->imf_context)
3171
ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _edje_entry_imf_event_commit_cb);
3172
ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb);
3173
ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb);
3174
ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_SELECTION_SET, _edje_entry_imf_event_selection_set_cb);
3176
ecore_imf_context_del(en->imf_context);
3177
en->imf_context = NULL;
3180
edje_object_signal_callback_del(ed->obj, "focus,part,in,*",
3182
_edje_entry_focus_in_cb);
3183
edje_object_signal_callback_del(ed->obj, "focus,part,out,*",
3185
_edje_entry_focus_out_cb);
3188
_compose_seq_reset(en);
3194
_edje_entry_real_part_configure(Edje *ed, Edje_Real_Part *rp)
3196
Evas_Coord x, y, w, h, xx, yy, ww, hh, xx2, yy2;
3198
Evas_Textblock_Cursor_Type cur_type;
3199
Eina_Bool bidi_cursor = EINA_FALSE;
3201
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3202
(!rp->typedata.text)) return;
3203
en = rp->typedata.text->entry_data;
3206
_sel_update(ed, en->cursor, rp->object, en);
3207
_anchors_update_check(ed, rp);
3208
if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
3210
switch (rp->part->cursor_mode)
3212
case EDJE_ENTRY_CURSOR_MODE_BEFORE:
3213
cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
3216
case EDJE_ENTRY_CURSOR_MODE_UNDER:
3217
/* no break for a reason */
3219
cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
3222
xx = yy = ww = hh = -1;
3223
evas_object_geometry_get(rp->object, &x, &y, &w, &h);
3224
bidi_cursor = evas_textblock_cursor_geometry_bidi_get(en->cursor, &xx, &yy, &ww, &hh, &xx2, &yy2, NULL, NULL, cur_type);
3231
if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
3232
edje_object_size_min_restricted_calc(en->cursor_bg, &bg_w, NULL, ww, 0);
3234
evas_object_move(en->cursor_bg, x + xx, y + yy);
3235
evas_object_resize(en->cursor_bg, bg_w, hh);
3241
if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
3242
edje_object_size_min_restricted_calc(en->cursor_fg, &fg_w, NULL, ww, 0);
3244
evas_object_move(en->cursor_fg, x + xx, y + yy);
3250
evas_object_move(en->cursor_fg2, x + xx2, y + yy2 + (hh / 2));
3251
evas_object_resize(en->cursor_fg, fg_w, hh / 2);
3252
evas_object_resize(en->cursor_fg2, fg_w, hh / 2);
3253
evas_object_show(en->cursor_fg2);
3258
evas_object_resize(en->cursor_fg, fg_w, hh);
3260
evas_object_hide(en->cursor_fg2);
3267
_edje_entry_selection_get(Edje_Real_Part *rp)
3271
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3272
(!rp->typedata.text)) return NULL;
3273
en = rp->typedata.text->entry_data;
3274
if (!en) return NULL;
3275
// get selection - convert to markup
3276
if ((!en->selection) && (en->have_selection))
3277
en->selection = evas_textblock_cursor_range_text_get
3278
(en->sel_start, en->sel_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
3279
return en->selection;
3283
_edje_entry_text_get(Edje_Real_Part *rp)
3287
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3288
(!rp->typedata.text)) return NULL;
3289
en = rp->typedata.text->entry_data;
3290
if (!en) return NULL;
3291
// get text - convert to markup
3292
return evas_object_textblock_text_markup_get(rp->object);
3296
_edje_entry_text_markup_set(Edje_Real_Part *rp, const char *text)
3301
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3302
(!rp->typedata.text)) return;
3303
en = rp->typedata.text->entry_data;
3305
ptext = evas_object_textblock_text_markup_get(rp->object);
3306
// some simple "do nothing if the text is the same" logic
3307
if (ptext == text) return;
3308
// if prev and cur is empty
3309
if (!ptext) ptext = "";
3310
if (!text) text = "";
3311
if ((!ptext[0]) && (!text[0])) return;
3313
if (!strcmp(ptext, text)) return;
3315
_edje_entry_imf_context_reset(rp);
3316
// set text as markup
3317
_sel_clear(en->ed, en->cursor, rp->object, en);
3318
evas_object_textblock_text_markup_set(rp->object, text);
3319
_edje_entry_set_cursor_start(rp);
3321
_anchors_get(en->cursor, rp->object, en);
3322
_edje_emit(en->ed, "entry,changed", rp->part->name);
3323
_edje_entry_imf_cursor_info_set(en);
3325
_edje_entry_real_part_configure(en->ed, rp);
3327
/* Don't emit cursor changed cause it didn't. It's just init to 0. */
3328
_edje_emit(en->ed, "cursor,changed", rp->part->name);
3333
_edje_entry_text_markup_append(Edje_Real_Part *rp, const char *text)
3337
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3338
(!rp->typedata.text)) return;
3339
en = rp->typedata.text->entry_data;
3340
Evas_Textblock_Cursor *end_cur;
3342
end_cur = evas_object_textblock_cursor_new(rp->object);
3343
evas_textblock_cursor_paragraph_last(end_cur);
3345
_text_filter_markup_prepend(en->ed, en, end_cur, text, NULL, NULL,
3346
EINA_TRUE, EINA_FALSE);
3347
evas_textblock_cursor_free(end_cur);
3349
/* We are updating according to the real cursor on purpose */
3350
_anchors_get(en->cursor, rp->object, en);
3351
_edje_emit(en->ed, "entry,changed", rp->part->name);
3353
_edje_entry_real_part_configure(en->ed, rp);
3357
_edje_entry_text_markup_insert(Edje_Real_Part *rp, const char *text)
3361
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3362
(!rp->typedata.text)) return;
3363
en = rp->typedata.text->entry_data;
3365
_edje_entry_imf_context_reset(rp);
3367
_text_filter_markup_prepend(en->ed, en, en->cursor, text, NULL, NULL,
3368
EINA_TRUE, EINA_FALSE);
3369
_anchors_get(en->cursor, rp->object, en);
3370
_edje_emit(en->ed, "entry,changed", rp->part->name);
3371
_edje_emit(en->ed, "cursor,changed", rp->part->name);
3373
_edje_entry_imf_cursor_info_set(en);
3374
_edje_entry_real_part_configure(en->ed, rp);
3378
_edje_entry_set_cursor_start(Edje_Real_Part *rp)
3382
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3383
(!rp->typedata.text)) return;
3384
en = rp->typedata.text->entry_data;
3386
_curs_start(en->cursor, rp->object, en);
3388
_edje_entry_imf_cursor_info_set(en);
3392
_edje_entry_set_cursor_end(Edje_Real_Part *rp)
3396
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3397
(!rp->typedata.text)) return;
3398
en = rp->typedata.text->entry_data;
3400
_curs_end(en->cursor, rp->object, en);
3402
_edje_entry_imf_cursor_info_set(en);
3406
_edje_entry_select_none(Edje_Real_Part *rp)
3410
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3411
(!rp->typedata.text)) return;
3412
en = rp->typedata.text->entry_data;
3414
_sel_clear(en->ed, en->cursor, rp->object, en);
3418
_edje_entry_select_all(Edje_Real_Part *rp)
3422
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3423
(!rp->typedata.text)) return;
3424
en = rp->typedata.text->entry_data;
3427
_edje_entry_imf_context_reset(rp);
3429
_sel_clear(en->ed, en->cursor, rp->object, en);
3430
_curs_start(en->cursor, rp->object, en);
3431
_edje_entry_imf_context_reset(en->rp);
3432
_sel_start(en->cursor, rp->object, en);
3433
_curs_end(en->cursor, rp->object, en);
3434
_sel_extend(en->ed, en->cursor, rp->object, en);
3436
_edje_entry_real_part_configure(en->ed, rp);
3440
_edje_entry_select_begin(Edje_Real_Part *rp)
3444
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3445
(!rp->typedata.text)) return;
3446
en = rp->typedata.text->entry_data;
3449
_sel_clear(en->ed, en->cursor, rp->object, en);
3450
_sel_enable(en->ed, en->cursor, rp->object, en);
3451
_sel_start(en->cursor, rp->object, en);
3452
_sel_extend(en->ed, en->cursor, rp->object, en);
3454
_edje_entry_real_part_configure(en->ed, rp);
3458
_edje_entry_select_extend(Edje_Real_Part *rp)
3462
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3463
(!rp->typedata.text)) return;
3464
en = rp->typedata.text->entry_data;
3466
_sel_extend(en->ed, en->cursor, rp->object, en);
3468
_edje_entry_real_part_configure(en->ed, rp);
3472
_edje_entry_anchor_geometry_get(Edje_Real_Part *rp, const char *anchor)
3478
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3479
(!rp->typedata.text)) return NULL;
3480
en = rp->typedata.text->entry_data;
3481
if (!en) return NULL;
3482
/* Update the anchors first in case entry is not inside the canvas
3484
_anchors_need_update(rp);
3485
EINA_LIST_FOREACH(en->anchors, l, an)
3487
const char *n = an->name;
3488
if ((an->item) || (!n)) continue;
3489
if (!strcmp(anchor, n))
3496
_edje_entry_anchors_list(Edje_Real_Part *rp)
3499
Eina_List *l, *anchors = NULL;
3502
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3503
(!rp->typedata.text)) return NULL;
3504
en = rp->typedata.text->entry_data;
3505
if (!en) return NULL;
3506
/* Update the anchors first in case entry is not inside the canvas
3508
_anchors_need_update(rp);
3509
if (!en->anchorlist)
3511
EINA_LIST_FOREACH(en->anchors, l, an)
3513
const char *n = an->name;
3514
if ((an->item) || (!n)) continue;
3515
anchors = eina_list_append(anchors, strdup(n));
3517
en->anchorlist = anchors;
3519
return en->anchorlist;
3523
_edje_entry_item_geometry_get(Edje_Real_Part *rp, const char *item, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
3529
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3530
(!rp->typedata.text)) return EINA_FALSE;
3531
en = rp->typedata.text->entry_data;
3532
if (!en) return EINA_FALSE;
3533
EINA_LIST_FOREACH(en->anchors, l, an)
3535
const char *n = an->name;
3536
if (!an->item) continue;
3538
if (!strcmp(item, n))
3540
evas_textblock_cursor_format_item_geometry_get(an->start, cx, cy, cw, ch);
3548
_edje_entry_items_list(Edje_Real_Part *rp)
3551
Eina_List *l, *items = NULL;
3554
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3555
(!rp->typedata.text)) return NULL;
3556
en = rp->typedata.text->entry_data;
3557
if (!en) return NULL;
3558
/* Update the anchors first in case entry is not inside the canvas
3560
_anchors_need_update(rp);
3563
EINA_LIST_FOREACH(en->anchors, l, an)
3565
const char *n = an->name;
3566
if (!an->item) continue;
3568
items = eina_list_append(items, strdup(n));
3570
en->itemlist = items;
3572
return en->itemlist;
3576
_edje_entry_cursor_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_BiDi_Direction *cdir)
3578
Evas_Coord x, y, w, h, xx, yy, ww, hh;
3580
Evas_Textblock_Cursor_Type cur_type;
3581
Evas_BiDi_Direction dir;
3583
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3584
(!rp->typedata.text)) return;
3585
en = rp->typedata.text->entry_data;
3587
switch (rp->part->cursor_mode)
3589
case EDJE_ENTRY_CURSOR_MODE_BEFORE:
3590
cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
3593
case EDJE_ENTRY_CURSOR_MODE_UNDER:
3594
/* no break for a reason */
3596
cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
3600
xx = yy = ww = hh = -1;
3601
evas_object_geometry_get(rp->object, &x, &y, &w, &h);
3602
evas_textblock_cursor_geometry_get(en->cursor, &xx, &yy, &ww, &hh, &dir, cur_type);
3604
if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
3605
edje_object_size_min_restricted_calc(en->cursor_fg, &ww, NULL, ww, 0);
3607
if (cx) *cx = x + xx;
3608
if (cy) *cy = y + yy;
3611
if (cdir) *cdir = dir;
3615
_edje_entry_user_insert(Edje_Real_Part *rp, const char *text)
3618
Edje_Entry_Change_Info *info;
3620
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3621
(!rp->typedata.text)) return;
3622
en = rp->typedata.text->entry_data;
3624
_edje_entry_imf_context_reset(rp);
3625
info = _text_filter_markup_prepend(en->ed, en, en->cursor, text, NULL, NULL,
3626
EINA_TRUE, EINA_TRUE);
3627
_anchors_get(en->cursor, rp->object, en);
3630
_edje_emit(en->ed, "entry,changed", rp->part->name);
3631
_edje_emit_full(en->ed, "entry,changed,user", rp->part->name,
3632
info, _free_entry_change_info);
3633
_edje_emit(en->ed, "cursor,changed", rp->part->name);
3636
_edje_entry_imf_cursor_info_set(en);
3637
_edje_entry_real_part_configure(en->ed, rp);
3641
_edje_entry_select_allow_set(Edje_Real_Part *rp, Eina_Bool allow)
3645
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3646
(!rp->typedata.text)) return;
3647
en = rp->typedata.text->entry_data;
3650
en->select_allow = allow;
3654
_edje_entry_select_allow_get(const Edje_Real_Part *rp)
3658
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3659
(!rp->typedata.text)) return EINA_FALSE;
3660
en = rp->typedata.text->entry_data;
3661
if (!en) return EINA_FALSE;
3662
return en->select_allow;
3666
_edje_entry_select_abort(Edje_Real_Part *rp)
3670
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3671
(!rp->typedata.text)) return;
3672
en = rp->typedata.text->entry_data;
3676
en->selecting = EINA_FALSE;
3678
_edje_entry_imf_context_reset(rp);
3679
_edje_entry_imf_cursor_info_set(en);
3680
_edje_entry_real_part_configure(en->ed, rp);
3685
_edje_entry_imf_context_get(Edje_Real_Part *rp)
3687
#ifdef HAVE_ECORE_IMF
3690
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3691
(!rp->typedata.text)) return NULL;
3692
en = rp->typedata.text->entry_data;
3693
if (!en) return NULL;
3695
return en->imf_context;
3703
_edje_entry_autocapital_type_set(Edje_Real_Part *rp, Edje_Text_Autocapital_Type autocapital_type)
3705
#ifdef HAVE_ECORE_IMF
3708
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3709
(!rp->typedata.text)) return;
3710
en = rp->typedata.text->entry_data;
3713
if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
3714
autocapital_type = EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
3716
if (en->imf_context)
3717
ecore_imf_context_autocapital_type_set(en->imf_context, (Ecore_IMF_Autocapital_Type)autocapital_type);
3720
(void)autocapital_type;
3724
Edje_Text_Autocapital_Type
3725
_edje_entry_autocapital_type_get(Edje_Real_Part *rp)
3727
#ifdef HAVE_ECORE_IMF
3730
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3731
(!rp->typedata.text)) return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
3732
en = rp->typedata.text->entry_data;
3733
if (!en) return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
3735
if (en->imf_context)
3736
return (Edje_Text_Autocapital_Type)ecore_imf_context_autocapital_type_get(en->imf_context);
3737
return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
3739
return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
3745
_edje_entry_prediction_allow_set(Edje_Real_Part *rp, Eina_Bool prediction)
3749
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3750
(!rp->typedata.text)) return;
3751
en = rp->typedata.text->entry_data;
3753
en->prediction_allow = prediction;
3754
#ifdef HAVE_ECORE_IMF
3755
if (en->imf_context)
3756
ecore_imf_context_prediction_allow_set(en->imf_context, prediction);
3761
_edje_entry_prediction_allow_get(Edje_Real_Part *rp)
3765
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3766
(!rp->typedata.text)) return EINA_FALSE;
3767
en = rp->typedata.text->entry_data;
3768
if (!en) return EINA_FALSE;
3769
return en->prediction_allow;
3773
_edje_entry_input_hint_set(Edje_Real_Part *rp, Edje_Input_Hints input_hints)
3777
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3778
(!rp->typedata.text)) return;
3779
en = rp->typedata.text->entry_data;
3781
#ifdef HAVE_ECORE_IMF
3782
if (en->imf_context)
3783
ecore_imf_context_input_hint_set(en->imf_context, (Ecore_IMF_Input_Hints)input_hints);
3790
_edje_entry_input_hint_get(const Edje_Real_Part *rp)
3794
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3795
(!rp->typedata.text)) return EDJE_INPUT_HINT_NONE;
3796
en = rp->typedata.text->entry_data;
3797
if (!en) return EDJE_INPUT_HINT_NONE;
3798
#ifdef HAVE_ECORE_IMF
3799
if (en->imf_context)
3800
return (Edje_Input_Hints)ecore_imf_context_input_hint_get(en->imf_context);
3803
return EDJE_INPUT_HINT_NONE;
3807
_edje_entry_input_panel_enabled_set(Edje_Real_Part *rp, Eina_Bool enabled)
3811
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3812
(!rp->typedata.text)) return;
3813
en = rp->typedata.text->entry_data;
3815
en->input_panel_enable = enabled;
3816
#ifdef HAVE_ECORE_IMF
3817
if (en->imf_context)
3818
ecore_imf_context_input_panel_enabled_set(en->imf_context, enabled);
3823
_edje_entry_input_panel_enabled_get(Edje_Real_Part *rp)
3827
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3828
(!rp->typedata.text)) return EINA_FALSE;
3829
en = rp->typedata.text->entry_data;
3830
if (!en) return EINA_FALSE;
3831
return en->input_panel_enable;
3835
_edje_entry_input_panel_show(Edje_Real_Part *rp)
3837
#ifdef HAVE_ECORE_IMF
3840
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3841
(!rp->typedata.text)) return;
3842
en = rp->typedata.text->entry_data;
3844
if (en->imf_context)
3845
ecore_imf_context_input_panel_show(en->imf_context);
3852
_edje_entry_input_panel_hide(Edje_Real_Part *rp)
3854
#ifdef HAVE_ECORE_IMF
3857
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3858
(!rp->typedata.text)) return;
3859
en = rp->typedata.text->entry_data;
3861
if (en->imf_context)
3862
ecore_imf_context_input_panel_hide(en->imf_context);
3869
_edje_entry_input_panel_language_set(Edje_Real_Part *rp, Edje_Input_Panel_Lang lang)
3873
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3874
(!rp->typedata.text)) return;
3875
en = rp->typedata.text->entry_data;
3877
en->input_panel_lang = lang;
3878
#ifdef HAVE_ECORE_IMF
3879
if (en->imf_context)
3880
ecore_imf_context_input_panel_language_set(en->imf_context, (Ecore_IMF_Input_Panel_Lang)lang);
3884
Edje_Input_Panel_Lang
3885
_edje_entry_input_panel_language_get(Edje_Real_Part *rp)
3889
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3890
(!rp->typedata.text)) return EDJE_INPUT_PANEL_LANG_AUTOMATIC;
3891
en = rp->typedata.text->entry_data;
3892
if (!en) return EDJE_INPUT_PANEL_LANG_AUTOMATIC;
3893
return en->input_panel_lang;
3897
_edje_entry_input_panel_imdata_set(Edje_Real_Part *rp, const void *data, int len)
3899
#ifdef HAVE_ECORE_IMF
3902
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3903
(!rp->typedata.text)) return;
3904
en = rp->typedata.text->entry_data;
3906
if (en->imf_context)
3907
ecore_imf_context_input_panel_imdata_set(en->imf_context, data, len);
3916
_edje_entry_input_panel_imdata_get(Edje_Real_Part *rp, void *data, int *len)
3918
#ifdef HAVE_ECORE_IMF
3921
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3922
(!rp->typedata.text)) return;
3923
en = rp->typedata.text->entry_data;
3925
if (en->imf_context)
3926
ecore_imf_context_input_panel_imdata_get(en->imf_context, data, len);
3935
_edje_entry_input_panel_return_key_type_set(Edje_Real_Part *rp, Edje_Input_Panel_Return_Key_Type return_key_type)
3937
#ifdef HAVE_ECORE_IMF
3940
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3941
(!rp->typedata.text)) return;
3942
en = rp->typedata.text->entry_data;
3944
if (en->imf_context)
3945
ecore_imf_context_input_panel_return_key_type_set(en->imf_context, (Ecore_IMF_Input_Panel_Return_Key_Type)return_key_type);
3948
(void)return_key_type;
3952
Edje_Input_Panel_Return_Key_Type
3953
_edje_entry_input_panel_return_key_type_get(Edje_Real_Part *rp)
3955
#ifdef HAVE_ECORE_IMF
3958
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3959
(!rp->typedata.text)) return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3960
en = rp->typedata.text->entry_data;
3961
if (!en) return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3962
if (en->imf_context)
3963
return (Edje_Input_Panel_Return_Key_Type)ecore_imf_context_input_panel_return_key_type_get(en->imf_context);
3964
return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3966
return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3972
_edje_entry_input_panel_return_key_disabled_set(Edje_Real_Part *rp, Eina_Bool disabled)
3974
#ifdef HAVE_ECORE_IMF
3977
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3978
(!rp->typedata.text)) return;
3979
en = rp->typedata.text->entry_data;
3981
if (en->imf_context)
3982
ecore_imf_context_input_panel_return_key_disabled_set(en->imf_context, disabled);
3990
_edje_entry_input_panel_return_key_disabled_get(Edje_Real_Part *rp)
3992
#ifdef HAVE_ECORE_IMF
3995
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3996
(!rp->typedata.text)) return EINA_FALSE;
3997
en = rp->typedata.text->entry_data;
3998
if (!en) return EINA_FALSE;
3999
if (en->imf_context)
4000
return ecore_imf_context_input_panel_return_key_disabled_get(en->imf_context);
4008
#ifdef HAVE_ECORE_IMF
4010
_edje_entry_input_panel_show_on_demand_set(Edje_Real_Part *rp, Eina_Bool ondemand)
4013
_edje_entry_input_panel_show_on_demand_set(Edje_Real_Part *rp, Eina_Bool ondemand EINA_UNUSED)
4018
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4019
(!rp->typedata.text)) return;
4020
en = rp->typedata.text->entry_data;
4022
#ifdef HAVE_ECORE_IMF
4023
if (en->imf_context)
4024
ecore_imf_context_input_panel_show_on_demand_set(en->imf_context, ondemand);
4029
_edje_entry_input_panel_show_on_demand_get(Edje_Real_Part *rp)
4033
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4034
(!rp->typedata.text)) return EINA_FALSE;
4035
en = rp->typedata.text->entry_data;
4036
if (!en) return EINA_FALSE;
4037
#ifdef HAVE_ECORE_IMF
4038
if (en->imf_context)
4040
Eina_Bool ret = ecore_imf_context_input_panel_show_on_demand_get(en->imf_context);
4047
static Evas_Textblock_Cursor *
4048
_cursor_get(Edje_Real_Part *rp, Edje_Cursor cur)
4052
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4053
(!rp->typedata.text)) return NULL;
4054
en = rp->typedata.text->entry_data;
4055
if (!en) return NULL;
4058
case EDJE_CURSOR_MAIN:
4061
case EDJE_CURSOR_SELECTION_BEGIN:
4062
return en->sel_start;
4064
case EDJE_CURSOR_SELECTION_END:
4067
case EDJE_CURSOR_PREEDIT_START:
4068
if (!en->preedit_start)
4069
en->preedit_start = evas_object_textblock_cursor_new(rp->object);
4070
return en->preedit_start;
4072
case EDJE_CURSOR_PREEDIT_END:
4073
if (!en->preedit_end)
4074
en->preedit_end = evas_object_textblock_cursor_new(rp->object);
4075
return en->preedit_end;
4077
case EDJE_CURSOR_USER:
4078
if (!en->cursor_user)
4079
en->cursor_user = evas_object_textblock_cursor_new(rp->object);
4080
return en->cursor_user;
4082
case EDJE_CURSOR_USER_EXTRA:
4083
if (!en->cursor_user_extra)
4084
en->cursor_user_extra = evas_object_textblock_cursor_new(rp->object);
4085
return en->cursor_user_extra;
4094
_edje_text_cursor_next(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c)
4098
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4099
(!rp->typedata.text)) return EINA_FALSE;
4100
en = rp->typedata.text->entry_data;
4101
if (!en) return EINA_FALSE;
4103
if (!c) return EINA_FALSE;
4105
_edje_entry_imf_context_reset(rp);
4107
if (!evas_textblock_cursor_cluster_next(c))
4111
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
4112
_edje_entry_imf_cursor_info_set(en);
4114
_edje_emit(en->ed, "cursor,changed", rp->part->name);
4115
_edje_entry_real_part_configure(en->ed, rp);
4120
_edje_entry_cursor_next(Edje_Real_Part *rp, Edje_Cursor cur)
4122
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4123
return _edje_text_cursor_next(rp, c);
4128
_edje_text_cursor_prev(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c)
4132
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4133
(!rp->typedata.text)) return EINA_FALSE;
4134
en = rp->typedata.text->entry_data;
4135
if (!en) return EINA_FALSE;
4136
if (!c) return EINA_FALSE;
4138
_edje_entry_imf_context_reset(rp);
4140
if (!evas_textblock_cursor_cluster_prev(c))
4142
if (evas_textblock_cursor_paragraph_prev(c)) goto ok;
4143
else return EINA_FALSE;
4146
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
4148
_edje_entry_imf_cursor_info_set(en);
4150
_edje_emit(en->ed, "cursor,changed", rp->part->name);
4151
_edje_entry_real_part_configure(en->ed, rp);
4156
_edje_entry_cursor_prev(Edje_Real_Part *rp, Edje_Cursor cur)
4158
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4159
return _edje_text_cursor_prev(rp, c);
4163
_edje_text_cursor_up(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c)
4166
Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
4169
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4170
(!rp->typedata.text)) return EINA_FALSE;
4171
en = rp->typedata.text->entry_data;
4172
if (!en) return EINA_FALSE;
4173
if (!c) return EINA_FALSE;
4175
_edje_entry_imf_context_reset(rp);
4177
ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL);
4179
if (ln < 0) return EINA_FALSE;
4180
if (!evas_object_textblock_line_number_geometry_get(rp->object, ln,
4181
&lx, &ly, &lw, &lh))
4183
evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
4184
if (!evas_textblock_cursor_cluster_coord_set(c, cx, ly + (lh / 2)))
4185
evas_textblock_cursor_line_char_last(c);
4186
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
4188
_edje_entry_imf_cursor_info_set(en);
4190
_edje_emit(en->ed, "cursor,changed", rp->part->name);
4191
_edje_entry_real_part_configure(en->ed, rp);
4196
_edje_entry_cursor_up(Edje_Real_Part *rp, Edje_Cursor cur)
4198
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4199
return _edje_text_cursor_up(rp, c);
4203
_edje_text_cursor_down(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c)
4206
Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
4209
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4210
(!rp->typedata.text)) return EINA_FALSE;
4211
en = rp->typedata.text->entry_data;
4212
if (!en) return EINA_FALSE;
4213
if (!c) return EINA_FALSE;
4215
_edje_entry_imf_context_reset(rp);
4217
ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL);
4219
if (!evas_object_textblock_line_number_geometry_get(rp->object, ln,
4220
&lx, &ly, &lw, &lh))
4222
evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
4223
if (!evas_textblock_cursor_cluster_coord_set(c, cx, ly + (lh / 2)))
4224
evas_textblock_cursor_line_char_last(c);
4226
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
4228
_edje_entry_imf_cursor_info_set(en);
4229
_edje_emit(en->ed, "cursor,changed", rp->part->name);
4230
_edje_entry_real_part_configure(en->ed, rp);
4235
_edje_entry_cursor_down(Edje_Real_Part *rp, Edje_Cursor cur)
4237
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4238
return _edje_text_cursor_down(rp, c);
4242
_edje_text_cursor_begin(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c)
4247
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4248
(!rp->typedata.text)) return;
4249
en = rp->typedata.text->entry_data;
4253
_edje_entry_imf_context_reset(rp);
4255
old_cur_pos = evas_textblock_cursor_pos_get(c);
4256
evas_textblock_cursor_paragraph_first(c);
4258
if (old_cur_pos == evas_textblock_cursor_pos_get(c))
4261
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
4263
_edje_entry_imf_cursor_info_set(en);
4264
_edje_emit(en->ed, "cursor,changed", rp->part->name);
4265
_edje_entry_real_part_configure(en->ed, rp);
4269
_edje_entry_cursor_begin(Edje_Real_Part *rp, Edje_Cursor cur)
4271
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4272
_edje_text_cursor_begin(rp, c);
4277
_edje_text_cursor_end(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c)
4282
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4283
(!rp->typedata.text)) return;
4284
en = rp->typedata.text->entry_data;
4288
_edje_entry_imf_context_reset(rp);
4290
old_cur_pos = evas_textblock_cursor_pos_get(c);
4291
_curs_end(c, rp->object, rp->typedata.text->entry_data);
4293
if (old_cur_pos == evas_textblock_cursor_pos_get(c))
4296
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
4298
_edje_entry_imf_cursor_info_set(en);
4300
_edje_emit(en->ed, "cursor,changed", rp->part->name);
4301
_edje_entry_real_part_configure(en->ed, rp);
4304
_edje_entry_cursor_end(Edje_Real_Part *rp, Edje_Cursor cur)
4306
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4307
_edje_text_cursor_end(rp, c);
4311
_edje_text_cursor_copy(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *d, Efl_Text_Cursor_Handle *c)
4315
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4316
(!rp->typedata.text)) return;
4317
en = rp->typedata.text->entry_data;
4319
evas_textblock_cursor_copy(c, d);
4320
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
4322
_edje_entry_imf_context_reset(rp);
4323
_edje_entry_imf_cursor_info_set(en);
4324
_edje_emit(en->ed, "cursor,changed", rp->part->name);
4325
_edje_entry_real_part_configure(en->ed, rp);
4329
_edje_entry_cursor_copy(Edje_Real_Part *rp, Edje_Cursor cur, Edje_Cursor dst)
4331
Evas_Textblock_Cursor *c;
4332
Evas_Textblock_Cursor *d;
4333
c = _cursor_get(rp, cur);
4335
d = _cursor_get(rp, dst);
4337
_edje_text_cursor_copy(rp, d, c);
4341
_edje_text_cursor_line_begin(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c)
4346
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4347
(!rp->typedata.text)) return;
4348
en = rp->typedata.text->entry_data;
4351
_edje_entry_imf_context_reset(rp);
4353
old_cur_pos = evas_textblock_cursor_pos_get(c);
4354
evas_textblock_cursor_line_char_first(c);
4356
if (old_cur_pos == evas_textblock_cursor_pos_get(c))
4359
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
4361
_edje_entry_imf_cursor_info_set(en);
4363
_edje_emit(en->ed, "cursor,changed", rp->part->name);
4364
_edje_entry_real_part_configure(en->ed, rp);
4368
_edje_entry_cursor_line_begin(Edje_Real_Part *rp, Edje_Cursor cur)
4370
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4371
_edje_text_cursor_line_begin(rp, c);
4375
_edje_text_cursor_line_end(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c)
4380
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4381
(!rp->typedata.text)) return;
4382
en = rp->typedata.text->entry_data;
4385
_edje_entry_imf_context_reset(rp);
4387
old_cur_pos = evas_textblock_cursor_pos_get(c);
4388
evas_textblock_cursor_line_char_last(c);
4390
if (old_cur_pos == evas_textblock_cursor_pos_get(c))
4393
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
4395
_edje_entry_imf_cursor_info_set(en);
4396
_edje_emit(en->ed, "cursor,changed", rp->part->name);
4397
_edje_entry_real_part_configure(en->ed, rp);
4401
_edje_entry_cursor_line_end(Edje_Real_Part *rp, Edje_Cursor cur)
4403
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4404
_edje_text_cursor_line_end(rp, c);
4408
_edje_text_cursor_coord_set(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c,
4409
Evas_Coord x, Evas_Coord y)
4411
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4412
(!rp->typedata.text)) return EINA_FALSE;
4413
Entry *en = rp->typedata.text->entry_data;
4414
if (!en) return EINA_FALSE;
4415
if ((c == _cursor_get(rp, EDJE_CURSOR_SELECTION_BEGIN)) ||
4416
(c == _cursor_get(rp, EDJE_CURSOR_SELECTION_END)))
4418
if (en->have_selection)
4422
free(en->selection);
4423
en->selection = NULL;
4425
_edje_emit(en->ed, "selection,changed", rp->part->name);
4428
return evas_textblock_cursor_cluster_coord_set(c, x, y);
4432
_edje_entry_cursor_coord_set(Edje_Real_Part *rp, Edje_Cursor cur,
4433
Evas_Coord x, Evas_Coord y)
4435
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4436
if (!c) return EINA_FALSE;
4437
return _edje_text_cursor_coord_set(rp, c, x, y);
4441
_edje_entry_cursor_is_format_get(Edje_Real_Part *rp, Edje_Cursor cur)
4443
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4444
if (!c) return EINA_FALSE;
4445
if (evas_textblock_cursor_is_format(c)) return EINA_TRUE;
4450
_edje_entry_cursor_is_visible_format_get(Edje_Real_Part *rp, Edje_Cursor cur)
4452
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4453
if (!c) return EINA_FALSE;
4454
return evas_textblock_cursor_format_is_visible_get(c);
4458
_edje_text_cursor_content_get(Edje_Real_Part *rp EINA_UNUSED, Efl_Text_Cursor_Handle *c)
4460
return evas_textblock_cursor_content_get(c);
4464
_edje_entry_cursor_content_get(Edje_Real_Part *rp, Edje_Cursor cur)
4466
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4468
if (!c) return NULL;
4470
return _edje_text_cursor_content_get(rp, c);
4474
_edje_text_cursor_pos_set(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c, int pos)
4476
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4477
(!rp->typedata.text)) return;
4478
Entry *en = rp->typedata.text->entry_data;
4481
/* Abort if cursor position didn't really change */
4482
if (evas_textblock_cursor_pos_get(c) == pos)
4485
_edje_entry_imf_context_reset(rp);
4486
evas_textblock_cursor_pos_set(c, pos);
4487
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
4489
_edje_entry_imf_cursor_info_set(en);
4490
_edje_emit(en->ed, "cursor,changed", rp->part->name);
4491
_edje_entry_real_part_configure(en->ed, rp);
4495
_edje_entry_cursor_pos_set(Edje_Real_Part *rp, Edje_Cursor cur, int pos)
4497
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4499
_edje_text_cursor_pos_set(rp, c, pos);
4503
_edje_text_cursor_pos_get(Edje_Real_Part *rp EINA_UNUSED, Efl_Text_Cursor_Handle *c)
4505
return evas_textblock_cursor_pos_get(c);
4509
_edje_entry_cursor_pos_get(Edje_Real_Part *rp, Edje_Cursor cur)
4511
Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4513
return _edje_text_cursor_pos_get(rp, c);
4517
_edje_entry_input_panel_layout_set(Edje_Real_Part *rp, Edje_Input_Panel_Layout layout)
4519
#ifdef HAVE_ECORE_IMF
4522
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4523
(!rp->typedata.text)) return;
4524
en = rp->typedata.text->entry_data;
4526
if (en->imf_context)
4527
ecore_imf_context_input_panel_layout_set(en->imf_context, (Ecore_IMF_Input_Panel_Layout)layout);
4534
Edje_Input_Panel_Layout
4535
_edje_entry_input_panel_layout_get(Edje_Real_Part *rp)
4537
#ifdef HAVE_ECORE_IMF
4540
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4541
(!rp->typedata.text)) return EDJE_INPUT_PANEL_LAYOUT_INVALID;
4542
en = rp->typedata.text->entry_data;
4543
if (!en) return EDJE_INPUT_PANEL_LAYOUT_INVALID;
4544
if (en->imf_context)
4545
return (Edje_Input_Panel_Layout)ecore_imf_context_input_panel_layout_get(en->imf_context);
4546
return EDJE_INPUT_PANEL_LAYOUT_INVALID;
4548
return EDJE_INPUT_PANEL_LAYOUT_INVALID;
4554
_edje_entry_input_panel_layout_variation_set(Edje_Real_Part *rp, int variation)
4558
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4559
(!rp->typedata.text)) return;
4560
en = rp->typedata.text->entry_data;
4562
#ifdef HAVE_ECORE_IMF
4563
if (en->imf_context)
4564
ecore_imf_context_input_panel_layout_variation_set(en->imf_context, variation);
4571
_edje_entry_input_panel_layout_variation_get(Edje_Real_Part *rp)
4575
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4576
(!rp->typedata.text)) return 0;
4577
en = rp->typedata.text->entry_data;
4579
#ifdef HAVE_ECORE_IMF
4580
if (en->imf_context)
4581
return ecore_imf_context_input_panel_layout_variation_get(en->imf_context);
4588
_edje_entry_imf_context_reset(Edje_Real_Part *rp)
4590
#ifdef HAVE_ECORE_IMF
4593
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4594
(!rp->typedata.text)) return;
4595
en = rp->typedata.text->entry_data;
4597
if (en->imf_context)
4598
ecore_imf_context_reset(en->imf_context);
4599
if (en->commit_cancel)
4600
en->commit_cancel = EINA_FALSE;
4607
_edje_entry_imf_cursor_location_set(Entry *en)
4609
#ifdef HAVE_ECORE_IMF
4610
Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0;
4611
Evas_BiDi_Direction dir = 0;
4612
if (!en || !en->rp || !en->imf_context) return;
4614
_edje_entry_cursor_geometry_get(en->rp, &cx, &cy, &cw, &ch, &dir);
4615
ecore_imf_context_cursor_location_set(en->imf_context, cx, cy, cw, ch);
4616
ecore_imf_context_bidi_direction_set(en->imf_context, (Ecore_IMF_BiDi_Direction)dir);
4623
_edje_entry_imf_cursor_info_set(Entry *en)
4627
#ifdef HAVE_ECORE_IMF
4628
if (!en || !en->rp || !en->imf_context) return;
4630
if (en->have_selection)
4632
if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) < 0)
4633
cursor_pos = evas_textblock_cursor_pos_get(en->sel_start);
4635
cursor_pos = evas_textblock_cursor_pos_get(en->sel_end);
4638
cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
4640
ecore_imf_context_cursor_position_set(en->imf_context, cursor_pos);
4642
_edje_entry_imf_cursor_location_set(en);
4649
_edje_entry_prediction_hint_set(Edje_Real_Part *rp, const char *prediction_hint)
4653
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4654
(!rp->typedata.text)) return;
4655
en = rp->typedata.text->entry_data;
4657
#ifdef HAVE_ECORE_IMF
4658
if (en->imf_context)
4659
ecore_imf_context_prediction_hint_set(en->imf_context, prediction_hint);
4661
(void)prediction_hint;
4666
_edje_entry_prediction_hint_hash_set(Edje_Real_Part *rp, const char *key, const char *value)
4670
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4671
(!rp->typedata.text)) return EINA_FALSE;
4672
en = rp->typedata.text->entry_data;
4673
if (!en) return EINA_FALSE;
4674
#ifdef HAVE_ECORE_IMF
4675
if (en->imf_context)
4676
return ecore_imf_context_prediction_hint_hash_set(en->imf_context, key, value);
4686
_edje_entry_prediction_hint_hash_del(Edje_Real_Part *rp, const char *key)
4690
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4691
(!rp->typedata.text)) return EINA_FALSE;
4692
en = rp->typedata.text->entry_data;
4693
if (!en) return EINA_FALSE;
4694
#ifdef HAVE_ECORE_IMF
4695
if (en->imf_context)
4696
return ecore_imf_context_prediction_hint_hash_del(en->imf_context, key);
4704
#ifdef HAVE_ECORE_IMF
4706
static Edje_Real_Part *
4707
_edje_entry_imf_default_focused_rp_get(Edje *ed)
4709
Eina_Stringshare *seat_name;
4710
Efl_Input_Device *seat;
4713
e = evas_object_evas_get(ed->obj);
4714
seat = evas_default_device_get(e, EVAS_DEVICE_CLASS_SEAT);
4715
seat_name = _edje_seat_name_get(ed, seat);
4717
return _edje_focused_part_get(ed, seat_name);
4721
_edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, char **text, int *cursor_pos)
4729
rp = _edje_entry_imf_default_focused_rp_get(ed);
4730
if (!rp) return EINA_FALSE;
4731
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4732
(!rp->typedata.text)) return EINA_FALSE;
4734
en = rp->typedata.text->entry_data;
4735
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
4736
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
4741
str = _edje_entry_text_get(rp);
4744
plain_text = evas_textblock_text_markup_to_utf8(NULL, str);
4748
if (ecore_imf_context_input_hint_get(ctx) & ECORE_IMF_INPUT_HINT_SENSITIVE_DATA)
4752
size_t len = eina_unicode_utf8_get_len(plain_text);
4753
char *u_text = (char *)malloc(len * sizeof(char) + 1);
4761
while (eina_unicode_utf8_next_get(plain_text, &idx))
4769
plain_text = strdup(u_text);
4774
*text = strdup(plain_text);
4791
if (en->have_selection && en->sel_start)
4792
*cursor_pos = evas_textblock_cursor_pos_get(en->sel_start);
4793
else if (en->cursor)
4794
*cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
4803
_edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, void *event_info)
4808
char *commit_str = event_info;
4809
Edje_Entry_Change_Info *info = NULL;
4811
rp = _edje_entry_imf_default_focused_rp_get(ed);
4813
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4814
(!rp->typedata.text)) return;
4816
en = rp->typedata.text->entry_data;
4817
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
4818
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
4821
if (en->have_selection)
4823
if (strcmp(commit_str, ""))
4825
/* delete selected characters */
4826
_range_del_emit(ed, en->cursor, rp->object, en);
4827
_sel_clear(ed, en->cursor, rp->object, en);
4831
/* delete preedit characters */
4835
// Skipping commit process when it is useless
4836
if (en->commit_cancel)
4838
en->commit_cancel = EINA_FALSE;
4842
if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
4843
_edje_password_show_last)
4844
_edje_entry_hide_visible_password(ed, en->rp);
4845
if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
4846
_edje_password_show_last && (!en->preedit_start))
4848
info = _text_filter_text_prepend(ed, en, en->cursor, commit_str,
4849
"+ password=off", "- password",
4850
EINA_TRUE, EINA_TRUE);
4855
ecore_timer_del(en->pw_timer);
4856
en->pw_timer = NULL;
4858
if (_edje_password_show_last_timeout >= 0)
4859
en->pw_timer = ecore_timer_add
4860
(_edje_password_show_last_timeout,
4861
_password_timer_cb, en);
4866
info = _text_filter_text_prepend(ed, en, en->cursor, commit_str,
4868
EINA_TRUE, EINA_TRUE);
4871
_edje_entry_imf_cursor_info_set(en);
4872
_anchors_get(en->cursor, rp->object, en);
4875
_edje_emit(ed, "entry,changed", rp->part->name);
4876
_edje_emit_full(ed, "entry,changed,user", rp->part->name,
4877
info, _free_entry_change_info);
4878
_edje_emit(ed, "cursor,changed", rp->part->name);
4880
_edje_entry_imf_cursor_info_set(en);
4881
_edje_entry_real_part_configure(ed, rp);
4885
_sort_cb(const void *a1, const void *a2)
4887
Ecore_IMF_Preedit_Attr *attr1 = (Ecore_IMF_Preedit_Attr *)a1;
4888
Ecore_IMF_Preedit_Attr *attr2 = (Ecore_IMF_Preedit_Attr *)a2;
4890
EINA_SAFETY_ON_NULL_RETURN_VAL(attr1, 0);
4891
EINA_SAFETY_ON_NULL_RETURN_VAL(attr2, 0);
4893
if (attr1->start_index < attr2->start_index) return -1;
4894
else if (attr1->start_index == attr2->start_index) return 0;
4899
_edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, void *event_info EINA_UNUSED)
4904
Edje_Entry_Change_Info *info = NULL;
4906
int preedit_start_pos, preedit_end_pos;
4907
char *preedit_string;
4908
char *markup_txt = NULL;
4911
// XXX: FIXME: EFL2 - make these 2 preedit_sel's different for efl
4912
// 2.0 and beyond. maybe use "preedit_sel", "preedit_hilight",
4913
// See https://phab.enlightenment.org/D2980 for this issue
4914
"preedit_sel", "preedit_sel",
4915
"preedit_sub1", "preedit_sub2", "preedit_sub3", "preedit_sub4"
4918
size_t preedit_type_size = sizeof(tagname) / sizeof(tagname[0]);
4919
Eina_Bool preedit_end_state = EINA_FALSE;
4920
Eina_List *attrs = NULL, *l = NULL;
4921
Ecore_IMF_Preedit_Attr *attr;
4923
Eina_Strbuf *preedit_attr_str;
4925
rp = _edje_entry_imf_default_focused_rp_get(ed);
4928
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4929
(!rp->typedata.text)) return;
4931
en = rp->typedata.text->entry_data;
4932
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
4933
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
4936
if (!en->imf_context) return;
4938
ecore_imf_context_preedit_string_with_attributes_get(en->imf_context,
4940
&attrs, &cursor_pos);
4941
if (!preedit_string) return;
4943
if (!strcmp(preedit_string, ""))
4944
preedit_end_state = EINA_TRUE;
4946
if (en->have_selection && !preedit_end_state)
4947
_range_del_emit(ed, en->cursor, rp->object, en);
4949
/* delete preedit characters */
4952
preedit_start_pos = evas_textblock_cursor_pos_get(en->cursor);
4954
/* insert preedit character(s) */
4955
if (strlen(preedit_string) > 0)
4957
buf = eina_strbuf_new();
4960
attrs = eina_list_sort(attrs, 0, EINA_COMPARE_CB(_sort_cb));
4962
EINA_LIST_FOREACH(attrs, l, attr)
4964
if (attr->preedit_type < preedit_type_size)
4966
preedit_attr_str = eina_strbuf_new();
4967
if (preedit_attr_str)
4969
eina_strbuf_append_n(preedit_attr_str, preedit_string + attr->start_index, attr->end_index - attr->start_index);
4970
markup_txt = evas_textblock_text_utf8_to_markup(NULL, eina_strbuf_string_get(preedit_attr_str));
4974
if (tagname[attr->preedit_type])
4975
eina_strbuf_append_printf(buf, "<%s>%s</%s>", tagname[attr->preedit_type], markup_txt, tagname[attr->preedit_type]);
4977
eina_strbuf_append_printf(buf, "%s", markup_txt);
4980
eina_strbuf_free(preedit_attr_str);
4984
eina_strbuf_append(buf, preedit_string);
4989
eina_strbuf_append(buf, preedit_string);
4992
// For skipping useless commit
4993
if (!preedit_end_state)
4994
en->have_preedit = EINA_TRUE;
4996
if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
4997
_edje_password_show_last)
4999
_edje_entry_hide_visible_password(ed, en->rp);
5000
info = _text_filter_markup_prepend(ed, en, en->cursor,
5001
eina_strbuf_string_get(buf),
5004
EINA_TRUE, EINA_TRUE);
5009
ecore_timer_del(en->pw_timer);
5010
en->pw_timer = NULL;
5012
if (_edje_password_show_last_timeout >= 0)
5013
en->pw_timer = ecore_timer_add
5014
(_edje_password_show_last_timeout,
5015
_password_timer_cb, en);
5019
info = _text_filter_markup_prepend(ed, en, en->cursor,
5020
eina_strbuf_string_get(buf),
5022
EINA_TRUE, EINA_TRUE);
5023
eina_strbuf_free(buf);
5026
if (!preedit_end_state)
5028
/* set preedit start cursor */
5029
if (!en->preedit_start)
5030
en->preedit_start = evas_object_textblock_cursor_new(rp->object);
5031
evas_textblock_cursor_copy(en->cursor, en->preedit_start);
5033
/* set preedit end cursor */
5034
if (!en->preedit_end)
5035
en->preedit_end = evas_object_textblock_cursor_new(rp->object);
5036
evas_textblock_cursor_copy(en->cursor, en->preedit_end);
5038
preedit_end_pos = evas_textblock_cursor_pos_get(en->cursor);
5040
for (i = 0; i < (preedit_end_pos - preedit_start_pos); i++)
5042
evas_textblock_cursor_char_prev(en->preedit_start);
5045
en->have_preedit = EINA_TRUE;
5047
/* set cursor position */
5048
evas_textblock_cursor_pos_set(en->cursor, preedit_start_pos + cursor_pos);
5051
_edje_entry_imf_cursor_info_set(en);
5052
_anchors_get(en->cursor, rp->object, en);
5053
_edje_emit_full(ed, "preedit,changed", rp->part->name, info,
5054
_free_entry_change_info);
5055
_edje_emit(ed, "cursor,changed", rp->part->name);
5057
/* delete attribute list */
5060
EINA_LIST_FREE(attrs, attr)
5064
free(preedit_string);
5068
_edje_entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, void *event_info)
5073
Ecore_IMF_Event_Delete_Surrounding *ev = event_info;
5074
Evas_Textblock_Cursor *del_start, *del_end;
5075
Edje_Entry_Change_Info *info;
5080
rp = _edje_entry_imf_default_focused_rp_get(ed);
5082
if ((!rp) || (!ev)) return;
5083
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
5084
(!rp->typedata.text)) return;
5086
en = rp->typedata.text->entry_data;
5087
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
5088
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
5091
cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
5093
del_start = evas_object_textblock_cursor_new(en->rp->object);
5094
evas_textblock_cursor_pos_set(del_start, cursor_pos + ev->offset);
5096
del_end = evas_object_textblock_cursor_new(en->rp->object);
5097
evas_textblock_cursor_pos_set(del_end, cursor_pos + ev->offset + ev->n_chars);
5099
start = evas_textblock_cursor_pos_get(del_start);
5100
end = evas_textblock_cursor_pos_get(del_end);
5101
if (start == end) goto end;
5103
info = calloc(1, sizeof(*info));
5106
ERR("Running very low on memory");
5109
info->insert = EINA_FALSE;
5110
info->change.del.start = start;
5111
info->change.del.end = end;
5113
tmp = evas_textblock_cursor_range_text_get(del_start, del_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
5114
info->change.del.content = eina_stringshare_add(tmp);
5117
evas_textblock_cursor_range_delete(del_start, del_end);
5118
_anchors_get(en->cursor, rp->object, en);
5119
_anchors_update_check(ed, rp);
5121
_edje_emit(ed, "entry,changed", en->rp->part->name);
5122
_edje_emit_full(ed, "entry,changed,user", en->rp->part->name, info,
5123
_free_entry_change_info);
5124
_edje_emit(ed, "cursor,changed", en->rp->part->name);
5125
_edje_emit(ed, "cursor,changed,manual", en->rp->part->name);
5127
_edje_entry_imf_cursor_info_set(en);
5128
_edje_entry_real_part_configure(ed, rp);
5131
evas_textblock_cursor_free(del_start);
5132
evas_textblock_cursor_free(del_end);
5136
_edje_entry_imf_event_selection_set_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, void *event_info)
5141
Ecore_IMF_Event_Selection *ev = event_info;
5143
rp = _edje_entry_imf_default_focused_rp_get(ed);
5144
if ((!rp) || (!ev)) return;
5145
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
5146
(!rp->typedata.text)) return;
5148
en = rp->typedata.text->entry_data;
5149
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
5150
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
5153
if (ev->start == ev->end)
5155
_edje_entry_cursor_pos_set(rp, EDJE_CURSOR_MAIN, ev->start);
5159
_sel_clear(ed, en->cursor, rp->object, en);
5160
evas_textblock_cursor_pos_set(en->cursor, ev->start);
5161
_sel_enable(ed, en->cursor, rp->object, en);
5162
_sel_start(en->cursor, rp->object, en);
5163
evas_textblock_cursor_pos_set(en->cursor, ev->end);
5164
_sel_extend(ed, en->cursor, rp->object, en);
5167
_edje_entry_real_part_configure(en->ed, rp);
5171
_edje_entry_imf_retrieve_selection_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, char **text)
5176
const char *selection_text = NULL;
5178
rp = _edje_entry_imf_default_focused_rp_get(ed);
5179
if (!rp) return EINA_FALSE;
5180
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
5181
(!rp->typedata.text)) return EINA_FALSE;
5183
en = rp->typedata.text->entry_data;
5184
if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
5185
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
5188
if (en->have_selection)
5190
selection_text = _edje_entry_selection_get(rp);
5193
*text = selection_text ? strdup(selection_text) : NULL;
5195
return selection_text ? EINA_TRUE : EINA_FALSE;
5203
Evas_Textblock_Cursor *
5204
_edje_text_cursor_get(Edje_Real_Part *rp, Edje_Cursor cur)
5206
return _cursor_get(rp, cur);
5209
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/