1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #define EFL_LAYOUT_CALC_PROTECTED
6 #define EFL_ACCESS_OBJECT_PROTECTED
7 #define EFL_ACCESS_TEXT_PROTECTED
8 #define EFL_ACCESS_EDITABLE_TEXT_PROTECTED
9 #define ELM_LAYOUT_PROTECTED
10 #define EFL_UI_FOCUS_OBJECT_PROTECTED
11 #define EFL_UI_WIDGET_FOCUS_MANAGER_PROTECTED 1
12 #define EFL_ACCESS_WIDGET_ACTION_PROTECTED
13 #define EFL_PART_PROTECTED
14
15 #include <Elementary.h>
16 #include <Elementary_Cursor.h>
17 #include "elm_priv.h"
18 #include "elm_widget_entry.h"
19
20 #include "elm_entry_part.eo.h"
21 #include "elm_part_helper.h"
22 #include "elm_hoversel_eo.h"
23
24 #define MY_CLASS ELM_ENTRY_CLASS
25 #define MY_CLASS_PFX elm_entry
26
27 #define MY_CLASS_NAME "Elm_Entry"
28 #define MY_CLASS_NAME_LEGACY "elm_entry"
29
30 /* Maximum chunk size to be inserted to the entry at once
31 * FIXME: This size is arbitrary, should probably choose a better size.
32 * Possibly also find a way to set it to a low value for weak computers,
33 * and to a big value for better computers. */
34 #define ELM_ENTRY_CHUNK_SIZE 10000
35 #define ELM_ENTRY_DELAY_WRITE_TIME 2.0
36
37 #define ELM_PRIV_ENTRY_SIGNALS(cmd) \
38 cmd(SIG_ABORTED, "aborted", "") \
39 cmd(SIG_ACTIVATED, "activated", "") \
40 cmd(SIG_ANCHOR_CLICKED, "anchor,clicked", "") \
41 cmd(SIG_ANCHOR_DOWN, "anchor,down", "") \
42 cmd(SIG_ANCHOR_HOVER_OPENED, "anchor,hover,opened", "") \
43 cmd(SIG_ANCHOR_IN, "anchor,in", "") \
44 cmd(SIG_ANCHOR_OUT, "anchor,out", "") \
45 cmd(SIG_ANCHOR_UP, "anchor,up", "") \
46 cmd(SIG_CHANGED, "changed", "") \
47 cmd(SIG_CHANGED_USER, "changed,user", "") \
48 cmd(SIG_CLICKED, "clicked", "") \
49 cmd(SIG_CLICKED_DOUBLE, "clicked,double", "") \
50 cmd(SIG_CLICKED_TRIPLE, "clicked,triple", "") \
51 cmd(SIG_CURSOR_CHANGED, "cursor,changed", "") \
52 cmd(SIG_CURSOR_CHANGED_MANUAL, "cursor,changed,manual", "") \
53 cmd(SIG_FOCUSED, "focused", "") \
54 cmd(SIG_UNFOCUSED, "unfocused", "") \
55 cmd(SIG_LONGPRESSED, "longpressed", "") \
56 cmd(SIG_MAX_LENGTH, "maxlength,reached", "") \
57 cmd(SIG_PREEDIT_CHANGED, "preedit,changed", "") \
58 cmd(SIG_PRESS, "press", "") \
59 cmd(SIG_REDO_REQUEST, "redo,request", "") \
60 cmd(SIG_SELECTION_CHANGED, "selection,changed", "") \
61 cmd(SIG_SELECTION_CLEARED, "selection,cleared", "") \
62 cmd(SIG_SELECTION_COPY, "selection,copy", "") \
63 cmd(SIG_SELECTION_CUT, "selection,cut", "") \
64 cmd(SIG_SELECTION_PASTE, "selection,paste", "") \
65 cmd(SIG_SELECTION_START, "selection,start", "") \
66 cmd(SIG_TEXT_SET_DONE, "text,set,done", "") \
67 cmd(SIG_THEME_CHANGED, "theme,changed", "") \
68 cmd(SIG_UNDO_REQUEST, "undo,request", "") \
69 cmd(SIG_REJECTED, "rejected", "")
70
71 ELM_PRIV_ENTRY_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
72
73 #define ENTRY_PASSWORD_MASK_CHARACTER 0x002A
74
75 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
76 ELM_PRIV_ENTRY_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
77 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
78 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
79 {NULL, NULL}
80 };
81 #undef ELM_PRIV_ENTRY_SIGNALS
82
83 static const Elm_Layout_Part_Alias_Description _text_aliases[] =
84 {
85 {"default", "elm.text"},
86 {"guide", "elm.guide"},
87 {NULL, NULL}
88 };
89
90 static const Elm_Layout_Part_Alias_Description _content_aliases[] =
91 {
92 {"icon", "elm.swallow.icon"},
93 {"end", "elm.swallow.end"},
94 {NULL, NULL}
95 };
96
97 static Eina_List *entries = NULL;
98
99 struct _Mod_Api
100 {
101 void (*obj_hook)(Evas_Object *obj);
102 void (*obj_unhook)(Evas_Object *obj);
103 void (*obj_longpress)(Evas_Object *obj);
104 };
105
106 static void _create_selection_handlers(Evas_Object *obj, Elm_Entry_Data *sd);
107 static void _magnifier_move(void *data);
108
109 static Evas_Object *
_entry_win_get(Evas_Object * obj)110 _entry_win_get(Evas_Object *obj)
111 {
112 Evas_Object *top;
113 top = elm_widget_top_get(obj);
114 if ((!elm_win_window_id_get(top)) && (elm_win_type_get(top) == ELM_WIN_INLINED_IMAGE))
115 top = efl_ui_win_inlined_parent_get(top);
116 return top;
117 }
118
119 static Mod_Api *
_module_find(Evas_Object * obj EINA_UNUSED)120 _module_find(Evas_Object *obj EINA_UNUSED)
121 {
122 static Elm_Module *m = NULL;
123
124 if (m) goto ok; // already found - just use
125 if (!(m = _elm_module_find_as("entry/api"))) return NULL;
126 // get module api
127 m->api = malloc(sizeof(Mod_Api));
128 if (!m->api) return NULL;
129
130 ((Mod_Api *)(m->api))->obj_hook = // called on creation
131 _elm_module_symbol_get(m, "obj_hook");
132 ((Mod_Api *)(m->api))->obj_unhook = // called on deletion
133 _elm_module_symbol_get(m, "obj_unhook");
134 ((Mod_Api *)(m->api))->obj_longpress = // called on long press menu
135 _elm_module_symbol_get(m, "obj_longpress");
136 ok: // ok - return api
137 return m->api;
138 }
139
140 static char *
_file_load(Eo * obj)141 _file_load(Eo *obj)
142 {
143 Eina_File *f;
144 char *text = NULL;
145 void *tmp = NULL;
146 size_t size;
147
148 f = eina_file_dup(efl_file_mmap_get(obj));
149 size = eina_file_size_get(f);
150 if (size)
151 {
152 tmp = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
153 if (!tmp) goto on_error;
154 }
155
156 text = malloc(size + 1);
157 if (!text) goto on_error;
158
159 if (size)
160 memcpy(text, tmp, size);
161 text[size] = 0;
162
163 if (eina_file_map_faulted(f, tmp))
164 {
165 ELM_SAFE_FREE(text, free);
166 }
167
168 on_error:
169 if (tmp) eina_file_map_free(f, tmp);
170 eina_file_close(f);
171
172 return text;
173 }
174
175 static char *
_plain_load(Eo * obj)176 _plain_load(Eo *obj)
177 {
178 char *text;
179
180 text = _file_load(obj);
181 if (text)
182 {
183 char *text2;
184
185 text2 = elm_entry_utf8_to_markup(text);
186 free(text);
187 return text2;
188 }
189
190 return NULL;
191 }
192
193 static Eina_Error
_load_do(Evas_Object * obj)194 _load_do(Evas_Object *obj)
195 {
196 char *text;
197 Eina_Bool fail = EINA_FALSE;
198 Eina_Error err = 0;
199
200 ELM_ENTRY_DATA_GET(obj, sd);
201
202 if (!sd->file)
203 {
204 elm_object_text_set(obj, "");
205 return 0;
206 }
207
208 switch (sd->format)
209 {
210 case ELM_TEXT_FORMAT_PLAIN_UTF8:
211 text = _plain_load(obj);
212 fail = !text;
213 break;
214
215 case ELM_TEXT_FORMAT_MARKUP_UTF8:
216 text = _file_load(obj);
217 fail = !text;
218 break;
219
220 default:
221 text = NULL;
222 err = EINVAL;
223 break;
224 }
225 if (fail)
226 {
227 err = errno;
228 /* FIXME: this is more like a hint but not totally accurate... */
229 if (!err) err = ENOENT;
230 }
231
232 if (text)
233 {
234 elm_object_text_set(obj, text);
235 free(text);
236
237 return 0;
238 }
239 elm_object_text_set(obj, "");
240
241 return err;
242 }
243
244 static void
_utf8_markup_save(const char * file,const char * text)245 _utf8_markup_save(const char *file,
246 const char *text)
247 {
248 FILE *f;
249
250 if (!text)
251 {
252 ecore_file_unlink(file);
253 return;
254 }
255
256 f = fopen(file, "wb");
257 if (!f)
258 {
259 ERR("Failed to open %s for writing", file);
260 return;
261 }
262
263 if (fputs(text, f) == EOF)
264 ERR("Failed to write text to file %s", file);
265 fclose(f);
266 }
267
268 static void
_utf8_plain_save(const char * file,const char * text)269 _utf8_plain_save(const char *file,
270 const char *text)
271 {
272 char *text2;
273
274 text2 = elm_entry_markup_to_utf8(text);
275 if (!text2)
276 return;
277
278 _utf8_markup_save(file, text2);
279 free(text2);
280 }
281
282 static void
_save_do(Evas_Object * obj)283 _save_do(Evas_Object *obj)
284 {
285 ELM_ENTRY_DATA_GET(obj, sd);
286
287 if (!efl_file_loaded_get(obj)) return;
288 switch (sd->format)
289 {
290 case ELM_TEXT_FORMAT_PLAIN_UTF8:
291 _utf8_plain_save(sd->file, elm_object_text_get(obj));
292 break;
293
294 case ELM_TEXT_FORMAT_MARKUP_UTF8:
295 _utf8_markup_save(sd->file, elm_object_text_get(obj));
296 break;
297
298 default:
299 break;
300 }
301 }
302
303 static Eina_Bool
_delay_write(void * data)304 _delay_write(void *data)
305 {
306 ELM_ENTRY_DATA_GET(data, sd);
307
308 _save_do(data);
309 sd->delay_write = NULL;
310
311 return ECORE_CALLBACK_CANCEL;
312 }
313
314 static void
_elm_entry_guide_update(Evas_Object * obj,Eina_Bool has_text)315 _elm_entry_guide_update(Evas_Object *obj,
316 Eina_Bool has_text)
317 {
318 ELM_ENTRY_DATA_GET(obj, sd);
319
320 if ((has_text) && (!sd->has_text))
321 edje_object_signal_emit(sd->entry_edje, "elm,guide,disabled", "elm");
322 else if ((!has_text) && (sd->has_text))
323 edje_object_signal_emit(sd->entry_edje, "elm,guide,enabled", "elm");
324
325 sd->has_text = has_text;
326 }
327
328 static void
_validate(Evas_Object * obj)329 _validate(Evas_Object *obj)
330 {
331 ELM_ENTRY_DATA_GET(obj, sd);
332 Eina_Bool res;
333 Elm_Validate_Content vc;
334 Eina_Strbuf *buf;
335
336 if (sd->validators == 0) return;
337
338 vc.text = edje_object_part_text_get(sd->entry_edje, "elm.text");
339 res = efl_event_callback_legacy_call(obj, ELM_ENTRY_EVENT_VALIDATE, (void *)&vc);
340 buf = eina_strbuf_new();
341 eina_strbuf_append_printf(buf, "validation,%s,%s", vc.signal, res == EINA_FALSE ? "fail" : "pass");
342 edje_object_signal_emit(sd->scr_edje, eina_strbuf_string_get(buf), "elm");
343 eina_tmpstr_del(vc.signal);
344 eina_strbuf_free(buf);
345 }
346
347 static Elm_Entry_Markup_Filter *
_filter_new(Elm_Entry_Filter_Cb func,void * data)348 _filter_new(Elm_Entry_Filter_Cb func,
349 void *data)
350 {
351 Elm_Entry_Markup_Filter *tf = ELM_NEW(Elm_Entry_Markup_Filter);
352
353 if (!tf) return NULL;
354
355 tf->func = func;
356 tf->orig_data = data;
357 if (func == elm_entry_filter_limit_size)
358 {
359 Elm_Entry_Filter_Limit_Size *lim = data, *lim2;
360
361 if (!data)
362 {
363 free(tf);
364
365 return NULL;
366 }
367
368 lim2 = malloc(sizeof(Elm_Entry_Filter_Limit_Size));
369 if (!lim2)
370 {
371 free(tf);
372
373 return NULL;
374 }
375 memcpy(lim2, lim, sizeof(Elm_Entry_Filter_Limit_Size));
376 tf->data = lim2;
377 }
378 else if (func == elm_entry_filter_accept_set)
379 {
380 Elm_Entry_Filter_Accept_Set *as = data, *as2;
381
382 if (!data)
383 {
384 free(tf);
385
386 return NULL;
387 }
388 as2 = malloc(sizeof(Elm_Entry_Filter_Accept_Set));
389 if (!as2)
390 {
391 free(tf);
392
393 return NULL;
394 }
395 if (as->accepted)
396 as2->accepted = eina_stringshare_add(as->accepted);
397 else
398 as2->accepted = NULL;
399 if (as->rejected)
400 as2->rejected = eina_stringshare_add(as->rejected);
401 else
402 as2->rejected = NULL;
403 tf->data = as2;
404 }
405 else
406 tf->data = data;
407 return tf;
408 }
409
410 static void
_filter_free(Elm_Entry_Markup_Filter * tf)411 _filter_free(Elm_Entry_Markup_Filter *tf)
412 {
413 if (tf->func == elm_entry_filter_limit_size)
414 {
415 Elm_Entry_Filter_Limit_Size *lim = tf->data;
416
417 free(lim);
418 }
419 else if (tf->func == elm_entry_filter_accept_set)
420 {
421 Elm_Entry_Filter_Accept_Set *as = tf->data;
422
423 if (as)
424 {
425 eina_stringshare_del(as->accepted);
426 eina_stringshare_del(as->rejected);
427
428 free(as);
429 }
430 }
431 free(tf);
432 }
433
434 static void
_mirrored_set(Evas_Object * obj,Eina_Bool rtl)435 _mirrored_set(Evas_Object *obj,
436 Eina_Bool rtl)
437 {
438 ELM_ENTRY_DATA_GET(obj, sd);
439
440 edje_object_mirrored_set(sd->entry_edje, rtl);
441
442 if (sd->anchor_hover.hover)
443 efl_ui_mirrored_set(sd->anchor_hover.hover, rtl);
444 }
445
446 static void
_hide_selection_handler(Evas_Object * obj)447 _hide_selection_handler(Evas_Object *obj)
448 {
449 ELM_ENTRY_DATA_GET(obj, sd);
450
451 if (!sd->start_handler) return;
452
453 if (sd->start_handler_shown)
454 {
455 edje_object_signal_emit(sd->start_handler, "elm,handler,hide", "elm");
456 sd->start_handler_shown = EINA_FALSE;
457 }
458 if (sd->end_handler_shown)
459 {
460 edje_object_signal_emit(sd->end_handler, "elm,handler,hide", "elm");
461 sd->end_handler_shown = EINA_FALSE;
462 }
463 }
464
465 static Eina_Rectangle *
_viewport_region_get(Evas_Object * obj)466 _viewport_region_get(Evas_Object *obj)
467 {
468 ELM_ENTRY_DATA_GET(obj, sd);
469 Eina_Rectangle *rect = eina_rectangle_new(0, 0, 0, 0);
470 Evas_Object *parent;
471
472 if (!rect) return NULL;
473 if (sd->scroll)
474 elm_interface_scrollable_content_viewport_geometry_get
475 (obj, &rect->x, &rect->y, &rect->w, &rect->h);
476 else
477 evas_object_geometry_get(sd->entry_edje, &rect->x, &rect->y, &rect->w, &rect->h);
478
479 parent = elm_widget_parent_get(obj);
480 while (parent)
481 {
482 if (efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
483 {
484 Eina_Rectangle r;
485 EINA_RECTANGLE_SET(&r, 0, 0, 0, 0);
486 evas_object_geometry_get(parent, &r.x, &r.y, &r.w, &r.h);
487 if (!eina_rectangle_intersection(rect, &r))
488 {
489 rect->x = rect->y = rect->w = rect->h = 0;
490 break;
491 }
492 }
493 parent = elm_widget_parent_get(parent);
494 }
495
496 return rect;
497 }
498
499 static void
_update_selection_handler(Evas_Object * obj)500 _update_selection_handler(Evas_Object *obj)
501 {
502 ELM_ENTRY_DATA_GET(obj, sd);
503
504 Evas_Coord sx, sy, sh;
505 Evas_Coord ent_x, ent_y;
506 Evas_Coord ex, ey, eh;
507 int start_pos, end_pos, last_pos;
508
509 if (!sd->sel_handler_disabled)
510 {
511 Eina_Rectangle *rect;
512 Evas_Coord hx, hy;
513 Eina_Bool hidden = EINA_FALSE;
514
515 if (!sd->start_handler)
516 _create_selection_handlers(obj, sd);
517
518 rect = _viewport_region_get(obj);
519 start_pos = edje_object_part_text_cursor_pos_get
520 (sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_BEGIN);
521 end_pos = edje_object_part_text_cursor_pos_get
522 (sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_END);
523
524 evas_object_geometry_get(sd->entry_edje, &ent_x, &ent_y, NULL, NULL);
525 last_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
526 EDJE_CURSOR_MAIN);
527 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
528 EDJE_CURSOR_MAIN, start_pos);
529 edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
530 &sx, &sy, NULL, &sh);
531 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
532 EDJE_CURSOR_MAIN, end_pos);
533 edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
534 &ex, &ey, NULL, &eh);
535 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
536 EDJE_CURSOR_MAIN, last_pos);
537 if (start_pos < end_pos)
538 {
539 hx = ent_x + sx;
540 hy = ent_y + sy + sh;
541 evas_object_move(sd->start_handler, hx, hy);
542 }
543 else
544 {
545 hx = ent_x + ex;
546 hy = ent_y + ey + eh;
547 evas_object_move(sd->start_handler, hx, hy);
548 }
549 if (!eina_rectangle_xcoord_inside(rect, hx) ||
550 !eina_rectangle_ycoord_inside(rect, hy))
551 {
552 hidden = EINA_TRUE;
553 }
554 if (!sd->start_handler_shown && !hidden)
555 {
556 edje_object_signal_emit(sd->start_handler,
557 "elm,handler,show", "elm");
558 sd->start_handler_shown = EINA_TRUE;
559 }
560 else if (sd->start_handler_shown && hidden)
561 {
562 edje_object_signal_emit(sd->start_handler,
563 "elm,handler,hide", "elm");
564 sd->start_handler_shown = EINA_FALSE;
565 }
566
567 hidden = EINA_FALSE;
568 if (start_pos < end_pos)
569 {
570 hx = ent_x + ex;
571 hy = ent_y + ey + eh;
572 evas_object_move(sd->end_handler, hx, hy);
573 }
574 else
575 {
576 hx = ent_x + sx;
577 hy = ent_y + sy + sh;
578 evas_object_move(sd->end_handler, hx, hy);
579 }
580 if (!eina_rectangle_xcoord_inside(rect, hx) ||
581 !eina_rectangle_ycoord_inside(rect, hy))
582 {
583 hidden = EINA_TRUE;
584 }
585 if (!sd->end_handler_shown && !hidden)
586 {
587 edje_object_signal_emit(sd->end_handler,
588 "elm,handler,show", "elm");
589 sd->end_handler_shown = EINA_TRUE;
590 }
591 else if (sd->end_handler_shown && hidden)
592 {
593 edje_object_signal_emit(sd->end_handler,
594 "elm,handler,hide", "elm");
595 sd->end_handler_shown = EINA_FALSE;
596 }
597 eina_rectangle_free(rect);
598 }
599 else
600 {
601 if (sd->start_handler_shown)
602 {
603 edje_object_signal_emit(sd->start_handler,
604 "elm,handler,hide", "elm");
605 sd->start_handler_shown = EINA_FALSE;
606 }
607 if (sd->end_handler_shown)
608 {
609 edje_object_signal_emit(sd->end_handler,
610 "elm,handler,hide", "elm");
611 sd->end_handler_shown = EINA_FALSE;
612 }
613 }
614 }
615
616 static const char *
_elm_entry_theme_group_get(Evas_Object * obj)617 _elm_entry_theme_group_get(Evas_Object *obj)
618 {
619 ELM_ENTRY_DATA_GET(obj, sd);
620
621 if (sd->editable)
622 {
623 if (sd->password) return "base-password";
624 else
625 {
626 if (sd->single_line) return "base-single";
627 else
628 {
629 switch (sd->line_wrap)
630 {
631 case ELM_WRAP_CHAR:
632 return "base-charwrap";
633
634 case ELM_WRAP_WORD:
635 return "base";
636
637 case ELM_WRAP_MIXED:
638 return "base-mixedwrap";
639
640 case ELM_WRAP_NONE:
641 default:
642 return "base-nowrap";
643 }
644 }
645 }
646 }
647 else
648 {
649 if (sd->password) return "base-password";
650 else
651 {
652 if (sd->single_line) return "base-single-noedit";
653 else
654 {
655 switch (sd->line_wrap)
656 {
657 case ELM_WRAP_CHAR:
658 return "base-noedit-charwrap";
659
660 case ELM_WRAP_WORD:
661 return "base-noedit";
662
663 case ELM_WRAP_MIXED:
664 return "base-noedit-mixedwrap";
665
666 case ELM_WRAP_NONE:
667 default:
668 return "base-nowrap-noedit";
669 }
670 }
671 }
672 }
673 }
674
675 static void
_edje_entry_user_insert(Evas_Object * obj,const char * data)676 _edje_entry_user_insert(Evas_Object *obj, const char *data)
677 {
678 if (!data) return;
679 ELM_ENTRY_DATA_GET(obj, sd);
680
681 sd->changed = EINA_TRUE;
682 edje_object_part_text_user_insert(sd->entry_edje, "elm.text", data);
683 elm_layout_sizing_eval(obj);
684 }
685
686 static Eina_Bool
_selection_data_cb(void * data EINA_UNUSED,Evas_Object * obj,Elm_Selection_Data * sel_data)687 _selection_data_cb(void *data EINA_UNUSED,
688 Evas_Object *obj,
689 Elm_Selection_Data *sel_data)
690 {
691 char *buf;
692
693 if (!sel_data->data) return EINA_FALSE;
694 ELM_ENTRY_DATA_GET(obj, sd);
695
696 buf = malloc(sel_data->len + 1);
697 if (!buf)
698 {
699 ERR("Failed to allocate memory, obj: %p", obj);
700 return EINA_FALSE;
701 }
702 memcpy(buf, sel_data->data, sel_data->len);
703 buf[sel_data->len] = '\0';
704
705 if ((sel_data->format & ELM_SEL_FORMAT_IMAGE) &&
706 (sd->cnp_mode != ELM_CNP_MODE_NO_IMAGE))
707 {
708 char *entry_tag;
709 int len;
710 static const char *tag_string =
711 "<item absize=240x180 href=file://%s></item>";
712
713 len = strlen(tag_string) + strlen(buf);
714 entry_tag = alloca(len + 1);
715 snprintf(entry_tag, len + 1, tag_string, buf);
716 _edje_entry_user_insert(obj, entry_tag);
717 }
718 else if (sd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
719 {
720 char *txt = _elm_util_text_to_mkup(buf);
721 if (txt)
722 {
723 _edje_entry_user_insert(obj, txt);
724 free(txt);
725 }
726 else
727 {
728 ERR("Failed to convert text to markup text!");
729 }
730 }
731 else
732 {
733 if (!(sel_data->format & ELM_SEL_FORMAT_MARKUP))
734 {
735 char *txt = _elm_util_text_to_mkup(buf);
736 if (txt)
737 {
738 _edje_entry_user_insert(obj, txt);
739 free(txt);
740 }
741 }
742 else
743 _edje_entry_user_insert(obj, buf);
744 }
745 free(buf);
746
747 return EINA_TRUE;
748 }
749
750 static void
_dnd_enter_cb(void * data EINA_UNUSED,Evas_Object * obj)751 _dnd_enter_cb(void *data EINA_UNUSED,
752 Evas_Object *obj)
753 {
754 elm_object_focus_set(obj, EINA_TRUE);
755 }
756
757 static void
_dnd_leave_cb(void * data EINA_UNUSED,Evas_Object * obj)758 _dnd_leave_cb(void *data EINA_UNUSED,
759 Evas_Object *obj)
760 {
761 if (_elm_config->desktop_entry)
762 elm_object_focus_set(obj, EINA_FALSE);
763 }
764
765 static void
_dnd_pos_cb(void * data EINA_UNUSED,Evas_Object * obj,Evas_Coord x,Evas_Coord y,Elm_Xdnd_Action action EINA_UNUSED)766 _dnd_pos_cb(void *data EINA_UNUSED,
767 Evas_Object *obj,
768 Evas_Coord x,
769 Evas_Coord y,
770 Elm_Xdnd_Action action EINA_UNUSED)
771 {
772 int pos;
773 Evas_Coord ox, oy, ex, ey;
774
775 ELM_ENTRY_DATA_GET(obj, sd);
776
777 evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
778 evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
779 x = x + ox - ex;
780 y = y + oy - ey;
781
782 edje_object_part_text_cursor_coord_set
783 (sd->entry_edje, "elm.text", EDJE_CURSOR_USER, x, y);
784 pos = edje_object_part_text_cursor_pos_get
785 (sd->entry_edje, "elm.text", EDJE_CURSOR_USER);
786 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
787 EDJE_CURSOR_MAIN, pos);
788 }
789
790 static Eina_Bool
_dnd_drop_cb(void * data EINA_UNUSED,Evas_Object * obj,Elm_Selection_Data * drop)791 _dnd_drop_cb(void *data EINA_UNUSED,
792 Evas_Object *obj,
793 Elm_Selection_Data *drop)
794 {
795 Eina_Bool rv;
796
797 ELM_ENTRY_DATA_GET(obj, sd);
798
799 rv = edje_object_part_text_cursor_coord_set
800 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN, drop->x, drop->y);
801
802 if (!rv) WRN("Warning: Failed to position cursor: paste anyway");
803
804 rv = _selection_data_cb(NULL, obj, drop);
805
806 return rv;
807 }
808
809 static Elm_Sel_Format
_get_drop_format(Evas_Object * obj)810 _get_drop_format(Evas_Object *obj)
811 {
812 ELM_ENTRY_DATA_GET(obj, sd);
813
814 if ((sd->editable) && (!sd->single_line) && (!sd->password) && (!sd->disabled))
815 return ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE;
816 return ELM_SEL_FORMAT_MARKUP;
817 }
818
819 static void
_flush_disabled_state(Eo * obj,Elm_Entry_Data * sd)820 _flush_disabled_state(Eo *obj, Elm_Entry_Data *sd)
821 {
822 const char *emission;
823 emission = efl_ui_widget_disabled_get(obj) ? "elm,state,disabled" : "elm,state,enabled";
824 edje_object_signal_emit(sd->entry_edje, emission, "elm");
825 if (sd->scroll)
826 {
827 edje_object_signal_emit(sd->scr_edje, emission, "elm");
828 elm_interface_scrollable_freeze_set(obj, efl_ui_widget_disabled_get(obj));
829 }
830 }
831
832 /* we can't reuse layout's here, because it's on entry_edje only */
833 EOLIAN static void
_elm_entry_efl_ui_widget_disabled_set(Eo * obj,Elm_Entry_Data * sd,Eina_Bool disabled)834 _elm_entry_efl_ui_widget_disabled_set(Eo *obj, Elm_Entry_Data *sd, Eina_Bool disabled)
835 {
836
837 efl_ui_widget_disabled_set(efl_super(obj, MY_CLASS), disabled);
838
839 elm_drop_target_del(obj, sd->drop_format,
840 _dnd_enter_cb, NULL,
841 _dnd_leave_cb, NULL,
842 _dnd_pos_cb, NULL,
843 _dnd_drop_cb, NULL);
844
845 _flush_disabled_state(obj, sd);
846 sd->disabled = efl_ui_widget_disabled_get(obj);
847
848 if (!efl_ui_widget_disabled_get(obj))
849 {
850 sd->drop_format = _get_drop_format(obj);
851 elm_drop_target_add(obj, sd->drop_format,
852 _dnd_enter_cb, NULL,
853 _dnd_leave_cb, NULL,
854 _dnd_pos_cb, NULL,
855 _dnd_drop_cb, NULL);
856 }
857 }
858
859 /* It gets the background object from from_edje object and
860 * sets the background object to to_edje object.
861 * The background object has to be moved to proper Edje object
862 * when scrollable status is changed. */
863 static void
_elm_entry_background_switch(Evas_Object * from_edje,Evas_Object * to_edje)864 _elm_entry_background_switch(Evas_Object *from_edje, Evas_Object *to_edje)
865 {
866 Evas_Object *bg_obj;
867
868 if (!from_edje || !to_edje) return;
869
870 if (edje_object_part_exists(from_edje, "elm.swallow.background") &&
871 edje_object_part_exists(to_edje, "elm.swallow.background") &&
872 !edje_object_part_swallow_get(to_edje, "elm.swallow.background"))
873 {
874 bg_obj = edje_object_part_swallow_get(from_edje, "elm.swallow.background");
875
876 if (bg_obj)
877 {
878 edje_object_part_unswallow(from_edje, bg_obj);
879 edje_object_part_swallow(to_edje, "elm.swallow.background", bg_obj);
880 }
881 }
882 }
883
884 /* we can't issue the layout's theming code here, cause it assumes an
885 * unique edje object, always */
886 EOLIAN static Eina_Error
_elm_entry_efl_ui_widget_theme_apply(Eo * obj,Elm_Entry_Data * sd)887 _elm_entry_efl_ui_widget_theme_apply(Eo *obj, Elm_Entry_Data *sd)
888 {
889 const char *str;
890 const char *t;
891 const char *stl_user;
892 const char *style = elm_widget_style_get(obj);
893 Eina_Error theme_apply;
894 int cursor_pos;
895
896 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_ERROR_GENERIC);
897
898 // Note: We are skipping elm_layout here! This is by design.
899 // This assumes the following inheritance: my_class -> layout -> widget ...
900 theme_apply = efl_ui_widget_theme_apply(efl_cast(obj, EFL_UI_WIDGET_CLASS));
901 if (theme_apply == EFL_UI_THEME_APPLY_ERROR_GENERIC) return EFL_UI_THEME_APPLY_ERROR_GENERIC;
902
903 evas_event_freeze(evas_object_evas_get(obj));
904
905 edje_object_part_text_hide_visible_password(sd->entry_edje, "elm.text");
906
907 edje_object_mirrored_set
908 (wd->resize_obj, efl_ui_mirrored_get(obj));
909
910 edje_object_scale_set
911 (wd->resize_obj,
912 efl_gfx_entity_scale_get(obj) * elm_config_scale_get());
913 if (sd->scroll)
914 {
915 edje_object_scale_set
916 (sd->entry_edje,
917 efl_gfx_entity_scale_get(obj) * elm_config_scale_get());
918 }
919
920 _mirrored_set(obj, efl_ui_mirrored_get(obj));
921
922 stl_user = eina_stringshare_add(edje_object_part_text_style_user_peek(sd->entry_edje, "elm.text"));
923 t = eina_stringshare_add(elm_object_text_get(obj));
924
925 elm_widget_theme_object_set
926 (obj, sd->entry_edje, "entry", _elm_entry_theme_group_get(obj), style);
927
928 if (sd->sel_allow && _elm_config->desktop_entry)
929 edje_object_part_text_select_allow_set
930 (sd->entry_edje, "elm.text", EINA_TRUE);
931 else
932 edje_object_part_text_select_allow_set
933 (sd->entry_edje, "elm.text", EINA_FALSE);
934
935 edje_object_part_text_style_user_push(sd->entry_edje, "elm.text", stl_user);
936 eina_stringshare_del(stl_user);
937
938 cursor_pos = edje_object_part_text_cursor_pos_get
939 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
940
941 if (cursor_pos != sd->cursor_pos)
942 {
943 sd->cursor_pos = cursor_pos;
944 sd->cur_changed = EINA_TRUE;
945 }
946
947 elm_object_text_set(obj, t);
948 eina_stringshare_del(t);
949
950 if (elm_widget_disabled_get(obj))
951 edje_object_signal_emit(sd->entry_edje, "elm,state,disabled", "elm");
952
953 edje_object_part_text_input_panel_layout_set
954 (sd->entry_edje, "elm.text", (Edje_Input_Panel_Layout)sd->input_panel_layout);
955 edje_object_part_text_input_panel_layout_variation_set
956 (sd->entry_edje, "elm.text", sd->input_panel_layout_variation);
957 edje_object_part_text_autocapital_type_set
958 (sd->entry_edje, "elm.text", (Edje_Text_Autocapital_Type)sd->autocapital_type);
959 edje_object_part_text_prediction_allow_set
960 (sd->entry_edje, "elm.text", sd->prediction_allow);
961 edje_object_part_text_input_hint_set
962 (sd->entry_edje, "elm.text", (Edje_Input_Hints)sd->input_hints);
963 edje_object_part_text_input_panel_enabled_set
964 (sd->entry_edje, "elm.text", sd->input_panel_enable);
965 edje_object_part_text_input_panel_imdata_set
966 (sd->entry_edje, "elm.text", sd->input_panel_imdata,
967 sd->input_panel_imdata_len);
968 edje_object_part_text_input_panel_return_key_type_set
969 (sd->entry_edje, "elm.text", (Edje_Input_Panel_Return_Key_Type)sd->input_panel_return_key_type);
970 edje_object_part_text_input_panel_return_key_disabled_set
971 (sd->entry_edje, "elm.text", sd->input_panel_return_key_disabled);
972 edje_object_part_text_input_panel_show_on_demand_set
973 (sd->entry_edje, "elm.text", sd->input_panel_show_on_demand);
974 edje_object_part_text_prediction_hint_set
975 (sd->entry_edje, "elm.text", sd->prediction_hint);
976
977 evas_object_ref(obj);
978
979 if (cursor_pos) elm_entry_cursor_pos_set(obj, cursor_pos);
980
981 if (efl_ui_focus_object_focus_get(obj))
982 {
983 edje_object_signal_emit(sd->entry_edje, "elm,action,focus", "elm");
984 if (sd->scroll)
985 edje_object_signal_emit(sd->scr_edje, "elm,action,focus", "elm");
986 }
987
988 edje_object_message_signal_process(sd->entry_edje);
989
990 Evas_Object* clip = evas_object_clip_get(sd->entry_edje);
991 evas_object_clip_set(sd->hit_rect, clip);
992
993 if (sd->scroll)
994 {
995 Eina_Error err = EFL_UI_THEME_APPLY_ERROR_GENERIC;
996
997 efl_ui_mirrored_set(obj, efl_ui_mirrored_get(obj));
998
999 if (sd->single_line)
1000 err = elm_widget_theme_object_set
1001 (obj, sd->scr_edje, "scroller", "entry_single", style);
1002 if (err)
1003 elm_widget_theme_object_set
1004 (obj, sd->scr_edje, "scroller", "entry", style);
1005
1006 elm_interface_scrollable_reset_signals(obj);
1007 _elm_entry_background_switch(sd->entry_edje, sd->scr_edje);
1008
1009 str = edje_object_data_get(sd->scr_edje, "focus_highlight");
1010 }
1011 else
1012 {
1013 _elm_entry_background_switch(sd->scr_edje, sd->entry_edje);
1014
1015 str = edje_object_data_get(sd->entry_edje, "focus_highlight");
1016 }
1017
1018 if ((str) && (!strcmp(str, "on")))
1019 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
1020 else
1021 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
1022
1023 if (sd->start_handler)
1024 {
1025 _elm_theme_object_set(obj, sd->start_handler,
1026 "entry", "handler/start", style);
1027 _elm_theme_object_set(obj, sd->end_handler,
1028 "entry", "handler/end", style);
1029 }
1030 elm_entry_icon_visible_set(obj, EINA_TRUE);
1031 elm_entry_end_visible_set(obj, EINA_TRUE);
1032
1033 if (sd->scroll)
1034 efl_layout_signal_emit(sd->entry_edje, "elm,scroll,enable", "elm");
1035 else
1036 efl_layout_signal_emit(sd->entry_edje, "elm,scroll,disable", "elm");
1037
1038 sd->changed = EINA_TRUE;
1039 elm_layout_sizing_eval(obj);
1040
1041 sd->has_text = !sd->has_text;
1042 _elm_entry_guide_update(obj, !sd->has_text);
1043 evas_event_thaw(evas_object_evas_get(obj));
1044 evas_event_thaw_eval(evas_object_evas_get(obj));
1045
1046 efl_event_callback_legacy_call(obj, EFL_UI_LAYOUT_EVENT_THEME_CHANGED, NULL);
1047
1048 evas_object_unref(obj);
1049
1050 _flush_disabled_state(obj, sd);
1051
1052 return theme_apply;
1053 }
1054
1055 static void
_cursor_geometry_recalc(Evas_Object * obj)1056 _cursor_geometry_recalc(Evas_Object *obj)
1057 {
1058 ELM_ENTRY_DATA_GET(obj, sd);
1059
1060 if (!sd->deferred_recalc_job)
1061 {
1062 if (sd->cur_changed)
1063 {
1064 Eina_Rect sr = {};
1065
1066 sd->cur_changed = EINA_FALSE;
1067 edje_object_part_text_cursor_geometry_get
1068 (sd->entry_edje, "elm.text", &sr.x, &sr.y, &sr.w, &sr.h);
1069 elm_widget_show_region_set(obj, sr, EINA_FALSE);
1070 }
1071 }
1072 else
1073 sd->deferred_cur = EINA_TRUE;
1074 }
1075
1076 static void
_deferred_recalc_job(void * data)1077 _deferred_recalc_job(void *data)
1078 {
1079 Evas_Coord minh = -1, resw = -1, minw = -1, fw = 0, fh = 0;
1080
1081 ELM_ENTRY_DATA_GET(data, sd);
1082
1083 sd->deferred_recalc_job = NULL;
1084
1085 evas_object_geometry_get(sd->entry_edje, NULL, NULL, &resw, NULL);
1086 edje_object_size_min_restricted_calc(sd->entry_edje, &minw, &minh, resw, 0);
1087 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1088
1089 /* This is a hack to workaround the way min size hints are treated.
1090 * If the minimum width is smaller than the restricted width, it
1091 * means the minimum doesn't matter. */
1092 if (minw <= resw)
1093 {
1094 Evas_Coord ominw = -1;
1095
1096 evas_object_size_hint_combined_min_get(data, &ominw, NULL);
1097 minw = ominw;
1098 }
1099
1100 sd->ent_mw = minw;
1101 sd->ent_mh = minh;
1102
1103 elm_coords_finger_size_adjust(1, &fw, 1, &fh);
1104 if (sd->scroll)
1105 {
1106 Evas_Coord vmw = 0, vmh = 0;
1107
1108 edje_object_size_min_calc(sd->scr_edje, &vmw, &vmh);
1109 if (sd->single_line)
1110 {
1111 evas_object_size_hint_min_set(data, vmw, minh + vmh);
1112 evas_object_size_hint_max_set(data, -1, minh + vmh);
1113 }
1114 else
1115 {
1116 evas_object_size_hint_min_set(data, vmw, vmh);
1117 evas_object_size_hint_max_set(data, -1, -1);
1118 }
1119 }
1120 else
1121 {
1122 if (sd->single_line)
1123 {
1124 evas_object_size_hint_min_set(data, minw, minh);
1125 evas_object_size_hint_max_set(data, -1, minh);
1126 }
1127 else
1128 {
1129 evas_object_size_hint_min_set(data, fw, minh);
1130 evas_object_size_hint_max_set(data, -1, -1);
1131 }
1132 }
1133
1134 if (sd->deferred_cur)
1135 {
1136 if (sd->cur_changed)
1137 {
1138 Eina_Rect sr = {};
1139
1140 sd->cur_changed = EINA_FALSE;
1141 edje_object_part_text_cursor_geometry_get
1142 (sd->entry_edje, "elm.text", &sr.x, &sr.y, &sr.w, &sr.h);
1143 elm_widget_show_region_set(data, sr, EINA_FALSE);
1144 }
1145 }
1146 }
1147
1148 EOLIAN static void
_elm_entry_efl_canvas_group_group_calculate(Eo * obj,Elm_Entry_Data * sd)1149 _elm_entry_efl_canvas_group_group_calculate(Eo *obj, Elm_Entry_Data *sd)
1150 {
1151 Evas_Coord minw = -1, minh = -1;
1152 Evas_Coord resw, resh;
1153
1154 evas_object_geometry_get(obj, NULL, NULL, &resw, &resh);
1155
1156 if (sd->line_wrap)
1157 {
1158 if ((resw == sd->last_w) && (!sd->changed))
1159 {
1160 if (sd->scroll)
1161 {
1162 Evas_Coord vw = 0, vh = 0, w = 0, h = 0;
1163
1164 elm_interface_scrollable_content_viewport_geometry_get
1165 (obj, NULL, NULL, &vw, &vh);
1166
1167 w = sd->ent_mw;
1168 h = sd->ent_mh;
1169 if (vw > sd->ent_mw) w = vw;
1170 if (vh > sd->ent_mh) h = vh;
1171 evas_object_resize(sd->entry_edje, w, h);
1172
1173 return;
1174 }
1175
1176 return;
1177 }
1178
1179 evas_event_freeze(evas_object_evas_get(obj));
1180 sd->changed = EINA_FALSE;
1181 sd->last_w = resw;
1182 if (sd->scroll)
1183 {
1184 Evas_Coord vw = 0, vh = 0, vmw = 0, vmh = 0, w = -1, h = -1;
1185
1186 evas_object_resize(sd->scr_edje, resw, resh);
1187 edje_object_size_min_calc(sd->scr_edje, &vmw, &vmh);
1188 elm_interface_scrollable_content_viewport_geometry_get
1189 (obj, NULL, NULL, &vw, &vh);
1190 edje_object_size_min_restricted_calc
1191 (sd->entry_edje, &minw, &minh, vw, 0);
1192 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1193
1194 /* This is a hack to workaround the way min size hints
1195 * are treated. If the minimum width is smaller than the
1196 * restricted width, it means the minimum doesn't
1197 * matter. */
1198 if (minw <= vw)
1199 {
1200 Evas_Coord ominw = -1;
1201
1202 evas_object_size_hint_combined_min_get(sd->entry_edje, &ominw, NULL);
1203 minw = ominw;
1204 }
1205 sd->ent_mw = minw;
1206 sd->ent_mh = minh;
1207
1208 if ((minw > 0) && (vw < minw)) vw = minw;
1209 if (minh > vh) vh = minh;
1210
1211 if (sd->single_line) h = vmh + minh;
1212 else h = vmh;
1213
1214 evas_object_resize(sd->entry_edje, vw, vh);
1215 evas_object_size_hint_min_set(obj, w, h);
1216
1217 if (sd->single_line)
1218 evas_object_size_hint_max_set(obj, -1, h);
1219 else
1220 evas_object_size_hint_max_set(obj, -1, -1);
1221 }
1222 else
1223 {
1224 ecore_job_del(sd->deferred_recalc_job);
1225 sd->deferred_recalc_job =
1226 ecore_job_add(_deferred_recalc_job, obj);
1227 }
1228
1229 evas_event_thaw(evas_object_evas_get(obj));
1230 evas_event_thaw_eval(evas_object_evas_get(obj));
1231 }
1232 else
1233 {
1234 if (!sd->changed) return;
1235 evas_event_freeze(evas_object_evas_get(obj));
1236 sd->changed = EINA_FALSE;
1237 sd->last_w = resw;
1238 if (sd->scroll)
1239 {
1240 Evas_Coord vw = 0, vh = 0, vmw = 0, vmh = 0, w = -1, h = -1;
1241
1242 edje_object_size_min_calc(sd->entry_edje, &minw, &minh);
1243 sd->ent_mw = minw;
1244 sd->ent_mh = minh;
1245 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1246
1247 elm_interface_scrollable_content_viewport_geometry_get
1248 (obj, NULL, NULL, &vw, &vh);
1249
1250 if (minw > vw) vw = minw;
1251 if (minh > vh) vh = minh;
1252
1253 evas_object_resize(sd->entry_edje, vw, vh);
1254 edje_object_size_min_calc(sd->scr_edje, &vmw, &vmh);
1255 if (sd->single_line) h = vmh + minh;
1256 else h = vmh;
1257
1258 evas_object_size_hint_min_set(obj, w, h);
1259 if (sd->single_line)
1260 evas_object_size_hint_max_set(obj, -1, h);
1261 else
1262 evas_object_size_hint_max_set(obj, -1, -1);
1263 }
1264 else
1265 {
1266 edje_object_size_min_calc(sd->entry_edje, &minw, &minh);
1267 sd->ent_mw = minw;
1268 sd->ent_mh = minh;
1269 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1270 evas_object_size_hint_min_set(obj, minw, minh);
1271
1272 if (sd->single_line)
1273 evas_object_size_hint_max_set(obj, -1, minh);
1274 else
1275 evas_object_size_hint_max_set(obj, -1, -1);
1276 }
1277 evas_event_thaw(evas_object_evas_get(obj));
1278 evas_event_thaw_eval(evas_object_evas_get(obj));
1279 }
1280
1281 _cursor_geometry_recalc(obj);
1282 }
1283
1284 static void
_return_key_enabled_check(Evas_Object * obj)1285 _return_key_enabled_check(Evas_Object *obj)
1286 {
1287 Eina_Bool return_key_disabled = EINA_FALSE;
1288
1289 ELM_ENTRY_DATA_GET(obj, sd);
1290
1291 if (!sd->auto_return_key) return;
1292
1293 if (elm_entry_is_empty(obj) == EINA_TRUE)
1294 return_key_disabled = EINA_TRUE;
1295
1296 elm_entry_input_panel_return_key_disabled_set(obj, return_key_disabled);
1297 }
1298
1299 static void
_elm_entry_focus_update(Eo * obj,Elm_Entry_Data * sd)1300 _elm_entry_focus_update(Eo *obj, Elm_Entry_Data *sd)
1301 {
1302 Evas_Object *top;
1303 Eina_Bool top_is_win = EINA_FALSE;
1304
1305 top = elm_widget_top_get(obj);
1306 if (top && efl_isa(top, EFL_UI_WIN_CLASS))
1307 top_is_win = EINA_TRUE;
1308
1309 if (efl_ui_focus_object_focus_get(obj) && sd->editable)
1310 {
1311 evas_object_focus_set(sd->entry_edje, EINA_TRUE);
1312 edje_object_signal_emit(sd->entry_edje, "elm,action,focus", "elm");
1313 if (sd->scroll)
1314 edje_object_signal_emit(sd->scr_edje, "elm,action,focus", "elm");
1315
1316 if (top && top_is_win && sd->input_panel_enable && !sd->input_panel_show_on_demand &&
1317 !edje_object_part_text_imf_context_get(sd->entry_edje, "elm.text"))
1318 elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON);
1319 if (_elm_config->atspi_mode)
1320 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_FOCUSED, EINA_TRUE);
1321 _return_key_enabled_check(obj);
1322 _validate(obj);
1323 }
1324 else
1325 {
1326 edje_object_signal_emit(sd->entry_edje, "elm,action,unfocus", "elm");
1327 if (sd->scroll)
1328 edje_object_signal_emit(sd->scr_edje, "elm,action,unfocus", "elm");
1329 evas_object_focus_set(sd->entry_edje, EINA_FALSE);
1330 if (top && top_is_win && sd->input_panel_enable &&
1331 !edje_object_part_text_imf_context_get(sd->entry_edje, "elm.text"))
1332 elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_OFF);
1333 if (_elm_config->atspi_mode)
1334 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_FOCUSED, EINA_FALSE);
1335
1336 if (_elm_config->selection_clear_enable)
1337 {
1338 if ((sd->have_selection) && (!sd->hoversel))
1339 {
1340 sd->sel_mode = EINA_FALSE;
1341 elm_widget_scroll_hold_pop(obj);
1342 edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text", EINA_FALSE);
1343 edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
1344 edje_object_part_text_select_none(sd->entry_edje, "elm.text");
1345 }
1346 }
1347 if (sd->scr_edje)
1348 edje_object_signal_emit(sd->scr_edje, "validation,default", "elm");
1349 }
1350 }
1351
1352 EOLIAN static Eina_Bool
_elm_entry_efl_ui_focus_object_on_focus_update(Eo * obj,Elm_Entry_Data * sd)1353 _elm_entry_efl_ui_focus_object_on_focus_update(Eo *obj, Elm_Entry_Data *sd)
1354 {
1355 _elm_entry_focus_update(obj, sd);
1356
1357 return EINA_TRUE;
1358 }
1359
1360 EOLIAN static Eina_Rect
_elm_entry_efl_ui_widget_interest_region_get(const Eo * obj,Elm_Entry_Data * sd)1361 _elm_entry_efl_ui_widget_interest_region_get(const Eo *obj, Elm_Entry_Data *sd)
1362 {
1363 Evas_Coord cx, cy, cw, ch;
1364 Evas_Coord edx, edy;
1365 Evas_Coord elx, ely, elw, elh;
1366 Eina_Rect r;
1367
1368 edje_object_part_text_cursor_geometry_get
1369 (sd->entry_edje, "elm.text", &cx, &cy, &cw, &ch);
1370
1371 if (sd->single_line)
1372 {
1373 evas_object_geometry_get(sd->entry_edje, &edx, &edy, NULL, &ch);
1374 cy = 0;
1375 }
1376 else
1377 {
1378 evas_object_geometry_get(sd->entry_edje, &edx, &edy, NULL, NULL);
1379 }
1380 evas_object_geometry_get(obj, &elx, &ely, &elw, &elh);
1381
1382 r.x = cx + edx - elx;
1383 if ((cw < elw) && (r.x + cw > elw)) r.x = elw - cw;
1384 r.y = cy + edy - ely;
1385 if ((ch < elh) && (r.y + ch > elh)) r.y = elh - ch;
1386 r.w = MAX(cw, 1);
1387 r.h = MAX(ch, 1);
1388
1389 return r;
1390 }
1391
1392 static void
_show_region_hook(void * data EINA_UNUSED,Evas_Object * obj,Eina_Rect r)1393 _show_region_hook(void *data EINA_UNUSED, Evas_Object *obj, Eina_Rect r)
1394 {
1395 elm_interface_scrollable_content_region_show(obj, r.x, r.y, r.w, r.h);
1396 }
1397
1398 EOLIAN static Eina_Bool
_elm_entry_efl_ui_widget_widget_sub_object_del(Eo * obj,Elm_Entry_Data * sd,Evas_Object * sobj)1399 _elm_entry_efl_ui_widget_widget_sub_object_del(Eo *obj, Elm_Entry_Data *sd, Evas_Object *sobj)
1400 {
1401 Eina_Bool ret = EINA_FALSE;
1402 /* unfortunately entry doesn't follow the signal pattern
1403 * elm,state,icon,{visible,hidden}, so we have to replicate this
1404 * smart function */
1405 if (sobj == edje_object_part_swallow_get(sd->scr_edje, "elm.swallow.icon"))
1406 {
1407 edje_object_signal_emit(sd->scr_edje, "elm,action,hide,icon", "elm");
1408 }
1409 else if (sobj == edje_object_part_swallow_get(sd->scr_edje, "elm.swallow.end"))
1410 {
1411 edje_object_signal_emit(sd->scr_edje, "elm,action,hide,end", "elm");
1412 }
1413
1414 ret = elm_widget_sub_object_del(efl_super(obj, MY_CLASS), sobj);
1415 if (!ret) return EINA_FALSE;
1416
1417 return EINA_TRUE;
1418 }
1419
1420 static void
_hoversel_position(Evas_Object * obj)1421 _hoversel_position(Evas_Object *obj)
1422 {
1423 Evas_Coord cx, cy, cw, ch, x, y, mw, mh, w, h;
1424
1425 ELM_ENTRY_DATA_GET(obj, sd);
1426
1427 cx = cy = 0;
1428 cw = ch = 1;
1429 evas_object_geometry_get(sd->entry_edje, &x, &y, &w, &h);
1430 if (sd->use_down)
1431 {
1432 cx = sd->downx - x;
1433 cy = sd->downy - y;
1434 cw = 1;
1435 ch = 1;
1436 }
1437 else
1438 edje_object_part_text_cursor_geometry_get
1439 (sd->entry_edje, "elm.text", &cx, &cy, &cw, &ch);
1440
1441 if (efl_canvas_group_need_recalculate_get(sd->hoversel))
1442 efl_canvas_group_calculate(sd->hoversel);
1443 evas_object_size_hint_combined_min_get(sd->hoversel, &mw, &mh);
1444 if (cx + mw > w)
1445 cx = w - mw;
1446 if (cy + mh > h)
1447 cy = h - mh;
1448 evas_object_geometry_set(sd->hoversel, x + cx, y + cy, mw, mh);
1449 }
1450
1451 static void
_hover_del_job(void * data)1452 _hover_del_job(void *data)
1453 {
1454 ELM_ENTRY_DATA_GET(data, sd);
1455
1456 ELM_SAFE_FREE(sd->hoversel, evas_object_del);
1457 sd->hov_deljob = NULL;
1458 }
1459
1460 static void
_hover_dismissed_cb(void * data,const Efl_Event * event EINA_UNUSED)1461 _hover_dismissed_cb(void *data, const Efl_Event *event EINA_UNUSED)
1462 {
1463 ELM_ENTRY_DATA_GET(data, sd);
1464
1465 sd->use_down = 0;
1466 if (sd->hoversel) evas_object_hide(sd->hoversel);
1467 if (sd->sel_mode)
1468 {
1469 if (!_elm_config->desktop_entry)
1470 {
1471 if (!sd->password)
1472 edje_object_part_text_select_allow_set
1473 (sd->entry_edje, "elm.text", EINA_TRUE);
1474 }
1475 }
1476 elm_widget_scroll_freeze_pop(data);
1477 ecore_job_del(sd->hov_deljob);
1478 sd->hov_deljob = ecore_job_add(_hover_del_job, data);
1479 }
1480
1481 static void
_hover_selected_cb(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1482 _hover_selected_cb(void *data,
1483 Evas_Object *obj EINA_UNUSED,
1484 void *event_info EINA_UNUSED)
1485 {
1486 ELM_ENTRY_DATA_GET(data, sd);
1487
1488 if (!sd->sel_allow) return;
1489
1490 sd->sel_mode = EINA_TRUE;
1491 edje_object_part_text_select_none(sd->entry_edje, "elm.text");
1492
1493 if (!_elm_config->desktop_entry)
1494 {
1495 if (!sd->password)
1496 edje_object_part_text_select_allow_set
1497 (sd->entry_edje, "elm.text", EINA_TRUE);
1498 }
1499 edje_object_signal_emit(sd->entry_edje, "elm,state,select,on", "elm");
1500
1501 if (!_elm_config->desktop_entry)
1502 elm_widget_scroll_hold_push(data);
1503 }
1504
1505 static char *
_item_tags_remove(const char * str)1506 _item_tags_remove(const char *str)
1507 {
1508 char *ret;
1509 Eina_Strbuf *buf;
1510
1511 if (!str)
1512 return NULL;
1513
1514 buf = eina_strbuf_new();
1515 if (!buf)
1516 return NULL;
1517
1518 if (!eina_strbuf_append(buf, str))
1519 {
1520 eina_strbuf_free(buf);
1521 return NULL;
1522 }
1523
1524 while (EINA_TRUE)
1525 {
1526 const char *temp = eina_strbuf_string_get(buf);
1527 char *start_tag = NULL;
1528 char *end_tag = NULL;
1529 size_t sindex;
1530 size_t eindex;
1531
1532 start_tag = strstr(temp, "<item");
1533 if (!start_tag)
1534 start_tag = strstr(temp, "</item");
1535 if (start_tag)
1536 end_tag = strstr(start_tag, ">");
1537 else
1538 break;
1539 if (!end_tag || start_tag > end_tag)
1540 break;
1541
1542 sindex = start_tag - temp;
1543 eindex = end_tag - temp + 1;
1544 if (!eina_strbuf_remove(buf, sindex, eindex))
1545 break;
1546 }
1547
1548 ret = eina_strbuf_string_steal(buf);
1549 eina_strbuf_free(buf);
1550
1551 return ret;
1552 }
1553
1554 void
_elm_entry_entry_paste(Evas_Object * obj,const char * entry)1555 _elm_entry_entry_paste(Evas_Object *obj,
1556 const char *entry)
1557 {
1558 char *str = NULL;
1559
1560 if (!entry) return;
1561
1562 ELM_ENTRY_CHECK(obj);
1563 ELM_ENTRY_DATA_GET(obj, sd);
1564
1565 if (!sd) return;
1566 if (sd->cnp_mode == ELM_CNP_MODE_NO_IMAGE)
1567 {
1568 str = _item_tags_remove(entry);
1569 if (!str) str = strdup(entry);
1570 }
1571 else
1572 str = strdup(entry);
1573 if (!str) str = (char *)entry;
1574
1575 _edje_entry_user_insert(obj, str);
1576
1577 if (str != entry) free(str);
1578 }
1579
1580 static void
_paste_cb(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1581 _paste_cb(void *data,
1582 Evas_Object *obj EINA_UNUSED,
1583 void *event_info EINA_UNUSED)
1584 {
1585 Elm_Sel_Format formats = ELM_SEL_FORMAT_MARKUP;
1586
1587 ELM_ENTRY_DATA_GET(data, sd);
1588
1589 if (!sd) return;
1590 efl_event_callback_legacy_call
1591 (data, EFL_UI_TEXTBOX_EVENT_SELECTION_PASTE, NULL);
1592
1593 sd->selection_asked = EINA_TRUE;
1594
1595 if (sd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
1596 formats = ELM_SEL_FORMAT_TEXT;
1597 else if (sd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
1598 formats |= ELM_SEL_FORMAT_IMAGE;
1599
1600 elm_cnp_selection_get
1601 (data, ELM_SEL_TYPE_CLIPBOARD, formats, _selection_data_cb, NULL);
1602 }
1603
1604 static void
_selection_clear(void * data,Elm_Sel_Type selection)1605 _selection_clear(void *data, Elm_Sel_Type selection)
1606 {
1607 ELM_ENTRY_DATA_GET(data, sd);
1608
1609 if (!sd) return;
1610 if (!sd->have_selection) return;
1611 if ((selection == ELM_SEL_TYPE_CLIPBOARD) ||
1612 (selection == ELM_SEL_TYPE_PRIMARY))
1613 {
1614 elm_entry_select_none(data);
1615 }
1616 }
1617
1618 static void
_selection_store(Elm_Sel_Type seltype,Evas_Object * obj)1619 _selection_store(Elm_Sel_Type seltype,
1620 Evas_Object *obj)
1621 {
1622 const char *sel;
1623
1624 ELM_ENTRY_DATA_GET(obj, sd);
1625
1626 if (!sd) return;
1627 sel = edje_object_part_text_selection_get(sd->entry_edje, "elm.text");
1628 if ((!sel) || (!sel[0])) return; /* avoid deleting our own selection */
1629
1630 elm_cnp_selection_set
1631 (obj, seltype, ELM_SEL_FORMAT_MARKUP, sel, strlen(sel) + 1);
1632 elm_cnp_selection_loss_callback_set(obj, seltype, _selection_clear, obj);
1633 if (seltype == ELM_SEL_TYPE_CLIPBOARD)
1634 eina_stringshare_replace(&sd->cut_sel, sel);
1635 }
1636
1637 static void
_cut_cb(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1638 _cut_cb(void *data,
1639 Evas_Object *obj EINA_UNUSED,
1640 void *event_info EINA_UNUSED)
1641 {
1642 ELM_ENTRY_DATA_GET(data, sd);
1643
1644 if (!sd) return;
1645 efl_event_callback_legacy_call
1646 (data, EFL_UI_TEXTBOX_EVENT_SELECTION_CUT, NULL);
1647 /* Store it */
1648 sd->sel_mode = EINA_FALSE;
1649 if (!_elm_config->desktop_entry)
1650 edje_object_part_text_select_allow_set
1651 (sd->entry_edje, "elm.text", EINA_FALSE);
1652 edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
1653
1654 if (!_elm_config->desktop_entry)
1655 elm_widget_scroll_hold_pop(data);
1656
1657 _selection_store(ELM_SEL_TYPE_CLIPBOARD, data);
1658 _edje_entry_user_insert(data, "");
1659 }
1660
1661 static void
_copy_cb(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1662 _copy_cb(void *data,
1663 Evas_Object *obj EINA_UNUSED,
1664 void *event_info EINA_UNUSED)
1665 {
1666 ELM_ENTRY_DATA_GET(data, sd);
1667
1668 if (!sd) return;
1669 efl_event_callback_legacy_call
1670 (data, EFL_UI_TEXTBOX_EVENT_SELECTION_COPY, NULL);
1671 sd->sel_mode = EINA_FALSE;
1672 if (!_elm_config->desktop_entry)
1673 {
1674 edje_object_part_text_select_allow_set
1675 (sd->entry_edje, "elm.text", EINA_FALSE);
1676 edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
1677 elm_widget_scroll_hold_pop(data);
1678 }
1679 _selection_store(ELM_SEL_TYPE_CLIPBOARD, data);
1680 }
1681
1682 static void
_hover_cancel_cb(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1683 _hover_cancel_cb(void *data,
1684 Evas_Object *obj EINA_UNUSED,
1685 void *event_info EINA_UNUSED)
1686 {
1687 ELM_ENTRY_DATA_GET(data, sd);
1688
1689 if (!sd) return;
1690 sd->sel_mode = EINA_FALSE;
1691 if (!_elm_config->desktop_entry)
1692 edje_object_part_text_select_allow_set
1693 (sd->entry_edje, "elm.text", EINA_FALSE);
1694 edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
1695 if (!_elm_config->desktop_entry)
1696 elm_widget_scroll_hold_pop(data);
1697 edje_object_part_text_select_none(sd->entry_edje, "elm.text");
1698 }
1699
1700 static void
_hover_item_clicked_cb(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1701 _hover_item_clicked_cb(void *data,
1702 Evas_Object *obj EINA_UNUSED,
1703 void *event_info EINA_UNUSED)
1704 {
1705 Elm_Entry_Context_Menu_Item *it = data;
1706 if (!it) return;
1707
1708 if (it->func) it->func(it->data, it->obj, it);
1709 }
1710
1711 static void
_menu_call(Evas_Object * obj)1712 _menu_call(Evas_Object *obj)
1713 {
1714 Evas_Object *top;
1715 const Eina_List *l;
1716 const Elm_Entry_Context_Menu_Item *it;
1717
1718 ELM_ENTRY_DATA_GET(obj, sd);
1719
1720 if (!sd) return;
1721 if (sd->anchor_hover.hover) return;
1722
1723 efl_event_callback_legacy_call(obj, ELM_ENTRY_EVENT_CONTEXT_OPEN, NULL);
1724
1725 if ((sd->api) && (sd->api->obj_longpress))
1726 {
1727 sd->api->obj_longpress(obj);
1728 }
1729 else if (sd->context_menu)
1730 {
1731 const char *context_menu_orientation;
1732 Eina_Bool ownersel;
1733
1734 ownersel = elm_cnp_clipboard_selection_has_owner(obj);
1735 if (!sd->items)
1736 {
1737 /* prevent stupid blank hoversel */
1738 if (sd->have_selection && sd->password) return;
1739 if (_elm_config->desktop_entry && (!sd->have_selection) && ((!sd->editable) || (!ownersel)))
1740 return;
1741 }
1742 if (sd->hoversel) evas_object_del(sd->hoversel);
1743 else elm_widget_scroll_freeze_push(obj);
1744
1745 sd->hoversel = elm_hoversel_add(obj);
1746 elm_object_tree_focus_allow_set(sd->hoversel, EINA_FALSE);
1747 context_menu_orientation = edje_object_data_get
1748 (sd->entry_edje, "context_menu_orientation");
1749
1750 if ((context_menu_orientation) &&
1751 (!strcmp(context_menu_orientation, "horizontal")))
1752 elm_hoversel_horizontal_set(sd->hoversel, EINA_TRUE);
1753
1754 elm_object_style_set(sd->hoversel, "entry");
1755 elm_widget_sub_object_add(obj, sd->hoversel);
1756 elm_object_text_set(sd->hoversel, "Text");
1757 top = elm_widget_top_get(obj);
1758
1759 if (top) elm_hoversel_hover_parent_set(sd->hoversel, top);
1760
1761 efl_event_callback_add
1762 (sd->hoversel, ELM_HOVERSEL_EVENT_DISMISSED, _hover_dismissed_cb, obj);
1763 if (sd->have_selection)
1764 {
1765 if (!sd->password)
1766 {
1767 if (sd->editable)
1768 elm_hoversel_item_add
1769 (sd->hoversel, E_("Cut"), NULL, ELM_ICON_NONE,
1770 _cut_cb, obj);
1771 elm_hoversel_item_add
1772 (sd->hoversel, E_("Copy"), NULL, ELM_ICON_NONE,
1773 _copy_cb, obj);
1774 if (sd->editable && ownersel)
1775 elm_hoversel_item_add
1776 (sd->hoversel, E_("Paste"), NULL, ELM_ICON_NONE,
1777 _paste_cb, obj);
1778 elm_hoversel_item_add
1779 (sd->hoversel, E_("Cancel"), NULL, ELM_ICON_NONE,
1780 _hover_cancel_cb, obj);
1781 }
1782 }
1783 else
1784 {
1785 if (!sd->sel_mode)
1786 {
1787 if (sd->sel_allow && !_elm_config->desktop_entry)
1788 {
1789 if (!sd->password)
1790 elm_hoversel_item_add
1791 (sd->hoversel, E_("Select"), NULL, ELM_ICON_NONE,
1792 _hover_selected_cb, obj);
1793 }
1794 if (ownersel)
1795 {
1796 if (sd->editable)
1797 elm_hoversel_item_add
1798 (sd->hoversel, E_("Paste"), NULL, ELM_ICON_NONE,
1799 _paste_cb, obj);
1800 }
1801 }
1802 else
1803 elm_hoversel_item_add
1804 (sd->hoversel, E_("Cancel"), NULL, ELM_ICON_NONE,
1805 _hover_cancel_cb, obj);
1806 }
1807
1808 EINA_LIST_FOREACH(sd->items, l, it)
1809 {
1810 elm_hoversel_item_add(sd->hoversel, it->label, it->icon_file,
1811 it->icon_type, _hover_item_clicked_cb, it);
1812 }
1813
1814 if (sd->hoversel)
1815 {
1816 _hoversel_position(obj);
1817 elm_hoversel_hover_begin(sd->hoversel);
1818 evas_object_show(sd->hoversel);
1819 }
1820
1821 if (!_elm_config->desktop_entry)
1822 {
1823 edje_object_part_text_select_allow_set
1824 (sd->entry_edje, "elm.text", EINA_FALSE);
1825 edje_object_part_text_select_abort(sd->entry_edje, "elm.text");
1826 }
1827 }
1828 }
1829
1830 static void
_magnifier_proxy_update(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1831 _magnifier_proxy_update(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1832 {
1833 _magnifier_move(data);
1834 }
1835
1836 static void
_magnifier_create(void * data)1837 _magnifier_create(void *data)
1838 {
1839 ELM_ENTRY_DATA_GET(data, sd);
1840
1841 if (!sd) return;
1842 double scale = _elm_config->magnifier_scale;
1843 Evas *e;
1844 Evas_Coord w, h, mw, mh;
1845
1846 evas_object_del(sd->mgf_proxy);
1847 evas_object_del(sd->mgf_bg);
1848 evas_object_del(sd->mgf_clip);
1849
1850 e = evas_object_evas_get(data);
1851
1852 //Bg
1853 sd->mgf_bg = edje_object_add(e);
1854 _elm_theme_object_set(data, sd->mgf_bg, "entry", "magnifier", "default");
1855 evas_object_show(sd->mgf_bg);
1856
1857 //Proxy
1858 sd->mgf_proxy = evas_object_image_add(e);
1859 evas_object_event_callback_add(sd->mgf_proxy, EVAS_CALLBACK_RESIZE,
1860 _magnifier_proxy_update, data);
1861 evas_object_event_callback_add(sd->mgf_proxy, EVAS_CALLBACK_MOVE,
1862 _magnifier_proxy_update, data);
1863 edje_object_part_swallow(sd->mgf_bg, "elm.swallow.content", sd->mgf_proxy);
1864 evas_object_image_source_set(sd->mgf_proxy, data);
1865 evas_object_geometry_get(data, NULL, NULL, &w, &h);
1866
1867 //Clipper
1868 sd->mgf_clip = evas_object_rectangle_add(e);
1869 evas_object_color_set(sd->mgf_clip, 0, 0, 0, 0);
1870 evas_object_show(sd->mgf_clip);
1871 evas_object_clip_set(sd->mgf_proxy, sd->mgf_clip);
1872
1873 mw = (Evas_Coord)(scale * (float) w);
1874 mh = (Evas_Coord)(scale * (float) h);
1875 if ((mw <= 0) || (mh <= 0)) return;
1876
1877 evas_object_layer_set(sd->mgf_bg, EVAS_LAYER_MAX);
1878 evas_object_layer_set(sd->mgf_proxy, EVAS_LAYER_MAX);
1879 }
1880
1881 static void
_magnifier_move(void * data)1882 _magnifier_move(void *data)
1883 {
1884 ELM_ENTRY_DATA_GET(data, sd);
1885
1886 if (!sd) return;
1887 Evas_Coord x, y, w, h;
1888 Evas_Coord px, py, pw, ph;
1889 Evas_Coord cx, cy, ch;
1890 Evas_Coord ex, ey;
1891 Evas_Coord mx, my, mw, mh;
1892 Evas_Coord diffx = 0;
1893 Evas_Object *top;
1894 double fx, fy, fw, fh;
1895 double scale = _elm_config->magnifier_scale;
1896
1897 edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
1898 &cx, &cy, NULL, &ch);
1899 if (sd->scroll)
1900 {
1901 Evas_Coord ox, oy;
1902 evas_object_geometry_get(sd->scr_edje, &ex, &ey, NULL, NULL);
1903 elm_interface_scrollable_content_pos_get(data, &ox, &oy);
1904 ex -= ox;
1905 ey -= oy;
1906 }
1907 else
1908 {
1909 evas_object_geometry_get(data, &ex, &ey, NULL, NULL);
1910 }
1911 cx += ex;
1912 cy += ey;
1913
1914 // calculate the position of the magnifier
1915 edje_object_parts_extends_calc(sd->mgf_bg, &x, &y, &w, &h);
1916
1917 mx = cx - x - (w / 2);
1918 my = cy - y - h;
1919 mw = w;
1920 mh = h;
1921
1922 // keep magnifier inside window
1923 top = elm_widget_top_get(data);
1924 if (top && efl_isa(top, EFL_UI_WIN_CLASS))
1925 {
1926 Evas_Coord wh, ww;
1927 evas_object_geometry_get(top, NULL, NULL, &ww, &wh);
1928 if (mx < 0)
1929 {
1930 diffx = mx;
1931 mx = 0;
1932 }
1933 if (mx + mw > ww)
1934 {
1935 diffx = - (ww - (mx + mw));
1936 mx = ww - mw;
1937 }
1938 if (my < 0)
1939 my = 0;
1940 if (my + mh > wh)
1941 my = wh - mh;
1942 }
1943
1944 // move the magnifier to the proper position
1945 evas_object_move(sd->mgf_bg, mx, my);
1946
1947 //Set the Proxy Render Area
1948 evas_object_geometry_get(data, &x, &y, &w, &h);
1949 evas_object_geometry_get(sd->mgf_proxy, &px, &py, &pw, &ph);
1950
1951 fx = -((cx - x) * scale) + (pw * 0.5) + diffx;
1952 fy = -((cy - y) * scale) + (ph * 0.5) - (ch * 0.5 * scale);
1953 fw = w * scale;
1954 fh = h * scale;
1955 evas_object_image_fill_set(sd->mgf_proxy, fx, fy, fw, fh);
1956
1957 //Update Clipper Area
1958 int tx = fx;
1959 int ty = fy;
1960 int tw = fw;
1961 int th = fh;
1962 if (tx > 0) px += tx;
1963 if (ty > 0) py += ty;
1964 if (-(tx - pw) > tw) pw -= (-((tx - pw) + tw));
1965 if (-(ty - ph) > th) ph -= (-((ty - ph) + th));
1966 evas_object_geometry_set(sd->mgf_clip, px, py, pw, ph);
1967 }
1968
1969 static void
_magnifier_hide(void * data)1970 _magnifier_hide(void *data)
1971 {
1972 ELM_ENTRY_DATA_GET(data, sd);
1973 if (!sd) return;
1974 edje_object_signal_emit(sd->mgf_bg, "elm,action,hide,magnifier", "elm");
1975 elm_widget_scroll_freeze_pop(data);
1976 evas_object_hide(sd->mgf_clip);
1977 }
1978
1979 static void
_magnifier_show(void * data)1980 _magnifier_show(void *data)
1981 {
1982 ELM_ENTRY_DATA_GET(data, sd);
1983 if (!sd) return;
1984 edje_object_signal_emit(sd->mgf_bg, "elm,action,show,magnifier", "elm");
1985 elm_widget_scroll_freeze_push(data);
1986 evas_object_show(sd->mgf_clip);
1987 }
1988
1989 static Eina_Bool
_long_press_cb(void * data)1990 _long_press_cb(void *data)
1991 {
1992 ELM_ENTRY_DATA_GET(data, sd);
1993
1994 if (!sd) return ECORE_CALLBACK_CANCEL;
1995 if (_elm_config->magnifier_enable)
1996 {
1997 _magnifier_create(data);
1998 _magnifier_show(data);
1999 _magnifier_move(data);
2000 }
2001 /* Context menu will not appear if context menu disabled is set
2002 * as false on a long press callback */
2003 else if (!_elm_config->context_menu_disabled &&
2004 (!_elm_config->desktop_entry))
2005 _menu_call(data);
2006
2007 sd->long_pressed = EINA_TRUE;
2008
2009 sd->longpress_timer = NULL;
2010 evas_object_smart_callback_call
2011 (data, "longpressed", NULL);
2012
2013 return ECORE_CALLBACK_CANCEL;
2014 }
2015
2016 static void
_key_down_cb(void * data,Evas * evas EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)2017 _key_down_cb(void *data,
2018 Evas *evas EINA_UNUSED,
2019 Evas_Object *obj EINA_UNUSED,
2020 void *event_info)
2021 {
2022 Evas_Event_Key_Down *ev = event_info;
2023 /* First check if context menu disabled is false or not, and
2024 * then check for key id */
2025 if ((!_elm_config->context_menu_disabled) && !strcmp(ev->key, "Menu"))
2026 _menu_call(data);
2027 }
2028
2029 static void
_mouse_down_cb(void * data,Evas * evas EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)2030 _mouse_down_cb(void *data,
2031 Evas *evas EINA_UNUSED,
2032 Evas_Object *obj EINA_UNUSED,
2033 void *event_info)
2034 {
2035 Evas_Event_Mouse_Down *ev = event_info;
2036
2037 ELM_ENTRY_DATA_GET(data, sd);
2038
2039 if (!sd) return;
2040 if (sd->disabled) return;
2041 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
2042 sd->downx = ev->canvas.x;
2043 sd->downy = ev->canvas.y;
2044 sd->long_pressed = EINA_FALSE;
2045
2046 if (ev->button == 1)
2047 {
2048 ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
2049 sd->longpress_timer = ecore_timer_add
2050 (_elm_config->longpress_timeout, _long_press_cb, data);
2051 }
2052 /* If right button is pressed and context menu disabled is true,
2053 * then only context menu will appear */
2054 else if (ev->button == 3 && (!_elm_config->context_menu_disabled))
2055 {
2056 if (_elm_config->desktop_entry)
2057 {
2058 sd->use_down = 1;
2059 _menu_call(data);
2060 }
2061 }
2062 }
2063
2064 static void
_mouse_up_cb(void * data,Evas * evas EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)2065 _mouse_up_cb(void *data,
2066 Evas *evas EINA_UNUSED,
2067 Evas_Object *obj EINA_UNUSED,
2068 void *event_info)
2069 {
2070 Evas_Event_Mouse_Up *ev = event_info;
2071 Eina_Bool top_is_win = EINA_FALSE;
2072 Evas_Object *top;
2073
2074 ELM_ENTRY_DATA_GET(data, sd);
2075
2076 if (!sd) return;
2077 if (sd->disabled) return;
2078 if (ev->button == 1)
2079 {
2080 ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
2081 /* Since context menu disabled flag was checked at long press start while mouse
2082 * down, hence the same should be checked at mouse up from a long press
2083 * as well */
2084 if ((sd->long_pressed) && (_elm_config->magnifier_enable))
2085 {
2086 _magnifier_hide(data);
2087 if (!_elm_config->context_menu_disabled)
2088 {
2089 _menu_call(data);
2090 }
2091 }
2092 else
2093 {
2094 top = elm_widget_top_get(data);
2095 if (top)
2096 {
2097 if (efl_isa(top, EFL_UI_WIN_CLASS))
2098 top_is_win = EINA_TRUE;
2099
2100 if (top_is_win && sd->input_panel_enable && sd->input_panel_show_on_demand &&
2101 !edje_object_part_text_imf_context_get(sd->entry_edje, "elm.text"))
2102 elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON);
2103 }
2104 }
2105 }
2106 /* Since context menu disabled flag was checked at mouse right key down,
2107 * hence the same should be stopped at mouse up of right key as well */
2108 else if ((ev->button == 3) && (!_elm_config->context_menu_disabled) &&
2109 (!_elm_config->desktop_entry))
2110 {
2111 sd->use_down = 1;
2112 _menu_call(data);
2113 }
2114 }
2115
2116 static void
_mouse_move_cb(void * data,Evas * evas EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)2117 _mouse_move_cb(void *data,
2118 Evas *evas EINA_UNUSED,
2119 Evas_Object *obj EINA_UNUSED,
2120 void *event_info)
2121 {
2122 Evas_Event_Mouse_Move *ev = event_info;
2123
2124 ELM_ENTRY_DATA_GET(data, sd);
2125
2126 if (!sd) return;
2127 if (sd->disabled) return;
2128 if (ev->buttons == 1)
2129 {
2130 if ((sd->long_pressed) && (_elm_config->magnifier_enable))
2131 {
2132 Evas_Coord x, y;
2133 Eina_Bool rv;
2134
2135 evas_object_geometry_get(sd->entry_edje, &x, &y, NULL, NULL);
2136 rv = edje_object_part_text_cursor_coord_set
2137 (sd->entry_edje, "elm.text", EDJE_CURSOR_USER,
2138 ev->cur.canvas.x - x, ev->cur.canvas.y - y);
2139 if (rv)
2140 {
2141 edje_object_part_text_cursor_copy
2142 (sd->entry_edje, "elm.text", EDJE_CURSOR_USER, EDJE_CURSOR_MAIN);
2143 }
2144 else
2145 WRN("Warning: Cannot move cursor");
2146
2147 _magnifier_move(data);
2148 }
2149 }
2150 if (!sd->sel_mode)
2151 {
2152 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
2153 {
2154 ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
2155 }
2156 else if (sd->longpress_timer)
2157 {
2158 Evas_Coord dx, dy;
2159
2160 dx = sd->downx - ev->cur.canvas.x;
2161 dx *= dx;
2162 dy = sd->downy - ev->cur.canvas.y;
2163 dy *= dy;
2164 if ((dx + dy) >
2165 ((_elm_config->finger_size / 2) *
2166 (_elm_config->finger_size / 2)))
2167 {
2168 ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
2169 }
2170 }
2171 }
2172 else if (sd->longpress_timer)
2173 {
2174 Evas_Coord dx, dy;
2175
2176 dx = sd->downx - ev->cur.canvas.x;
2177 dx *= dx;
2178 dy = sd->downy - ev->cur.canvas.y;
2179 dy *= dy;
2180 if ((dx + dy) >
2181 ((_elm_config->finger_size / 2) *
2182 (_elm_config->finger_size / 2)))
2183 {
2184 ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
2185 }
2186 }
2187 }
2188
2189 static void
_entry_changed_handle(void * data,const Efl_Event_Description * event)2190 _entry_changed_handle(void *data,
2191 const Efl_Event_Description* event)
2192 {
2193 Evas_Coord minh;
2194 const char *text;
2195
2196 ELM_ENTRY_DATA_GET(data, sd);
2197
2198 if (!sd) return;
2199 evas_event_freeze(evas_object_evas_get(data));
2200 sd->changed = EINA_TRUE;
2201 /* Reset the size hints which are no more relevant. Keep the
2202 * height, this is a hack, but doesn't really matter cause we'll
2203 * re-eval in a moment. */
2204 evas_object_size_hint_combined_min_get(data, NULL, &minh);
2205 evas_object_size_hint_min_set(data, -1, minh);
2206
2207 elm_layout_sizing_eval(data);
2208 ELM_SAFE_FREE(sd->text, eina_stringshare_del);
2209 ELM_SAFE_FREE(sd->delay_write, ecore_timer_del);
2210 evas_event_thaw(evas_object_evas_get(data));
2211 evas_event_thaw_eval(evas_object_evas_get(data));
2212 if ((sd->auto_save) && (sd->file))
2213 sd->delay_write = ecore_timer_add(ELM_ENTRY_DELAY_WRITE_TIME,
2214 _delay_write, data);
2215
2216 _return_key_enabled_check(data);
2217 text = edje_object_part_text_get(sd->entry_edje, "elm.text");
2218 if (text)
2219 {
2220 if (text[0])
2221 _elm_entry_guide_update(data, EINA_TRUE);
2222 else
2223 _elm_entry_guide_update(data, EINA_FALSE);
2224 }
2225 _validate(data);
2226
2227 /* callback - this could call callbacks that delete the
2228 * entry... thus... any access to sd after this could be
2229 * invalid */
2230 efl_event_callback_legacy_call(data, event, NULL);
2231 }
2232
2233 static void
_entry_changed_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2234 _entry_changed_signal_cb(void *data,
2235 Evas_Object *obj EINA_UNUSED,
2236 const char *emission EINA_UNUSED,
2237 const char *source EINA_UNUSED)
2238 {
2239 _entry_changed_handle(data, ELM_ENTRY_EVENT_CHANGED);
2240 }
2241
2242 static void
_entry_changed_user_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2243 _entry_changed_user_signal_cb(void *data,
2244 Evas_Object *obj EINA_UNUSED,
2245 const char *emission EINA_UNUSED,
2246 const char *source EINA_UNUSED)
2247 {
2248 Elm_Entry_Change_Info info;
2249 Edje_Entry_Change_Info *edje_info = (Edje_Entry_Change_Info *)
2250 edje_object_signal_callback_extra_data_get();
2251
2252 if (edje_info)
2253 {
2254 memcpy(&info, edje_info, sizeof(info));
2255 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_CHANGED_USER, &info);
2256 }
2257 else
2258 {
2259 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_CHANGED_USER, NULL);
2260 }
2261 if (_elm_config->atspi_mode)
2262 {
2263 Efl_Access_Text_Change_Info atspi_info;
2264 if (edje_info && edje_info->insert)
2265 {
2266 atspi_info.content = elm_entry_markup_to_utf8(edje_info->change.insert.content);
2267 atspi_info.pos = edje_info->change.insert.pos;
2268 atspi_info.len = edje_info->change.insert.plain_length;
2269 efl_access_object_event_emit(data, EFL_ACCESS_TEXT_EVENT_ACCESS_TEXT_INSERTED, &atspi_info);
2270 free((void *)atspi_info.content);
2271 }
2272 else if (edje_info && !edje_info->insert)
2273 {
2274 atspi_info.content = elm_entry_markup_to_utf8(edje_info->change.del.content);
2275 atspi_info.pos = MIN(edje_info->change.del.start, edje_info->change.del.end);
2276 atspi_info.len = MAX(edje_info->change.del.start, edje_info->change.del.end) - atspi_info.pos;
2277 efl_access_object_event_emit(data, EFL_ACCESS_TEXT_EVENT_ACCESS_TEXT_REMOVED, &atspi_info);
2278 free((void *)atspi_info.content);
2279 }
2280 }
2281 }
2282
2283 static void
_entry_preedit_changed_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2284 _entry_preedit_changed_signal_cb(void *data,
2285 Evas_Object *obj EINA_UNUSED,
2286 const char *emission EINA_UNUSED,
2287 const char *source EINA_UNUSED)
2288 {
2289 char *text = NULL;
2290 Edje_Entry_Change_Info *edje_info = (Edje_Entry_Change_Info *)
2291 edje_object_signal_callback_extra_data_get();
2292 _entry_changed_handle(data, ELM_ENTRY_EVENT_PREEDIT_CHANGED);
2293
2294 if (_elm_config->atspi_mode)
2295 {
2296 Efl_Access_Text_Change_Info atspi_info;
2297 if (edje_info && edje_info->insert)
2298 {
2299 text = elm_entry_markup_to_utf8(edje_info->change.insert.content);
2300 atspi_info.content = text;
2301 atspi_info.pos = edje_info->change.insert.pos;
2302 atspi_info.len = edje_info->change.insert.plain_length;
2303 efl_access_object_event_emit(
2304 data,
2305 EFL_ACCESS_TEXT_EVENT_ACCESS_TEXT_INSERTED,
2306 &atspi_info);
2307 free(text);
2308 }
2309 }
2310 }
2311
2312 static void
_entry_undo_request_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2313 _entry_undo_request_signal_cb(void *data,
2314 Evas_Object *obj EINA_UNUSED,
2315 const char *emission EINA_UNUSED,
2316 const char *source EINA_UNUSED)
2317 {
2318 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_UNDO_REQUEST, NULL);
2319 }
2320
2321 static void
_entry_redo_request_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2322 _entry_redo_request_signal_cb(void *data,
2323 Evas_Object *obj EINA_UNUSED,
2324 const char *emission EINA_UNUSED,
2325 const char *source EINA_UNUSED)
2326 {
2327 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_REDO_REQUEST, NULL);
2328 }
2329
2330 static void
_entry_selection_start_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2331 _entry_selection_start_signal_cb(void *data,
2332 Evas_Object *obj EINA_UNUSED,
2333 const char *emission EINA_UNUSED,
2334 const char *source EINA_UNUSED)
2335 {
2336 const Eina_List *l;
2337 Evas_Object *entry;
2338
2339 EINA_LIST_FOREACH(entries, l, entry)
2340 {
2341 if (entry != data) elm_entry_select_none(entry);
2342 }
2343
2344 Eina_Bool b_value = EINA_TRUE;
2345 efl_event_callback_legacy_call
2346 (data, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, &b_value);
2347
2348 elm_object_focus_set(data, EINA_TRUE);
2349 }
2350
2351 static void
_entry_selection_all_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2352 _entry_selection_all_signal_cb(void *data,
2353 Evas_Object *obj EINA_UNUSED,
2354 const char *emission EINA_UNUSED,
2355 const char *source EINA_UNUSED)
2356 {
2357 elm_entry_select_all(data);
2358 }
2359
2360 static void
_entry_selection_none_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2361 _entry_selection_none_signal_cb(void *data,
2362 Evas_Object *obj EINA_UNUSED,
2363 const char *emission EINA_UNUSED,
2364 const char *source EINA_UNUSED)
2365 {
2366 elm_entry_select_none(data);
2367 }
2368
2369 // XXX: still try primary selection even if on wl in case it's
2370 // supported
2371 //static inline Eina_Bool
2372 //_entry_win_is_wl(Evas_Object *obj)
2373 //{
2374 // Evas_Object *win = _entry_win_get(obj);
2375 // /* primary selection does not exist (yet) */
2376 // return win && elm_win_wl_window_get(win);
2377 //}
2378
2379 static void
_entry_selection_changed_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2380 _entry_selection_changed_signal_cb(void *data,
2381 Evas_Object *obj EINA_UNUSED,
2382 const char *emission EINA_UNUSED,
2383 const char *source EINA_UNUSED)
2384 {
2385 ELM_ENTRY_DATA_GET(data, sd);
2386
2387 if (!sd) return;
2388 sd->have_selection = EINA_TRUE;
2389 //FIXME how to get selection range in legacy !?
2390 Eina_Range range = EINA_RANGE_EMPTY();
2391 efl_event_callback_legacy_call
2392 (data, EFL_TEXT_INTERACTIVE_EVENT_SELECTION_CHANGED, &range);
2393 // XXX: still try primary selection even if on wl in case it's
2394 // supported
2395 // if (!_entry_win_is_wl(data))
2396 _selection_store(ELM_SEL_TYPE_PRIMARY, data);
2397 _update_selection_handler(data);
2398 if (_elm_config->atspi_mode)
2399 efl_access_object_event_emit( data, EFL_ACCESS_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, NULL);
2400 }
2401
2402 static void
_entry_selection_cleared_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2403 _entry_selection_cleared_signal_cb(void *data,
2404 Evas_Object *obj EINA_UNUSED,
2405 const char *emission EINA_UNUSED,
2406 const char *source EINA_UNUSED)
2407 {
2408 ELM_ENTRY_DATA_GET(data, sd);
2409
2410 if (!sd) return;
2411 if (!sd->have_selection) return;
2412
2413 sd->have_selection = EINA_FALSE;
2414 Eina_Bool b_value = sd->have_selection;
2415 efl_event_callback_legacy_call
2416 (data, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, &b_value);
2417 // XXX: still try primary selection even if on wl in case it's
2418 // supported
2419 // if (!_entry_win_is_wl(data))
2420 {
2421 if (sd->cut_sel)
2422 {
2423 elm_cnp_selection_set
2424 (data, ELM_SEL_TYPE_PRIMARY, ELM_SEL_FORMAT_MARKUP,
2425 sd->cut_sel, eina_stringshare_strlen(sd->cut_sel));
2426 elm_cnp_selection_loss_callback_set(data, ELM_SEL_TYPE_PRIMARY, _selection_clear, data);
2427
2428 ELM_SAFE_FREE(sd->cut_sel, eina_stringshare_del);
2429 }
2430 else
2431 {
2432 elm_object_cnp_selection_clear(data, ELM_SEL_TYPE_PRIMARY);
2433 }
2434 }
2435 _hide_selection_handler(data);
2436 }
2437
2438 static void
_entry_paste_request_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission,const char * source EINA_UNUSED)2439 _entry_paste_request_signal_cb(void *data,
2440 Evas_Object *obj EINA_UNUSED,
2441 const char *emission,
2442 const char *source EINA_UNUSED)
2443 {
2444 Evas_Object *top;
2445
2446 ELM_ENTRY_DATA_GET(data, sd);
2447
2448 if (!sd) return;
2449 Elm_Sel_Type type = (emission[sizeof("ntry,paste,request,")] == '1') ?
2450 ELM_SEL_TYPE_PRIMARY : ELM_SEL_TYPE_CLIPBOARD;
2451
2452 if (!sd->editable) return;
2453 // XXX: still try primary selection even if on wl in case it's
2454 // supported
2455 // if ((type == ELM_SEL_TYPE_PRIMARY) && _entry_win_is_wl(data)) return;
2456 efl_event_callback_legacy_call
2457 (data, EFL_UI_TEXTBOX_EVENT_SELECTION_PASTE, NULL);
2458
2459 top = _entry_win_get(data);
2460 if (top)
2461 {
2462 Elm_Sel_Format formats = ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_TEXT;
2463
2464 sd->selection_asked = EINA_TRUE;
2465
2466 if (sd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
2467 formats = ELM_SEL_FORMAT_TEXT;
2468 else if (sd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
2469 formats |= ELM_SEL_FORMAT_IMAGE;
2470
2471 elm_cnp_selection_get(data, type, formats, _selection_data_cb, NULL);
2472 }
2473 }
2474
2475 static void
_entry_copy_notify_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2476 _entry_copy_notify_signal_cb(void *data,
2477 Evas_Object *obj EINA_UNUSED,
2478 const char *emission EINA_UNUSED,
2479 const char *source EINA_UNUSED)
2480 {
2481 _copy_cb(data, NULL, NULL);
2482 }
2483
2484 static void
_entry_cut_notify_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2485 _entry_cut_notify_signal_cb(void *data,
2486 Evas_Object *obj EINA_UNUSED,
2487 const char *emission EINA_UNUSED,
2488 const char *source EINA_UNUSED)
2489 {
2490 _cut_cb(data, NULL, NULL);
2491 }
2492
2493 static void
_entry_cursor_changed_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2494 _entry_cursor_changed_signal_cb(void *data,
2495 Evas_Object *obj EINA_UNUSED,
2496 const char *emission EINA_UNUSED,
2497 const char *source EINA_UNUSED)
2498 {
2499 ELM_ENTRY_DATA_GET(data, sd);
2500 if (!sd) return;
2501 sd->cursor_pos = edje_object_part_text_cursor_pos_get
2502 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
2503 sd->cur_changed = EINA_TRUE;
2504 if (efl_ui_focus_object_focus_get(data))
2505 edje_object_signal_emit(sd->entry_edje, "elm,action,show,cursor", "elm");
2506 _cursor_geometry_recalc(data);
2507
2508 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_CURSOR_CHANGED, NULL);
2509
2510 if (_elm_config->atspi_mode)
2511 efl_access_object_event_emit( data, EFL_ACCESS_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL);
2512 }
2513
2514 static void
_entry_cursor_changed_manual_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2515 _entry_cursor_changed_manual_signal_cb(void *data,
2516 Evas_Object *obj EINA_UNUSED,
2517 const char *emission EINA_UNUSED,
2518 const char *source EINA_UNUSED)
2519 {
2520 efl_event_callback_legacy_call
2521 (data, ELM_ENTRY_EVENT_CURSOR_CHANGED_MANUAL, NULL);
2522 if (_elm_config->atspi_mode)
2523 efl_access_object_event_emit( data, EFL_ACCESS_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL);
2524 }
2525
2526 static void
_signal_anchor_geoms_do_things_with_lol(Elm_Entry_Data * sd,Elm_Entry_Anchor_Info * ei)2527 _signal_anchor_geoms_do_things_with_lol(Elm_Entry_Data *sd,
2528 Elm_Entry_Anchor_Info *ei)
2529 {
2530 Evas_Textblock_Rectangle *r;
2531 const Eina_List *geoms, *l;
2532 Evas_Coord px, py, x, y;
2533
2534 geoms = edje_object_part_text_anchor_geometry_get
2535 (sd->entry_edje, "elm.text", ei->name);
2536
2537 if (!geoms) return;
2538
2539 evas_object_geometry_get(
2540 edje_object_part_object_get(sd->entry_edje, "elm.text"),
2541 &x, &y, NULL, NULL);
2542 evas_pointer_canvas_xy_get
2543 (evas_object_evas_get(sd->entry_edje), &px, &py);
2544
2545 EINA_LIST_FOREACH(geoms, l, r)
2546 {
2547 if (((r->x + x) <= px) && ((r->y + y) <= py) &&
2548 ((r->x + x + r->w) > px) && ((r->y + y + r->h) > py))
2549 {
2550 ei->x = r->x + x;
2551 ei->y = r->y + y;
2552 ei->w = r->w;
2553 ei->h = r->h;
2554 break;
2555 }
2556 }
2557 }
2558
2559 static void
_entry_anchor_down_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2560 _entry_anchor_down_signal_cb(void *data,
2561 Evas_Object *obj EINA_UNUSED,
2562 const char *emission EINA_UNUSED,
2563 const char *source EINA_UNUSED)
2564 {
2565 Elm_Entry_Anchor_Info ei;
2566 const char *p;
2567 char *p2;
2568
2569 ELM_ENTRY_DATA_GET(data, sd);
2570
2571 if (!sd) return;
2572 p = emission + sizeof("nchor,mouse,down,");
2573 ei.button = strtol(p, &p2, 10);
2574 ei.name = p2 + 1;
2575 ei.x = ei.y = ei.w = ei.h = 0;
2576
2577 _signal_anchor_geoms_do_things_with_lol(sd, &ei);
2578
2579 if (!sd->disabled)
2580 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_ANCHOR_DOWN, &ei);
2581 }
2582
2583 static void
_entry_anchor_up_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2584 _entry_anchor_up_signal_cb(void *data,
2585 Evas_Object *obj EINA_UNUSED,
2586 const char *emission EINA_UNUSED,
2587 const char *source EINA_UNUSED)
2588 {
2589 Elm_Entry_Anchor_Info ei;
2590 const char *p;
2591 char *p2;
2592
2593 ELM_ENTRY_DATA_GET(data, sd);
2594
2595 if (!sd) return;
2596 p = emission + sizeof("nchor,mouse,up,");
2597 ei.button = strtol(p, &p2, 10);
2598 ei.name = p2 + 1;
2599 ei.x = ei.y = ei.w = ei.h = 0;
2600
2601 _signal_anchor_geoms_do_things_with_lol(sd, &ei);
2602
2603 if (!sd->disabled)
2604 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_ANCHOR_UP, &ei);
2605 }
2606
2607 static void
_anchor_hover_del_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)2608 _anchor_hover_del_cb(void *data,
2609 Evas *e EINA_UNUSED,
2610 Evas_Object *obj EINA_UNUSED,
2611 void *event_info EINA_UNUSED)
2612 {
2613 ELM_ENTRY_DATA_GET(data, sd);
2614
2615 if (!sd) return;
2616 ELM_SAFE_FREE(sd->anchor_hover.pop, evas_object_del);
2617 evas_object_event_callback_del_full
2618 (sd->anchor_hover.hover, EVAS_CALLBACK_DEL, _anchor_hover_del_cb, obj);
2619 }
2620
2621 static void
_anchor_hover_clicked_cb(void * data,const Efl_Event * event EINA_UNUSED)2622 _anchor_hover_clicked_cb(void *data, const Efl_Event *event EINA_UNUSED)
2623 {
2624 elm_entry_anchor_hover_end(data);
2625 }
2626
2627 static void
_entry_hover_anchor_clicked_do(Evas_Object * obj,Elm_Entry_Anchor_Info * info)2628 _entry_hover_anchor_clicked_do(Evas_Object *obj,
2629 Elm_Entry_Anchor_Info *info)
2630 {
2631 Evas_Object *hover_parent;
2632 Evas_Coord x, w, y, h, px, py;
2633 Elm_Entry_Anchor_Hover_Info ei;
2634
2635 ELM_ENTRY_DATA_GET(obj, sd);
2636
2637 if (!sd) return;
2638 if (sd->hoversel) return;
2639
2640 ei.anchor_info = info;
2641
2642 sd->anchor_hover.pop = elm_icon_add(obj);
2643 evas_object_geometry_set(sd->anchor_hover.pop,
2644 info->x, info->y, info->w, info->h);
2645
2646 sd->anchor_hover.hover = elm_hover_add(obj);
2647 evas_object_event_callback_add
2648 (sd->anchor_hover.hover, EVAS_CALLBACK_DEL, _anchor_hover_del_cb, obj);
2649 efl_ui_mirrored_set
2650 (sd->anchor_hover.hover, efl_ui_mirrored_get(obj));
2651 if (sd->anchor_hover.hover_style)
2652 elm_object_style_set
2653 (sd->anchor_hover.hover, sd->anchor_hover.hover_style);
2654
2655 hover_parent = sd->anchor_hover.hover_parent;
2656 if (!hover_parent) hover_parent = obj;
2657 elm_hover_parent_set(sd->anchor_hover.hover, hover_parent);
2658 elm_hover_target_set(sd->anchor_hover.hover, sd->anchor_hover.pop);
2659 ei.hover = sd->anchor_hover.hover;
2660
2661 evas_object_geometry_get(hover_parent, &x, &y, &w, &h);
2662 ei.hover_parent.x = x;
2663 ei.hover_parent.y = y;
2664 ei.hover_parent.w = w;
2665 ei.hover_parent.h = h;
2666 px = info->x + (info->w / 2);
2667 py = info->y + (info->h / 2);
2668 ei.hover_left = 1;
2669 if (px < (x + (w / 3))) ei.hover_left = 0;
2670 ei.hover_right = 1;
2671 if (px > (x + ((w * 2) / 3))) ei.hover_right = 0;
2672 ei.hover_top = 1;
2673 if (py < (y + (h / 3))) ei.hover_top = 0;
2674 ei.hover_bottom = 1;
2675 if (py > (y + ((h * 2) / 3))) ei.hover_bottom = 0;
2676
2677 /* Swap right and left because they switch sides in RTL */
2678 if (efl_ui_mirrored_get(sd->anchor_hover.hover))
2679 {
2680 Eina_Bool tmp = ei.hover_left;
2681
2682 ei.hover_left = ei.hover_right;
2683 ei.hover_right = tmp;
2684 }
2685
2686 efl_event_callback_legacy_call(obj, ELM_ENTRY_EVENT_ANCHOR_HOVER_OPENED, &ei);
2687 efl_event_callback_add
2688 (sd->anchor_hover.hover, EFL_INPUT_EVENT_CLICKED, _anchor_hover_clicked_cb, obj);
2689
2690 /* FIXME: Should just check if there's any callback registered to
2691 * the smart events instead. This is used to determine if anyone
2692 * cares about the hover or not. */
2693 if (!elm_layout_content_get(sd->anchor_hover.hover, "middle") &&
2694 !elm_layout_content_get(sd->anchor_hover.hover, "left") &&
2695 !elm_layout_content_get(sd->anchor_hover.hover, "right") &&
2696 !elm_layout_content_get(sd->anchor_hover.hover, "top") &&
2697 !elm_layout_content_get(sd->anchor_hover.hover, "bottom"))
2698 {
2699 ELM_SAFE_FREE(sd->anchor_hover.hover, evas_object_del);
2700 }
2701 else
2702 evas_object_show(sd->anchor_hover.hover);
2703 }
2704
2705 static void
_entry_anchor_clicked_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission,const char * source EINA_UNUSED)2706 _entry_anchor_clicked_signal_cb(void *data,
2707 Evas_Object *obj EINA_UNUSED,
2708 const char *emission,
2709 const char *source EINA_UNUSED)
2710 {
2711 Elm_Entry_Anchor_Info ei;
2712 const char *p;
2713 char *p2;
2714
2715 ELM_ENTRY_DATA_GET(data, sd);
2716
2717 if (!sd) return;
2718 p = emission + sizeof("nchor,mouse,clicked,");
2719 ei.button = strtol(p, &p2, 10);
2720 ei.name = p2 + 1;
2721 ei.x = ei.y = ei.w = ei.h = 0;
2722
2723 _signal_anchor_geoms_do_things_with_lol(sd, &ei);
2724
2725 if (!sd->disabled)
2726 {
2727 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_ANCHOR_CLICKED, &ei);
2728 _entry_hover_anchor_clicked_do(data, &ei);
2729 }
2730 }
2731
2732 static void
_entry_anchor_move_signal_cb(void * data EINA_UNUSED,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2733 _entry_anchor_move_signal_cb(void *data EINA_UNUSED,
2734 Evas_Object *obj EINA_UNUSED,
2735 const char *emission EINA_UNUSED,
2736 const char *source EINA_UNUSED)
2737 {
2738 }
2739
2740 static void
_entry_anchor_in_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2741 _entry_anchor_in_signal_cb(void *data,
2742 Evas_Object *obj EINA_UNUSED,
2743 const char *emission EINA_UNUSED,
2744 const char *source EINA_UNUSED)
2745 {
2746 Elm_Entry_Anchor_Info ei;
2747
2748 ELM_ENTRY_DATA_GET(data, sd);
2749
2750 if (!sd) return;
2751 ei.name = emission + sizeof("nchor,mouse,in,");
2752 ei.button = 0;
2753 ei.x = ei.y = ei.w = ei.h = 0;
2754
2755 _signal_anchor_geoms_do_things_with_lol(sd, &ei);
2756
2757 if (!sd->disabled)
2758 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_ANCHOR_IN, &ei);
2759 }
2760
2761 static void
_entry_anchor_out_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2762 _entry_anchor_out_signal_cb(void *data,
2763 Evas_Object *obj EINA_UNUSED,
2764 const char *emission EINA_UNUSED,
2765 const char *source EINA_UNUSED)
2766 {
2767 Elm_Entry_Anchor_Info ei;
2768
2769 ELM_ENTRY_DATA_GET(data, sd);
2770
2771 if (!sd) return;
2772 ei.name = emission + sizeof("nchor,mouse,out,");
2773 ei.button = 0;
2774 ei.x = ei.y = ei.w = ei.h = 0;
2775
2776 _signal_anchor_geoms_do_things_with_lol(sd, &ei);
2777
2778 if (!sd->disabled)
2779 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_ANCHOR_OUT, &ei);
2780 }
2781
2782 static void
_entry_key_enter_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2783 _entry_key_enter_signal_cb(void *data,
2784 Evas_Object *obj EINA_UNUSED,
2785 const char *emission EINA_UNUSED,
2786 const char *source EINA_UNUSED)
2787 {
2788 ELM_ENTRY_DATA_GET(data, sd);
2789
2790 if (sd->single_line)
2791 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_ACTIVATED, NULL);
2792 }
2793
2794 static void
_entry_key_escape_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2795 _entry_key_escape_signal_cb(void *data,
2796 Evas_Object *obj EINA_UNUSED,
2797 const char *emission EINA_UNUSED,
2798 const char *source EINA_UNUSED)
2799 {
2800 ELM_ENTRY_DATA_GET(data, sd);
2801
2802 if (sd->single_line)
2803 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_ABORTED, NULL);
2804 }
2805
2806 static void
_entry_mouse_down_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2807 _entry_mouse_down_signal_cb(void *data,
2808 Evas_Object *obj EINA_UNUSED,
2809 const char *emission EINA_UNUSED,
2810 const char *source EINA_UNUSED)
2811 {
2812 efl_event_callback_legacy_call(data, ELM_ENTRY_EVENT_PRESS, NULL);
2813 }
2814
2815 static void
_entry_mouse_clicked_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2816 _entry_mouse_clicked_signal_cb(void *data,
2817 Evas_Object *obj EINA_UNUSED,
2818 const char *emission EINA_UNUSED,
2819 const char *source EINA_UNUSED)
2820 {
2821 evas_object_smart_callback_call
2822 ( data, "clicked", NULL);
2823 }
2824
2825 static void
_entry_mouse_double_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2826 _entry_mouse_double_signal_cb(void *data,
2827 Evas_Object *obj EINA_UNUSED,
2828 const char *emission EINA_UNUSED,
2829 const char *source EINA_UNUSED)
2830 {
2831 evas_object_smart_callback_call
2832 ( data, "clicked,double", NULL);
2833 }
2834
2835 static void
_entry_mouse_triple_signal_cb(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)2836 _entry_mouse_triple_signal_cb(void *data,
2837 Evas_Object *obj EINA_UNUSED,
2838 const char *emission EINA_UNUSED,
2839 const char *source EINA_UNUSED)
2840 {
2841 evas_object_smart_callback_call
2842 ( data, "clicked,triple", NULL);
2843 }
2844
2845 static Evas_Object *
_item_get(void * data,Evas_Object * edje EINA_UNUSED,const char * part EINA_UNUSED,const char * item)2846 _item_get(void *data,
2847 Evas_Object *edje EINA_UNUSED,
2848 const char *part EINA_UNUSED,
2849 const char *item)
2850 {
2851 Eina_List *l;
2852 Evas_Object *o;
2853 Elm_Entry_Item_Provider *ip;
2854 const char *style = elm_widget_style_get(data);
2855
2856 ELM_ENTRY_DATA_GET(data, sd);
2857
2858 if (!sd) return NULL;
2859 EINA_LIST_FOREACH(sd->item_providers, l, ip)
2860 {
2861 o = ip->func(ip->data, data, item);
2862 if (o) return o;
2863 }
2864 if (item && !strncmp(item, "file://", 7))
2865 {
2866 const char *fname = item + 7;
2867
2868 o = evas_object_image_filled_add(evas_object_evas_get(data));
2869 evas_object_image_load_orientation_set(o, EINA_TRUE);
2870 evas_object_image_file_set(o, fname, NULL);
2871 if (evas_object_image_load_error_get(o) == EVAS_LOAD_ERROR_NONE)
2872 {
2873 evas_object_show(o);
2874 }
2875 else
2876 {
2877 evas_object_del(o);
2878 o = edje_object_add(evas_object_evas_get(data));
2879 _elm_theme_object_set
2880 (data, o, "entry/emoticon", "wtf", style);
2881 }
2882 return o;
2883 }
2884
2885 o = edje_object_add(evas_object_evas_get(data));
2886 if (_elm_theme_object_set
2887 (data, o, "entry", item, style) == EFL_UI_THEME_APPLY_ERROR_GENERIC)
2888 _elm_theme_object_set
2889 (data, o, "entry/emoticon", "wtf", style);
2890 return o;
2891 }
2892
2893 static Eina_Bool
_entry_has_new_line(const char * text)2894 _entry_has_new_line(const char *text)
2895 {
2896 if (!text) return EINA_FALSE;
2897
2898 const char * pTemp = text;
2899
2900 while ((pTemp = strchr(pTemp, '<')))
2901 {
2902 pTemp++;
2903 if (!strncmp(pTemp, "br", 2) || !strncmp(pTemp, "ps", 2))
2904 {
2905 pTemp += 2;
2906 if (pTemp[0] != '\0' && (pTemp[0] == '>' || (pTemp[0] == '/' && pTemp[1] == '>')))
2907 {
2908 return EINA_TRUE;
2909 }
2910 }
2911 }
2912 return EINA_FALSE;
2913 }
2914
2915 static char *
_entry_remove_new_line(const char * text)2916 _entry_remove_new_line(const char *text)
2917 {
2918 Eina_Strbuf *str;
2919 char *new_text;
2920
2921 if (!_entry_has_new_line(text)) return NULL;
2922
2923 str = eina_strbuf_new();
2924 eina_strbuf_append(str, text);
2925 eina_strbuf_replace_all(str, "<br>", "");
2926 eina_strbuf_replace_all(str, "<br/>", "");
2927 eina_strbuf_replace_all(str, "<ps>", "");
2928 eina_strbuf_replace_all(str, "<ps/>", "");
2929 new_text = eina_strbuf_string_steal(str);
2930 eina_strbuf_free(str);
2931 return new_text;
2932 }
2933
2934 static void
_entry_new_line_filter_init(Evas_Object * obj)2935 _entry_new_line_filter_init(Evas_Object *obj)
2936 {
2937 const char *text;
2938 char *text2 = NULL;
2939
2940 if (elm_entry_is_empty(obj)) return;
2941
2942 text = elm_entry_entry_get(obj);
2943 text2 = _entry_remove_new_line(text);
2944 if (text2)
2945 {
2946 elm_entry_entry_set(obj, text2);
2947 free(text2);
2948 }
2949 }
2950
2951 static void
_entry_new_line_filter_cb(void * data EINA_UNUSED,Evas_Object * entry EINA_UNUSED,char ** text)2952 _entry_new_line_filter_cb(void *data EINA_UNUSED,
2953 Evas_Object *entry EINA_UNUSED,
2954 char **text)
2955 {
2956 char *ret;
2957
2958 if (!*text) return;
2959
2960 ret = _entry_remove_new_line(*text);
2961
2962 if (ret)
2963 {
2964 free(*text);
2965 *text = ret;
2966 }
2967 }
2968
2969 static void
_markup_filter_cb(void * data,Evas_Object * edje EINA_UNUSED,const char * part EINA_UNUSED,char ** text)2970 _markup_filter_cb(void *data,
2971 Evas_Object *edje EINA_UNUSED,
2972 const char *part EINA_UNUSED,
2973 char **text)
2974 {
2975 Eina_List *l;
2976 Elm_Entry_Markup_Filter *tf;
2977
2978 ELM_ENTRY_DATA_GET(data, sd);
2979
2980 if (!sd) return;
2981 EINA_LIST_FOREACH(sd->markup_filters, l, tf)
2982 {
2983 tf->func(tf->data, data, text);
2984 if (!*text)
2985 break;
2986 }
2987 }
2988
2989 /* This function is used to insert text by chunks in jobs */
2990 static Eina_Bool
_text_append_idler(void * data)2991 _text_append_idler(void *data)
2992 {
2993 int start;
2994 char backup;
2995 Evas_Object *obj = (Evas_Object *)data;
2996
2997 ELM_ENTRY_DATA_GET(obj, sd);
2998
2999 if (!sd) return ECORE_CALLBACK_CANCEL;
3000 evas_event_freeze(evas_object_evas_get(obj));
3001 ELM_SAFE_FREE(sd->text, eina_stringshare_del);
3002 sd->changed = EINA_TRUE;
3003
3004 start = sd->append_text_position;
3005 if ((start + ELM_ENTRY_CHUNK_SIZE) < sd->append_text_len)
3006 {
3007 int pos = start;
3008 int tag_start, esc_start;
3009
3010 tag_start = esc_start = -1;
3011 /* Find proper markup cut place */
3012 while (pos - start < ELM_ENTRY_CHUNK_SIZE)
3013 {
3014 int prev_pos = pos;
3015 Eina_Unicode tmp =
3016 eina_unicode_utf8_next_get(sd->append_text_left, &pos);
3017
3018 if (esc_start == -1)
3019 {
3020 if (tmp == '<')
3021 tag_start = prev_pos;
3022 else if (tmp == '>')
3023 tag_start = -1;
3024 }
3025 if (tag_start == -1)
3026 {
3027 if (tmp == '&')
3028 esc_start = prev_pos;
3029 else if (tmp == ';')
3030 esc_start = -1;
3031 }
3032 }
3033
3034 if (tag_start >= 0)
3035 {
3036 sd->append_text_position = tag_start;
3037 }
3038 else if (esc_start >= 0)
3039 {
3040 sd->append_text_position = esc_start;
3041 }
3042 else
3043 {
3044 sd->append_text_position = pos;
3045 }
3046 }
3047 else
3048 {
3049 sd->append_text_position = sd->append_text_len;
3050 }
3051
3052 backup = sd->append_text_left[sd->append_text_position];
3053 sd->append_text_left[sd->append_text_position] = '\0';
3054
3055 edje_object_part_text_append
3056 (sd->entry_edje, "elm.text", sd->append_text_left + start);
3057
3058 sd->append_text_left[sd->append_text_position] = backup;
3059
3060 evas_event_thaw(evas_object_evas_get(obj));
3061 evas_event_thaw_eval(evas_object_evas_get(obj));
3062
3063 _elm_entry_guide_update(obj, EINA_TRUE);
3064
3065 /* If there's still more to go, renew the idler, else, cleanup */
3066 if (sd->append_text_position < sd->append_text_len)
3067 {
3068 return ECORE_CALLBACK_RENEW;
3069 }
3070 else
3071 {
3072 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
3073 EDJE_CURSOR_MAIN, sd->cursor_pos);
3074 free(sd->append_text_left);
3075 sd->append_text_left = NULL;
3076 sd->append_text_idler = NULL;
3077 efl_event_callback_legacy_call
3078 (obj, ELM_ENTRY_EVENT_TEXT_SET_DONE, NULL);
3079 return ECORE_CALLBACK_CANCEL;
3080 }
3081 }
3082
3083 static void
my_string_copy_truncate(char * dest,const char * src,size_t len)3084 my_string_copy_truncate(char *dest, const char *src, size_t len)
3085 {
3086 char *p;
3087 for (p = dest; len > 0; p++, src++, len--)
3088 {
3089 *p = *src;
3090 if (*src == 0) break;
3091 }
3092 }
3093
3094 static void
_chars_add_till_limit(Evas_Object * obj,char ** text,int can_add,Length_Unit unit)3095 _chars_add_till_limit(Evas_Object *obj,
3096 char **text,
3097 int can_add,
3098 Length_Unit unit)
3099 {
3100 int i = 0, current_len = 0;
3101 char *new_text;
3102
3103 if (!*text) return;
3104 if (unit >= LENGTH_UNIT_LAST) return;
3105 if (strstr(*text, "<preedit")) return;
3106
3107 new_text = *text;
3108 current_len = strlen(*text);
3109 while (*new_text)
3110 {
3111 int idx = 0, unit_size = 0;
3112 char *markup, *utfstr;
3113
3114 if (*new_text == '<')
3115 {
3116 while (*(new_text + idx) != '>')
3117 {
3118 idx++;
3119 if (!*(new_text + idx)) break;
3120 }
3121 }
3122 else if (*new_text == '&')
3123 {
3124 while (*(new_text + idx) != ';')
3125 {
3126 idx++;
3127 if (!*(new_text + idx)) break;
3128 }
3129 }
3130 idx = evas_string_char_next_get(new_text, idx, NULL);
3131 markup = malloc(idx + 1);
3132 if (markup)
3133 {
3134 strncpy(markup, new_text, idx);
3135 markup[idx] = 0;
3136 utfstr = elm_entry_markup_to_utf8(markup);
3137 if (utfstr)
3138 {
3139 if (unit == LENGTH_UNIT_BYTE)
3140 unit_size = strlen(utfstr);
3141 else if (unit == LENGTH_UNIT_CHAR)
3142 unit_size = evas_string_char_len_get(utfstr);
3143 ELM_SAFE_FREE(utfstr, free);
3144 }
3145 ELM_SAFE_FREE(markup, free);
3146 }
3147 if (can_add < unit_size)
3148 {
3149 if (!i)
3150 {
3151 efl_event_callback_legacy_call
3152 (obj, ELM_ENTRY_EVENT_MAXLENGTH_REACHED, NULL);
3153 ELM_SAFE_FREE(*text, free);
3154 return;
3155 }
3156 can_add = 0;
3157 my_string_copy_truncate(new_text, new_text + idx,
3158 current_len - ((new_text + idx) - *text));
3159 current_len -= idx;
3160 (*text)[current_len] = 0;
3161 }
3162 else
3163 {
3164 new_text += idx;
3165 can_add -= unit_size;
3166 }
3167 i++;
3168 }
3169
3170 efl_event_callback_legacy_call(obj, ELM_ENTRY_EVENT_MAXLENGTH_REACHED, NULL);
3171 }
3172
3173 EOLIAN static void
_elm_entry_efl_layout_signal_signal_emit(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,const char * emission,const char * source)3174 _elm_entry_efl_layout_signal_signal_emit(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, const char *emission, const char *source)
3175 {
3176 /* always pass to both edje objs */
3177 edje_object_signal_emit(sd->entry_edje, emission, source);
3178 edje_object_message_signal_process(sd->entry_edje);
3179
3180 if (sd->scr_edje)
3181 {
3182 edje_object_signal_emit(sd->scr_edje, emission, source);
3183 edje_object_message_signal_process(sd->scr_edje);
3184 }
3185 }
3186
3187 static Eina_Bool
_elm_entry_efl_layout_signal_signal_callback_add(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,const char * emission,const char * source,void * func_data,EflLayoutSignalCb func,Eina_Free_Cb func_free_cb)3188 _elm_entry_efl_layout_signal_signal_callback_add(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd,
3189 const char *emission, const char *source,
3190 void *func_data, EflLayoutSignalCb func, Eina_Free_Cb func_free_cb)
3191 {
3192 Eina_Bool ok;
3193
3194 ok = efl_layout_signal_callback_add(sd->entry_edje, emission, source, func_data, func, func_free_cb);
3195 if (sd->scr_edje)
3196 ok = efl_layout_signal_callback_add(sd->scr_edje, emission, source, func_data, func, func_free_cb);
3197
3198 return ok;
3199 }
3200
3201 static Eina_Bool
_elm_entry_efl_layout_signal_signal_callback_del(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,const char * emission,const char * source,void * func_data,EflLayoutSignalCb func,Eina_Free_Cb func_free_cb)3202 _elm_entry_efl_layout_signal_signal_callback_del(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd,
3203 const char *emission, const char *source,
3204 void *func_data, EflLayoutSignalCb func, Eina_Free_Cb func_free_cb)
3205 {
3206 Eina_Bool ok;
3207
3208 ok = efl_layout_signal_callback_del(sd->entry_edje, emission, source, func_data, func, func_free_cb);
3209 if (sd->scr_edje)
3210 ok = efl_layout_signal_callback_del(sd->scr_edje, emission, source, func_data, func, func_free_cb);
3211
3212 return ok;
3213 }
3214
3215 // Legacy support... del() returns the user data.
3216 void
_elm_entry_signal_callback_add_legacy(Eo * obj,const char * emission,const char * source,Edje_Signal_Cb func_cb,void * data)3217 _elm_entry_signal_callback_add_legacy(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)
3218 {
3219 Elm_Entry_Data *sd;
3220
3221 sd = efl_data_scope_safe_get(obj, MY_CLASS);
3222 if (!sd) return;
3223
3224 _elm_layout_signal_callback_add_legacy(obj, sd->entry_edje, &sd->edje_signals,
3225 emission, source, func_cb, data);
3226
3227 if (sd->scr_edje)
3228 efl_layout_signal_callback_add(sd->scr_edje, emission, source, data, func_cb, NULL);
3229 }
3230
3231 void *
_elm_entry_signal_callback_del_legacy(Eo * obj,const char * emission,const char * source,Edje_Signal_Cb func_cb)3232 _elm_entry_signal_callback_del_legacy(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb)
3233 {
3234 Elm_Entry_Data *sd;
3235 void *data;
3236
3237 sd = efl_data_scope_safe_get(obj, MY_CLASS);
3238 if (!sd) return NULL;
3239
3240 data = _elm_layout_signal_callback_del_legacy(obj, sd->entry_edje, &sd->edje_signals,
3241 emission, source, func_cb);
3242
3243 if (sd->scr_edje)
3244 efl_layout_signal_callback_del(sd->scr_edje, emission, source, data, func_cb, NULL);
3245
3246 return data;
3247 }
3248
3249 static Eina_Bool
_elm_entry_content_set(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,const char * part,Evas_Object * content)3250 _elm_entry_content_set(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *part, Evas_Object *content)
3251 {
3252 Eina_Bool int_ret = EINA_FALSE;
3253 int_ret = efl_content_set(efl_part(efl_super(obj, MY_CLASS), part), content);
3254 if (!int_ret) return EINA_FALSE;
3255
3256 /* too bad entry does not follow the pattern
3257 * "elm,state,{icon,end},visible", we have to repeat ourselves */
3258 if (!part || !strcmp(part, "icon") || !strcmp(part, "elm.swallow.icon"))
3259 elm_entry_icon_visible_set(obj, EINA_TRUE);
3260
3261 if (part && (!strcmp(part, "end") || !strcmp(part, "elm.swallow.end")))
3262 elm_entry_end_visible_set(obj, EINA_TRUE);
3263
3264 return EINA_TRUE;
3265 }
3266
3267 static Evas_Object*
_elm_entry_content_unset(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,const char * part)3268 _elm_entry_content_unset(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *part)
3269 {
3270 Evas_Object *ret = NULL;
3271 ret = efl_content_unset(efl_part(efl_super(obj, MY_CLASS), part));
3272 if (!ret) return NULL;
3273
3274 /* too bad entry does not follow the pattern
3275 * "elm,state,{icon,end},hidden", we have to repeat ourselves */
3276 if (!part || !strcmp(part, "icon") || !strcmp(part, "elm.swallow.icon"))
3277 elm_entry_icon_visible_set(obj, EINA_FALSE);
3278
3279 if (part && (!strcmp(part, "end") || !strcmp(part, "elm.swallow.end")))
3280 elm_entry_end_visible_set(obj, EINA_FALSE);
3281
3282 return ret;
3283 }
3284
3285 static void
_entry_text_append(Evas_Object * obj,const char * entry,Eina_Bool set)3286 _entry_text_append(Evas_Object* obj, const char* entry, Eina_Bool set)
3287 {
3288 int len = 0;
3289 if (!entry) return;
3290
3291 ELM_ENTRY_DATA_GET(obj, sd);
3292 if (!sd) return;
3293 len = strlen(entry);
3294
3295 if (sd->append_text_left)
3296 {
3297 char *tmpbuf;
3298
3299 tmpbuf = realloc(sd->append_text_left, sd->append_text_len + len + 1);
3300 if (!tmpbuf)
3301 {
3302 /* Do something */
3303 return;
3304 }
3305 sd->append_text_left = tmpbuf;
3306 memcpy(sd->append_text_left + sd->append_text_len, entry, len + 1);
3307 sd->append_text_len += len;
3308 }
3309 else
3310 {
3311 if (len > ELM_ENTRY_CHUNK_SIZE)
3312 {
3313 sd->append_text_left = (char *)malloc(len + 1);
3314 }
3315
3316 if (sd->append_text_left)
3317 {
3318 memcpy(sd->append_text_left, entry, len + 1);
3319 sd->append_text_position = 0;
3320 sd->append_text_len = len;
3321 sd->append_text_idler = ecore_idler_add(_text_append_idler, obj);
3322 }
3323 else
3324 {
3325 if (set)
3326 {
3327 edje_object_part_text_set(sd->entry_edje, "elm.text", entry);
3328 }
3329 else
3330 {
3331 edje_object_part_text_append(sd->entry_edje, "elm.text", entry);
3332 }
3333 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
3334 EDJE_CURSOR_MAIN, sd->cursor_pos);
3335 efl_event_callback_legacy_call(obj, ELM_ENTRY_EVENT_TEXT_SET_DONE, NULL);
3336 }
3337 }
3338 }
3339
3340 static Eina_Bool
_elm_entry_text_set(Eo * obj,Elm_Entry_Data * sd,const char * part,const char * entry)3341 _elm_entry_text_set(Eo *obj, Elm_Entry_Data *sd, const char *part, const char *entry)
3342 {
3343 int len = 0;
3344 const char * current_text = NULL;
3345
3346 if (!entry) entry = "";
3347 if (!_elm_layout_part_aliasing_eval(obj, &part, EINA_TRUE))
3348 return EINA_FALSE;
3349
3350 if (strcmp(part, "elm.text"))
3351 {
3352 edje_object_part_text_set(sd->entry_edje, part, entry);
3353
3354 return EINA_TRUE;
3355 }
3356
3357 evas_event_freeze(evas_object_evas_get(obj));
3358
3359 /* Clear currently pending job if there is one */
3360 if (sd->append_text_idler)
3361 {
3362 ecore_idler_del(sd->append_text_idler);
3363 ELM_SAFE_FREE(sd->append_text_left, free);
3364 sd->append_text_idler = NULL;
3365 }
3366
3367 len = strlen(entry);
3368 if (sd->append_text_left)
3369 {
3370 free(sd->append_text_left);
3371 sd->append_text_left = NULL;
3372 }
3373
3374 /* If old and new text are the same do nothing */
3375 current_text = edje_object_part_text_get(sd->entry_edje, "elm.text");
3376 if (eina_streq(current_text, entry))
3377 goto done;
3378
3379 ELM_SAFE_FREE(sd->text, eina_stringshare_del);
3380 sd->changed = EINA_TRUE;
3381
3382 /* Need to clear the entry first */
3383 sd->cursor_pos = edje_object_part_text_cursor_pos_get
3384 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
3385 edje_object_part_text_set(sd->entry_edje, "elm.text", "");
3386 _entry_text_append(obj, entry, EINA_TRUE);
3387
3388 if (len > 0)
3389 _elm_entry_guide_update(obj, EINA_TRUE);
3390 else
3391 _elm_entry_guide_update(obj, EINA_FALSE);
3392
3393 done:
3394 evas_event_thaw(evas_object_evas_get(obj));
3395 evas_event_thaw_eval(evas_object_evas_get(obj));
3396 return EINA_TRUE;
3397 }
3398
3399 static const char *
_elm_entry_text_get(Eo * obj,Elm_Entry_Data * sd,const char * item)3400 _elm_entry_text_get(Eo *obj, Elm_Entry_Data *sd, const char *item)
3401 {
3402 const char *text;
3403
3404 if (!_elm_layout_part_aliasing_eval(obj, &item, EINA_TRUE))
3405 return NULL;
3406
3407 if (strcmp(item, "elm.text"))
3408 return edje_object_part_text_get(sd->entry_edje, item);
3409
3410 text = edje_object_part_text_get(sd->entry_edje, "elm.text");
3411 if (!text)
3412 {
3413 ERR("text=NULL for edje %p, part 'elm.text'", sd->entry_edje);
3414
3415 return NULL;
3416 }
3417
3418 if (sd->append_text_len > 0)
3419 {
3420 char *tmpbuf;
3421 size_t len, tlen;
3422
3423 tlen = strlen(text);
3424 len = tlen + sd->append_text_len - sd->append_text_position;
3425 /* FIXME: need that or we do copy uninitialised data */
3426 tmpbuf = calloc(1, len + 1);
3427 if (!tmpbuf)
3428 {
3429 ERR("Failed to allocate memory for entry's text %p", obj);
3430 return NULL;
3431 }
3432 memcpy(tmpbuf, text, tlen);
3433
3434 if (sd->append_text_left)
3435 memcpy(tmpbuf + tlen, sd->append_text_left
3436 + sd->append_text_position, sd->append_text_len
3437 - sd->append_text_position);
3438 tmpbuf[len] = '\0';
3439 eina_stringshare_replace(&sd->text, tmpbuf);
3440 free(tmpbuf);
3441 }
3442 else
3443 {
3444 eina_stringshare_replace(&sd->text, text);
3445 }
3446
3447 return sd->text;
3448 }
3449
3450 static char *
_access_info_cb(void * data EINA_UNUSED,Evas_Object * obj)3451 _access_info_cb(void *data EINA_UNUSED, Evas_Object *obj)
3452 {
3453 const char *txt;
3454
3455 ELM_ENTRY_DATA_GET(obj, sd);
3456
3457 if (!sd) return NULL;
3458 if (sd->password) return NULL;
3459
3460 txt = elm_widget_access_info_get(obj);
3461
3462 if (!txt)
3463 return _elm_util_mkup_to_text(elm_entry_entry_get(obj));
3464 else return strdup(txt);
3465 }
3466
3467 static char *
_access_state_cb(void * data EINA_UNUSED,Evas_Object * obj)3468 _access_state_cb(void *data EINA_UNUSED, Evas_Object *obj)
3469 {
3470 Eina_Strbuf *buf;
3471 char *ret;
3472
3473 ELM_ENTRY_DATA_GET(obj, sd);
3474
3475 if (!sd) return NULL;
3476 ret = NULL;
3477 buf = eina_strbuf_new();
3478
3479 if (elm_widget_disabled_get(obj))
3480 eina_strbuf_append(buf, "State: Disabled");
3481
3482 if (!sd->editable)
3483 {
3484 if (!eina_strbuf_length_get(buf))
3485 eina_strbuf_append(buf, "State: Not Editable");
3486 else eina_strbuf_append(buf, ", Not Editable");
3487 }
3488
3489 if (sd->password)
3490 {
3491 if (!eina_strbuf_length_get(buf))
3492 eina_strbuf_append(buf, "State: Password");
3493 else eina_strbuf_append(buf, ", Password");
3494 }
3495
3496 if (!eina_strbuf_length_get(buf)) goto buf_free;
3497
3498 ret = eina_strbuf_string_steal(buf);
3499
3500 buf_free:
3501 eina_strbuf_free(buf);
3502 return ret;
3503 }
3504
3505 static void
_entry_selection_callbacks_unregister(Evas_Object * obj)3506 _entry_selection_callbacks_unregister(Evas_Object *obj)
3507 {
3508 ELM_ENTRY_DATA_GET(obj, sd);
3509
3510 edje_object_signal_callback_del_full
3511 (sd->entry_edje, "selection,start", "elm.text",
3512 _entry_selection_start_signal_cb, obj);
3513 edje_object_signal_callback_del_full
3514 (sd->entry_edje, "selection,changed", "elm.text",
3515 _entry_selection_changed_signal_cb, obj);
3516 edje_object_signal_callback_del_full
3517 (sd->entry_edje, "entry,selection,all,request",
3518 "elm.text", _entry_selection_all_signal_cb, obj);
3519 edje_object_signal_callback_del_full
3520 (sd->entry_edje, "entry,selection,none,request",
3521 "elm.text", _entry_selection_none_signal_cb, obj);
3522 edje_object_signal_callback_del_full
3523 (sd->entry_edje, "selection,cleared", "elm.text",
3524 _entry_selection_cleared_signal_cb, obj);
3525 edje_object_signal_callback_del_full
3526 (sd->entry_edje, "entry,paste,request,*", "elm.text",
3527 _entry_paste_request_signal_cb, obj);
3528 edje_object_signal_callback_del_full
3529 (sd->entry_edje, "entry,copy,notify", "elm.text",
3530 _entry_copy_notify_signal_cb, obj);
3531 edje_object_signal_callback_del_full
3532 (sd->entry_edje, "entry,cut,notify", "elm.text",
3533 _entry_cut_notify_signal_cb, obj);
3534 }
3535
3536 static void
_entry_selection_callbacks_register(Evas_Object * obj)3537 _entry_selection_callbacks_register(Evas_Object *obj)
3538 {
3539 ELM_ENTRY_DATA_GET(obj, sd);
3540
3541 edje_object_signal_callback_add
3542 (sd->entry_edje, "selection,start", "elm.text",
3543 _entry_selection_start_signal_cb, obj);
3544 edje_object_signal_callback_add
3545 (sd->entry_edje, "selection,changed", "elm.text",
3546 _entry_selection_changed_signal_cb, obj);
3547 edje_object_signal_callback_add
3548 (sd->entry_edje, "entry,selection,all,request",
3549 "elm.text", _entry_selection_all_signal_cb, obj);
3550 edje_object_signal_callback_add
3551 (sd->entry_edje, "entry,selection,none,request",
3552 "elm.text", _entry_selection_none_signal_cb, obj);
3553 edje_object_signal_callback_add
3554 (sd->entry_edje, "selection,cleared", "elm.text",
3555 _entry_selection_cleared_signal_cb, obj);
3556 edje_object_signal_callback_add
3557 (sd->entry_edje, "entry,paste,request,*", "elm.text",
3558 _entry_paste_request_signal_cb, obj);
3559 edje_object_signal_callback_add
3560 (sd->entry_edje, "entry,copy,notify", "elm.text",
3561 _entry_copy_notify_signal_cb, obj);
3562 edje_object_signal_callback_add
3563 (sd->entry_edje, "entry,cut,notify", "elm.text",
3564 _entry_cut_notify_signal_cb, obj);
3565 }
3566
3567 static void
_elm_entry_resize_internal(Evas_Object * obj)3568 _elm_entry_resize_internal(Evas_Object *obj)
3569 {
3570 ELM_ENTRY_DATA_GET(obj, sd);
3571
3572 if (!sd) return;
3573 if (sd->line_wrap)
3574 {
3575 elm_layout_sizing_eval(obj);
3576 }
3577 else if (sd->scroll)
3578 {
3579 Evas_Coord vw = 0, vh = 0;
3580
3581 elm_interface_scrollable_content_viewport_geometry_get
3582 (obj, NULL, NULL, &vw, &vh);
3583 if (vw < sd->ent_mw) vw = sd->ent_mw;
3584 if (vh < sd->ent_mh) vh = sd->ent_mh;
3585 evas_object_resize(sd->entry_edje, vw, vh);
3586 }
3587
3588 if (sd->hoversel) _hoversel_position(obj);
3589 }
3590
3591 static void
_resize_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)3592 _resize_cb(void *data,
3593 Evas *e EINA_UNUSED,
3594 Evas_Object *obj EINA_UNUSED,
3595 void *event_info EINA_UNUSED)
3596 {
3597 _elm_entry_resize_internal(data);
3598 }
3599
3600 static void
_selection_handlers_offset_calc(Evas_Object * obj,Evas_Object * handler,Evas_Coord canvasx,Evas_Coord canvasy)3601 _selection_handlers_offset_calc(Evas_Object *obj, Evas_Object *handler, Evas_Coord canvasx, Evas_Coord canvasy)
3602 {
3603 Evas_Coord ex, ey;
3604 Evas_Coord cx, cy, cw, ch;
3605 Evas_Coord hh;
3606
3607 ELM_ENTRY_DATA_GET(obj, sd);
3608
3609 if (!sd) return;
3610 evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
3611 edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
3612 &cx, &cy, &cw, &ch);
3613 edje_object_size_min_calc(handler, NULL, &hh);
3614
3615 sd->ox = canvasx - (ex + cx + (cw / 2));
3616 if (ch > hh)
3617 sd->oy = canvasy - (ey + cy + ch);
3618 else
3619 sd->oy = canvasy - (ey + cy + (ch / 2));
3620
3621 ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
3622 sd->long_pressed = EINA_FALSE;
3623 if (_elm_config->magnifier_enable)
3624 {
3625 _magnifier_create(obj);
3626 _magnifier_show(obj);
3627 _magnifier_move(obj);
3628 }
3629 }
3630
3631 static void
_start_handler_mouse_down_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)3632 _start_handler_mouse_down_cb(void *data,
3633 Evas *e EINA_UNUSED,
3634 Evas_Object *obj EINA_UNUSED,
3635 void *event_info)
3636 {
3637 ELM_ENTRY_DATA_GET(data, sd);
3638
3639 if (!sd) return;
3640 Evas_Event_Mouse_Down *ev = event_info;
3641 int start_pos, end_pos, main_pos, pos;
3642
3643 sd->start_handler_down = EINA_TRUE;
3644 start_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
3645 EDJE_CURSOR_SELECTION_BEGIN);
3646 end_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
3647 EDJE_CURSOR_SELECTION_END);
3648 main_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
3649 EDJE_CURSOR_MAIN);
3650 if (start_pos <= end_pos)
3651 {
3652 pos = start_pos;
3653 sd->sel_handler_cursor = EDJE_CURSOR_SELECTION_BEGIN;
3654 }
3655 else
3656 {
3657 pos = end_pos;
3658 sd->sel_handler_cursor = EDJE_CURSOR_SELECTION_END;
3659 }
3660 if (pos != main_pos)
3661 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
3662 EDJE_CURSOR_MAIN, pos);
3663 _selection_handlers_offset_calc(data, sd->start_handler, ev->canvas.x, ev->canvas.y);
3664 }
3665
3666 static void
_start_handler_mouse_up_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)3667 _start_handler_mouse_up_cb(void *data,
3668 Evas *e EINA_UNUSED,
3669 Evas_Object *obj EINA_UNUSED,
3670 void *event_info EINA_UNUSED)
3671 {
3672 ELM_ENTRY_DATA_GET(data, sd);
3673
3674 if (!sd) return;
3675 sd->start_handler_down = EINA_FALSE;
3676 if (_elm_config->magnifier_enable)
3677 _magnifier_hide(data);
3678 /* Context menu should not appear, even in case of selector mode, if the
3679 * flag is false (disabled) */
3680 if ((!_elm_config->context_menu_disabled) &&
3681 (!_elm_config->desktop_entry) && (sd->long_pressed))
3682 _menu_call(data);
3683 }
3684
3685 static void
_start_handler_mouse_move_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)3686 _start_handler_mouse_move_cb(void *data,
3687 Evas *e EINA_UNUSED,
3688 Evas_Object *obj EINA_UNUSED,
3689 void *event_info)
3690 {
3691 ELM_ENTRY_DATA_GET(data, sd);
3692
3693 if (!sd) return;
3694 if (!sd->start_handler_down) return;
3695 Evas_Event_Mouse_Move *ev = event_info;
3696 Evas_Coord ex, ey;
3697 Evas_Coord cx, cy;
3698 int pos;
3699
3700 evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
3701 cx = ev->cur.canvas.x - sd->ox - ex;
3702 cy = ev->cur.canvas.y - sd->oy - ey;
3703 if (cx <= 0) cx = 1;
3704
3705 edje_object_part_text_cursor_coord_set(sd->entry_edje, "elm.text",
3706 sd->sel_handler_cursor, cx, cy);
3707 pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
3708 sd->sel_handler_cursor);
3709 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
3710 EDJE_CURSOR_MAIN, pos);
3711 ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
3712 sd->long_pressed = EINA_FALSE;
3713 if (_elm_config->magnifier_enable)
3714 _magnifier_move(data);
3715 }
3716
3717 static void
_end_handler_mouse_down_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)3718 _end_handler_mouse_down_cb(void *data,
3719 Evas *e EINA_UNUSED,
3720 Evas_Object *obj EINA_UNUSED,
3721 void *event_info)
3722 {
3723 ELM_ENTRY_DATA_GET(data, sd);
3724
3725 if (!sd) return;
3726 Evas_Event_Mouse_Down *ev = event_info;
3727 int pos, start_pos, end_pos, main_pos;
3728
3729 sd->end_handler_down = EINA_TRUE;
3730 start_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
3731 EDJE_CURSOR_SELECTION_BEGIN);
3732 end_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
3733 EDJE_CURSOR_SELECTION_END);
3734 if (start_pos < end_pos)
3735 {
3736 pos = end_pos;
3737 sd->sel_handler_cursor = EDJE_CURSOR_SELECTION_END;
3738 }
3739 else
3740 {
3741 pos = start_pos;
3742 sd->sel_handler_cursor = EDJE_CURSOR_SELECTION_BEGIN;
3743 }
3744 main_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
3745 EDJE_CURSOR_MAIN);
3746 if (pos != main_pos)
3747 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
3748 EDJE_CURSOR_MAIN, pos);
3749 _selection_handlers_offset_calc(data, sd->end_handler, ev->canvas.x, ev->canvas.y);
3750 }
3751
3752 static void
_end_handler_mouse_up_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)3753 _end_handler_mouse_up_cb(void *data,
3754 Evas *e EINA_UNUSED,
3755 Evas_Object *obj EINA_UNUSED,
3756 void *event_info EINA_UNUSED)
3757 {
3758 ELM_ENTRY_DATA_GET(data, sd);
3759
3760 if (!sd) return;
3761 sd->end_handler_down = EINA_FALSE;
3762 if (_elm_config->magnifier_enable)
3763 _magnifier_hide(data);
3764 /* Context menu appear was checked in case of selector start, and hence
3765 * the same should be checked at selector end as well */
3766 if ((!_elm_config->context_menu_disabled) &&
3767 (!_elm_config->desktop_entry) && (sd->long_pressed))
3768 _menu_call(data);
3769 }
3770
3771 static void
_end_handler_mouse_move_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)3772 _end_handler_mouse_move_cb(void *data,
3773 Evas *e EINA_UNUSED,
3774 Evas_Object *obj EINA_UNUSED,
3775 void *event_info)
3776 {
3777 ELM_ENTRY_DATA_GET(data, sd);
3778
3779 if (!sd) return;
3780 if (!sd->end_handler_down) return;
3781 Evas_Event_Mouse_Move *ev = event_info;
3782 Evas_Coord ex, ey;
3783 Evas_Coord cx, cy;
3784 int pos;
3785
3786 evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
3787 cx = ev->cur.canvas.x - sd->ox - ex;
3788 cy = ev->cur.canvas.y - sd->oy - ey;
3789 if (cx <= 0) cx = 1;
3790
3791 edje_object_part_text_cursor_coord_set(sd->entry_edje, "elm.text",
3792 sd->sel_handler_cursor, cx, cy);
3793 pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
3794 sd->sel_handler_cursor);
3795 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
3796 EDJE_CURSOR_MAIN, pos);
3797 ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
3798 sd->long_pressed = EINA_FALSE;
3799 if (_elm_config->magnifier_enable)
3800 _magnifier_move(data);
3801 }
3802
3803 static void
_entry_on_size_evaluate_signal(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)3804 _entry_on_size_evaluate_signal(void *data,
3805 Evas_Object *obj EINA_UNUSED,
3806 const char *emission EINA_UNUSED,
3807 const char *source EINA_UNUSED)
3808 {
3809 ELM_ENTRY_DATA_GET(data, sd);
3810 if (!sd) return;
3811 sd->cur_changed = EINA_TRUE;
3812 elm_entry_calc_force(data);
3813 }
3814
3815 EOLIAN static void
_elm_entry_efl_canvas_group_group_add(Eo * obj,Elm_Entry_Data * priv)3816 _elm_entry_efl_canvas_group_group_add(Eo *obj, Elm_Entry_Data *priv)
3817 {
3818 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
3819
3820 if (!elm_widget_theme_klass_get(obj))
3821 elm_widget_theme_klass_set(obj, "entry");
3822 efl_canvas_group_add(efl_super(obj, MY_CLASS));
3823
3824 priv->entry_edje = wd->resize_obj;
3825
3826 priv->cnp_mode = ELM_CNP_MODE_MARKUP;
3827 priv->line_wrap = ELM_WRAP_WORD;
3828 priv->context_menu = EINA_TRUE;
3829 priv->auto_save = EINA_TRUE;
3830 priv->editable = EINA_TRUE;
3831 priv->sel_allow = _elm_config->entry_select_allow;
3832
3833 priv->drop_format = ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE;
3834 elm_drop_target_add(obj, priv->drop_format,
3835 _dnd_enter_cb, NULL,
3836 _dnd_leave_cb, NULL,
3837 _dnd_pos_cb, NULL,
3838 _dnd_drop_cb, NULL);
3839
3840 if (elm_widget_theme_object_set(obj, wd->resize_obj,
3841 elm_widget_theme_klass_get(obj),
3842 elm_widget_theme_element_get(obj),
3843 elm_widget_theme_style_get(obj)) == EFL_UI_THEME_APPLY_ERROR_GENERIC)
3844 CRI("Failed to set layout!");
3845
3846 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
3847 evas_object_data_set(priv->hit_rect, "_elm_leaveme", obj);
3848
3849 Evas_Object* clip = evas_object_clip_get(priv->entry_edje);
3850 evas_object_clip_set(priv->hit_rect, clip);
3851
3852 evas_object_smart_member_add(priv->hit_rect, obj);
3853 elm_widget_sub_object_add(obj, priv->hit_rect);
3854
3855 /* common scroller hit rectangle setup */
3856 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
3857 evas_object_show(priv->hit_rect);
3858 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
3859
3860 elm_interface_scrollable_objects_set(obj, priv->entry_edje, priv->hit_rect);
3861
3862 edje_object_item_provider_set(priv->entry_edje, _item_get, obj);
3863
3864 edje_object_text_markup_filter_callback_add
3865 (priv->entry_edje, "elm.text", _markup_filter_cb, obj);
3866
3867 evas_object_event_callback_add
3868 (priv->entry_edje, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, obj);
3869 evas_object_event_callback_add
3870 (priv->entry_edje, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down_cb, obj);
3871 evas_object_event_callback_add
3872 (priv->entry_edje, EVAS_CALLBACK_MOUSE_UP, _mouse_up_cb, obj);
3873 evas_object_event_callback_add
3874 (priv->entry_edje, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move_cb, obj);
3875
3876 /* this code can't go in smart_resize. sizing gets wrong */
3877 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
3878
3879 edje_object_signal_callback_add
3880 (priv->entry_edje, "entry,changed", "elm.text",
3881 _entry_changed_signal_cb, obj);
3882 edje_object_signal_callback_add
3883 (priv->entry_edje, "entry,changed,user", "elm.text",
3884 _entry_changed_user_signal_cb, obj);
3885 edje_object_signal_callback_add
3886 (priv->entry_edje, "preedit,changed", "elm.text",
3887 _entry_preedit_changed_signal_cb, obj);
3888
3889 _entry_selection_callbacks_register(obj);
3890
3891 edje_object_signal_callback_add
3892 (priv->entry_edje, "cursor,changed", "elm.text",
3893 _entry_cursor_changed_signal_cb, obj);
3894 edje_object_signal_callback_add
3895 (priv->entry_edje, "cursor,changed,manual", "elm.text",
3896 _entry_cursor_changed_manual_signal_cb, obj);
3897 edje_object_signal_callback_add
3898 (priv->entry_edje, "anchor,mouse,down,*", "elm.text",
3899 _entry_anchor_down_signal_cb, obj);
3900 edje_object_signal_callback_add
3901 (priv->entry_edje, "anchor,mouse,up,*", "elm.text",
3902 _entry_anchor_up_signal_cb, obj);
3903 edje_object_signal_callback_add
3904 (priv->entry_edje, "anchor,mouse,clicked,*", "elm.text",
3905 _entry_anchor_clicked_signal_cb, obj);
3906 edje_object_signal_callback_add
3907 (priv->entry_edje, "anchor,mouse,move,*", "elm.text",
3908 _entry_anchor_move_signal_cb, obj);
3909 edje_object_signal_callback_add
3910 (priv->entry_edje, "anchor,mouse,in,*", "elm.text",
3911 _entry_anchor_in_signal_cb, obj);
3912 edje_object_signal_callback_add
3913 (priv->entry_edje, "anchor,mouse,out,*", "elm.text",
3914 _entry_anchor_out_signal_cb, obj);
3915 edje_object_signal_callback_add
3916 (priv->entry_edje, "entry,key,enter", "elm.text",
3917 _entry_key_enter_signal_cb, obj);
3918 edje_object_signal_callback_add
3919 (priv->entry_edje, "entry,key,escape", "elm.text",
3920 _entry_key_escape_signal_cb, obj);
3921 edje_object_signal_callback_add
3922 (priv->entry_edje, "mouse,down,1", "elm.text",
3923 _entry_mouse_down_signal_cb, obj);
3924 edje_object_signal_callback_add
3925 (priv->entry_edje, "mouse,clicked,1", "elm.text",
3926 _entry_mouse_clicked_signal_cb, obj);
3927 edje_object_signal_callback_add
3928 (priv->entry_edje, "mouse,down,1,double", "elm.text",
3929 _entry_mouse_double_signal_cb, obj);
3930 edje_object_signal_callback_add
3931 (priv->entry_edje, "mouse,down,1,triple", "elm.text",
3932 _entry_mouse_triple_signal_cb, obj);
3933 edje_object_signal_callback_add
3934 (priv->entry_edje, "entry,undo,request", "elm.text",
3935 _entry_undo_request_signal_cb, obj);
3936 edje_object_signal_callback_add
3937 (priv->entry_edje, "entry,redo,request", "elm.text",
3938 _entry_redo_request_signal_cb, obj);
3939
3940 elm_layout_text_set(obj, "elm.text", "");
3941
3942 elm_object_sub_cursor_set
3943 (wd->resize_obj, obj, ELM_CURSOR_XTERM);
3944 elm_widget_can_focus_set(obj, EINA_TRUE);
3945 if (priv->sel_allow && _elm_config->desktop_entry)
3946 edje_object_part_text_select_allow_set
3947 (priv->entry_edje, "elm.text", EINA_TRUE);
3948
3949 elm_layout_sizing_eval(obj);
3950
3951 elm_entry_input_panel_layout_set(obj, ELM_INPUT_PANEL_LAYOUT_NORMAL);
3952 elm_entry_input_panel_enabled_set(obj, EINA_TRUE);
3953 elm_entry_prediction_allow_set(obj, EINA_TRUE);
3954 elm_entry_input_hint_set(obj, ELM_INPUT_HINT_AUTO_COMPLETE);
3955
3956 priv->autocapital_type = (Elm_Autocapital_Type)edje_object_part_text_autocapital_type_get
3957 (priv->entry_edje, "elm.text");
3958
3959 entries = eina_list_prepend(entries, obj);
3960
3961 // module - find module for entry
3962 priv->api = _module_find(obj);
3963 // if found - hook in
3964 if ((priv->api) && (priv->api->obj_hook)) priv->api->obj_hook(obj);
3965
3966 _mirrored_set(obj, efl_ui_mirrored_get(obj));
3967
3968 // access
3969 _elm_access_object_register(obj, priv->entry_edje);
3970 _elm_access_text_set
3971 (_elm_access_info_get(obj), ELM_ACCESS_TYPE, E_("Entry"));
3972 _elm_access_callback_set
3973 (_elm_access_info_get(obj), ELM_ACCESS_INFO, _access_info_cb, NULL);
3974 _elm_access_callback_set
3975 (_elm_access_info_get(obj), ELM_ACCESS_STATE, _access_state_cb, NULL);
3976
3977 if (_elm_config->desktop_entry)
3978 priv->sel_handler_disabled = EINA_TRUE;
3979
3980 edje_object_signal_callback_add
3981 (priv->entry_edje, "size,eval", "elm",
3982 _entry_on_size_evaluate_signal, obj);
3983 }
3984
3985 static void
_create_selection_handlers(Evas_Object * obj,Elm_Entry_Data * sd)3986 _create_selection_handlers(Evas_Object *obj, Elm_Entry_Data *sd)
3987 {
3988 Evas_Object *handle;
3989 const char *style = elm_widget_style_get(obj);
3990
3991 handle = edje_object_add(evas_object_evas_get(obj));
3992 sd->start_handler = handle;
3993 _elm_theme_object_set(obj, handle, "entry", "handler/start", style);
3994 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_DOWN,
3995 _start_handler_mouse_down_cb, obj);
3996 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_MOVE,
3997 _start_handler_mouse_move_cb, obj);
3998 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_UP,
3999 _start_handler_mouse_up_cb, obj);
4000 evas_object_show(handle);
4001
4002 handle = edje_object_add(evas_object_evas_get(obj));
4003 sd->end_handler = handle;
4004 _elm_theme_object_set(obj, handle, "entry", "handler/end", style);
4005 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_DOWN,
4006 _end_handler_mouse_down_cb, obj);
4007 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_MOVE,
4008 _end_handler_mouse_move_cb, obj);
4009 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_UP,
4010 _end_handler_mouse_up_cb, obj);
4011 evas_object_show(handle);
4012 }
4013
4014 EOLIAN static void
_elm_entry_efl_canvas_group_group_del(Eo * obj,Elm_Entry_Data * sd)4015 _elm_entry_efl_canvas_group_group_del(Eo *obj, Elm_Entry_Data *sd)
4016 {
4017 Elm_Entry_Context_Menu_Item *it;
4018 Elm_Entry_Item_Provider *ip;
4019 Elm_Entry_Markup_Filter *tf;
4020
4021 if (sd->delay_write)
4022 {
4023 ELM_SAFE_FREE(sd->delay_write, ecore_timer_del);
4024 if (sd->auto_save) _save_do(obj);
4025 }
4026
4027 edje_object_signal_callback_del_full
4028 (sd->entry_edje, "size,eval", "elm",
4029 _entry_on_size_evaluate_signal, obj);
4030
4031 if (sd->scroll)
4032 elm_interface_scrollable_content_viewport_resize_cb_set(obj, NULL);
4033
4034 elm_entry_anchor_hover_end(obj);
4035 elm_entry_anchor_hover_parent_set(obj, NULL);
4036
4037 evas_event_freeze(evas_object_evas_get(obj));
4038
4039 eina_stringshare_del(sd->file);
4040
4041 ecore_job_del(sd->hov_deljob);
4042 if ((sd->api) && (sd->api->obj_unhook))
4043 sd->api->obj_unhook(obj); // module - unhook
4044
4045 evas_object_del(sd->mgf_proxy);
4046 evas_object_del(sd->mgf_bg);
4047 evas_object_del(sd->mgf_clip);
4048
4049 entries = eina_list_remove(entries, obj);
4050 eina_stringshare_del(sd->cut_sel);
4051 eina_stringshare_del(sd->text);
4052 ecore_job_del(sd->deferred_recalc_job);
4053 if (sd->append_text_idler)
4054 {
4055 ecore_idler_del(sd->append_text_idler);
4056 ELM_SAFE_FREE(sd->append_text_left, free);
4057 sd->append_text_idler = NULL;
4058 }
4059 ecore_timer_del(sd->longpress_timer);
4060 EINA_LIST_FREE(sd->items, it)
4061 {
4062 eina_stringshare_del(it->label);
4063 eina_stringshare_del(it->icon_file);
4064 eina_stringshare_del(it->icon_group);
4065 free(it);
4066 }
4067 EINA_LIST_FREE(sd->item_providers, ip)
4068 {
4069 free(ip);
4070 }
4071 EINA_LIST_FREE(sd->markup_filters, tf)
4072 {
4073 _filter_free(tf);
4074 }
4075 ELM_SAFE_FREE(sd->delay_write, ecore_timer_del);
4076 free(sd->input_panel_imdata);
4077
4078 if (sd->prediction_hint)
4079 {
4080 ELM_SAFE_FREE(sd->prediction_hint, free);
4081 }
4082
4083 eina_stringshare_del(sd->anchor_hover.hover_style);
4084
4085 evas_event_thaw(evas_object_evas_get(obj));
4086 evas_event_thaw_eval(evas_object_evas_get(obj));
4087
4088 if (sd->start_handler)
4089 {
4090 evas_object_del(sd->start_handler);
4091 evas_object_del(sd->end_handler);
4092 }
4093
4094 efl_canvas_group_del(efl_super(obj, MY_CLASS));
4095 }
4096
4097 EOLIAN static void
_elm_entry_efl_gfx_entity_position_set(Eo * obj,Elm_Entry_Data * sd,Eina_Position2D pos)4098 _elm_entry_efl_gfx_entity_position_set(Eo *obj, Elm_Entry_Data *sd, Eina_Position2D pos)
4099 {
4100 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y))
4101 return;
4102
4103 efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
4104 efl_gfx_entity_position_set(sd->hit_rect, pos);
4105
4106 if (sd->hoversel) _hoversel_position(obj);
4107
4108 if (edje_object_part_text_selection_get(sd->entry_edje, "elm.text"))
4109 _update_selection_handler(obj);
4110 }
4111
4112 EOLIAN static void
_elm_entry_efl_gfx_entity_size_set(Eo * obj,Elm_Entry_Data * sd,Eina_Size2D sz)4113 _elm_entry_efl_gfx_entity_size_set(Eo *obj, Elm_Entry_Data *sd, Eina_Size2D sz)
4114 {
4115 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, sz.w, sz.h))
4116 return;
4117
4118 efl_gfx_entity_size_set(sd->hit_rect, sz);
4119 if (sd->have_selection)
4120 _update_selection_handler(obj);
4121
4122 efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
4123 }
4124
4125 EOLIAN static void
_elm_entry_efl_gfx_entity_visible_set(Eo * obj,Elm_Entry_Data * sd,Eina_Bool vis)4126 _elm_entry_efl_gfx_entity_visible_set(Eo *obj, Elm_Entry_Data *sd, Eina_Bool vis)
4127 {
4128 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_VISIBLE, 0, vis))
4129 return;
4130
4131 efl_gfx_entity_visible_set(efl_super(obj, MY_CLASS), vis);
4132
4133 if (sd->have_selection)
4134 {
4135 if (vis) _update_selection_handler(obj);
4136 else _hide_selection_handler(obj);
4137 }
4138 }
4139
4140 EOLIAN static void
_elm_entry_efl_canvas_group_group_member_add(Eo * obj,Elm_Entry_Data * sd,Evas_Object * member)4141 _elm_entry_efl_canvas_group_group_member_add(Eo *obj, Elm_Entry_Data *sd, Evas_Object *member)
4142 {
4143 efl_canvas_group_member_add(efl_super(obj, MY_CLASS), member);
4144
4145 if (sd->hit_rect)
4146 evas_object_raise(sd->hit_rect);
4147 }
4148
4149 EAPI Evas_Object *
elm_entry_add(Evas_Object * parent)4150 elm_entry_add(Evas_Object *parent)
4151 {
4152 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
4153 return elm_legacy_add(MY_CLASS, parent);
4154 }
4155
4156 static void
_cb_added(void * data EINA_UNUSED,const Efl_Event * ev)4157 _cb_added(void *data EINA_UNUSED, const Efl_Event *ev)
4158 {
4159 const Efl_Callback_Array_Item_Full *event = ev->info;
4160
4161 ELM_ENTRY_DATA_GET(ev->object, sd);
4162 // XXX: BUG - not walking the array until a NULL entry
4163 if (event->desc == ELM_ENTRY_EVENT_VALIDATE)
4164 sd->validators++;
4165 }
4166
4167 static void
_cb_deleted(void * data EINA_UNUSED,const Efl_Event * ev)4168 _cb_deleted(void *data EINA_UNUSED, const Efl_Event *ev)
4169 {
4170 const Efl_Callback_Array_Item_Full *event = ev->info;
4171
4172 ELM_ENTRY_DATA_GET(ev->object, sd);
4173 // XXX: BUG - not walking the array until a NULL entry
4174 if (event->desc == ELM_ENTRY_EVENT_VALIDATE)
4175 sd->validators--;
4176 return;
4177
4178 }
4179
4180 EOLIAN static Eo *
_elm_entry_efl_object_constructor(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED)4181 _elm_entry_efl_object_constructor(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED)
4182 {
4183 obj = efl_constructor(efl_super(obj, MY_CLASS));
4184 efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
4185 evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
4186 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_ENTRY);
4187 efl_event_callback_add(obj, EFL_EVENT_CALLBACK_ADD, _cb_added, NULL);
4188 efl_event_callback_add(obj, EFL_EVENT_CALLBACK_DEL, _cb_deleted, NULL);
4189 legacy_object_focus_handle(obj);
4190
4191 return obj;
4192 }
4193
4194 EOLIAN static void
_elm_entry_text_style_user_push(Eo * obj,Elm_Entry_Data * sd,const char * style)4195 _elm_entry_text_style_user_push(Eo *obj, Elm_Entry_Data *sd, const char *style)
4196 {
4197 edje_object_part_text_style_user_push(sd->entry_edje, "elm.text", style);
4198 efl_ui_widget_theme_apply(obj);
4199 }
4200
4201 EOLIAN static void
_elm_entry_text_style_user_pop(Eo * obj,Elm_Entry_Data * sd)4202 _elm_entry_text_style_user_pop(Eo *obj, Elm_Entry_Data *sd)
4203 {
4204 edje_object_part_text_style_user_pop(sd->entry_edje, "elm.text");
4205
4206 efl_ui_widget_theme_apply(obj);
4207 }
4208
4209 EOLIAN static const char*
_elm_entry_text_style_user_peek(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4210 _elm_entry_text_style_user_peek(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4211 {
4212 return edje_object_part_text_style_user_peek(sd->entry_edje, "elm.text");
4213 }
4214
4215 EOLIAN static void
_elm_entry_single_line_set(Eo * obj,Elm_Entry_Data * sd,Eina_Bool single_line)4216 _elm_entry_single_line_set(Eo *obj, Elm_Entry_Data *sd, Eina_Bool single_line)
4217 {
4218 if (sd->single_line == single_line) return;
4219
4220 sd->single_line = single_line;
4221 sd->line_wrap = ELM_WRAP_NONE;
4222 if (elm_entry_cnp_mode_get(obj) == ELM_CNP_MODE_MARKUP)
4223 elm_entry_cnp_mode_set(obj, ELM_CNP_MODE_NO_IMAGE);
4224 if (sd->single_line)
4225 {
4226 _entry_new_line_filter_init(obj);
4227 elm_entry_markup_filter_append(obj, _entry_new_line_filter_cb, NULL);
4228 }
4229 else
4230 {
4231 elm_entry_markup_filter_remove(obj, _entry_new_line_filter_cb, NULL);
4232 }
4233 efl_ui_widget_theme_apply(obj);
4234
4235 if (sd->scroll)
4236 {
4237 if (sd->single_line)
4238 elm_interface_scrollable_policy_set(obj, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
4239 else
4240 {
4241 elm_interface_scrollable_policy_set(obj, sd->policy_h, sd->policy_v);
4242 }
4243 elm_layout_sizing_eval(obj);
4244 }
4245 }
4246
4247 EOLIAN static Eina_Bool
_elm_entry_single_line_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4248 _elm_entry_single_line_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4249 {
4250 return sd->single_line;
4251 }
4252
4253 EOLIAN static void
_elm_entry_password_set(Eo * obj,Elm_Entry_Data * sd,Eina_Bool password)4254 _elm_entry_password_set(Eo *obj, Elm_Entry_Data *sd, Eina_Bool password)
4255 {
4256 password = !!password;
4257
4258 if (sd->password == password) return;
4259 sd->password = password;
4260
4261 elm_drop_target_del(obj, sd->drop_format,
4262 _dnd_enter_cb, NULL,
4263 _dnd_leave_cb, NULL,
4264 _dnd_pos_cb, NULL,
4265 _dnd_drop_cb, NULL);
4266 if (password)
4267 {
4268 sd->single_line = EINA_TRUE;
4269 sd->line_wrap = ELM_WRAP_NONE;
4270 elm_entry_input_hint_set(obj, ((sd->input_hints & ~ELM_INPUT_HINT_AUTO_COMPLETE) | ELM_INPUT_HINT_SENSITIVE_DATA));
4271 _entry_selection_callbacks_unregister(obj);
4272 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_PASSWORD_TEXT);
4273 }
4274 else
4275 {
4276 sd->drop_format = _get_drop_format(obj);
4277 elm_drop_target_add(obj, sd->drop_format,
4278 _dnd_enter_cb, NULL,
4279 _dnd_leave_cb, NULL,
4280 _dnd_pos_cb, NULL,
4281 _dnd_drop_cb, NULL);
4282
4283 elm_entry_input_hint_set(obj, ((sd->input_hints | ELM_INPUT_HINT_AUTO_COMPLETE) & ~ELM_INPUT_HINT_SENSITIVE_DATA));
4284 _entry_selection_callbacks_register(obj);
4285 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_ENTRY);
4286 }
4287
4288 efl_ui_widget_theme_apply(obj);
4289 }
4290
4291 EOLIAN static Eina_Bool
_elm_entry_password_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4292 _elm_entry_password_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4293 {
4294 return sd->password;
4295 }
4296
4297 EAPI void
elm_entry_calc_force(Evas_Object * obj)4298 elm_entry_calc_force(Evas_Object *obj)
4299 {
4300 efl_layout_calc_force(obj);
4301 }
4302
4303 EAPI void
elm_entry_entry_set(Evas_Object * obj,const char * entry)4304 elm_entry_entry_set(Evas_Object *obj,
4305 const char *entry)
4306 {
4307 ELM_ENTRY_CHECK(obj);
4308 efl_text_set(efl_part(obj, "elm.text"), entry);
4309 }
4310
4311 EAPI const char *
elm_entry_entry_get(const Evas_Object * obj)4312 elm_entry_entry_get(const Evas_Object *obj)
4313 {
4314 ELM_ENTRY_CHECK(obj) NULL;
4315 const char *text = NULL;
4316 text = efl_text_get(efl_part(obj, "elm.text"));
4317 return text;
4318 }
4319
4320 EOLIAN static void
_elm_entry_entry_append(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,const char * entry)4321 _elm_entry_entry_append(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, const char *entry)
4322 {
4323 if (!entry) entry = "";
4324
4325 sd->changed = EINA_TRUE;
4326 _entry_text_append(obj, entry, EINA_FALSE);
4327 }
4328
4329 EOLIAN static Eina_Bool
_elm_entry_is_empty(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4330 _elm_entry_is_empty(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4331 {
4332 edje_object_part_text_cursor_copy
4333 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN, EDJE_CURSOR_USER);
4334 edje_object_part_text_cursor_pos_set
4335 (sd->entry_edje, "elm.text", EDJE_CURSOR_USER, 1);
4336 if (edje_object_part_text_cursor_pos_get
4337 (sd->entry_edje, "elm.text", EDJE_CURSOR_USER) == 1)
4338 return EINA_FALSE;
4339
4340 return EINA_TRUE;
4341 }
4342
4343 EOLIAN static Evas_Object*
_elm_entry_textblock_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4344 _elm_entry_textblock_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4345 {
4346 return (Evas_Object *)edje_object_part_object_get
4347 (sd->entry_edje, "elm.text");
4348 }
4349
4350 EOLIAN static void
_elm_entry_efl_layout_calc_calc_force(Eo * obj,Elm_Entry_Data * sd)4351 _elm_entry_efl_layout_calc_calc_force(Eo *obj, Elm_Entry_Data *sd)
4352 {
4353 edje_object_calc_force(sd->entry_edje);
4354 sd->changed = EINA_TRUE;
4355 elm_layout_sizing_eval(obj);
4356 }
4357
4358 EOLIAN static const char*
_elm_entry_selection_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4359 _elm_entry_selection_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4360 {
4361 if ((sd->password)) return NULL;
4362 return edje_object_part_text_selection_get(sd->entry_edje, "elm.text");
4363 }
4364
4365 EOLIAN static void
_elm_entry_selection_handler_disabled_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Eina_Bool disabled)4366 _elm_entry_selection_handler_disabled_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Eina_Bool disabled)
4367 {
4368 if (sd->sel_handler_disabled == disabled) return;
4369 sd->sel_handler_disabled = disabled;
4370 }
4371
4372 EOLIAN static Eina_Bool
_elm_entry_selection_handler_disabled_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4373 _elm_entry_selection_handler_disabled_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4374 {
4375 return sd->sel_handler_disabled;
4376 }
4377
4378 EOLIAN static void
_elm_entry_entry_insert(Eo * obj,Elm_Entry_Data * sd,const char * entry)4379 _elm_entry_entry_insert(Eo *obj, Elm_Entry_Data *sd, const char *entry)
4380 {
4381 edje_object_part_text_insert(sd->entry_edje, "elm.text", entry);
4382 sd->changed = EINA_TRUE;
4383 elm_layout_sizing_eval(obj);
4384 }
4385
4386 EOLIAN static void
_elm_entry_line_wrap_set(Eo * obj,Elm_Entry_Data * sd,Elm_Wrap_Type wrap)4387 _elm_entry_line_wrap_set(Eo *obj, Elm_Entry_Data *sd, Elm_Wrap_Type wrap)
4388 {
4389 if (sd->line_wrap == wrap) return;
4390 sd->last_w = -1;
4391 sd->line_wrap = wrap;
4392 if (wrap == ELM_WRAP_NONE)
4393 ELM_SAFE_FREE(sd->deferred_recalc_job, ecore_job_del);
4394 efl_ui_widget_theme_apply(obj);
4395 }
4396
4397 EOLIAN static Elm_Wrap_Type
_elm_entry_line_wrap_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4398 _elm_entry_line_wrap_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4399 {
4400 return sd->line_wrap;
4401 }
4402
4403 EOLIAN static void
_elm_entry_editable_set(Eo * obj,Elm_Entry_Data * sd,Eina_Bool editable)4404 _elm_entry_editable_set(Eo *obj, Elm_Entry_Data *sd, Eina_Bool editable)
4405 {
4406 if (sd->editable == editable) return;
4407 sd->editable = editable;
4408 efl_ui_widget_theme_apply(obj);
4409 _elm_entry_focus_update(obj, sd);
4410
4411 //legacy focus event emission
4412 if (efl_ui_focus_object_focus_get(obj))
4413 evas_object_smart_callback_call(obj, "focused", NULL);
4414 else
4415 evas_object_smart_callback_call(obj, "unfocused", NULL);
4416
4417 elm_drop_target_del(obj, sd->drop_format,
4418 _dnd_enter_cb, NULL,
4419 _dnd_leave_cb, NULL,
4420 _dnd_pos_cb, NULL,
4421 _dnd_drop_cb, NULL);
4422 if (editable)
4423 {
4424 sd->drop_format = _get_drop_format(obj);
4425 elm_drop_target_add(obj, sd->drop_format,
4426 _dnd_enter_cb, NULL,
4427 _dnd_leave_cb, NULL,
4428 _dnd_pos_cb, NULL,
4429 _dnd_drop_cb, NULL);
4430 }
4431 }
4432
4433 EOLIAN static Eina_Bool
_elm_entry_editable_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4434 _elm_entry_editable_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4435 {
4436 return sd->editable;
4437 }
4438
4439 EOLIAN static void
_elm_entry_select_none(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4440 _elm_entry_select_none(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4441 {
4442 if ((sd->password)) return;
4443 if (sd->sel_mode)
4444 {
4445 sd->sel_mode = EINA_FALSE;
4446 if (!_elm_config->desktop_entry)
4447 edje_object_part_text_select_allow_set
4448 (sd->entry_edje, "elm.text", EINA_FALSE);
4449 edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
4450 }
4451 if (sd->have_selection)
4452 {
4453 Eina_Bool b_value = sd->have_selection;
4454 efl_event_callback_legacy_call
4455 (obj, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, &b_value);
4456 }
4457
4458 sd->have_selection = EINA_FALSE;
4459 edje_object_part_text_select_none(sd->entry_edje, "elm.text");
4460
4461 _hide_selection_handler(obj);
4462 }
4463
4464 EOLIAN static void
_elm_entry_select_all(Eo * obj,Elm_Entry_Data * sd)4465 _elm_entry_select_all(Eo *obj, Elm_Entry_Data *sd)
4466 {
4467 if (elm_entry_is_empty(obj)) return;
4468 if ((sd->password)) return;
4469 if (sd->sel_mode)
4470 {
4471 sd->sel_mode = EINA_FALSE;
4472 if (!_elm_config->desktop_entry)
4473 edje_object_part_text_select_allow_set
4474 (sd->entry_edje, "elm.text", EINA_FALSE);
4475 edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
4476 }
4477 edje_object_part_text_select_all(sd->entry_edje, "elm.text");
4478 }
4479
4480 EOLIAN static void
_elm_entry_select_region_set(Eo * obj,Elm_Entry_Data * sd,int start,int end)4481 _elm_entry_select_region_set(Eo *obj, Elm_Entry_Data *sd, int start, int end)
4482 {
4483 if (elm_entry_is_empty(obj)) return;
4484 if ((sd->password)) return;
4485 if (sd->sel_mode)
4486 {
4487 sd->sel_mode = EINA_FALSE;
4488 if (!_elm_config->desktop_entry)
4489 edje_object_part_text_select_allow_set
4490 (sd->entry_edje, "elm.text", EINA_FALSE);
4491 edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
4492 }
4493
4494 /* Set have selection false to not be cleared handler in
4495 selection_cleared_signal_cb() since that callback will be called while
4496 resetting edje text. */
4497 sd->have_selection = EINA_FALSE;
4498
4499 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN, start);
4500 edje_object_part_text_select_begin(sd->entry_edje, "elm.text");
4501 edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN, end);
4502 edje_object_part_text_select_extend(sd->entry_edje, "elm.text");
4503 }
4504
4505 EOLIAN static void
_elm_entry_select_region_get(const Eo * obj,Elm_Entry_Data * sd,int * start,int * end)4506 _elm_entry_select_region_get(const Eo *obj, Elm_Entry_Data *sd, int *start, int *end)
4507 {
4508 if (!elm_entry_selection_get(obj))
4509 {
4510 if (start) *start = -1;
4511 if (end) *end = -1;
4512 return;
4513 }
4514
4515 if (start)
4516 *start = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_BEGIN);
4517 if (end)
4518 *end = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_END);
4519 }
4520
4521 EOLIAN static Eina_Bool
_elm_entry_textblock_cursor_geometry_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Evas_Coord * x,Evas_Coord * y,Evas_Coord * w,Evas_Coord * h)4522 _elm_entry_textblock_cursor_geometry_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
4523 {
4524 edje_object_part_text_cursor_geometry_get
4525 (sd->entry_edje, "elm.text", x, y, w, h);
4526 return EINA_TRUE;
4527 }
4528
4529 EOLIAN static Eina_Bool
_elm_entry_cursor_next(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4530 _elm_entry_cursor_next(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4531 {
4532 return edje_object_part_text_cursor_next
4533 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4534 }
4535
4536 EOLIAN static Eina_Bool
_elm_entry_cursor_prev(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4537 _elm_entry_cursor_prev(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4538 {
4539 return edje_object_part_text_cursor_prev
4540 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4541 }
4542
4543 EOLIAN static Eina_Bool
_elm_entry_cursor_up(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4544 _elm_entry_cursor_up(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4545 {
4546 return edje_object_part_text_cursor_up
4547 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4548 }
4549
4550 EOLIAN static Eina_Bool
_elm_entry_cursor_down(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4551 _elm_entry_cursor_down(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4552 {
4553 return edje_object_part_text_cursor_down
4554 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4555 }
4556
4557 EOLIAN static void
_elm_entry_cursor_begin_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4558 _elm_entry_cursor_begin_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4559 {
4560 edje_object_part_text_cursor_begin_set
4561 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4562 }
4563
4564 EOLIAN static void
_elm_entry_cursor_end_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4565 _elm_entry_cursor_end_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4566 {
4567 edje_object_part_text_cursor_end_set
4568 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4569 }
4570
4571 EOLIAN static void
_elm_entry_cursor_line_begin_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4572 _elm_entry_cursor_line_begin_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4573 {
4574 edje_object_part_text_cursor_line_begin_set
4575 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4576 }
4577
4578 EOLIAN static void
_elm_entry_cursor_line_end_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4579 _elm_entry_cursor_line_end_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4580 {
4581 edje_object_part_text_cursor_line_end_set
4582 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4583 }
4584
4585 EOLIAN static void
_elm_entry_cursor_selection_begin(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4586 _elm_entry_cursor_selection_begin(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4587 {
4588 edje_object_part_text_select_begin(sd->entry_edje, "elm.text");
4589 }
4590
4591 EOLIAN static void
_elm_entry_cursor_selection_end(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4592 _elm_entry_cursor_selection_end(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4593 {
4594 edje_object_part_text_select_extend(sd->entry_edje, "elm.text");
4595 }
4596
4597 EOLIAN static Eina_Bool
_elm_entry_cursor_is_format_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4598 _elm_entry_cursor_is_format_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4599 {
4600 return edje_object_part_text_cursor_is_format_get
4601 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4602 }
4603
4604 EOLIAN static Eina_Bool
_elm_entry_cursor_is_visible_format_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4605 _elm_entry_cursor_is_visible_format_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4606 {
4607 return edje_object_part_text_cursor_is_visible_format_get
4608 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4609 }
4610
4611 EOLIAN static char*
_elm_entry_textblock_cursor_content_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4612 _elm_entry_textblock_cursor_content_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4613 {
4614 return edje_object_part_text_cursor_content_get
4615 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4616 }
4617
4618 EOLIAN static void
_elm_entry_cursor_pos_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,int pos)4619 _elm_entry_cursor_pos_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, int pos)
4620 {
4621 edje_object_part_text_cursor_pos_set
4622 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN, pos);
4623 edje_object_message_signal_process(sd->entry_edje);
4624 }
4625
4626 EOLIAN static int
_elm_entry_cursor_pos_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4627 _elm_entry_cursor_pos_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4628 {
4629 return edje_object_part_text_cursor_pos_get
4630 (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
4631 }
4632
4633 EOLIAN static void
_elm_entry_selection_cut(Eo * obj,Elm_Entry_Data * sd)4634 _elm_entry_selection_cut(Eo *obj, Elm_Entry_Data *sd)
4635 {
4636 if ((sd->password)) return;
4637 _cut_cb(obj, NULL, NULL);
4638 }
4639
4640 EOLIAN static void
_elm_entry_selection_copy(Eo * obj,Elm_Entry_Data * sd)4641 _elm_entry_selection_copy(Eo *obj, Elm_Entry_Data *sd)
4642 {
4643 if ((sd->password)) return;
4644 _copy_cb(obj, NULL, NULL);
4645 }
4646
4647 EOLIAN static void
_elm_entry_selection_paste(Eo * obj,Elm_Entry_Data * sd)4648 _elm_entry_selection_paste(Eo *obj, Elm_Entry_Data *sd)
4649 {
4650 if ((sd->password)) return;
4651 _paste_cb(obj, NULL, NULL);
4652 }
4653
4654 EOLIAN static void
_elm_entry_context_menu_clear(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4655 _elm_entry_context_menu_clear(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4656 {
4657 Elm_Entry_Context_Menu_Item *it;
4658
4659 EINA_LIST_FREE(sd->items, it)
4660 {
4661 eina_stringshare_del(it->label);
4662 eina_stringshare_del(it->icon_file);
4663 eina_stringshare_del(it->icon_group);
4664 free(it);
4665 }
4666 }
4667
4668 EOLIAN static void
_elm_entry_context_menu_item_add(Eo * obj,Elm_Entry_Data * sd,const char * label,const char * icon_file,Elm_Icon_Type icon_type,Evas_Smart_Cb func,const void * data)4669 _elm_entry_context_menu_item_add(Eo *obj, Elm_Entry_Data *sd, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data)
4670 {
4671 Elm_Entry_Context_Menu_Item *it;
4672
4673 it = calloc(1, sizeof(Elm_Entry_Context_Menu_Item));
4674 if (!it) return;
4675
4676 sd->items = eina_list_append(sd->items, it);
4677 it->obj = obj;
4678 it->label = eina_stringshare_add(label);
4679 it->icon_file = eina_stringshare_add(icon_file);
4680 it->icon_type = icon_type;
4681 it->func = func;
4682 it->data = (void *)data;
4683 }
4684
4685 EOLIAN static void
_elm_entry_context_menu_disabled_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Eina_Bool disabled)4686 _elm_entry_context_menu_disabled_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Eina_Bool disabled)
4687 {
4688 if (sd->context_menu == !disabled) return;
4689 sd->context_menu = !disabled;
4690 }
4691
4692 EOLIAN static Eina_Bool
_elm_entry_context_menu_disabled_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)4693 _elm_entry_context_menu_disabled_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
4694 {
4695 return !sd->context_menu;
4696 }
4697
4698 EAPI const char *
elm_entry_context_menu_item_label_get(const Elm_Entry_Context_Menu_Item * item)4699 elm_entry_context_menu_item_label_get(const Elm_Entry_Context_Menu_Item *item)
4700 {
4701 if (!item) return NULL;
4702 return item->label;
4703 }
4704
4705 EAPI void
elm_entry_context_menu_item_icon_get(const Elm_Entry_Context_Menu_Item * item,const char ** icon_file,const char ** icon_group,Elm_Icon_Type * icon_type)4706 elm_entry_context_menu_item_icon_get(const Elm_Entry_Context_Menu_Item *item,
4707 const char **icon_file,
4708 const char **icon_group,
4709 Elm_Icon_Type *icon_type)
4710 {
4711 if (!item) return;
4712 if (icon_file) *icon_file = item->icon_file;
4713 if (icon_group) *icon_group = item->icon_group;
4714 if (icon_type) *icon_type = item->icon_type;
4715 }
4716
4717 EOLIAN static void
_elm_entry_item_provider_append(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Entry_Item_Provider_Cb func,void * data)4718 _elm_entry_item_provider_append(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data)
4719 {
4720 Elm_Entry_Item_Provider *ip;
4721
4722 EINA_SAFETY_ON_NULL_RETURN(func);
4723
4724 ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
4725 if (!ip) return;
4726
4727 ip->func = func;
4728 ip->data = data;
4729 sd->item_providers = eina_list_append(sd->item_providers, ip);
4730 }
4731
4732 EOLIAN static void
_elm_entry_item_provider_prepend(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Entry_Item_Provider_Cb func,void * data)4733 _elm_entry_item_provider_prepend(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data)
4734 {
4735 Elm_Entry_Item_Provider *ip;
4736
4737 EINA_SAFETY_ON_NULL_RETURN(func);
4738
4739 ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
4740 if (!ip) return;
4741
4742 ip->func = func;
4743 ip->data = data;
4744 sd->item_providers = eina_list_prepend(sd->item_providers, ip);
4745 }
4746
4747 EOLIAN static void
_elm_entry_item_provider_remove(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Entry_Item_Provider_Cb func,void * data)4748 _elm_entry_item_provider_remove(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data)
4749 {
4750 Eina_List *l;
4751 Elm_Entry_Item_Provider *ip;
4752
4753 EINA_SAFETY_ON_NULL_RETURN(func);
4754
4755 EINA_LIST_FOREACH(sd->item_providers, l, ip)
4756 {
4757 if ((ip->func == func) && ((!data) || (ip->data == data)))
4758 {
4759 sd->item_providers = eina_list_remove_list(sd->item_providers, l);
4760 free(ip);
4761 return;
4762 }
4763 }
4764 }
4765
4766 EOLIAN static void
_elm_entry_markup_filter_append(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Entry_Filter_Cb func,void * data)4767 _elm_entry_markup_filter_append(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Entry_Filter_Cb func, void *data)
4768 {
4769 Elm_Entry_Markup_Filter *tf;
4770
4771 EINA_SAFETY_ON_NULL_RETURN(func);
4772
4773 tf = _filter_new(func, data);
4774 if (!tf) return;
4775
4776 sd->markup_filters = eina_list_append(sd->markup_filters, tf);
4777 }
4778
4779 EOLIAN static void
_elm_entry_markup_filter_prepend(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Entry_Filter_Cb func,void * data)4780 _elm_entry_markup_filter_prepend(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Entry_Filter_Cb func, void *data)
4781 {
4782 Elm_Entry_Markup_Filter *tf;
4783
4784 EINA_SAFETY_ON_NULL_RETURN(func);
4785
4786 tf = _filter_new(func, data);
4787 if (!tf) return;
4788
4789 sd->markup_filters = eina_list_prepend(sd->markup_filters, tf);
4790 }
4791
4792 EOLIAN static void
_elm_entry_markup_filter_remove(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Entry_Filter_Cb func,void * data)4793 _elm_entry_markup_filter_remove(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Entry_Filter_Cb func, void *data)
4794 {
4795 Eina_List *l;
4796 Elm_Entry_Markup_Filter *tf;
4797
4798 EINA_SAFETY_ON_NULL_RETURN(func);
4799
4800 EINA_LIST_FOREACH(sd->markup_filters, l, tf)
4801 {
4802 if ((tf->func == func) && ((!data) || (tf->orig_data == data)))
4803 {
4804 sd->markup_filters = eina_list_remove_list(sd->markup_filters, l);
4805 _filter_free(tf);
4806 return;
4807 }
4808 }
4809 }
4810
4811 EAPI char *
elm_entry_markup_to_utf8(const char * s)4812 elm_entry_markup_to_utf8(const char *s)
4813 {
4814 char *ss = _elm_util_mkup_to_text(s);
4815 if (!ss) ss = strdup("");
4816 return ss;
4817 }
4818
4819 EAPI char *
elm_entry_utf8_to_markup(const char * s)4820 elm_entry_utf8_to_markup(const char *s)
4821 {
4822 char *ss = _elm_util_text_to_mkup(s);
4823 if (!ss) ss = strdup("");
4824 return ss;
4825 }
4826
4827 static const char *
_text_get(const Evas_Object * obj)4828 _text_get(const Evas_Object *obj)
4829 {
4830 return elm_object_text_get(obj);
4831 }
4832
4833 EAPI void
elm_entry_filter_limit_size(void * data,Evas_Object * entry,char ** text)4834 elm_entry_filter_limit_size(void *data,
4835 Evas_Object *entry,
4836 char **text)
4837 {
4838 const char *(*text_get)(const Evas_Object *);
4839 Elm_Entry_Filter_Limit_Size *lim = data;
4840 char *current, *utfstr;
4841 int len, newlen;
4842
4843 EINA_SAFETY_ON_NULL_RETURN(data);
4844 EINA_SAFETY_ON_NULL_RETURN(entry);
4845 EINA_SAFETY_ON_NULL_RETURN(text);
4846
4847 /* hack. I don't want to copy the entire function to work with
4848 * scrolled_entry */
4849 text_get = _text_get;
4850
4851 current = elm_entry_markup_to_utf8(text_get(entry));
4852 utfstr = elm_entry_markup_to_utf8(*text);
4853
4854 if (lim->max_char_count > 0)
4855 {
4856 len = evas_string_char_len_get(current);
4857 newlen = evas_string_char_len_get(utfstr);
4858 if ((len >= lim->max_char_count) && (newlen > 0))
4859 {
4860 efl_event_callback_legacy_call
4861 (entry, ELM_ENTRY_EVENT_MAXLENGTH_REACHED, NULL);
4862 ELM_SAFE_FREE(*text, free);
4863 free(current);
4864 free(utfstr);
4865 return;
4866 }
4867 if ((len + newlen) > lim->max_char_count)
4868 _chars_add_till_limit
4869 (entry, text, (lim->max_char_count - len), LENGTH_UNIT_CHAR);
4870 }
4871 else if (lim->max_byte_count > 0)
4872 {
4873 len = strlen(current);
4874 newlen = strlen(utfstr);
4875 if ((len >= lim->max_byte_count) && (newlen > 0))
4876 {
4877 efl_event_callback_legacy_call
4878 (entry, ELM_ENTRY_EVENT_MAXLENGTH_REACHED, NULL);
4879 ELM_SAFE_FREE(*text, free);
4880 free(current);
4881 free(utfstr);
4882 return;
4883 }
4884 if ((len + newlen) > lim->max_byte_count)
4885 _chars_add_till_limit
4886 (entry, text, (lim->max_byte_count - len), LENGTH_UNIT_BYTE);
4887 }
4888
4889 free(current);
4890 free(utfstr);
4891 }
4892
4893 EAPI void
elm_entry_filter_accept_set(void * data,Evas_Object * entry,char ** text)4894 elm_entry_filter_accept_set(void *data,
4895 Evas_Object *entry,
4896 char **text)
4897 {
4898 int read_idx, last_read_idx = 0, read_char;
4899 Elm_Entry_Filter_Accept_Set *as = data;
4900 Eina_Bool goes_in;
4901 Eina_Bool rejected = EINA_FALSE;
4902 const char *set;
4903 char *insert;
4904
4905 EINA_SAFETY_ON_NULL_RETURN(data);
4906 EINA_SAFETY_ON_NULL_RETURN(text);
4907
4908 if ((!as->accepted) && (!as->rejected))
4909 return;
4910
4911 if (as->accepted)
4912 {
4913 set = as->accepted;
4914 goes_in = EINA_TRUE;
4915 }
4916 else
4917 {
4918 set = as->rejected;
4919 goes_in = EINA_FALSE;
4920 }
4921
4922 insert = *text;
4923 read_idx = evas_string_char_next_get(*text, 0, &read_char);
4924 while (read_char)
4925 {
4926 int cmp_idx, cmp_char;
4927 Eina_Bool in_set = EINA_FALSE;
4928
4929 if (read_char == '<')
4930 {
4931 while (read_char && (read_char != '>'))
4932 read_idx = evas_string_char_next_get(*text, read_idx, &read_char);
4933
4934 if (goes_in) in_set = EINA_TRUE;
4935 else in_set = EINA_FALSE;
4936 }
4937 else
4938 {
4939 if (read_char == '&')
4940 {
4941 while (read_char && (read_char != ';'))
4942 read_idx = evas_string_char_next_get(*text, read_idx, &read_char);
4943
4944 if (!read_char)
4945 {
4946 if (goes_in) in_set = EINA_TRUE;
4947 else in_set = EINA_FALSE;
4948 goto inserting;
4949 }
4950 if (read_char == ';')
4951 {
4952 char *tag;
4953 int utf8 = 0;
4954 tag = malloc(read_idx - last_read_idx + 1);
4955 if (tag)
4956 {
4957 char *markup;
4958 strncpy(tag, (*text) + last_read_idx, read_idx - last_read_idx);
4959 tag[read_idx - last_read_idx] = 0;
4960 markup = elm_entry_markup_to_utf8(tag);
4961 free(tag);
4962 if (markup)
4963 {
4964 utf8 = *markup;
4965 free(markup);
4966 }
4967 if (!utf8)
4968 {
4969 in_set = EINA_FALSE;
4970 goto inserting;
4971 }
4972 read_char = utf8;
4973 }
4974 }
4975 }
4976
4977 cmp_idx = evas_string_char_next_get(set, 0, &cmp_char);
4978 while (cmp_char)
4979 {
4980 if (read_char == cmp_char)
4981 {
4982 in_set = EINA_TRUE;
4983 break;
4984 }
4985 cmp_idx = evas_string_char_next_get(set, cmp_idx, &cmp_char);
4986 }
4987 }
4988
4989 inserting:
4990
4991 if (in_set == goes_in)
4992 {
4993 int size = read_idx - last_read_idx;
4994 const char *src = (*text) + last_read_idx;
4995 if (src != insert)
4996 memcpy(insert, *text + last_read_idx, size);
4997 insert += size;
4998 }
4999 else
5000 {
5001 rejected = EINA_TRUE;
5002 }
5003
5004 if (read_char)
5005 {
5006 last_read_idx = read_idx;
5007 read_idx = evas_string_char_next_get(*text, read_idx, &read_char);
5008 }
5009 }
5010 *insert = 0;
5011 if (rejected)
5012 efl_event_callback_legacy_call(entry, ELM_ENTRY_EVENT_REJECTED, NULL);
5013 }
5014
5015 EOLIAN static void
_elm_entry_file_text_format_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Text_Format format)5016 _elm_entry_file_text_format_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Text_Format format)
5017 {
5018 sd->format = format;
5019 }
5020
5021 EAPI Eina_Bool
elm_entry_file_set(Evas_Object * obj,const char * file,Elm_Text_Format format)5022 elm_entry_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format)
5023 {
5024 Eina_Bool ret = EINA_FALSE;
5025 ELM_ENTRY_DATA_GET_OR_RETURN_VAL(obj, sd, ret);
5026 ELM_SAFE_FREE(sd->delay_write, ecore_timer_del);
5027 if (sd->auto_save) _save_do(obj);
5028 elm_obj_entry_file_text_format_set(obj, format);
5029 sd->file_setting = EINA_TRUE;
5030 ret = efl_file_simple_load(obj, file, NULL);
5031 sd->file_setting = EINA_FALSE;
5032 return ret;
5033 }
5034
5035 EOLIAN static void
_elm_entry_efl_file_unload(Eo * obj,Elm_Entry_Data * sd EINA_UNUSED)5036 _elm_entry_efl_file_unload(Eo *obj, Elm_Entry_Data *sd EINA_UNUSED)
5037 {
5038 elm_object_text_set(obj, "");
5039 efl_file_unload(efl_super(obj, MY_CLASS));
5040 }
5041
5042 EOLIAN static Eina_Error
_elm_entry_efl_file_load(Eo * obj,Elm_Entry_Data * sd)5043 _elm_entry_efl_file_load(Eo *obj, Elm_Entry_Data *sd)
5044 {
5045 Eina_Error err;
5046
5047 if (!sd->file_setting)
5048 CRI("EO methods should not be used directly on legacy objects!");
5049
5050 if (efl_file_loaded_get(obj)) return 0;
5051 err = efl_file_load(efl_super(obj, MY_CLASS));
5052 if (err) return err;
5053 return _load_do(obj);
5054 }
5055
5056 EOLIAN static Eina_Error
_elm_entry_efl_file_file_set(Eo * obj,Elm_Entry_Data * sd,const char * file)5057 _elm_entry_efl_file_file_set(Eo *obj, Elm_Entry_Data *sd, const char *file)
5058 {
5059 if (!sd->file_setting)
5060 CRI("EO methods should not be used directly on legacy objects!");
5061 eina_stringshare_replace(&sd->file, file);
5062 return efl_file_set(efl_super(obj, MY_CLASS), file);
5063 }
5064
5065 EAPI void
elm_entry_file_get(const Evas_Object * obj,const char ** file,Elm_Text_Format * format)5066 elm_entry_file_get(const Evas_Object *obj, const char **file, Elm_Text_Format *format)
5067 {
5068 if (file) *file = efl_file_get(obj);
5069 if (format)
5070 {
5071 ELM_ENTRY_DATA_GET(obj, sd);
5072 if (!sd) return;
5073 *format = sd->format;
5074 }
5075 }
5076
5077 EOLIAN static void
_elm_entry_file_save(Eo * obj,Elm_Entry_Data * sd)5078 _elm_entry_file_save(Eo *obj, Elm_Entry_Data *sd)
5079 {
5080 ELM_SAFE_FREE(sd->delay_write, ecore_timer_del);
5081 _save_do(obj);
5082 sd->delay_write = ecore_timer_add(ELM_ENTRY_DELAY_WRITE_TIME,
5083 _delay_write, obj);
5084 }
5085
5086 EOLIAN static void
_elm_entry_autosave_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Eina_Bool auto_save)5087 _elm_entry_autosave_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Eina_Bool auto_save)
5088 {
5089 sd->auto_save = !!auto_save;
5090 }
5091
5092 EOLIAN static Eina_Bool
_elm_entry_autosave_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5093 _elm_entry_autosave_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5094 {
5095 return sd->auto_save;
5096 }
5097
5098 EINA_DEPRECATED EAPI void
elm_entry_cnp_textonly_set(Evas_Object * obj,Eina_Bool textonly)5099 elm_entry_cnp_textonly_set(Evas_Object *obj,
5100 Eina_Bool textonly)
5101 {
5102 Elm_Cnp_Mode cnp_mode = ELM_CNP_MODE_MARKUP;
5103
5104 ELM_ENTRY_CHECK(obj);
5105
5106 if (textonly)
5107 cnp_mode = ELM_CNP_MODE_NO_IMAGE;
5108 elm_entry_cnp_mode_set(obj, cnp_mode);
5109 }
5110
5111 EINA_DEPRECATED EAPI Eina_Bool
elm_entry_cnp_textonly_get(const Evas_Object * obj)5112 elm_entry_cnp_textonly_get(const Evas_Object *obj)
5113 {
5114 ELM_ENTRY_CHECK(obj) EINA_FALSE;
5115
5116 return elm_entry_cnp_mode_get(obj) != ELM_CNP_MODE_MARKUP;
5117 }
5118
5119 EOLIAN static void
_elm_entry_cnp_mode_set(Eo * obj,Elm_Entry_Data * sd,Elm_Cnp_Mode cnp_mode)5120 _elm_entry_cnp_mode_set(Eo *obj, Elm_Entry_Data *sd, Elm_Cnp_Mode cnp_mode)
5121 {
5122 Elm_Sel_Format format = ELM_SEL_FORMAT_MARKUP;
5123
5124
5125 if (sd->cnp_mode == cnp_mode) return;
5126 sd->cnp_mode = cnp_mode;
5127 if (sd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
5128 format = ELM_SEL_FORMAT_TEXT;
5129 else if (cnp_mode == ELM_CNP_MODE_MARKUP)
5130 format |= ELM_SEL_FORMAT_IMAGE;
5131
5132 elm_drop_target_del(obj, sd->drop_format,
5133 _dnd_enter_cb, NULL,
5134 _dnd_leave_cb, NULL,
5135 _dnd_pos_cb, NULL,
5136 _dnd_drop_cb, NULL);
5137 sd->drop_format = format;
5138 elm_drop_target_add(obj, sd->drop_format,
5139 _dnd_enter_cb, NULL,
5140 _dnd_leave_cb, NULL,
5141 _dnd_pos_cb, NULL,
5142 _dnd_drop_cb, NULL);
5143 }
5144
5145 EOLIAN static Elm_Cnp_Mode
_elm_entry_cnp_mode_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5146 _elm_entry_cnp_mode_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5147 {
5148 return sd->cnp_mode;
5149 }
5150
5151 static void
_elm_entry_content_viewport_resize_cb(Evas_Object * obj,Evas_Coord w EINA_UNUSED,Evas_Coord h EINA_UNUSED)5152 _elm_entry_content_viewport_resize_cb(Evas_Object *obj,
5153 Evas_Coord w EINA_UNUSED, Evas_Coord h EINA_UNUSED)
5154 {
5155 _elm_entry_resize_internal(obj);
5156 }
5157
5158 static void
_scroll_cb(Evas_Object * obj,void * data EINA_UNUSED)5159 _scroll_cb(Evas_Object *obj, void *data EINA_UNUSED)
5160 {
5161 ELM_ENTRY_DATA_GET(obj, sd);
5162 /* here we need to emit the signal that the elm_scroller would have done */
5163 evas_object_smart_callback_call(obj, "scroll", NULL);
5164
5165 if (sd->have_selection)
5166 _update_selection_handler(obj);
5167 }
5168
5169 EOLIAN static void
_elm_entry_scrollable_set(Eo * obj,Elm_Entry_Data * sd,Eina_Bool scroll)5170 _elm_entry_scrollable_set(Eo *obj, Elm_Entry_Data *sd, Eina_Bool scroll)
5171 {
5172 scroll = !!scroll;
5173 if (sd->scroll == scroll) return;
5174 sd->scroll = scroll;
5175
5176 if (sd->scroll)
5177 {
5178 /* we now must re-theme ourselves to a scroller decoration
5179 * and move the entry looking object to be the content of the
5180 * scrollable view */
5181 elm_widget_resize_object_set(obj, NULL);
5182 elm_widget_sub_object_add(obj, sd->entry_edje);
5183
5184 if (!sd->scr_edje)
5185 {
5186 sd->scr_edje = edje_object_add(evas_object_evas_get(obj));
5187
5188 elm_widget_theme_object_set
5189 (obj, sd->scr_edje, "scroller", "entry",
5190 elm_widget_style_get(obj));
5191
5192 evas_object_size_hint_weight_set
5193 (sd->scr_edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
5194 evas_object_size_hint_align_set
5195 (sd->scr_edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
5196
5197 evas_object_propagate_events_set(sd->scr_edje, EINA_TRUE);
5198 }
5199
5200 elm_widget_resize_object_set(obj, sd->scr_edje);
5201
5202 elm_interface_scrollable_objects_set(obj, sd->scr_edje, sd->hit_rect);
5203
5204 elm_interface_scrollable_scroll_cb_set(obj, _scroll_cb);
5205
5206 elm_interface_scrollable_bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
5207 if (sd->single_line)
5208 elm_interface_scrollable_policy_set(obj, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
5209 else
5210 elm_interface_scrollable_policy_set(obj, sd->policy_h, sd->policy_v);
5211 elm_interface_scrollable_content_set(obj, sd->entry_edje);
5212 elm_interface_scrollable_content_viewport_resize_cb_set(obj, _elm_entry_content_viewport_resize_cb);
5213 elm_widget_on_show_region_hook_set(obj, NULL, _show_region_hook, NULL);
5214 }
5215 else
5216 {
5217 if (sd->scr_edje)
5218 {
5219 elm_interface_scrollable_content_set(obj, NULL);
5220 evas_object_hide(sd->scr_edje);
5221 }
5222 elm_widget_resize_object_set(obj, sd->entry_edje);
5223
5224 if (sd->scr_edje)
5225 elm_widget_sub_object_add(obj, sd->scr_edje);
5226
5227 elm_interface_scrollable_objects_set(obj, sd->entry_edje, sd->hit_rect);
5228
5229 elm_widget_on_show_region_hook_set(obj, NULL, NULL, NULL);
5230 }
5231 sd->last_w = -1;
5232 efl_ui_widget_theme_apply(obj);
5233 }
5234
5235 EOLIAN static Eina_Bool
_elm_entry_scrollable_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5236 _elm_entry_scrollable_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5237 {
5238 return sd->scroll;
5239 }
5240
5241 EOLIAN static void
_elm_entry_icon_visible_set(Eo * obj,Elm_Entry_Data * sd,Eina_Bool setting)5242 _elm_entry_icon_visible_set(Eo *obj, Elm_Entry_Data *sd, Eina_Bool setting)
5243 {
5244 if (!edje_object_part_swallow_get(sd->scr_edje, "elm.swallow.icon")) return;
5245
5246 if (setting)
5247 edje_object_signal_emit(sd->scr_edje, "elm,action,show,icon", "elm");
5248 else
5249 edje_object_signal_emit(sd->scr_edje, "elm,action,hide,icon", "elm");
5250
5251 elm_layout_sizing_eval(obj);
5252 }
5253
5254 EOLIAN static void
_elm_entry_end_visible_set(Eo * obj,Elm_Entry_Data * sd,Eina_Bool setting)5255 _elm_entry_end_visible_set(Eo *obj, Elm_Entry_Data *sd, Eina_Bool setting)
5256 {
5257 if (!edje_object_part_swallow_get(sd->scr_edje, "elm.swallow.end")) return;
5258
5259 if (setting)
5260 edje_object_signal_emit(sd->scr_edje, "elm,action,show,end", "elm");
5261 else
5262 edje_object_signal_emit(sd->scr_edje, "elm,action,hide,end", "elm");
5263
5264 elm_layout_sizing_eval(obj);
5265 }
5266
5267 EAPI void
elm_entry_scrollbar_policy_set(Evas_Object * obj,Elm_Scroller_Policy h,Elm_Scroller_Policy v)5268 elm_entry_scrollbar_policy_set(Evas_Object *obj,
5269 Elm_Scroller_Policy h,
5270 Elm_Scroller_Policy v)
5271 {
5272 ELM_ENTRY_CHECK(obj);
5273 elm_interface_scrollable_policy_set(obj, h, v);
5274 }
5275
5276 EOLIAN static void
_elm_entry_elm_interface_scrollable_policy_set(Eo * obj,Elm_Entry_Data * sd,Elm_Scroller_Policy h,Elm_Scroller_Policy v)5277 _elm_entry_elm_interface_scrollable_policy_set(Eo *obj, Elm_Entry_Data *sd, Elm_Scroller_Policy h, Elm_Scroller_Policy v)
5278 {
5279 sd->policy_h = h;
5280 sd->policy_v = v;
5281 elm_interface_scrollable_policy_set(efl_super(obj, MY_CLASS), sd->policy_h, sd->policy_v);
5282 }
5283
5284 EAPI void
elm_entry_bounce_set(Evas_Object * obj,Eina_Bool h_bounce,Eina_Bool v_bounce)5285 elm_entry_bounce_set(Evas_Object *obj,
5286 Eina_Bool h_bounce,
5287 Eina_Bool v_bounce)
5288 {
5289 ELM_ENTRY_CHECK(obj);
5290 elm_interface_scrollable_bounce_allow_set(obj, h_bounce, v_bounce);
5291 }
5292
5293 EOLIAN static void
_elm_entry_elm_interface_scrollable_bounce_allow_set(Eo * obj,Elm_Entry_Data * sd,Eina_Bool h_bounce,Eina_Bool v_bounce)5294 _elm_entry_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Entry_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
5295 {
5296 sd->h_bounce = h_bounce;
5297 sd->v_bounce = v_bounce;
5298 elm_interface_scrollable_bounce_allow_set(efl_super(obj, MY_CLASS), h_bounce, v_bounce);
5299 }
5300
5301 EAPI void
elm_entry_bounce_get(const Evas_Object * obj,Eina_Bool * h_bounce,Eina_Bool * v_bounce)5302 elm_entry_bounce_get(const Evas_Object *obj,
5303 Eina_Bool *h_bounce,
5304 Eina_Bool *v_bounce)
5305 {
5306 ELM_ENTRY_CHECK(obj);
5307 elm_interface_scrollable_bounce_allow_get((Eo *) obj, h_bounce, v_bounce);
5308 }
5309
5310 EOLIAN static void
_elm_entry_input_panel_layout_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Input_Panel_Layout layout)5311 _elm_entry_input_panel_layout_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Input_Panel_Layout layout)
5312 {
5313 sd->input_panel_layout = layout;
5314
5315 edje_object_part_text_input_panel_layout_set
5316 (sd->entry_edje, "elm.text", (Edje_Input_Panel_Layout)layout);
5317
5318 switch (layout)
5319 {
5320 case ELM_INPUT_PANEL_LAYOUT_URL:
5321 case ELM_INPUT_PANEL_LAYOUT_EMAIL:
5322 case ELM_INPUT_PANEL_LAYOUT_PASSWORD:
5323 elm_entry_autocapital_type_set(obj, ELM_AUTOCAPITAL_TYPE_NONE);
5324 break;
5325 default:
5326 elm_entry_autocapital_type_set(obj, ELM_AUTOCAPITAL_TYPE_SENTENCE);
5327 break;
5328 }
5329
5330 if (layout == ELM_INPUT_PANEL_LAYOUT_PASSWORD)
5331 elm_entry_input_hint_set(obj, ((sd->input_hints & ~ELM_INPUT_HINT_AUTO_COMPLETE) | ELM_INPUT_HINT_SENSITIVE_DATA));
5332 else if (layout == ELM_INPUT_PANEL_LAYOUT_TERMINAL)
5333 elm_entry_input_hint_set(obj, (sd->input_hints & ~ELM_INPUT_HINT_AUTO_COMPLETE));
5334 }
5335
5336 EOLIAN static Elm_Input_Panel_Layout
_elm_entry_input_panel_layout_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5337 _elm_entry_input_panel_layout_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5338 {
5339 return sd->input_panel_layout;
5340 }
5341
5342 EOLIAN static void
_elm_entry_input_panel_layout_variation_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,int variation)5343 _elm_entry_input_panel_layout_variation_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, int variation)
5344 {
5345 sd->input_panel_layout_variation = variation;
5346
5347 edje_object_part_text_input_panel_layout_variation_set
5348 (sd->entry_edje, "elm.text", variation);
5349
5350 if (sd->input_panel_layout == ELM_INPUT_PANEL_LAYOUT_NORMAL &&
5351 variation == ELM_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_PERSON_NAME)
5352 elm_entry_autocapital_type_set(obj, ELM_AUTOCAPITAL_TYPE_WORD);
5353 }
5354
5355 EOLIAN static int
_elm_entry_input_panel_layout_variation_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5356 _elm_entry_input_panel_layout_variation_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5357 {
5358 return sd->input_panel_layout_variation;
5359 }
5360
5361 EOLIAN static void
_elm_entry_autocapital_type_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Autocapital_Type autocapital_type)5362 _elm_entry_autocapital_type_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Autocapital_Type autocapital_type)
5363 {
5364 sd->autocapital_type = autocapital_type;
5365 edje_object_part_text_autocapital_type_set
5366 (sd->entry_edje, "elm.text", (Edje_Text_Autocapital_Type)autocapital_type);
5367 }
5368
5369 EOLIAN static Elm_Autocapital_Type
_elm_entry_autocapital_type_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5370 _elm_entry_autocapital_type_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5371 {
5372 return sd->autocapital_type;
5373 }
5374
5375 EOLIAN static void
_elm_entry_prediction_allow_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Eina_Bool prediction)5376 _elm_entry_prediction_allow_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Eina_Bool prediction)
5377 {
5378 sd->prediction_allow = prediction;
5379 edje_object_part_text_prediction_allow_set
5380 (sd->entry_edje, "elm.text", prediction);
5381 }
5382
5383 EOLIAN static Eina_Bool
_elm_entry_prediction_allow_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5384 _elm_entry_prediction_allow_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5385 {
5386 return sd->prediction_allow;
5387 }
5388
5389 EOLIAN static void
_elm_entry_input_hint_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Input_Hints hints)5390 _elm_entry_input_hint_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Input_Hints hints)
5391 {
5392 sd->input_hints = hints;
5393
5394 edje_object_part_text_input_hint_set
5395 (sd->entry_edje, "elm.text", (Edje_Input_Hints)hints);
5396 }
5397
5398 EOLIAN static Elm_Input_Hints
_elm_entry_input_hint_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5399 _elm_entry_input_hint_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5400 {
5401 return sd->input_hints;
5402 }
5403
5404 EOLIAN static void
_elm_entry_prediction_hint_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,const char * prediction_hint)5405 _elm_entry_prediction_hint_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, const char *prediction_hint)
5406 {
5407 if (sd->prediction_hint)
5408 free(sd->prediction_hint);
5409
5410 sd->prediction_hint = strdup(prediction_hint);
5411
5412 edje_object_part_text_prediction_hint_set
5413 (sd->entry_edje, "elm.text", prediction_hint);
5414 }
5415
5416 EOLIAN static Eina_Bool
_elm_entry_prediction_hint_hash_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,const char * key,const char * value)5417 _elm_entry_prediction_hint_hash_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, const char *key, const char *value)
5418 {
5419 return edje_object_part_text_prediction_hint_hash_set
5420 (sd->entry_edje, "elm.text", key, value);
5421 }
5422
5423 EOLIAN static Eina_Bool
_elm_entry_prediction_hint_hash_del(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,const char * key)5424 _elm_entry_prediction_hint_hash_del(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, const char *key)
5425 {
5426 return edje_object_part_text_prediction_hint_hash_del
5427 (sd->entry_edje, "elm.text", key);
5428 }
5429
5430 EOLIAN static void
_elm_entry_imf_context_reset(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5431 _elm_entry_imf_context_reset(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5432 {
5433 edje_object_part_text_imf_context_reset(sd->entry_edje, "elm.text");
5434 }
5435
5436 EOLIAN static void
_elm_entry_input_panel_enabled_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Eina_Bool enabled)5437 _elm_entry_input_panel_enabled_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Eina_Bool enabled)
5438 {
5439 sd->input_panel_enable = enabled;
5440 edje_object_part_text_input_panel_enabled_set
5441 (sd->entry_edje, "elm.text", enabled);
5442 }
5443
5444 EOLIAN static Eina_Bool
_elm_entry_input_panel_enabled_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5445 _elm_entry_input_panel_enabled_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5446 {
5447 return sd->input_panel_enable;
5448 }
5449
5450 EOLIAN static void
_elm_entry_input_panel_show(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5451 _elm_entry_input_panel_show(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5452 {
5453 edje_object_part_text_input_panel_show(sd->entry_edje, "elm.text");
5454 }
5455
5456 EOLIAN static void
_elm_entry_input_panel_hide(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5457 _elm_entry_input_panel_hide(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5458 {
5459
5460 edje_object_part_text_input_panel_hide(sd->entry_edje, "elm.text");
5461 }
5462
5463 EOLIAN static void
_elm_entry_input_panel_language_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Input_Panel_Lang lang)5464 _elm_entry_input_panel_language_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Input_Panel_Lang lang)
5465 {
5466 sd->input_panel_lang = lang;
5467 edje_object_part_text_input_panel_language_set
5468 (sd->entry_edje, "elm.text", (Edje_Input_Panel_Lang)lang);
5469 }
5470
5471 EOLIAN static Elm_Input_Panel_Lang
_elm_entry_input_panel_language_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5472 _elm_entry_input_panel_language_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5473 {
5474 return sd->input_panel_lang;
5475 }
5476
5477 EOLIAN static void
_elm_entry_input_panel_imdata_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,const void * data,int len)5478 _elm_entry_input_panel_imdata_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, const void *data, int len)
5479 {
5480 free(sd->input_panel_imdata);
5481
5482 sd->input_panel_imdata = calloc(1, len);
5483 sd->input_panel_imdata_len = len;
5484 memcpy(sd->input_panel_imdata, data, len);
5485
5486 edje_object_part_text_input_panel_imdata_set
5487 (sd->entry_edje, "elm.text", sd->input_panel_imdata,
5488 sd->input_panel_imdata_len);
5489 }
5490
5491 EOLIAN static void
_elm_entry_input_panel_imdata_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,void * data,int * len)5492 _elm_entry_input_panel_imdata_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, void *data, int *len)
5493 {
5494 edje_object_part_text_input_panel_imdata_get
5495 (sd->entry_edje, "elm.text", data, len);
5496 }
5497
5498 EOLIAN static void
_elm_entry_input_panel_return_key_type_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Elm_Input_Panel_Return_Key_Type return_key_type)5499 _elm_entry_input_panel_return_key_type_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Elm_Input_Panel_Return_Key_Type return_key_type)
5500 {
5501 sd->input_panel_return_key_type = return_key_type;
5502
5503 edje_object_part_text_input_panel_return_key_type_set
5504 (sd->entry_edje, "elm.text", (Edje_Input_Panel_Return_Key_Type)return_key_type);
5505 }
5506
5507 EOLIAN static Elm_Input_Panel_Return_Key_Type
_elm_entry_input_panel_return_key_type_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5508 _elm_entry_input_panel_return_key_type_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5509 {
5510 return sd->input_panel_return_key_type;
5511 }
5512
5513 EOLIAN static void
_elm_entry_input_panel_return_key_disabled_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Eina_Bool disabled)5514 _elm_entry_input_panel_return_key_disabled_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Eina_Bool disabled)
5515 {
5516 sd->input_panel_return_key_disabled = disabled;
5517
5518 edje_object_part_text_input_panel_return_key_disabled_set
5519 (sd->entry_edje, "elm.text", disabled);
5520 }
5521
5522 EOLIAN static Eina_Bool
_elm_entry_input_panel_return_key_disabled_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5523 _elm_entry_input_panel_return_key_disabled_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5524 {
5525 return sd->input_panel_return_key_disabled;
5526 }
5527
5528 EOLIAN static void
_elm_entry_input_panel_return_key_autoenabled_set(Eo * obj,Elm_Entry_Data * sd,Eina_Bool enabled)5529 _elm_entry_input_panel_return_key_autoenabled_set(Eo *obj, Elm_Entry_Data *sd, Eina_Bool enabled)
5530 {
5531 sd->auto_return_key = enabled;
5532 _return_key_enabled_check(obj);
5533 }
5534
5535 EOLIAN static void
_elm_entry_input_panel_show_on_demand_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Eina_Bool ondemand)5536 _elm_entry_input_panel_show_on_demand_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Eina_Bool ondemand)
5537 {
5538 sd->input_panel_show_on_demand = ondemand;
5539
5540 edje_object_part_text_input_panel_show_on_demand_set
5541 (sd->entry_edje, "elm.text", ondemand);
5542 }
5543
5544 EOLIAN static Eina_Bool
_elm_entry_input_panel_show_on_demand_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5545 _elm_entry_input_panel_show_on_demand_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5546 {
5547 return sd->input_panel_show_on_demand;
5548 }
5549
5550 EOLIAN static void*
_elm_entry_imf_context_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5551 _elm_entry_imf_context_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5552 {
5553 if (!sd) return NULL;
5554
5555 return edje_object_part_text_imf_context_get(sd->entry_edje, "elm.text");
5556 }
5557
5558 /* START - ANCHOR HOVER */
5559 static void
_anchor_parent_del_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)5560 _anchor_parent_del_cb(void *data,
5561 Evas *e EINA_UNUSED,
5562 Evas_Object *obj EINA_UNUSED,
5563 void *event_info EINA_UNUSED)
5564 {
5565 ELM_ENTRY_DATA_GET(data, sd);
5566
5567 sd->anchor_hover.hover_parent = NULL;
5568 }
5569
5570 EOLIAN static void
_elm_entry_anchor_hover_parent_set(Eo * obj,Elm_Entry_Data * sd,Evas_Object * parent)5571 _elm_entry_anchor_hover_parent_set(Eo *obj, Elm_Entry_Data *sd, Evas_Object *parent)
5572 {
5573 if (sd->anchor_hover.hover_parent)
5574 evas_object_event_callback_del_full
5575 (sd->anchor_hover.hover_parent, EVAS_CALLBACK_DEL,
5576 _anchor_parent_del_cb, obj);
5577 sd->anchor_hover.hover_parent = parent;
5578 if (sd->anchor_hover.hover_parent)
5579 evas_object_event_callback_add
5580 (sd->anchor_hover.hover_parent, EVAS_CALLBACK_DEL,
5581 _anchor_parent_del_cb, obj);
5582 }
5583
5584 EOLIAN static Evas_Object*
_elm_entry_anchor_hover_parent_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5585 _elm_entry_anchor_hover_parent_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5586 {
5587 return sd->anchor_hover.hover_parent;
5588 }
5589
5590 EOLIAN static void
_elm_entry_anchor_hover_style_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,const char * style)5591 _elm_entry_anchor_hover_style_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, const char *style)
5592 {
5593 eina_stringshare_replace(&sd->anchor_hover.hover_style, style);
5594 }
5595
5596 EOLIAN static const char*
_elm_entry_anchor_hover_style_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5597 _elm_entry_anchor_hover_style_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5598 {
5599 return sd->anchor_hover.hover_style;
5600 }
5601
5602 EOLIAN static void
_elm_entry_anchor_hover_end(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5603 _elm_entry_anchor_hover_end(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5604 {
5605 ELM_SAFE_FREE(sd->anchor_hover.hover, evas_object_del);
5606 ELM_SAFE_FREE(sd->anchor_hover.pop, evas_object_del);
5607 }
5608 /* END - ANCHOR HOVER */
5609
5610 static void
_activate(Evas_Object * obj)5611 _activate(Evas_Object *obj)
5612 {
5613 ELM_ENTRY_DATA_GET(obj, sd);
5614
5615 if (!elm_widget_disabled_get(obj) &&
5616 !evas_object_freeze_events_get(obj))
5617 {
5618 evas_object_smart_callback_call
5619 ( obj, "clicked", NULL);
5620 if (sd->editable && sd->input_panel_enable)
5621 edje_object_part_text_input_panel_show(sd->entry_edje, "elm.text");
5622 }
5623 }
5624
5625 EOLIAN static Eina_Bool
_elm_entry_efl_ui_widget_on_access_activate(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,Efl_Ui_Activate act)5626 _elm_entry_efl_ui_widget_on_access_activate(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, Efl_Ui_Activate act)
5627 {
5628 if (act != EFL_UI_ACTIVATE_DEFAULT) return EINA_FALSE;
5629 _activate(obj);
5630
5631 return EINA_TRUE;
5632 }
5633
5634 EOLIAN static void
_elm_entry_select_allow_set(Eo * obj EINA_UNUSED,Elm_Entry_Data * sd,Eina_Bool allow)5635 _elm_entry_select_allow_set(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd, Eina_Bool allow)
5636 {
5637 if (sd->sel_allow == allow) return;
5638 sd->sel_allow = allow;
5639
5640 edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text", allow);
5641 }
5642
5643 EOLIAN static Eina_Bool
_elm_entry_select_allow_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd)5644 _elm_entry_select_allow_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd)
5645 {
5646 return sd->sel_allow;
5647 }
5648
5649 static void
_elm_entry_class_constructor(Efl_Class * klass)5650 _elm_entry_class_constructor(Efl_Class *klass)
5651 {
5652 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
5653 }
5654
5655 // ATSPI Accessibility
5656
5657 EOLIAN static Eina_Unicode
_elm_entry_efl_access_text_character_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int offset)5658 _elm_entry_efl_access_text_character_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int offset)
5659 {
5660 char *txt;
5661 int idx = 0;
5662 Eina_Unicode ret = 0;
5663 if (offset < 0) return ret;
5664
5665 txt = _elm_util_mkup_to_text(elm_entry_entry_get(obj));
5666 if (!txt) return ret;
5667
5668 ret = eina_unicode_utf8_next_get(txt, &idx);
5669 while (offset--) ret = eina_unicode_utf8_next_get(txt, &idx);
5670
5671 free(txt);
5672
5673 if (_pd->password)
5674 ret = ENTRY_PASSWORD_MASK_CHARACTER;
5675
5676 return ret;
5677 }
5678
5679 EOLIAN static int
_elm_entry_efl_access_text_character_count_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED)5680 _elm_entry_efl_access_text_character_count_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED)
5681 {
5682 char *txt;
5683 int ret = -1;
5684
5685 txt = _elm_util_mkup_to_text(elm_entry_entry_get(obj));
5686 if (!txt) return ret;
5687
5688 ret = eina_unicode_utf8_get_len(txt);
5689 free(txt);
5690
5691 return ret;
5692 }
5693
5694 EOLIAN static void
_elm_entry_efl_access_text_string_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,Efl_Access_Text_Granularity granularity,int * start_offset,int * end_offset,char ** ret EFL_TRANSFER_OWNERSHIP)5695 _elm_entry_efl_access_text_string_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, Efl_Access_Text_Granularity granularity, int *start_offset, int *end_offset, char **ret EFL_TRANSFER_OWNERSHIP)
5696 {
5697 Evas_Textblock_Cursor *cur = NULL, *cur2 = NULL;
5698 Evas_Object *tblk;
5699
5700 EINA_SAFETY_ON_NULL_RETURN(ret);
5701 *ret = NULL;
5702
5703 tblk = elm_entry_textblock_get(obj);
5704 if (!tblk) goto fail;
5705
5706 cur = evas_object_textblock_cursor_new(tblk);
5707 cur2 = evas_object_textblock_cursor_new(tblk);
5708 if (!cur || !cur2) goto fail;
5709
5710 evas_textblock_cursor_pos_set(cur, *start_offset);
5711 if (evas_textblock_cursor_pos_get(cur) != *start_offset) goto fail;
5712
5713 switch (granularity)
5714 {
5715 case EFL_ACCESS_TEXT_GRANULARITY_CHAR:
5716 break;
5717 case EFL_ACCESS_TEXT_GRANULARITY_WORD:
5718 evas_textblock_cursor_word_start(cur);
5719 break;
5720 case EFL_ACCESS_TEXT_GRANULARITY_SENTENCE:
5721 // TODO - add sentence support in textblock first
5722 break;
5723 case EFL_ACCESS_TEXT_GRANULARITY_LINE:
5724 evas_textblock_cursor_line_char_first(cur);
5725 break;
5726 case EFL_ACCESS_TEXT_GRANULARITY_PARAGRAPH:
5727 evas_textblock_cursor_paragraph_char_first(cur);
5728 break;
5729 }
5730
5731 *start_offset = evas_textblock_cursor_pos_get(cur);
5732 evas_textblock_cursor_copy(cur, cur2);
5733
5734 switch (granularity)
5735 {
5736 case EFL_ACCESS_TEXT_GRANULARITY_CHAR:
5737 evas_textblock_cursor_char_next(cur2);
5738 break;
5739 case EFL_ACCESS_TEXT_GRANULARITY_WORD:
5740 evas_textblock_cursor_word_end(cur2);
5741 // since word_end sets cursor position ON (before) last
5742 // char of word, we need to manually advance cursor to get
5743 // proper string from function range_text_get
5744 evas_textblock_cursor_char_next(cur2);
5745 break;
5746 case EFL_ACCESS_TEXT_GRANULARITY_SENTENCE:
5747 // TODO - add sentence support in textblock first
5748 break;
5749 case EFL_ACCESS_TEXT_GRANULARITY_LINE:
5750 evas_textblock_cursor_line_char_last(cur2);
5751 break;
5752 case EFL_ACCESS_TEXT_GRANULARITY_PARAGRAPH:
5753 evas_textblock_cursor_paragraph_char_last(cur2);
5754 break;
5755 }
5756
5757 if (end_offset) *end_offset = evas_textblock_cursor_pos_get(cur2);
5758
5759 *ret = evas_textblock_cursor_range_text_get(cur, cur2, EVAS_TEXTBLOCK_TEXT_PLAIN);
5760
5761 evas_textblock_cursor_free(cur);
5762 evas_textblock_cursor_free(cur2);
5763
5764 if (*ret && _pd->password)
5765 {
5766 int i = 0;
5767 while (*ret[i] != '\0')
5768 *ret[i++] = ENTRY_PASSWORD_MASK_CHARACTER;
5769 }
5770
5771 return;
5772
5773 fail:
5774 if (start_offset) *start_offset = -1;
5775 if (end_offset) *end_offset = -1;
5776 if (cur) evas_textblock_cursor_free(cur);
5777 if (cur2) evas_textblock_cursor_free(cur2);
5778 *ret = NULL;
5779 }
5780
5781 EOLIAN static char*
_elm_entry_efl_access_text_access_text_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int start_offset,int end_offset)5782 _elm_entry_efl_access_text_access_text_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start_offset, int end_offset)
5783 {
5784 Evas_Textblock_Cursor *cur = NULL, *cur2 = NULL;
5785 Evas_Object *tblk;
5786 char *ret = NULL;
5787
5788 tblk = elm_entry_textblock_get(obj);
5789 if (!tblk) goto fail;
5790
5791 cur = evas_object_textblock_cursor_new(tblk);
5792 cur2 = evas_object_textblock_cursor_new(tblk);
5793 if (!cur || !cur2) goto fail;
5794
5795 evas_textblock_cursor_pos_set(cur, start_offset);
5796 if (evas_textblock_cursor_pos_get(cur) != start_offset) goto fail;
5797
5798 evas_textblock_cursor_pos_set(cur2, end_offset);
5799 if (evas_textblock_cursor_pos_get(cur2) != end_offset) goto fail;
5800
5801 ret = evas_textblock_cursor_range_text_get(cur, cur2, EVAS_TEXTBLOCK_TEXT_PLAIN);
5802
5803 evas_textblock_cursor_free(cur);
5804 evas_textblock_cursor_free(cur2);
5805
5806 if (ret && _pd->password)
5807 {
5808 int i = 0;
5809 while (ret[i] != '\0')
5810 ret[i++] = ENTRY_PASSWORD_MASK_CHARACTER;
5811 }
5812
5813 return ret;
5814
5815 fail:
5816 if (cur) evas_textblock_cursor_free(cur);
5817 if (cur2) evas_textblock_cursor_free(cur2);
5818 return NULL;
5819 }
5820
5821 EOLIAN static int
_elm_entry_efl_access_text_caret_offset_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED)5822 _elm_entry_efl_access_text_caret_offset_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED)
5823 {
5824 return elm_entry_cursor_pos_get(obj);
5825 }
5826
5827 EOLIAN static Eina_Bool
_elm_entry_efl_access_text_caret_offset_set(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int offset)5828 _elm_entry_efl_access_text_caret_offset_set(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int offset)
5829 {
5830 elm_entry_cursor_pos_set(obj, offset);
5831 return EINA_TRUE;
5832 }
5833
5834 EOLIAN static int
_elm_entry_efl_access_text_selections_count_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED)5835 _elm_entry_efl_access_text_selections_count_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED)
5836 {
5837 return elm_entry_selection_get(obj) ? 1 : 0;
5838 }
5839
5840 EOLIAN static void
_elm_entry_efl_access_text_access_selection_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int selection_number,int * start_offset,int * end_offset)5841 _elm_entry_efl_access_text_access_selection_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int selection_number, int *start_offset, int *end_offset)
5842 {
5843 if (selection_number != 0) return;
5844
5845 elm_obj_entry_select_region_get(obj, start_offset, end_offset);
5846 }
5847
5848 EOLIAN static Eina_Bool
_elm_entry_efl_access_text_access_selection_set(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int selection_number,int start_offset,int end_offset)5849 _elm_entry_efl_access_text_access_selection_set(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int selection_number, int start_offset, int end_offset)
5850 {
5851 if (selection_number != 0) return EINA_FALSE;
5852
5853 elm_entry_select_region_set(obj, start_offset, end_offset);
5854
5855 return EINA_TRUE;
5856 }
5857
5858 EOLIAN static Eina_Bool
_elm_entry_efl_access_text_selection_remove(Eo * obj,Elm_Entry_Data * pd EINA_UNUSED,int selection_number)5859 _elm_entry_efl_access_text_selection_remove(Eo *obj, Elm_Entry_Data *pd EINA_UNUSED, int selection_number)
5860 {
5861 if (selection_number != 0) return EINA_FALSE;
5862 elm_entry_select_none(obj);
5863 return EINA_TRUE;
5864 }
5865
5866 EOLIAN static Eina_Bool
_elm_entry_efl_access_text_selection_add(Eo * obj,Elm_Entry_Data * pd EINA_UNUSED,int start_offset,int end_offset)5867 _elm_entry_efl_access_text_selection_add(Eo *obj, Elm_Entry_Data *pd EINA_UNUSED, int start_offset, int end_offset)
5868 {
5869 elm_entry_select_region_set(obj, start_offset, end_offset);
5870
5871 return EINA_TRUE;
5872 }
5873
5874 EOLIAN static Eina_List*
_elm_entry_efl_access_text_bounded_ranges_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * _pd EINA_UNUSED,Eina_Bool screen_coods EINA_UNUSED,Eina_Rect rect EINA_UNUSED,Efl_Access_Text_Clip_Type xclip EINA_UNUSED,Efl_Access_Text_Clip_Type yclip EINA_UNUSED)5875 _elm_entry_efl_access_text_bounded_ranges_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *_pd EINA_UNUSED, Eina_Bool screen_coods EINA_UNUSED, Eina_Rect rect EINA_UNUSED, Efl_Access_Text_Clip_Type xclip EINA_UNUSED, Efl_Access_Text_Clip_Type yclip EINA_UNUSED)
5876 {
5877 return NULL;
5878 }
5879
5880 EOLIAN static int
_elm_entry_efl_access_text_offset_at_point_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,Eina_Bool screen_coods,int x,int y)5881 _elm_entry_efl_access_text_offset_at_point_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, Eina_Bool screen_coods, int x, int y)
5882 {
5883 Evas_Object *txtblk;
5884 Evas_Textblock_Cursor *cur;
5885 int ret;
5886
5887 txtblk = elm_entry_textblock_get(obj);
5888 if (!txtblk) return -1;
5889
5890 cur = evas_object_textblock_cursor_new(txtblk);
5891 if (!cur) return -1;
5892
5893 if (screen_coods)
5894 {
5895 int ee_x, ee_y;
5896 Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
5897 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
5898 x -= ee_x;
5899 y -= ee_y;
5900 }
5901
5902 if (!evas_textblock_cursor_char_coord_set(cur, x, y))
5903 {
5904 evas_textblock_cursor_free(cur);
5905 return -1;
5906 }
5907
5908 ret = evas_textblock_cursor_pos_get(cur);
5909 evas_textblock_cursor_free(cur);
5910
5911 return ret;
5912 }
5913
5914 EOLIAN static Eina_Bool
_elm_entry_efl_access_text_character_extents_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int offset,Eina_Bool screen_coods,Eina_Rect * rect)5915 _elm_entry_efl_access_text_character_extents_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int offset, Eina_Bool screen_coods, Eina_Rect *rect)
5916 {
5917 Evas_Object *txtblk;
5918 Evas_Textblock_Cursor *cur;
5919 int ret;
5920
5921 txtblk = elm_entry_textblock_get(obj);
5922 if (!txtblk) return EINA_FALSE;
5923
5924 cur = evas_object_textblock_cursor_new(txtblk);
5925 if (!cur) return EINA_FALSE;
5926
5927 evas_textblock_cursor_pos_set(cur, offset);
5928
5929 ret = evas_textblock_cursor_char_geometry_get(cur, &rect->x, &rect->y, &rect->w, &rect->h);
5930 evas_textblock_cursor_free(cur);
5931
5932 if (ret == -1) return EINA_FALSE;
5933
5934 if (screen_coods)
5935 {
5936 int ee_x, ee_y;
5937 Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
5938 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
5939 rect->x += ee_x;
5940 rect->y += ee_y;
5941 }
5942
5943 return EINA_TRUE;
5944 }
5945
5946 EOLIAN static Eina_Bool
_elm_entry_efl_access_text_range_extents_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,Eina_Bool screen_coods,int start_offset,int end_offset,Eina_Rect * rect)5947 _elm_entry_efl_access_text_range_extents_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, Eina_Bool screen_coods, int start_offset, int end_offset, Eina_Rect *rect)
5948 {
5949 Evas_Object *txtblk;
5950 Evas_Textblock_Cursor *cur1, *cur2;
5951 int ret;
5952 int x, xx, y, yy;
5953
5954 txtblk = elm_entry_textblock_get(obj);
5955 if (!txtblk) return EINA_FALSE;
5956
5957 cur1 = evas_object_textblock_cursor_new(txtblk);
5958 if (!cur1) return EINA_FALSE;
5959
5960 cur2 = evas_object_textblock_cursor_new(txtblk);
5961 if (!cur2)
5962 {
5963 evas_textblock_cursor_free(cur1);
5964 return EINA_FALSE;
5965 }
5966
5967 evas_textblock_cursor_pos_set(cur1, start_offset);
5968 evas_textblock_cursor_pos_set(cur2, end_offset);
5969
5970 ret = evas_textblock_cursor_char_geometry_get(cur1, &x, &y, NULL, NULL);
5971 ret += evas_textblock_cursor_char_geometry_get(cur2, &xx, &yy, NULL, NULL);
5972
5973 evas_textblock_cursor_free(cur1);
5974 evas_textblock_cursor_free(cur2);
5975
5976 if (ret != 0) return EINA_FALSE;
5977
5978 rect->x = x < xx ? x : xx;
5979 rect->y = y < yy ? y : yy;
5980 rect->w = abs(x - xx);
5981 rect->h = abs(y - yy);
5982
5983 if (screen_coods)
5984 {
5985 int ee_x, ee_y;
5986 Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
5987 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
5988 rect->x += ee_x;
5989 rect->y += ee_y;
5990 }
5991
5992 return EINA_TRUE;
5993 }
5994
5995 static Efl_Access_Text_Attribute*
_textblock_node_format_to_atspi_text_attr(const Evas_Object_Textblock_Node_Format * format)5996 _textblock_node_format_to_atspi_text_attr(const Evas_Object_Textblock_Node_Format *format)
5997 {
5998 Efl_Access_Text_Attribute *ret = NULL;
5999 const char *txt;
6000
6001 txt = evas_textblock_node_format_text_get(format);
6002 if (!txt) return NULL;
6003
6004 if (txt[0] == '-') return NULL; // skip closing format
6005
6006 if (!strncmp(txt, "+ ", 2))
6007 {
6008 const char *tmp = &txt[2];
6009
6010 while (*tmp != '\0' && *tmp != '=') tmp++;
6011 if (*tmp++ != '=') return NULL;
6012
6013 ret = calloc(1, sizeof(Efl_Access_Text_Attribute));
6014 if (!ret) return NULL;
6015
6016 ret->value = eina_stringshare_add(tmp);
6017 int size = &txt[2] - tmp + 1;
6018 ret->name = eina_stringshare_add_length(&txt[2], size > 0 ? size : -size);
6019 }
6020
6021 return ret;
6022 }
6023
6024 EOLIAN static Eina_Bool
_elm_entry_efl_access_text_attribute_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,const char * attr_name EINA_UNUSED,int * start_offset,int * end_offset,char ** value)6025 _elm_entry_efl_access_text_attribute_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *attr_name EINA_UNUSED, int *start_offset, int *end_offset, char **value)
6026 {
6027 Evas_Object *txtblk;
6028 Evas_Textblock_Cursor *cur1, *cur2;
6029 Eina_List *formats, *l;
6030 Evas_Object_Textblock_Node_Format *format;
6031 Efl_Access_Text_Attribute *attr;
6032
6033 txtblk = elm_entry_textblock_get(obj);
6034 if (!txtblk) return EINA_FALSE;
6035
6036 cur1 = evas_object_textblock_cursor_new(txtblk);
6037 if (!cur1) return EINA_FALSE;
6038
6039 cur2 = evas_object_textblock_cursor_new(txtblk);
6040 if (!cur2)
6041 {
6042 evas_textblock_cursor_free(cur1);
6043 return EINA_FALSE;
6044 }
6045
6046 evas_textblock_cursor_pos_set(cur1, *start_offset);
6047 evas_textblock_cursor_pos_set(cur2, *end_offset);
6048
6049 formats = evas_textblock_cursor_range_formats_get(cur1, cur2);
6050
6051 evas_textblock_cursor_free(cur1);
6052 evas_textblock_cursor_free(cur2);
6053
6054 if (!formats) return EINA_FALSE;
6055
6056 EINA_LIST_FOREACH(formats, l , format)
6057 {
6058 attr = _textblock_node_format_to_atspi_text_attr(format);
6059 if (!attr) continue;
6060 if (!strcmp(attr->name, attr_name))
6061 {
6062 *value = attr->value ? strdup(attr->value) : NULL;
6063 elm_atspi_text_text_attribute_free(attr);
6064 return EINA_TRUE;
6065 }
6066 elm_atspi_text_text_attribute_free(attr);
6067 }
6068
6069 return EINA_FALSE;
6070 }
6071
6072 EOLIAN static void
_elm_entry_efl_access_text_text_attributes_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int * start_offset,int * end_offset,Eina_List ** ret EFL_TRANSFER_OWNERSHIP)6073 _elm_entry_efl_access_text_text_attributes_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int *start_offset, int *end_offset, Eina_List **ret EFL_TRANSFER_OWNERSHIP)
6074 {
6075 Evas_Object *txtblk;
6076 Evas_Textblock_Cursor *cur1, *cur2;
6077 Eina_List *formats, *l;
6078 Evas_Object_Textblock_Node_Format *format;
6079 Efl_Access_Text_Attribute *attr;
6080
6081 EINA_SAFETY_ON_NULL_RETURN(ret);
6082 *ret = NULL;
6083
6084 txtblk = elm_entry_textblock_get(obj);
6085 if (!txtblk) return;
6086
6087 cur1 = evas_object_textblock_cursor_new(txtblk);
6088 if (!cur1) return;
6089
6090 cur2 = evas_object_textblock_cursor_new(txtblk);
6091 if (!cur2)
6092 {
6093 evas_textblock_cursor_free(cur1);
6094 return;
6095 }
6096
6097 evas_textblock_cursor_pos_set(cur1, *start_offset);
6098 evas_textblock_cursor_pos_set(cur2, *end_offset);
6099
6100 formats = evas_textblock_cursor_range_formats_get(cur1, cur2);
6101
6102 evas_textblock_cursor_free(cur1);
6103 evas_textblock_cursor_free(cur2);
6104
6105 if (!formats) return;
6106
6107 EINA_LIST_FOREACH(formats, l , format)
6108 {
6109 attr = _textblock_node_format_to_atspi_text_attr(format);
6110 if (!attr) continue;
6111 *ret = eina_list_append(*ret, attr);
6112 }
6113 }
6114
6115 EOLIAN static Eina_List*
_elm_entry_efl_access_text_default_attributes_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * _pd EINA_UNUSED)6116 _elm_entry_efl_access_text_default_attributes_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *_pd EINA_UNUSED)
6117 {
6118 Evas_Object *txtblk;
6119 Eina_List *ret = NULL;
6120 const Evas_Object_Textblock_Node_Format *format;
6121 Efl_Access_Text_Attribute *attr;
6122
6123 txtblk = elm_entry_textblock_get(obj);
6124 if (!txtblk) return NULL;
6125
6126 format = evas_textblock_node_format_first_get(txtblk);
6127 if (!format) return NULL;
6128
6129 do
6130 {
6131 attr = _textblock_node_format_to_atspi_text_attr(format);
6132 if (!attr) continue;
6133 ret = eina_list_append(ret, attr);
6134 }
6135 while ((format = evas_textblock_node_format_next_get(format)) != NULL);
6136
6137 return ret;
6138 }
6139
6140 EOLIAN static Eina_Bool
_elm_entry_efl_access_editable_text_text_content_set(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,const char * content)6141 _elm_entry_efl_access_editable_text_text_content_set(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *content)
6142 {
6143 elm_entry_entry_set(obj, content);
6144 return EINA_TRUE;
6145 }
6146
6147 EOLIAN static Eina_Bool
_elm_entry_efl_access_editable_text_insert(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,const char * string,int position)6148 _elm_entry_efl_access_editable_text_insert(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *string, int position)
6149 {
6150 elm_entry_cursor_pos_set(obj, position);
6151 elm_entry_entry_insert(obj, string);
6152
6153 return EINA_TRUE;
6154 }
6155
6156 EOLIAN static Eina_Bool
_elm_entry_efl_access_editable_text_copy(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int start,int end)6157 _elm_entry_efl_access_editable_text_copy(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start, int end)
6158 {
6159 elm_entry_select_region_set(obj, start, end);
6160 elm_entry_selection_copy(obj);
6161
6162 return EINA_TRUE;
6163 }
6164
6165 EOLIAN static Eina_Bool
_elm_entry_efl_access_editable_text_delete(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int start_offset,int end_offset)6166 _elm_entry_efl_access_editable_text_delete(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start_offset, int end_offset)
6167 {
6168 Evas_Object *txtblk;
6169 Evas_Textblock_Cursor *cur1, *cur2;
6170
6171 txtblk = elm_entry_textblock_get(obj);
6172 if (!txtblk) return EINA_FALSE;
6173
6174 cur1 = evas_object_textblock_cursor_new(txtblk);
6175 if (!cur1) return EINA_FALSE;
6176
6177 cur2 = evas_object_textblock_cursor_new(txtblk);
6178 if (!cur2)
6179 {
6180 evas_textblock_cursor_free(cur1);
6181 return EINA_FALSE;
6182 }
6183
6184 evas_textblock_cursor_pos_set(cur1, start_offset);
6185 evas_textblock_cursor_pos_set(cur2, end_offset);
6186
6187 evas_textblock_cursor_range_delete(cur1, cur2);
6188
6189 evas_textblock_cursor_free(cur1);
6190 evas_textblock_cursor_free(cur2);
6191
6192 elm_entry_calc_force(obj);
6193
6194 return EINA_TRUE;
6195 }
6196
6197 EOLIAN static Eina_Bool
_elm_entry_efl_access_editable_text_paste(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int position)6198 _elm_entry_efl_access_editable_text_paste(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int position)
6199 {
6200 elm_entry_cursor_pos_set(obj, position);
6201 elm_entry_selection_paste(obj);
6202 return EINA_TRUE;
6203 }
6204
6205 EOLIAN static Eina_Bool
_elm_entry_efl_access_editable_text_cut(Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED,int start,int end)6206 _elm_entry_efl_access_editable_text_cut(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start, int end)
6207 {
6208 elm_entry_select_region_set(obj, start, end);
6209 elm_entry_selection_cut(obj);
6210 return EINA_TRUE;
6211 }
6212
6213 EOLIAN static Efl_Access_State_Set
_elm_entry_efl_access_object_state_set_get(const Eo * obj,Elm_Entry_Data * _pd EINA_UNUSED)6214 _elm_entry_efl_access_object_state_set_get(const Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED)
6215 {
6216 Efl_Access_State_Set ret;
6217 ret = efl_access_object_state_set_get(efl_super(obj, ELM_ENTRY_CLASS));
6218
6219 if (elm_entry_editable_get(obj))
6220 STATE_TYPE_SET(ret, EFL_ACCESS_STATE_TYPE_EDITABLE);
6221
6222 return ret;
6223 }
6224
6225 EOLIAN static const char*
_elm_entry_efl_access_object_i18n_name_get(const Eo * obj,Elm_Entry_Data * sd)6226 _elm_entry_efl_access_object_i18n_name_get(const Eo *obj, Elm_Entry_Data *sd)
6227 {
6228 const char *name;
6229 name = efl_access_object_i18n_name_get(efl_super(obj, ELM_ENTRY_CLASS));
6230 if (name && strncmp("", name, 1)) return name;
6231
6232 if (sd->password) return NULL;
6233
6234 name = _elm_widget_accessible_plain_name_get(obj, elm_entry_entry_get(obj));
6235 if (name && strncmp("", name, 1)) return name;
6236
6237 const char *ret = edje_object_part_text_get(sd->entry_edje, "elm.guide");
6238 return _elm_widget_accessible_plain_name_get(obj, ret);
6239 }
6240
6241 static Eina_Bool
_action_activate(Evas_Object * obj,const char * params EINA_UNUSED)6242 _action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
6243 {
6244 _activate(obj);
6245 return EINA_TRUE;
6246 }
6247
6248 EOLIAN const Efl_Access_Action_Data *
_elm_entry_efl_access_widget_action_elm_actions_get(const Eo * obj EINA_UNUSED,Elm_Entry_Data * sd EINA_UNUSED)6249 _elm_entry_efl_access_widget_action_elm_actions_get(const Eo *obj EINA_UNUSED, Elm_Entry_Data *sd EINA_UNUSED)
6250 {
6251 static Efl_Access_Action_Data atspi_actions[] = {
6252 { "activate", "activate", NULL, _action_activate },
6253 { NULL, NULL, NULL, NULL}
6254 };
6255 return &atspi_actions[0];
6256 }
6257
6258 EOLIAN static Efl_Ui_Focus_Manager*
_elm_entry_efl_ui_widget_focus_manager_focus_manager_create(Eo * obj,Elm_Entry_Data * pd EINA_UNUSED,Efl_Ui_Focus_Object * root)6259 _elm_entry_efl_ui_widget_focus_manager_focus_manager_create(Eo *obj, Elm_Entry_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root)
6260 {
6261 return efl_add(EFL_UI_FOCUS_MANAGER_CALC_CLASS, obj,
6262 efl_ui_focus_manager_root_set(efl_added, root)
6263 );
6264 }
6265
6266
6267 /* Efl.Part begin */
6268
6269 ELM_PART_OVERRIDE(elm_entry, ELM_ENTRY, Elm_Entry_Data)
6270 ELM_PART_OVERRIDE_CONTENT_SET(elm_entry, ELM_ENTRY, Elm_Entry_Data)
6271 ELM_PART_OVERRIDE_CONTENT_UNSET(elm_entry, ELM_ENTRY, Elm_Entry_Data)
6272 ELM_PART_OVERRIDE_TEXT_SET(elm_entry, ELM_ENTRY, Elm_Entry_Data)
6273 ELM_PART_OVERRIDE_TEXT_GET(elm_entry, ELM_ENTRY, Elm_Entry_Data)
6274 ELM_PART_CONTENT_DEFAULT_GET(elm_entry, "icon")
6275 #include "elm_entry_part.eo.c"
6276
6277 /* Efl.Part end */
6278
6279 /* Internal EO APIs and hidden overrides */
6280
6281 EFL_UI_LAYOUT_CONTENT_ALIASES_IMPLEMENT(MY_CLASS_PFX)
6282 EFL_UI_LAYOUT_TEXT_ALIASES_IMPLEMENT(MY_CLASS_PFX)
6283
6284 #define ELM_ENTRY_EXTRA_OPS \
6285 ELM_PART_CONTENT_DEFAULT_OPS(elm_entry), \
6286 EFL_CANVAS_GROUP_ADD_DEL_OPS(elm_entry), \
6287 EFL_UI_LAYOUT_CONTENT_ALIASES_OPS(MY_CLASS_PFX), \
6288 EFL_UI_LAYOUT_TEXT_ALIASES_OPS(MY_CLASS_PFX), \
6289 EFL_CANVAS_GROUP_CALC_OPS(elm_entry)
6290
6291 #include "elm_entry_eo.c"
6292