remove deprecated function related with
[framework/uifw/elementary.git] / src / lib / elm_entry.c
1 #include <Elementary.h>
2 #include <Elementary_Cursor.h>
3 #include "elm_priv.h"
4 #include "els_scroller.h"
5
6
7 /* Maximum chunk size to be inserted to the entry at once
8  * FIXME: This size is arbitrary, should probably choose a better size.
9  * Possibly also find a way to set it to a low value for weak computers,
10  * and to a big value for better computers. */
11 #define _CHUNK_SIZE 10000
12
13 typedef struct _Mod_Api Mod_Api;
14
15 typedef struct _Widget_Data Widget_Data;
16 typedef struct _Elm_Entry_Context_Menu_Item Elm_Entry_Context_Menu_Item;
17 typedef struct _Elm_Entry_Item_Provider Elm_Entry_Item_Provider;
18 typedef struct _Elm_Entry_Markup_Filter Elm_Entry_Markup_Filter;
19
20 struct _Widget_Data
21 {
22    Evas_Object *ent, *scroller;
23    Evas_Object *hoversel;
24    Ecore_Job *deferred_recalc_job;
25    Ecore_Event_Handler *sel_notify_handler;
26    Ecore_Event_Handler *sel_clear_handler;
27    Ecore_Timer *longpress_timer;
28    Ecore_Timer *delay_write;
29    /* for deferred appending */
30    Ecore_Idler *append_text_idler;
31    char *append_text_left;
32    int append_text_position;
33    int append_text_len;
34    /* Only for clipboard */
35    const char *cut_sel;
36    const char *text;
37    const char *file;
38    Elm_Text_Format format;
39    Evas_Coord lastw, entmw, entmh;
40    Evas_Coord downx, downy;
41    Eina_List *items;
42    Eina_List *item_providers;
43    Eina_List *text_filters;
44    Eina_List *markup_filters;
45    Ecore_Job *hovdeljob;
46    Mod_Api *api; // module api if supplied
47    int cursor_pos;
48    Elm_Scroller_Policy policy_h, policy_v;
49    Elm_Wrap_Type linewrap;
50    Elm_Input_Panel_Layout input_panel_layout;
51    Elm_Autocapital_Type autocapital_type;
52    Elm_Input_Panel_Lang input_panel_lang;
53    Elm_Input_Panel_Return_Key_Type input_panel_return_key_type;
54    void *input_panel_imdata;
55    int input_panel_imdata_len;
56    struct {
57         Evas_Object *hover_parent;
58         Evas_Object *pop, *hover;
59         const char *hover_style;
60    } anchor_hover;
61    Eina_Bool changed : 1;
62    Eina_Bool single_line : 1;
63    Eina_Bool password : 1;
64    Eina_Bool editable : 1;
65    Eina_Bool selection_asked : 1;
66    Eina_Bool have_selection : 1;
67    Eina_Bool selmode : 1;
68    Eina_Bool deferred_cur : 1;
69    Eina_Bool cur_changed : 1;
70    Eina_Bool disabled : 1;
71    Eina_Bool context_menu : 1;
72    Eina_Bool drag_selection_asked : 1;
73    Eina_Bool can_write : 1;
74    Eina_Bool autosave : 1;
75    Eina_Bool usedown : 1;
76    Eina_Bool scroll : 1;
77    Eina_Bool h_bounce : 1;
78    Eina_Bool v_bounce : 1;
79    Eina_Bool input_panel_enable : 1;
80    Eina_Bool prediction_allow : 1;
81    Eina_Bool input_panel_return_key_disabled : 1;
82    Eina_Bool autoreturnkey : 1;
83    Elm_Cnp_Mode cnp_mode : 2;
84 };
85
86 struct _Elm_Entry_Context_Menu_Item
87 {
88    Evas_Object *obj;
89    const char *label;
90    const char *icon_file;
91    const char *icon_group;
92    Elm_Icon_Type icon_type;
93    Evas_Smart_Cb func;
94    void *data;
95 };
96
97 struct _Elm_Entry_Item_Provider
98 {
99    Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item);
100    void *data;
101 };
102
103 struct _Elm_Entry_Markup_Filter
104 {
105    Elm_Entry_Filter_Cb func;
106    void *data;
107 };
108
109 typedef enum _Length_Unit
110 {
111    LENGTH_UNIT_CHAR,
112    LENGTH_UNIT_BYTE,
113    LENGTH_UNIT_LAST
114 } Length_Unit;
115
116 static const char *widtype = NULL;
117
118 #ifdef HAVE_ELEMENTARY_X
119 static Eina_Bool _drag_drop_cb(void *data, Evas_Object *obj, Elm_Selection_Data *);
120 #endif
121 static void _del_hook(Evas_Object *obj);
122 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
123 static void _theme_hook(Evas_Object *obj);
124 static void _disable_hook(Evas_Object *obj);
125 static void _sizing_eval(Evas_Object *obj);
126 static void _on_focus_hook(void *data, Evas_Object *obj);
127 static void _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content);
128 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
129 static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
130 static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
131 static const char *_getbase(Evas_Object *obj);
132 static void _signal_entry_changed(void *data, Evas_Object *obj, const char *emission, const char *source);
133 static void _signal_selection_start(void *data, Evas_Object *obj, const char *emission, const char *source);
134 static void _signal_selection_changed(void *data, Evas_Object *obj, const char *emission, const char *source);
135 static void _signal_selection_cleared(void *data, Evas_Object *obj, const char *emission, const char *source);
136 static void _signal_entry_paste_request(void *data, Evas_Object *obj, const char *emission, const char *source);
137 static void _signal_entry_copy_notify(void *data, Evas_Object *obj, const char *emission, const char *source);
138 static void _signal_entry_cut_notify(void *data, Evas_Object *obj, const char *emission, const char *source);
139 static void _signal_cursor_changed(void *data, Evas_Object *obj, const char *emission, const char *source);
140 static void _add_chars_till_limit(Evas_Object *obj, char **text, int can_add, Length_Unit unit);
141 static void _entry_hover_anchor_clicked(void *data, Evas_Object *obj, void *event_info);
142
143 static const char SIG_CHANGED[] = "changed";
144 static const char SIG_CHANGED_USER[] = "changed,user";
145 static const char SIG_ACTIVATED[] = "activated";
146 static const char SIG_PRESS[] = "press";
147 static const char SIG_LONGPRESSED[] = "longpressed";
148 static const char SIG_CLICKED[] = "clicked";
149 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
150 static const char SIG_CLICKED_TRIPLE[] = "clicked,triple";
151 static const char SIG_FOCUSED[] = "focused";
152 static const char SIG_UNFOCUSED[] = "unfocused";
153 static const char SIG_SELECTION_PASTE[] = "selection,paste";
154 static const char SIG_SELECTION_COPY[] = "selection,copy";
155 static const char SIG_SELECTION_CUT[] = "selection,cut";
156 static const char SIG_SELECTION_START[] = "selection,start";
157 static const char SIG_SELECTION_CHANGED[] = "selection,changed";
158 static const char SIG_SELECTION_CLEARED[] = "selection,cleared";
159 static const char SIG_CURSOR_CHANGED[] = "cursor,changed";
160 static const char SIG_CURSOR_CHANGED_MANUAL[] = "cursor,changed,manual";
161 static const char SIG_ANCHOR_CLICKED[] = "anchor,clicked";
162 static const char SIG_ANCHOR_HOVER_OPENED[] = "anchor,hover,opened";
163 static const char SIG_ANCHOR_DOWN[] = "anchor,down";
164 static const char SIG_ANCHOR_UP[] = "anchor,up";
165 static const char SIG_ANCHOR_IN[] = "anchor,in";
166 static const char SIG_ANCHOR_OUT[] = "anchor,out";
167 static const char SIG_PREEDIT_CHANGED[] = "preedit,changed";
168 static const char SIG_UNDO_REQUEST[] = "undo,request";
169 static const char SIG_REDO_REQUEST[] = "redo,request";
170 static const Evas_Smart_Cb_Description _signals[] = {
171        {SIG_CHANGED, ""},
172        {SIG_ACTIVATED, ""},
173        {SIG_PRESS, ""},
174        {SIG_LONGPRESSED, ""},
175        {SIG_CLICKED, ""},
176        {SIG_CLICKED_DOUBLE, ""},
177        {SIG_CLICKED_TRIPLE, ""},
178        {SIG_FOCUSED, ""},
179        {SIG_UNFOCUSED, ""},
180        {SIG_SELECTION_PASTE, ""},
181        {SIG_SELECTION_COPY, ""},
182        {SIG_SELECTION_CUT, ""},
183        {SIG_SELECTION_START, ""},
184        {SIG_SELECTION_CHANGED, ""},
185        {SIG_SELECTION_CLEARED, ""},
186        {SIG_CURSOR_CHANGED, ""},
187        {SIG_CURSOR_CHANGED_MANUAL, ""},
188        {SIG_ANCHOR_CLICKED, ""},
189        {SIG_ANCHOR_HOVER_OPENED, ""},
190        {SIG_ANCHOR_DOWN, ""},
191        {SIG_ANCHOR_UP, ""},
192        {SIG_ANCHOR_IN, ""},
193        {SIG_ANCHOR_OUT, ""},
194        {SIG_PREEDIT_CHANGED, ""},
195        {SIG_CHANGED_USER, ""},
196        {SIG_UNDO_REQUEST, ""},
197        {SIG_REDO_REQUEST, ""},
198        {NULL, NULL}
199 };
200
201 static Eina_List *entries = NULL;
202
203 struct _Mod_Api
204 {
205    void (*obj_hook) (Evas_Object *obj);
206    void (*obj_unhook) (Evas_Object *obj);
207    void (*obj_longpress) (Evas_Object *obj);
208 };
209
210 static Mod_Api *
211 _module(Evas_Object *obj __UNUSED__)
212 {
213    static Elm_Module *m = NULL;
214    if (m) goto ok; // already found - just use
215    if (!(m = _elm_module_find_as("entry/api"))) return NULL;
216    // get module api
217    m->api = malloc(sizeof(Mod_Api));
218    if (!m->api) return NULL;
219    ((Mod_Api *)(m->api)      )->obj_hook = // called on creation
220       _elm_module_symbol_get(m, "obj_hook");
221    ((Mod_Api *)(m->api)      )->obj_unhook = // called on deletion
222       _elm_module_symbol_get(m, "obj_unhook");
223    ((Mod_Api *)(m->api)      )->obj_longpress = // called on long press menu
224       _elm_module_symbol_get(m, "obj_longpress");
225 ok: // ok - return api
226    return m->api;
227 }
228
229 static char *
230 _buf_append(char *buf, const char *str, int *len, int *alloc)
231 {
232    int len2 = strlen(str);
233    if ((*len + len2) >= *alloc)
234      {
235         char *buf2 = realloc(buf, *alloc + len2 + 512);
236         if (!buf2) return NULL;
237         buf = buf2;
238         *alloc += (512 + len2);
239      }
240    strcpy(buf + *len, str);
241    *len += len2;
242    return buf;
243 }
244
245 static char *
246 _load_file(const char *file)
247 {
248    FILE *f;
249    size_t size;
250    int alloc = 0, len = 0;
251    char *text = NULL, buf[16384 + 1];
252
253    f = fopen(file, "rb");
254    if (!f) return NULL;
255    while ((size = fread(buf, 1, sizeof(buf) - 1, f)))
256      {
257         char *tmp_text;
258         buf[size] = 0;
259         tmp_text = _buf_append(text, buf, &len, &alloc);
260         if (!tmp_text) break;
261         text = tmp_text;
262      }
263    fclose(f);
264    return text;
265 }
266
267 static char *
268 _load_plain(const char *file)
269 {
270    char *text;
271
272    text = _load_file(file);
273    if (text)
274      {
275         char *text2;
276
277         text2 = elm_entry_utf8_to_markup(text);
278         free(text);
279         return text2;
280      }
281    return NULL;
282 }
283
284 static Eina_Bool
285 _load(Evas_Object *obj)
286 {
287    Widget_Data *wd = elm_widget_data_get(obj);
288    char *text;
289    if (!wd) return EINA_FALSE;
290    if (!wd->file)
291      {
292         elm_object_text_set(obj, "");
293         return EINA_TRUE;
294      }
295    switch (wd->format)
296      {
297       case ELM_TEXT_FORMAT_PLAIN_UTF8:
298          text = _load_plain(wd->file);
299          break;
300       case ELM_TEXT_FORMAT_MARKUP_UTF8:
301          text = _load_file(wd->file);
302          break;
303       default:
304          text = NULL;
305          break;
306      }
307    if (text)
308      {
309         elm_object_text_set(obj, text);
310         free(text);
311         return EINA_TRUE;
312      }
313    else
314      {
315         elm_object_text_set(obj, "");
316         return EINA_FALSE;
317      }
318 }
319
320 static void
321 _save_markup_utf8(const char *file, const char *text)
322 {
323    FILE *f;
324
325    if ((!text) || (!text[0]))
326      {
327         ecore_file_unlink(file);
328         return;
329      }
330    f = fopen(file, "wb");
331    if (!f)
332      {
333         // FIXME: report a write error
334         return;
335      }
336    fputs(text, f); // FIXME: catch error
337    fclose(f);
338 }
339
340 static void
341 _save_plain_utf8(const char *file, const char *text)
342 {
343    char *text2;
344
345    text2 = elm_entry_markup_to_utf8(text);
346    if (!text2)
347      return;
348    _save_markup_utf8(file, text2);
349    free(text2);
350 }
351
352 static void
353 _save(Evas_Object *obj)
354 {
355    Widget_Data *wd = elm_widget_data_get(obj);
356    if (!wd) return;
357    if (!wd->file) return;
358    switch (wd->format)
359      {
360       case ELM_TEXT_FORMAT_PLAIN_UTF8:
361          _save_plain_utf8(wd->file, elm_object_text_get(obj));
362          break;
363       case ELM_TEXT_FORMAT_MARKUP_UTF8:
364          _save_markup_utf8(wd->file, elm_object_text_get(obj));
365          break;
366       default:
367          break;
368      }
369 }
370
371 static Eina_Bool
372 _delay_write(void *data)
373 {
374    Widget_Data *wd = elm_widget_data_get(data);
375    if (!wd) return ECORE_CALLBACK_CANCEL;
376    _save(data);
377    wd->delay_write = NULL;
378    return ECORE_CALLBACK_CANCEL;
379 }
380
381 static Elm_Entry_Markup_Filter *
382 _filter_new(Elm_Entry_Filter_Cb func, void *data)
383 {
384    Elm_Entry_Markup_Filter *tf = ELM_NEW(Elm_Entry_Markup_Filter);
385    if (!tf) return NULL;
386
387    tf->func = func;
388    if (func == elm_entry_filter_limit_size)
389      {
390         Elm_Entry_Filter_Limit_Size *lim = data, *lim2;
391
392         if (!data)
393           {
394              free(tf);
395              return NULL;
396           }
397         lim2 = malloc(sizeof(Elm_Entry_Filter_Limit_Size));
398         if (!lim2)
399           {
400              free(tf);
401              return NULL;
402           }
403         memcpy(lim2, lim, sizeof(Elm_Entry_Filter_Limit_Size));
404         tf->data = lim2;
405      }
406    else if (func == elm_entry_filter_accept_set)
407      {
408         Elm_Entry_Filter_Accept_Set *as = data, *as2;
409
410         if (!data)
411           {
412              free(tf);
413              return NULL;
414           }
415         as2 = malloc(sizeof(Elm_Entry_Filter_Accept_Set));
416         if (!as2)
417           {
418              free(tf);
419              return NULL;
420           }
421         if (as->accepted)
422           as2->accepted = eina_stringshare_add(as->accepted);
423         else
424           as2->accepted = NULL;
425         if (as->rejected)
426           as2->rejected = eina_stringshare_add(as->rejected);
427         else
428           as2->rejected = NULL;
429         tf->data = as2;
430      }
431    else
432      tf->data = data;
433    return tf;
434 }
435
436 static void
437 _filter_free(Elm_Entry_Markup_Filter *tf)
438 {
439    if (tf->func == elm_entry_filter_limit_size)
440      {
441         Elm_Entry_Filter_Limit_Size *lim = tf->data;
442         if (lim) free(lim);
443      }
444    else if (tf->func == elm_entry_filter_accept_set)
445      {
446         Elm_Entry_Filter_Accept_Set *as = tf->data;
447         if (as)
448           {
449              if (as->accepted) eina_stringshare_del(as->accepted);
450              if (as->rejected) eina_stringshare_del(as->rejected);
451              free(as);
452           }
453      }
454    free(tf);
455 }
456
457 static void
458 _del_pre_hook(Evas_Object *obj)
459 {
460    Widget_Data *wd = elm_widget_data_get(obj);
461    if (!wd) return;
462    if (wd->delay_write)
463      {
464         ecore_timer_del(wd->delay_write);
465         wd->delay_write = NULL;
466         if (wd->autosave) _save(obj);
467      }
468    elm_entry_anchor_hover_end(obj);
469    elm_entry_anchor_hover_parent_set(obj, NULL);
470 }
471
472 static void
473 _del_hook(Evas_Object *obj)
474 {
475    Widget_Data *wd = elm_widget_data_get(obj);
476    Elm_Entry_Context_Menu_Item *it;
477    Elm_Entry_Item_Provider *ip;
478    Elm_Entry_Markup_Filter *tf;
479
480    evas_event_freeze(evas_object_evas_get(obj));
481
482    if (wd->file) eina_stringshare_del(wd->file);
483
484    if (wd->hovdeljob) ecore_job_del(wd->hovdeljob);
485    if ((wd->api) && (wd->api->obj_unhook)) wd->api->obj_unhook(obj); // module - unhook
486
487    entries = eina_list_remove(entries, obj);
488 #ifdef HAVE_ELEMENTARY_X
489    if (wd->sel_notify_handler)
490      ecore_event_handler_del(wd->sel_notify_handler);
491    if (wd->sel_clear_handler)
492      ecore_event_handler_del(wd->sel_clear_handler);
493 #endif
494    if (wd->cut_sel) eina_stringshare_del(wd->cut_sel);
495    if (wd->text) eina_stringshare_del(wd->text);
496    if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
497    if (wd->append_text_idler)
498      {
499         ecore_idler_del(wd->append_text_idler);
500         free(wd->append_text_left);
501         wd->append_text_left = NULL;
502         wd->append_text_idler = NULL;
503      }
504    if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
505    EINA_LIST_FREE(wd->items, it)
506      {
507         eina_stringshare_del(it->label);
508         eina_stringshare_del(it->icon_file);
509         eina_stringshare_del(it->icon_group);
510         free(it);
511      }
512    EINA_LIST_FREE(wd->item_providers, ip)
513      {
514         free(ip);
515      }
516    EINA_LIST_FREE(wd->text_filters, tf)
517      {
518         _filter_free(tf);
519      }
520    EINA_LIST_FREE(wd->markup_filters, tf)
521      {
522         _filter_free(tf);
523      }
524    if (wd->delay_write) ecore_timer_del(wd->delay_write);
525    if (wd->input_panel_imdata) free(wd->input_panel_imdata);
526    free(wd);
527
528    if (wd->anchor_hover.hover_style) eina_stringshare_del(wd->anchor_hover.hover_style);
529    evas_event_thaw(evas_object_evas_get(obj));
530    evas_event_thaw_eval(evas_object_evas_get(obj));
531 }
532
533 static void
534 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
535 {
536    Widget_Data *wd = elm_widget_data_get(obj);
537    edje_object_mirrored_set(wd->ent, rtl);
538    if (wd->anchor_hover.hover)
539       elm_widget_mirrored_set(wd->anchor_hover.hover, rtl);
540 }
541
542 static void
543 _theme_hook(Evas_Object *obj)
544 {
545    Widget_Data *wd = elm_widget_data_get(obj);
546    const char *t;
547
548    evas_event_freeze(evas_object_evas_get(obj));
549    _elm_widget_mirrored_reload(obj);
550    _mirrored_set(obj, elm_widget_mirrored_get(obj));
551
552    t = eina_stringshare_add(elm_object_text_get(obj));
553    _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
554    if (_elm_config->desktop_entry)
555      edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_TRUE);
556    elm_object_text_set(obj, t);
557    eina_stringshare_del(t);
558    if (elm_widget_disabled_get(obj))
559      edje_object_signal_emit(wd->ent, "elm,state,disabled", "elm");
560    edje_object_part_text_input_panel_layout_set(wd->ent, "elm.text", wd->input_panel_layout);
561    edje_object_part_text_autocapital_type_set(wd->ent, "elm.text", wd->autocapital_type);
562    edje_object_part_text_prediction_allow_set(wd->ent, "elm.text", wd->prediction_allow);
563    edje_object_part_text_input_panel_enabled_set(wd->ent, "elm.text", wd->input_panel_enable);
564    edje_object_part_text_input_panel_imdata_set(wd->ent, "elm.text", wd->input_panel_imdata, wd->input_panel_imdata_len);
565    edje_object_part_text_input_panel_return_key_type_set(wd->ent, "elm.text", wd->input_panel_return_key_type);
566    edje_object_part_text_input_panel_return_key_disabled_set(wd->ent, "elm.text", wd->input_panel_return_key_disabled);
567
568    if (wd->cursor_pos != 0)
569      elm_entry_cursor_pos_set(obj, wd->cursor_pos);
570    if (elm_widget_focus_get(obj))
571      edje_object_signal_emit(wd->ent, "elm,action,focus", "elm");
572    edje_object_message_signal_process(wd->ent);
573    edje_object_scale_set(wd->ent, elm_widget_scale_get(obj) * _elm_config->scale);
574    if (wd->scroll)
575      {
576         const char *str;
577         Evas_Object *edj;
578
579         elm_smart_scroller_mirrored_set(wd->scroller, elm_widget_mirrored_get(obj));
580         elm_smart_scroller_object_theme_set(obj, wd->scroller, "scroller", "entry",
581                                        elm_widget_style_get(obj));
582         edj = elm_smart_scroller_edje_object_get(wd->scroller);
583         str = edje_object_data_get(edj, "focus_highlight");
584         if ((str) && (!strcmp(str, "on")))
585           elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
586         else
587           elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
588      }
589    _sizing_eval(obj);
590    evas_event_thaw(evas_object_evas_get(obj));
591    evas_event_thaw_eval(evas_object_evas_get(obj));
592 }
593
594 static void
595 _disable_hook(Evas_Object *obj)
596 {
597    Widget_Data *wd = elm_widget_data_get(obj);
598
599    if (elm_widget_disabled_get(obj))
600      {
601         edje_object_signal_emit(wd->ent, "elm,state,disabled", "elm");
602         wd->disabled = EINA_TRUE;
603      }
604    else
605      {
606         edje_object_signal_emit(wd->ent, "elm,state,enabled", "elm");
607         wd->disabled = EINA_FALSE;
608      }
609 }
610
611 static void
612 _recalc_cursor_geometry(Evas_Object *obj)
613 {
614    Widget_Data *wd = elm_widget_data_get(obj);
615    if (!wd) return;
616    evas_object_smart_callback_call(obj, SIG_CURSOR_CHANGED, NULL);
617    if (!wd->deferred_recalc_job)
618      {
619         Evas_Coord cx, cy, cw, ch;
620         edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text",
621                                                   &cx, &cy, &cw, &ch);
622         if (wd->cur_changed)
623           {
624              elm_widget_show_region_set(obj, cx, cy, cw, ch, EINA_FALSE);
625              wd->cur_changed = EINA_FALSE;
626           }
627      }
628    else
629      wd->deferred_cur = EINA_TRUE;
630 }
631
632 static void
633 _elm_deferred_recalc_job(void *data)
634 {
635    Widget_Data *wd = elm_widget_data_get(data);
636    Evas_Coord minh = -1, resw = -1, minw = -1, fw = 0, fh = 0;
637    if (!wd) return;
638    wd->deferred_recalc_job = NULL;
639
640    evas_object_geometry_get(wd->ent, NULL, NULL, &resw, NULL);
641    edje_object_size_min_restricted_calc(wd->ent, &minw, &minh, resw, 0);
642    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
643    /* This is a hack to workaround the way min size hints are treated.
644     * If the minimum width is smaller than the restricted width, it means
645     * the mininmum doesn't matter. */
646    if (minw <= resw)
647      {
648         Evas_Coord ominw = -1;
649         evas_object_size_hint_min_get(data, &ominw, NULL);
650         minw = ominw;
651      }
652
653    wd->entmw = minw;
654    wd->entmh = minh;
655
656    elm_coords_finger_size_adjust(1, &fw, 1, &fh);
657    if (wd->scroll)
658      {
659         Evas_Coord vmw = 0, vmh = 0;
660
661         edje_object_size_min_calc
662            (elm_smart_scroller_edje_object_get(wd->scroller),
663                &vmw, &vmh);
664         if (wd->single_line)
665           {
666              evas_object_size_hint_min_set(data, vmw, minh + vmh);
667              evas_object_size_hint_max_set(data, -1, minh + vmh);
668           }
669         else
670           {
671              evas_object_size_hint_min_set(data, vmw, vmh);
672              evas_object_size_hint_max_set(data, -1, -1);
673           }
674      }
675    else
676      {
677         if (wd->single_line)
678           {
679              evas_object_size_hint_min_set(data, minw, minh);
680              evas_object_size_hint_max_set(data, -1, minh);
681           }
682         else
683           {
684              evas_object_size_hint_min_set(data, fw, minh);
685              evas_object_size_hint_max_set(data, -1, -1);
686           }
687      }
688
689    if (wd->deferred_cur)
690      {
691         Evas_Coord cx, cy, cw, ch;
692         edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text",
693                                                   &cx, &cy, &cw, &ch);
694         if (wd->cur_changed)
695           {
696              elm_widget_show_region_set(data, cx, cy, cw, ch, EINA_FALSE);
697              wd->cur_changed = EINA_FALSE;
698           }
699      }
700 }
701
702 static void
703 _sizing_eval(Evas_Object *obj)
704 {
705    Widget_Data *wd = elm_widget_data_get(obj);
706    Evas_Coord minw = -1, minh = -1;
707    Evas_Coord resw, resh;
708    if (!wd) return;
709
710    evas_object_geometry_get(obj, NULL, NULL, &resw, &resh);
711    if (wd->linewrap)
712      {
713         if ((resw == wd->lastw) && (!wd->changed)) return;
714         evas_event_freeze(evas_object_evas_get(obj));
715         wd->changed = EINA_FALSE;
716         wd->lastw = resw;
717         if (wd->scroll)
718           {
719              Evas_Coord vw = 0, vh = 0, vmw = 0, vmh = 0, w = -1, h = -1;
720
721              evas_object_resize(wd->scroller, resw, resh);
722              edje_object_size_min_calc
723                 (elm_smart_scroller_edje_object_get(wd->scroller),
724                  &vmw, &vmh);
725              elm_smart_scroller_child_viewport_size_get(wd->scroller, &vw, &vh);
726              edje_object_size_min_restricted_calc(wd->ent, &minw, &minh, vw, 0);
727              elm_coords_finger_size_adjust(1, &minw, 1, &minh);
728              /* This is a hack to workaround the way min size hints are treated.
729               * If the minimum width is smaller than the restricted width, it means
730               * the mininmum doesn't matter. */
731              if (minw <= vw)
732                {
733                   Evas_Coord ominw = -1;
734                   evas_object_size_hint_min_get(wd->ent, &ominw, NULL);
735                   minw = ominw;
736                }
737              wd->entmw = minw;
738              wd->entmh = minh;
739
740              if ((minw > 0) && (vw < minw)) vw = minw;
741              if (minh > vh) vh = minh;
742
743              if (wd->single_line) h = vmh + minh;
744              else h = vmh;
745              evas_object_resize(wd->ent, vw, vh);
746              evas_object_size_hint_min_set(obj, w, h);
747              if (wd->single_line)
748                evas_object_size_hint_max_set(obj, -1, h);
749              else
750                evas_object_size_hint_max_set(obj, -1, -1);
751           }
752         else
753           {
754              if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
755              wd->deferred_recalc_job = ecore_job_add(_elm_deferred_recalc_job, obj);
756           }
757         evas_event_thaw(evas_object_evas_get(obj));
758         evas_event_thaw_eval(evas_object_evas_get(obj));
759      }
760    else
761      {
762         if (!wd->changed) return;
763         evas_event_freeze(evas_object_evas_get(obj));
764         wd->changed = EINA_FALSE;
765         wd->lastw = resw;
766         if (wd->scroll)
767           {
768              Evas_Coord vw = 0, vh = 0, vmw = 0, vmh = 0, w = -1, h = -1;
769
770              edje_object_size_min_calc(wd->ent, &minw, &minh);
771              wd->entmw = minw;
772              wd->entmh = minh;
773              elm_coords_finger_size_adjust(1, &minw, 1, &minh);
774
775              elm_smart_scroller_child_viewport_size_get(wd->scroller, &vw, &vh);
776
777              if (minw > vw) vw = minw;
778              if (minh > vh) vh = minh;
779
780              evas_object_resize(wd->ent, vw, vh);
781              edje_object_size_min_calc
782                 (elm_smart_scroller_edje_object_get(wd->scroller),
783                  &vmw, &vmh);
784              if (wd->single_line) h = vmh + minh;
785              else h = vmh;
786              evas_object_size_hint_min_set(obj, w, h);
787              if (wd->single_line)
788                evas_object_size_hint_max_set(obj, -1, h);
789              else
790                evas_object_size_hint_max_set(obj, -1, -1);
791           }
792         else
793           {
794              edje_object_size_min_calc(wd->ent, &minw, &minh);
795              wd->entmw = minw;
796              wd->entmh = minh;
797              elm_coords_finger_size_adjust(1, &minw, 1, &minh);
798              evas_object_size_hint_min_set(obj, minw, minh);
799              if (wd->single_line)
800                evas_object_size_hint_max_set(obj, -1, minh);
801              else
802                evas_object_size_hint_max_set(obj, -1, -1);
803           }
804         evas_event_thaw(evas_object_evas_get(obj));
805         evas_event_thaw_eval(evas_object_evas_get(obj));
806      }
807
808    _recalc_cursor_geometry(obj);
809 }
810
811 static void
812 _check_enable_return_key(Evas_Object *obj)
813 {
814    Widget_Data *wd = elm_widget_data_get(obj);
815    Eina_Bool return_key_disabled = EINA_FALSE;
816    if (!wd) return;
817
818    if (!wd->autoreturnkey) return;
819
820    if (elm_entry_is_empty(obj) == EINA_TRUE)
821      return_key_disabled = EINA_TRUE;
822
823    elm_entry_input_panel_return_key_disabled_set(obj, return_key_disabled);
824 }
825
826 static void
827 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
828 {
829    Widget_Data *wd = elm_widget_data_get(obj);
830    Evas_Object *top = elm_widget_top_get(obj);
831    if (!wd) return;
832    if (!wd->editable) return;
833    if (elm_widget_focus_get(obj))
834      {
835         evas_object_focus_set(wd->ent, EINA_TRUE);
836         edje_object_signal_emit(wd->ent, "elm,action,focus", "elm");
837         if (top && wd->input_panel_enable)
838           elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON);
839         evas_object_smart_callback_call(obj, SIG_FOCUSED, NULL);
840         _check_enable_return_key(obj);
841      }
842    else
843      {
844         edje_object_signal_emit(wd->ent, "elm,action,unfocus", "elm");
845         evas_object_focus_set(wd->ent, EINA_FALSE);
846         if (top && wd->input_panel_enable)
847           elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_OFF);
848         evas_object_smart_callback_call(obj, SIG_UNFOCUSED, NULL);
849      }
850 }
851
852 static void
853 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
854 {
855    Widget_Data *wd = elm_widget_data_get(obj);
856    Evas_Object *edje;
857    if ((!wd) || (!content)) return;
858
859    if (wd->scroll)
860       edje = elm_smart_scroller_edje_object_get(wd->scroller);
861    else
862       edje = wd->ent;
863
864    /* Delete the currently swallowed object */
865    Evas_Object *cswallow;
866
867    if (!part || !strcmp(part, "icon"))
868      {
869         cswallow = edje_object_part_swallow_get(edje, "elm.swallow.icon");
870         edje_object_signal_emit(edje, "elm,action,show,icon", "elm");
871      }
872    else if (!strcmp(part, "end"))
873      {
874         cswallow = edje_object_part_swallow_get(edje, "elm.swallow.end");
875         edje_object_signal_emit(edje, "elm,action,show,end", "elm");
876      }
877    else
878      cswallow = edje_object_part_swallow_get(edje, part);
879
880    if (cswallow) evas_object_del(cswallow);
881
882    evas_event_freeze(evas_object_evas_get(obj));
883    elm_widget_sub_object_add(obj, content);
884
885    if (!part || !strcmp(part, "icon"))
886      edje_object_part_swallow(edje, "elm.swallow.icon", content);
887    else if (!strcmp(part, "end"))
888      edje_object_part_swallow(edje, "elm.swallow.end", content);
889    else
890      edje_object_part_swallow(edje, part, content);
891
892    _sizing_eval(obj);
893    evas_event_thaw(evas_object_evas_get(obj));
894    evas_event_thaw_eval(evas_object_evas_get(obj));
895 }
896
897 static Evas_Object *
898 _content_unset_hook(Evas_Object *obj, const char *part)
899 {
900    Widget_Data *wd = elm_widget_data_get(obj);
901    Evas_Object *content, *edje;
902    if (!wd) return NULL;
903
904    if (wd->scroll)
905       edje = elm_smart_scroller_edje_object_get(wd->scroller);
906    else
907       edje = wd->ent;
908
909    if (!part || !strcmp(part, "icon"))
910      {
911         edje_object_signal_emit(edje, "elm,action,hide,icon", "elm");
912         content = edje_object_part_swallow_get(edje, "elm.swallow.icon");
913      }
914    else if (!strcmp(part, "end"))
915      {
916         edje_object_signal_emit(edje, "elm,action,hide,end", "elm");
917         content = edje_object_part_swallow_get(edje, "elm.swallow.end");
918      }
919    else
920      content = edje_object_part_swallow_get(edje, part);
921
922    edje_object_part_swallow(edje, part, NULL);
923    if (!content) return NULL;
924    evas_event_freeze(evas_object_evas_get(obj));
925    elm_widget_sub_object_del(obj, content);
926    edje_object_part_unswallow(wd->ent, content);
927    _sizing_eval(obj);
928    evas_event_thaw(evas_object_evas_get(obj));
929    evas_event_thaw_eval(evas_object_evas_get(obj));
930
931    return content;
932 }
933
934 static Evas_Object *
935 _content_get_hook(const Evas_Object *obj, const char *part)
936 {
937    Widget_Data *wd = elm_widget_data_get(obj);
938    Evas_Object *content = NULL, *edje;
939    if (!wd) return NULL;
940
941    if (wd->scroll)
942       edje = elm_smart_scroller_edje_object_get(wd->scroller);
943    else
944       edje = wd->ent;
945
946    if (!edje) return NULL;
947
948    if (!part || !strcmp(part, "icon"))
949      content = edje_object_part_swallow_get(edje, "elm.swallow.icon");
950    else if (!strcmp(part, "end"))
951      content = edje_object_part_swallow_get(edje, "elm.swallow.end");
952    else
953      content = edje_object_part_swallow_get(edje, part);
954
955    return content;
956 }
957
958 static void
959 _translate_hook(Evas_Object *obj)
960 {
961    evas_object_smart_callback_call(obj, "language,changed", NULL);
962 }
963
964 static void
965 _signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
966 {
967    Widget_Data *wd = elm_widget_data_get(obj);
968    if (!wd) return;
969    edje_object_signal_emit(wd->ent, emission, source);
970    if (wd->scroller)
971      edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scroller),
972                              emission, source);
973 }
974
975 static void
976 _signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)
977 {
978    Widget_Data *wd = elm_widget_data_get(obj);
979    if (!wd) return;
980    edje_object_signal_callback_add(wd->ent, emission, source, func_cb, data);
981    if (wd->scroller)
982      edje_object_signal_callback_add(elm_smart_scroller_edje_object_get(wd->scroller),
983                                      emission, source, func_cb, data);
984 }
985
986 static void
987 _signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)
988 {
989    Widget_Data *wd = elm_widget_data_get(obj);
990    edje_object_signal_callback_del_full(wd->ent, emission, source, func_cb,
991                                         data);
992    if (wd->scroller)
993      edje_object_signal_callback_del_full(elm_smart_scroller_edje_object_get(wd->scroller),
994                                           emission, source, func_cb, data);
995 }
996
997 static void
998 _on_focus_region_hook(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
999 {
1000    Widget_Data *wd = elm_widget_data_get(obj);
1001    edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text", x, y, w, h);
1002 }
1003
1004 static void
1005 _focus_region_hook(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
1006 {
1007    Widget_Data *wd = elm_widget_data_get(obj);
1008    if (wd->scroll)
1009      elm_smart_scroller_child_region_show(wd->scroller, x, y, w, h);
1010 }
1011
1012 static void
1013 _show_region_hook(void *data, Evas_Object *obj)
1014 {
1015    Widget_Data *wd = elm_widget_data_get(data);
1016    Evas_Coord x, y, w, h;
1017    if (!wd) return;
1018    elm_widget_show_region_get(obj, &x, &y, &w, &h);
1019    if (wd->scroll)
1020      elm_smart_scroller_child_region_show(wd->scroller, x, y, w, h);
1021 }
1022
1023 static void
1024 _sub_del(void *data, Evas_Object *obj, void *event_info)
1025 {
1026    Widget_Data *wd = data;
1027    Evas_Object *sub = event_info;
1028    Evas_Object *edje;
1029
1030    if (wd->scroll)
1031       edje = elm_smart_scroller_edje_object_get(wd->scroller);
1032    else
1033       edje = wd->ent;
1034
1035    if (sub == edje_object_part_swallow_get(edje, "elm.swallow.icon"))
1036      {
1037         edje_object_part_unswallow(edje, sub);
1038         if (edje)
1039           edje_object_signal_emit(edje, "elm,action,hide,icon", "elm");
1040      }
1041    else if (sub == edje_object_part_swallow_get(edje, "elm.swallow.end"))
1042      {
1043         edje_object_part_unswallow(edje, sub);
1044         if (edje)
1045           edje_object_signal_emit(edje, "elm,action,hide,end", "elm");
1046      }
1047    _sizing_eval(obj);
1048 }
1049
1050 static void
1051 _hoversel_position(Evas_Object *obj)
1052 {
1053    Widget_Data *wd = elm_widget_data_get(obj);
1054    Evas_Coord cx, cy, cw, ch, x, y, mw, mh;
1055    if (!wd) return;
1056
1057    cx = cy = 0;
1058    cw = ch = 1;
1059    evas_object_geometry_get(wd->ent, &x, &y, NULL, NULL);
1060    if (wd->usedown)
1061      {
1062         cx = wd->downx - x;
1063         cy = wd->downy - y;
1064         cw = 1;
1065         ch = 1;
1066      }
1067    else
1068      edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text",
1069                                                &cx, &cy, &cw, &ch);
1070    evas_object_size_hint_min_get(wd->hoversel, &mw, &mh);
1071    if (cw < mw)
1072      {
1073         cx += (cw - mw) / 2;
1074         cw = mw;
1075      }
1076    if (ch < mh)
1077      {
1078         cy += (ch - mh) / 2;
1079         ch = mh;
1080      }
1081    evas_object_move(wd->hoversel, x + cx, y + cy);
1082    evas_object_resize(wd->hoversel, cw, ch);
1083 }
1084
1085 static void
1086 _move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1087 {
1088    Widget_Data *wd = elm_widget_data_get(data);
1089
1090    if (wd->hoversel) _hoversel_position(data);
1091 }
1092
1093 static void
1094 _resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1095 {
1096    Widget_Data *wd = elm_widget_data_get(data);
1097    if (!wd) return;
1098
1099    if (wd->linewrap)
1100      {
1101         _sizing_eval(data);
1102      }
1103    else if (wd->scroll)
1104      {
1105         Evas_Coord vw = 0, vh = 0;
1106
1107         elm_smart_scroller_child_viewport_size_get(wd->scroller, &vw, &vh);
1108         if (vw < wd->entmw) vw = wd->entmw;
1109         if (vh < wd->entmh) vh = wd->entmh;
1110         evas_object_resize(wd->ent, vw, vh);
1111      }
1112    if (wd->hoversel) _hoversel_position(data);
1113 }
1114
1115 static void
1116 _hover_del(void *data)
1117 {
1118    Widget_Data *wd = elm_widget_data_get(data);
1119    if (!wd) return;
1120
1121    if (wd->hoversel)
1122      {
1123         evas_object_del(wd->hoversel);
1124         wd->hoversel = NULL;
1125      }
1126    wd->hovdeljob = NULL;
1127 }
1128
1129 static void
1130 _dismissed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1131 {
1132    Widget_Data *wd = elm_widget_data_get(data);
1133    if (!wd) return;
1134    wd->usedown = 0;
1135    if (wd->hoversel) evas_object_hide(wd->hoversel);
1136    if (wd->selmode)
1137      {
1138         if (!_elm_config->desktop_entry)
1139           {
1140              if (!wd->password)
1141                edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_TRUE);
1142           }
1143      }
1144    elm_widget_scroll_freeze_pop(data);
1145    if (wd->hovdeljob) ecore_job_del(wd->hovdeljob);
1146    wd->hovdeljob = ecore_job_add(_hover_del, data);
1147 }
1148
1149 static void
1150 _select(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1151 {
1152    Widget_Data *wd = elm_widget_data_get(data);
1153    if (!wd) return;
1154    wd->selmode = EINA_TRUE;
1155    edje_object_part_text_select_none(wd->ent, "elm.text");
1156    if (!_elm_config->desktop_entry)
1157      {
1158         if (!wd->password)
1159           edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_TRUE);
1160      }
1161    edje_object_signal_emit(wd->ent, "elm,state,select,on", "elm");
1162    if (!_elm_config->desktop_entry)
1163      elm_widget_scroll_hold_push(data);
1164 }
1165
1166 static char *
1167 _remove_item_tags(const char *str)
1168 {
1169    char *ret;
1170    if (!str)
1171      return NULL;
1172
1173    Eina_Strbuf *buf = eina_strbuf_new();
1174    if (!buf)
1175      return NULL;
1176
1177    if (!eina_strbuf_append(buf, str))
1178      return NULL;
1179
1180    while (EINA_TRUE)
1181      {
1182         const char *temp = eina_strbuf_string_get(buf);
1183         
1184         char *startTag = NULL;
1185         char *endTag = NULL;
1186
1187         startTag = strstr(temp, "<item");
1188         if (!startTag)
1189           startTag = strstr(temp, "</item");
1190         if (startTag)
1191           endTag = strstr(startTag, ">");
1192         else
1193           break;
1194         if (!endTag || startTag > endTag)
1195           break;
1196
1197         size_t sindex = startTag - temp;
1198         size_t eindex = endTag - temp + 1;
1199         if (!eina_strbuf_remove(buf, sindex, eindex))
1200           break;
1201      }
1202    ret = eina_strbuf_string_steal(buf);
1203    eina_strbuf_free(buf);
1204    return ret;
1205 }
1206
1207 void
1208 _elm_entry_entry_paste(Evas_Object *obj, const char *entry)
1209 {
1210    Widget_Data *wd = elm_widget_data_get(obj);
1211    char *str = NULL;
1212    
1213    if (wd->cnp_mode == ELM_CNP_MODE_NO_IMAGE)
1214      {
1215         str = _remove_item_tags(entry);
1216         if (!str) str = strdup(entry);
1217      }
1218    else
1219      str = strdup(entry);
1220    if (!str) str = (char *)entry;
1221
1222    edje_object_part_text_user_insert(wd->ent, "elm.text", str);
1223    if (str != entry) free(str);
1224 }
1225
1226 static void
1227 _paste(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1228 {
1229    Widget_Data *wd = elm_widget_data_get(data);
1230    if (!wd) return;
1231    evas_object_smart_callback_call(data, SIG_SELECTION_PASTE, NULL);
1232    if (wd->sel_notify_handler)
1233      {
1234 #ifdef HAVE_ELEMENTARY_X
1235         Elm_Sel_Format formats = ELM_SEL_FORMAT_MARKUP;
1236         wd->selection_asked = EINA_TRUE;
1237         if (wd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
1238           formats = ELM_SEL_FORMAT_TEXT;
1239         else if (wd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
1240           formats |= ELM_SEL_FORMAT_IMAGE;
1241         elm_cnp_selection_get(data, ELM_SEL_TYPE_CLIPBOARD, formats, NULL, NULL);
1242 #endif
1243      }
1244 }
1245
1246 static void
1247 _store_selection(Elm_Sel_Type seltype, Evas_Object *obj)
1248 {
1249    Widget_Data *wd = elm_widget_data_get(obj);
1250    const char *sel;
1251
1252    if (!wd) return;
1253    sel = edje_object_part_text_selection_get(wd->ent, "elm.text");
1254    if ((!sel) || (!sel[0])) return; /* avoid deleting our own selection */
1255    elm_cnp_selection_set(obj, seltype, ELM_SEL_FORMAT_MARKUP, sel, strlen(sel));
1256    if (seltype == ELM_SEL_TYPE_CLIPBOARD)
1257      eina_stringshare_replace(&wd->cut_sel, sel);
1258 }
1259
1260 static void
1261 _cut(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1262 {
1263    Widget_Data *wd = elm_widget_data_get(data);
1264
1265    /* Store it */
1266    wd->selmode = EINA_FALSE;
1267    if (!_elm_config->desktop_entry)
1268      edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
1269    edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
1270    if (!_elm_config->desktop_entry)
1271      elm_widget_scroll_hold_pop(data);
1272    _store_selection(ELM_SEL_TYPE_CLIPBOARD, data);
1273    edje_object_part_text_user_insert(wd->ent, "elm.text", "");
1274    _sizing_eval(data);
1275 }
1276
1277 static void
1278 _copy(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1279 {
1280    Widget_Data *wd = elm_widget_data_get(data);
1281    if (!wd) return;
1282    wd->selmode = EINA_FALSE;
1283    if (!_elm_config->desktop_entry)
1284      {
1285         edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
1286         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
1287         elm_widget_scroll_hold_pop(data);
1288      }
1289    _store_selection(ELM_SEL_TYPE_CLIPBOARD, data);
1290    //   edje_object_part_text_select_none(wd->ent, "elm.text");
1291 }
1292
1293 static void
1294 _cancel(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1295 {
1296    Widget_Data *wd = elm_widget_data_get(data);
1297    if (!wd) return;
1298    wd->selmode = EINA_FALSE;
1299    if (!_elm_config->desktop_entry)
1300      edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
1301    edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
1302    if (!_elm_config->desktop_entry)
1303      elm_widget_scroll_hold_pop(data);
1304    edje_object_part_text_select_none(wd->ent, "elm.text");
1305 }
1306
1307 static void
1308 _item_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1309 {
1310    Elm_Entry_Context_Menu_Item *it = data;
1311    Evas_Object *obj2 = it->obj;
1312    if (it->func) it->func(it->data, obj2, NULL);
1313 }
1314
1315 static void
1316 _menu_press(Evas_Object *obj)
1317 {
1318    Widget_Data *wd = elm_widget_data_get(obj);
1319    Evas_Object *top;
1320    const Eina_List *l;
1321    const Elm_Entry_Context_Menu_Item *it;
1322    if (!wd) return;
1323    if ((wd->api) && (wd->api->obj_longpress))
1324      {
1325         wd->api->obj_longpress(obj);
1326      }
1327    else if (wd->context_menu)
1328      {
1329         const char *context_menu_orientation;
1330
1331         if (wd->hoversel) evas_object_del(wd->hoversel);
1332         else elm_widget_scroll_freeze_push(obj);
1333         wd->hoversel = elm_hoversel_add(obj);
1334         context_menu_orientation = edje_object_data_get
1335            (wd->ent, "context_menu_orientation");
1336         if ((context_menu_orientation) &&
1337             (!strcmp(context_menu_orientation, "horizontal")))
1338           elm_hoversel_horizontal_set(wd->hoversel, EINA_TRUE);
1339         elm_object_style_set(wd->hoversel, "entry");
1340         elm_widget_sub_object_add(obj, wd->hoversel);
1341         elm_object_text_set(wd->hoversel, "Text");
1342         top = elm_widget_top_get(obj);
1343         if (top) elm_hoversel_hover_parent_set(wd->hoversel, top);
1344         evas_object_smart_callback_add(wd->hoversel, "dismissed", _dismissed, obj);
1345         if (wd->have_selection)
1346           {
1347              if (!wd->password)
1348                {
1349                   if (wd->have_selection)
1350                     {
1351                        elm_hoversel_item_add(wd->hoversel, E_("Copy"), NULL, ELM_ICON_NONE,
1352                                              _copy, obj);
1353                        if (wd->editable)
1354                          elm_hoversel_item_add(wd->hoversel, E_("Cut"), NULL, ELM_ICON_NONE,
1355                                                _cut, obj);
1356                     }
1357                   elm_hoversel_item_add(wd->hoversel, E_("Cancel"), NULL, ELM_ICON_NONE,
1358                                         _cancel, obj);
1359                }
1360           }
1361         else
1362           {
1363              if (!wd->selmode)
1364                {
1365                   if (!_elm_config->desktop_entry)
1366                     {
1367                        if (!wd->password)
1368                          elm_hoversel_item_add(wd->hoversel, E_("Select"), NULL, ELM_ICON_NONE,
1369                                                _select, obj);
1370                     }
1371                   if (elm_selection_selection_has_owner())
1372                     {
1373                        if (wd->editable)
1374                          elm_hoversel_item_add(wd->hoversel, E_("Paste"), NULL, ELM_ICON_NONE,
1375                                                _paste, obj);
1376                     }
1377                }
1378           }
1379         EINA_LIST_FOREACH(wd->items, l, it)
1380           {
1381              elm_hoversel_item_add(wd->hoversel, it->label, it->icon_file,
1382                                    it->icon_type, _item_clicked, it);
1383           }
1384         if (wd->hoversel)
1385           {
1386              _hoversel_position(obj);
1387              evas_object_show(wd->hoversel);
1388              elm_hoversel_hover_begin(wd->hoversel);
1389           }
1390         if (!_elm_config->desktop_entry)
1391           {
1392              edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
1393              edje_object_part_text_select_abort(wd->ent, "elm.text");
1394           }
1395      }
1396 }
1397
1398 static Eina_Bool
1399 _long_press(void *data)
1400 {
1401    Widget_Data *wd = elm_widget_data_get(data);
1402    if (!wd) return ECORE_CALLBACK_CANCEL;
1403    _menu_press(data);
1404    wd->longpress_timer = NULL;
1405    evas_object_smart_callback_call(data, SIG_LONGPRESSED, NULL);
1406    return ECORE_CALLBACK_CANCEL;
1407 }
1408
1409 static void
1410 _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1411 {
1412    Widget_Data *wd = elm_widget_data_get(data);
1413    Evas_Event_Mouse_Down *ev = event_info;
1414    if (!wd) return;
1415    if (wd->disabled) return;
1416    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1417    wd->downx = ev->canvas.x;
1418    wd->downy = ev->canvas.y;
1419    if (ev->button == 1)
1420      {
1421         if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
1422         wd->longpress_timer = ecore_timer_add(_elm_config->longpress_timeout, _long_press, data);
1423      }
1424 }
1425
1426 static void
1427 _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1428 {
1429    Widget_Data *wd = elm_widget_data_get(data);
1430    Evas_Event_Mouse_Up *ev = event_info;
1431    if (!wd) return;
1432    if (wd->disabled) return;
1433    if (ev->button == 1)
1434      {
1435         if (wd->longpress_timer)
1436           {
1437              ecore_timer_del(wd->longpress_timer);
1438              wd->longpress_timer = NULL;
1439           }
1440      }
1441    else if (ev->button == 3)
1442      {
1443         wd->usedown = 1;
1444         _menu_press(data);
1445      }
1446 }
1447
1448 static void
1449 _mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1450 {
1451    Widget_Data *wd = elm_widget_data_get(data);
1452    Evas_Event_Mouse_Move *ev = event_info;
1453    if (!wd) return;
1454    if (wd->disabled) return;
1455    if (!wd->selmode)
1456      {
1457         if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1458           {
1459              if (wd->longpress_timer)
1460                {
1461                   ecore_timer_del(wd->longpress_timer);
1462                   wd->longpress_timer = NULL;
1463                }
1464           }
1465         else if (wd->longpress_timer)
1466           {
1467              Evas_Coord dx, dy;
1468
1469              dx = wd->downx - ev->cur.canvas.x;
1470              dx *= dx;
1471              dy = wd->downy - ev->cur.canvas.y;
1472              dy *= dy;
1473              if ((dx + dy) >
1474                  ((_elm_config->finger_size / 2) *
1475                   (_elm_config->finger_size / 2)))
1476                {
1477                   ecore_timer_del(wd->longpress_timer);
1478                   wd->longpress_timer = NULL;
1479                }
1480           }
1481      }
1482    else if (wd->longpress_timer)
1483      {
1484         Evas_Coord dx, dy;
1485
1486         dx = wd->downx - ev->cur.canvas.x;
1487         dx *= dx;
1488         dy = wd->downy - ev->cur.canvas.y;
1489         dy *= dy;
1490         if ((dx + dy) >
1491             ((_elm_config->finger_size / 2) *
1492              (_elm_config->finger_size / 2)))
1493           {
1494              ecore_timer_del(wd->longpress_timer);
1495              wd->longpress_timer = NULL;
1496           }
1497      }
1498 }
1499
1500 static const char *
1501 _getbase(Evas_Object *obj)
1502 {
1503    Widget_Data *wd = elm_widget_data_get(obj);
1504    if (!wd) return "base";
1505    if (wd->editable)
1506      {
1507         if (wd->password) return "base-password";
1508         else
1509           {
1510              if (wd->single_line) return "base-single";
1511              else
1512                {
1513                   switch (wd->linewrap)
1514                     {
1515                      case ELM_WRAP_CHAR:
1516                         return "base-charwrap";
1517                      case ELM_WRAP_WORD:
1518                         return "base";
1519                      case ELM_WRAP_MIXED:
1520                         return "base-mixedwrap";
1521                      case ELM_WRAP_NONE:
1522                      default:
1523                         return "base-nowrap";
1524                     }
1525                }
1526           }
1527      }
1528    else
1529      {
1530         if (wd->password) return "base-password";
1531         else
1532           {
1533              if (wd->single_line) return "base-single-noedit";
1534              else
1535                {
1536                   switch (wd->linewrap)
1537                     {
1538                      case ELM_WRAP_CHAR:
1539                         return "base-noedit-charwrap";
1540                      case ELM_WRAP_WORD:
1541                         return "base-noedit";
1542                      case ELM_WRAP_MIXED:
1543                         return "base-noedit-mixedwrap";
1544                      case ELM_WRAP_NONE:
1545                      default:
1546                         return "base-nowrap-noedit";
1547                     }
1548                }
1549           }
1550      }
1551 }
1552
1553 static void
1554 _entry_changed_common_handling(void *data, const char *event)
1555 {
1556    Widget_Data *wd = elm_widget_data_get(data);
1557    Evas_Coord minh;
1558    if (!wd) return;
1559    evas_event_freeze(evas_object_evas_get(data));
1560    wd->changed = EINA_TRUE;
1561    /* Reset the size hints which are no more relevant.
1562     * Keep the height, this is a hack, but doesn't really matter
1563     * cause we'll re-eval in a moment. */
1564    evas_object_size_hint_min_get(data, NULL, &minh);
1565    evas_object_size_hint_min_set(data, -1, minh);
1566    _sizing_eval(data);
1567    if (wd->text) eina_stringshare_del(wd->text);
1568    wd->text = NULL;
1569    if (wd->delay_write)
1570      {
1571         ecore_timer_del(wd->delay_write);
1572         wd->delay_write = NULL;
1573      }
1574    evas_event_thaw(evas_object_evas_get(data));
1575    evas_event_thaw_eval(evas_object_evas_get(data));
1576    if ((wd->autosave) && (wd->file))
1577      wd->delay_write = ecore_timer_add(2.0, _delay_write, data);
1578    /* callback - this could call callbacks that delete the entry... thus...
1579     * any access to wd after this could be invalid */
1580    evas_object_smart_callback_call(data, event, NULL);
1581    _check_enable_return_key(data);
1582 }
1583
1584 static void
1585 _signal_entry_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1586 {
1587    _entry_changed_common_handling(data, SIG_CHANGED);
1588 }
1589
1590 static void
1591 _signal_entry_changed_user(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1592 {
1593    Elm_Entry_Change_Info info;
1594    Edje_Entry_Change_Info *edje_info = (Edje_Entry_Change_Info *)
1595       edje_object_signal_callback_extra_data_get();
1596    if (edje_info)
1597      {
1598         memcpy(&info, edje_info, sizeof(info));
1599         evas_object_smart_callback_call(data, SIG_CHANGED_USER, &info);
1600      }
1601    else
1602      {
1603         evas_object_smart_callback_call(data, SIG_CHANGED_USER, NULL);
1604      }
1605 }
1606
1607 static void
1608 _signal_preedit_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1609 {
1610    _entry_changed_common_handling(data, SIG_PREEDIT_CHANGED);
1611 }
1612
1613 static void
1614 _signal_undo_request(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1615 {
1616    evas_object_smart_callback_call(data, SIG_UNDO_REQUEST, NULL);
1617 }
1618
1619 static void
1620 _signal_redo_request(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1621 {
1622    evas_object_smart_callback_call(data, SIG_REDO_REQUEST, NULL);
1623 }
1624
1625 static void
1626 _signal_selection_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1627 {
1628    Widget_Data *wd = elm_widget_data_get(data);
1629    const Eina_List *l;
1630    Evas_Object *entry;
1631    if (!wd) return;
1632    EINA_LIST_FOREACH(entries, l, entry)
1633      {
1634         if (entry != data) elm_entry_select_none(entry);
1635      }
1636    wd->have_selection = EINA_TRUE;
1637    evas_object_smart_callback_call(data, SIG_SELECTION_START, NULL);
1638 #ifdef HAVE_ELEMENTARY_X
1639    if (wd->sel_notify_handler)
1640      {
1641         const char *txt = elm_entry_selection_get(data);
1642         Evas_Object *top;
1643
1644         top = elm_widget_top_get(data);
1645         if (txt && top && (elm_win_xwindow_get(top)))
1646           elm_cnp_selection_set(data, ELM_SEL_TYPE_PRIMARY,
1647                                 ELM_SEL_FORMAT_MARKUP, txt, strlen(txt));
1648      }
1649 #endif
1650 }
1651
1652 static void
1653 _signal_selection_all(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1654 {
1655    Widget_Data *wd = elm_widget_data_get(data);
1656    if (!wd) return;
1657    elm_entry_select_all(data);
1658 }
1659
1660 static void
1661 _signal_selection_none(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1662 {
1663    Widget_Data *wd = elm_widget_data_get(data);
1664    if (!wd) return;
1665    elm_entry_select_none(data);
1666 }
1667
1668 static void
1669 _signal_selection_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1670 {
1671    Widget_Data *wd = elm_widget_data_get(data);
1672    if (!wd) return;
1673    wd->have_selection = EINA_TRUE;
1674    evas_object_smart_callback_call(data, SIG_SELECTION_CHANGED, NULL);
1675    _store_selection(ELM_SEL_TYPE_PRIMARY, data);
1676 }
1677
1678 static void
1679 _signal_selection_cleared(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1680 {
1681    Widget_Data *wd = elm_widget_data_get(data);
1682    if (!wd) return;
1683    if (!wd->have_selection) return;
1684    wd->have_selection = EINA_FALSE;
1685    evas_object_smart_callback_call(data, SIG_SELECTION_CLEARED, NULL);
1686    if (wd->sel_notify_handler)
1687      {
1688         if (wd->cut_sel)
1689           {
1690 #ifdef HAVE_ELEMENTARY_X
1691              Evas_Object *top;
1692
1693              top = elm_widget_top_get(data);
1694              if ((top) && (elm_win_xwindow_get(top)))
1695                elm_cnp_selection_set(data, ELM_SEL_TYPE_PRIMARY,
1696                                      ELM_SEL_FORMAT_MARKUP, wd->cut_sel,
1697                                      strlen(wd->cut_sel));
1698 #endif
1699              eina_stringshare_del(wd->cut_sel);
1700              wd->cut_sel = NULL;
1701           }
1702         else
1703           {
1704 #ifdef HAVE_ELEMENTARY_X
1705              Evas_Object *top;
1706
1707              top = elm_widget_top_get(data);
1708              if ((top) && (elm_win_xwindow_get(top)))
1709                elm_object_cnp_selection_clear(data, ELM_SEL_TYPE_PRIMARY);
1710 #endif
1711           }
1712      }
1713 }
1714
1715 static void
1716 _signal_entry_paste_request(void *data, Evas_Object *obj __UNUSED__, const char *emission, const char *source __UNUSED__)
1717 {
1718    Widget_Data *wd = elm_widget_data_get(data);
1719    Elm_Sel_Type type = (emission[sizeof("ntry,paste,request,")] == '1') ?
1720      ELM_SEL_TYPE_PRIMARY : ELM_SEL_TYPE_CLIPBOARD;
1721    if (!wd) return;
1722    if (!wd->editable) return;
1723    evas_object_smart_callback_call(data, SIG_SELECTION_PASTE, NULL);
1724    if (wd->sel_notify_handler)
1725      {
1726 #ifdef HAVE_ELEMENTARY_X
1727         Evas_Object *top;
1728
1729         top = elm_widget_top_get(data);
1730         if ((top) && (elm_win_xwindow_get(top)))
1731           {
1732              wd->selection_asked = EINA_TRUE;
1733              Elm_Sel_Format formats = ELM_SEL_FORMAT_MARKUP;
1734              if (wd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
1735                formats = ELM_SEL_FORMAT_TEXT;
1736              else if (wd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
1737                formats |= ELM_SEL_FORMAT_IMAGE;
1738              elm_cnp_selection_get(data, type, formats,
1739                                    NULL, NULL);
1740           }
1741 #endif
1742      }
1743 }
1744
1745 static void
1746 _signal_entry_copy_notify(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1747 {
1748    evas_object_smart_callback_call(data, SIG_SELECTION_COPY, NULL);
1749    _copy(data, NULL, NULL);
1750 }
1751
1752 static void
1753 _signal_entry_cut_notify(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1754 {
1755    evas_object_smart_callback_call(data, SIG_SELECTION_CUT, NULL);
1756    _cut(data, NULL, NULL);
1757 }
1758
1759 static void
1760 _signal_cursor_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1761 {
1762    Widget_Data *wd = elm_widget_data_get(data);
1763    if (!wd) return;
1764    wd->cursor_pos = edje_object_part_text_cursor_pos_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
1765    wd->cur_changed = EINA_TRUE;
1766    _recalc_cursor_geometry(data);
1767 }
1768
1769 static void
1770 _signal_cursor_changed_manual(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1771 {
1772    evas_object_smart_callback_call(data, SIG_CURSOR_CHANGED_MANUAL, NULL);
1773 }
1774
1775
1776 static void
1777 _signal_anchor_geoms_do_things_with(Widget_Data *wd, Elm_Entry_Anchor_Info *ei)
1778 {
1779    const Eina_List *geoms, *l;
1780    Evas_Textblock_Rectangle *r;
1781    Evas_Coord px, py, x, y;
1782
1783    geoms = edje_object_part_text_anchor_geometry_get(wd->ent, "elm.text", ei->name);
1784    if (!geoms) return;
1785
1786
1787    evas_object_geometry_get(wd->ent, &x, &y, NULL, NULL);
1788    evas_pointer_canvas_xy_get(evas_object_evas_get(wd->ent), &px, &py);
1789    EINA_LIST_FOREACH(geoms, l, r)
1790      {
1791         if (((r->x + x) <= px) && ((r->y + y) <= py) &&
1792             ((r->x + x + r->w) > px) && ((r->y + y + r->h) > py))
1793           {
1794              ei->x = r->x + x;
1795              ei->y = r->y + y;
1796              ei->w = r->w;
1797              ei->h = r->h;
1798              break;
1799           }
1800      }
1801 }
1802
1803 static void
1804 _signal_anchor_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1805 {
1806    Widget_Data *wd = elm_widget_data_get(data);
1807    Elm_Entry_Anchor_Info ei;
1808    const char *p;
1809    char *p2;
1810    if (!wd) return;
1811    p = emission + sizeof("nchor,mouse,down,");
1812    ei.button = strtol(p, &p2, 10);
1813    ei.name = p2 + 1;
1814    ei.x = ei.y = ei.w = ei.h = 0;
1815
1816    _signal_anchor_geoms_do_things_with(wd, &ei);
1817
1818    if (!wd->disabled)
1819      evas_object_smart_callback_call(data, SIG_ANCHOR_DOWN, &ei);
1820 }
1821
1822 static void
1823 _signal_anchor_up(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1824 {
1825    Widget_Data *wd = elm_widget_data_get(data);
1826    Elm_Entry_Anchor_Info ei;
1827    const char *p;
1828    char *p2;
1829    if (!wd) return;
1830    p = emission + sizeof("nchor,mouse,up,");
1831    ei.button = strtol(p, &p2, 10);
1832    ei.name = p2 + 1;
1833    ei.x = ei.y = ei.w = ei.h = 0;
1834
1835    _signal_anchor_geoms_do_things_with(wd, &ei);
1836
1837    if (!wd->disabled)
1838      evas_object_smart_callback_call(data, SIG_ANCHOR_UP, &ei);
1839 }
1840
1841 static void
1842 _signal_anchor_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission, const char *source __UNUSED__)
1843 {
1844    Widget_Data *wd = elm_widget_data_get(data);
1845    Elm_Entry_Anchor_Info ei;
1846    const char *p;
1847    char *p2;
1848    if (!wd) return;
1849    p = emission + sizeof("nchor,mouse,clicked,");
1850    ei.button = strtol(p, &p2, 10);
1851    ei.name = p2 + 1;
1852    ei.x = ei.y = ei.w = ei.h = 0;
1853
1854    _signal_anchor_geoms_do_things_with(wd, &ei);
1855
1856    if (!wd->disabled)
1857      {
1858         evas_object_smart_callback_call(data, SIG_ANCHOR_CLICKED, &ei);
1859
1860         _entry_hover_anchor_clicked(data, data, &ei);
1861      }
1862 }
1863
1864 static void
1865 _signal_anchor_move(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1866 {
1867    Widget_Data *wd = elm_widget_data_get(data);
1868    if (!wd) return;
1869 }
1870
1871 static void
1872 _signal_anchor_in(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1873 {
1874    Widget_Data *wd = elm_widget_data_get(data);
1875    Elm_Entry_Anchor_Info ei;
1876    if (!wd) return;
1877    ei.name = emission + sizeof("nchor,mouse,in,");
1878    ei.button = 0;
1879    ei.x = ei.y = ei.w = ei.h = 0;
1880
1881    _signal_anchor_geoms_do_things_with(wd, &ei);
1882
1883    if (!wd->disabled)
1884      evas_object_smart_callback_call(data, SIG_ANCHOR_IN, &ei);
1885 }
1886
1887 static void
1888 _signal_anchor_out(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1889 {
1890    Widget_Data *wd = elm_widget_data_get(data);
1891    Elm_Entry_Anchor_Info ei;
1892    if (!wd) return;
1893    ei.name = emission + sizeof("nchor,mouse,out,");
1894    ei.button = 0;
1895    ei.x = ei.y = ei.w = ei.h = 0;
1896
1897    _signal_anchor_geoms_do_things_with(wd, &ei);
1898
1899    if (!wd->disabled)
1900      evas_object_smart_callback_call(data, SIG_ANCHOR_OUT, &ei);
1901 }
1902
1903 static void
1904 _signal_key_enter(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1905 {
1906    Widget_Data *wd = elm_widget_data_get(data);
1907    if (!wd) return;
1908    evas_object_smart_callback_call(data, SIG_ACTIVATED, NULL);
1909 }
1910
1911 static void
1912 _signal_mouse_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1913 {
1914    Widget_Data *wd = elm_widget_data_get(data);
1915    if (!wd) return;
1916    evas_object_smart_callback_call(data, SIG_PRESS, NULL);
1917 }
1918
1919 static void
1920 _signal_mouse_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1921 {
1922    Widget_Data *wd = elm_widget_data_get(data);
1923    if (!wd) return;
1924    evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
1925 }
1926
1927 static void
1928 _signal_mouse_double(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1929 {
1930    Widget_Data *wd = elm_widget_data_get(data);
1931    if (!wd) return;
1932    evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
1933 }
1934
1935 static void
1936 _signal_mouse_triple(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1937 {
1938    Widget_Data *wd = elm_widget_data_get(data);
1939    if (!wd) return;
1940    evas_object_smart_callback_call(data, SIG_CLICKED_TRIPLE, NULL);
1941 }
1942
1943 #ifdef HAVE_ELEMENTARY_X
1944 static Eina_Bool
1945 _event_selection_notify(void *data, int type __UNUSED__, void *event)
1946 {
1947    Widget_Data *wd = elm_widget_data_get(data);
1948    Ecore_X_Event_Selection_Notify *ev = event;
1949    if (!wd) return ECORE_CALLBACK_PASS_ON;
1950    if ((!wd->selection_asked) && (!wd->drag_selection_asked))
1951      return ECORE_CALLBACK_PASS_ON;
1952
1953    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
1954        (ev->selection == ECORE_X_SELECTION_PRIMARY))
1955      {
1956         Ecore_X_Selection_Data_Text *text_data;
1957
1958         text_data = ev->data;
1959         if (text_data->data.content == ECORE_X_SELECTION_CONTENT_TEXT)
1960           {
1961              if (text_data->text)
1962                {
1963                   char *txt = _elm_util_text_to_mkup(text_data->text);
1964
1965                   if (txt)
1966                     {
1967                        elm_entry_entry_insert(data, txt);
1968                        free(txt);
1969                     }
1970                }
1971           }
1972         wd->selection_asked = EINA_FALSE;
1973      }
1974    else if (ev->selection == ECORE_X_SELECTION_XDND)
1975      {
1976         Ecore_X_Selection_Data_Text *text_data;
1977
1978         text_data = ev->data;
1979         if (text_data->data.content == ECORE_X_SELECTION_CONTENT_TEXT)
1980           {
1981              if (text_data->text)
1982                {
1983                   char *txt = _elm_util_text_to_mkup(text_data->text);
1984
1985                   if (txt)
1986                     {
1987                        /* Massive FIXME: this should be at the drag point */
1988                        elm_entry_entry_insert(data, txt);
1989                        free(txt);
1990                     }
1991                }
1992           }
1993         wd->drag_selection_asked = EINA_FALSE;
1994
1995         ecore_x_dnd_send_finished();
1996
1997      }
1998    return ECORE_CALLBACK_PASS_ON;
1999 }
2000
2001 static Eina_Bool
2002 _event_selection_clear(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
2003 {
2004    Widget_Data *wd = elm_widget_data_get(data);
2005    Ecore_X_Event_Selection_Clear *ev = event;
2006    if (!wd) return ECORE_CALLBACK_PASS_ON;
2007    if (!wd->have_selection) return ECORE_CALLBACK_PASS_ON;
2008    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
2009        (ev->selection == ECORE_X_SELECTION_PRIMARY))
2010      {
2011         elm_entry_select_none(data);
2012      }
2013    return ECORE_CALLBACK_PASS_ON;
2014 }
2015
2016 static Eina_Bool
2017 _drag_drop_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Selection_Data *drop)
2018 {
2019    Widget_Data *wd;
2020    Eina_Bool rv;
2021
2022    wd = elm_widget_data_get(obj);
2023    if (!wd) return EINA_FALSE;
2024    printf("Inserting at (%d,%d) %s\n",drop->x,drop->y,(char*)drop->data);
2025
2026    edje_object_part_text_cursor_copy(wd->ent, "elm.text",
2027                                      EDJE_CURSOR_MAIN,/*->*/EDJE_CURSOR_USER);
2028    rv = edje_object_part_text_cursor_coord_set(wd->ent,"elm.text",
2029                                                EDJE_CURSOR_MAIN,drop->x,drop->y);
2030    if (!rv) printf("Warning: Failed to position cursor: paste anyway\n");
2031    elm_entry_entry_insert(obj, drop->data);
2032    edje_object_part_text_cursor_copy(wd->ent, "elm.text",
2033                                      EDJE_CURSOR_USER,/*->*/EDJE_CURSOR_MAIN);
2034
2035    return EINA_TRUE;
2036 }
2037 #endif
2038
2039 static Evas_Object *
2040 _get_item(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, const char *item)
2041 {
2042    Widget_Data *wd = elm_widget_data_get(data);
2043    Evas_Object *o;
2044    Eina_List *l;
2045    Elm_Entry_Item_Provider *ip;
2046
2047    EINA_LIST_FOREACH(wd->item_providers, l, ip)
2048      {
2049         o = ip->func(ip->data, data, item);
2050         if (o) return o;
2051      }
2052    if (!strncmp(item, "file://", 7))
2053      {
2054         const char *fname = item + 7;
2055
2056         o = evas_object_image_filled_add(evas_object_evas_get(data));
2057         evas_object_image_file_set(o, fname, NULL);
2058         if (evas_object_image_load_error_get(o) == EVAS_LOAD_ERROR_NONE)
2059           {
2060              evas_object_show(o);
2061           }
2062         else
2063           {
2064              evas_object_del(o);
2065              o = edje_object_add(evas_object_evas_get(data));
2066              _elm_theme_object_set(data, o, "entry/emoticon", "wtf", elm_widget_style_get(data));
2067           }
2068         return o;
2069      }
2070    o = edje_object_add(evas_object_evas_get(data));
2071    if (!_elm_theme_object_set(data, o, "entry", item, elm_widget_style_get(data)))
2072      _elm_theme_object_set(data, o, "entry/emoticon", "wtf", elm_widget_style_get(data));
2073    return o;
2074 }
2075
2076 static void
2077 _text_filter(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, Edje_Text_Filter_Type type, char **text)
2078 {
2079    Widget_Data *wd = elm_widget_data_get(data);
2080    Eina_List *l;
2081    Elm_Entry_Markup_Filter *tf;
2082
2083    if (type == EDJE_TEXT_FILTER_FORMAT)
2084      return;
2085
2086    EINA_LIST_FOREACH(wd->text_filters, l, tf)
2087      {
2088         tf->func(tf->data, data, text);
2089         if (!*text)
2090           break;
2091      }
2092 }
2093
2094 static void
2095 _markup_filter(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, char **text)
2096 {
2097    Widget_Data *wd = elm_widget_data_get(data);
2098    Eina_List *l;
2099    Elm_Entry_Markup_Filter *tf;
2100
2101    EINA_LIST_FOREACH(wd->markup_filters, l, tf)
2102      {
2103         tf->func(tf->data, data, text);
2104         if (!*text)
2105           break;
2106      }
2107 }
2108
2109 /* This function is used to insert text by chunks in jobs */
2110 static Eina_Bool
2111 _text_append_idler(void *data)
2112 {
2113    int start;
2114    char backup;
2115    Evas_Object *obj = (Evas_Object *) data;
2116    Widget_Data *wd = elm_widget_data_get(obj);
2117    evas_event_freeze(evas_object_evas_get(obj));
2118    if (wd->text) eina_stringshare_del(wd->text);
2119    wd->text = NULL;
2120    wd->changed = EINA_TRUE;
2121
2122    start = wd->append_text_position;
2123    if (start + _CHUNK_SIZE < wd->append_text_len)
2124      {
2125         int pos = start;
2126         int tag_start, esc_start;
2127
2128         tag_start = esc_start = -1;
2129         /* Find proper markup cut place */
2130         while (pos - start < _CHUNK_SIZE)
2131           {
2132              int prev_pos = pos;
2133              Eina_Unicode tmp =
2134                 eina_unicode_utf8_get_next(wd->append_text_left, &pos);
2135              if (esc_start == -1)
2136                {
2137                   if (tmp == '<')
2138                      tag_start = prev_pos;
2139                   else if (tmp == '>')
2140                      tag_start = -1;
2141                }
2142              if (tag_start == -1)
2143                {
2144                   if (tmp == '&')
2145                      esc_start = prev_pos;
2146                   else if (tmp == ';')
2147                      esc_start = -1;
2148                }
2149           }
2150
2151         if (tag_start >= 0)
2152           {
2153              wd->append_text_position = tag_start;
2154           }
2155         else if (esc_start >= 0)
2156           {
2157              wd->append_text_position = esc_start;
2158           }
2159         else
2160           {
2161              wd->append_text_position = pos;
2162           }
2163      }
2164    else
2165      {
2166         wd->append_text_position = wd->append_text_len;
2167      }
2168
2169    backup = wd->append_text_left[wd->append_text_position];
2170    wd->append_text_left[wd->append_text_position] = '\0';
2171
2172    edje_object_part_text_append(wd->ent, "elm.text",
2173                                 wd->append_text_left + start);
2174
2175    wd->append_text_left[wd->append_text_position] = backup;
2176
2177    evas_event_thaw(evas_object_evas_get(obj));
2178    evas_event_thaw_eval(evas_object_evas_get(obj));
2179
2180    /* If there's still more to go, renew the idler, else, cleanup */
2181    if (wd->append_text_position < wd->append_text_len)
2182      {
2183         return ECORE_CALLBACK_RENEW;
2184      }
2185    else
2186      {
2187         free(wd->append_text_left);
2188         wd->append_text_left = NULL;
2189         wd->append_text_idler = NULL;
2190         return ECORE_CALLBACK_CANCEL;
2191      }
2192 }
2193
2194 static void
2195 _add_chars_till_limit(Evas_Object *obj, char **text, int can_add, Length_Unit unit)
2196 {
2197    int i = 0, current_len = 0;
2198    char *new_text;
2199
2200    if (!*text) return;
2201    if (unit >= LENGTH_UNIT_LAST) return;
2202    new_text = *text;
2203    current_len = strlen(*text);
2204    while (*new_text)
2205      {
2206         int idx = 0, unit_size = 0;
2207         char *markup, *utfstr;
2208         if (*new_text == '<')
2209           {
2210              while (*(new_text + idx) != '>')
2211                {
2212                   idx++;
2213                   if (!*(new_text + idx)) break;
2214                }
2215           }
2216         else if (*new_text == '&')
2217           {
2218              while (*(new_text + idx) != ';')
2219                {
2220                   idx++;
2221                   if (!*(new_text + idx)) break;
2222                }
2223           }
2224         idx = evas_string_char_next_get(new_text, idx, NULL);
2225         markup = malloc(idx + 1);
2226         if (markup)
2227           {
2228              strncpy(markup, new_text, idx);
2229              markup[idx] = 0;
2230              utfstr = elm_entry_markup_to_utf8(markup);
2231              if (utfstr)
2232                {
2233                   if (unit == LENGTH_UNIT_BYTE)
2234                     unit_size = strlen(utfstr);
2235                   else if (unit == LENGTH_UNIT_CHAR)
2236                     unit_size = evas_string_char_len_get(utfstr);
2237                   free(utfstr);
2238                   utfstr = NULL;
2239                }
2240              free(markup);
2241              markup = NULL;
2242           }
2243         if (can_add < unit_size)
2244           {
2245              if (!i)
2246                {
2247                   evas_object_smart_callback_call(obj, "maxlength,reached", NULL);
2248                   free(*text);
2249                   *text = NULL;
2250                   return;
2251                }
2252              can_add = 0;
2253              strncpy(new_text, new_text + idx, current_len - ((new_text + idx) - *text));
2254              current_len -= idx;
2255              (*text)[current_len] = 0;
2256           }
2257         else
2258           {
2259              new_text += idx;
2260              can_add -= unit_size;
2261           }
2262         i++;
2263      }
2264    evas_object_smart_callback_call(obj, "maxlength,reached", NULL);
2265 }
2266
2267 static void
2268 _elm_entry_text_set(Evas_Object *obj, const char *item, const char *entry)
2269 {
2270    int len = 0;
2271    ELM_CHECK_WIDTYPE(obj, widtype);
2272    Widget_Data *wd = elm_widget_data_get(obj);
2273    if (!wd) return;
2274    evas_event_freeze(evas_object_evas_get(obj));
2275    if (!entry) entry = "";
2276    if (item && strcmp(item, "default"))
2277      {
2278         edje_object_part_text_set(wd->ent, item, entry);
2279         return;
2280      }
2281
2282    if (wd->text) eina_stringshare_del(wd->text);
2283    wd->text = NULL;
2284    wd->changed = EINA_TRUE;
2285
2286    /* Clear currently pending job if there is one */
2287    if (wd->append_text_idler)
2288      {
2289         ecore_idler_del(wd->append_text_idler);
2290         free(wd->append_text_left);
2291         wd->append_text_left = NULL;
2292         wd->append_text_idler = NULL;
2293      }
2294
2295    len = strlen(entry);
2296    /* Split to ~_CHUNK_SIZE chunks */
2297    if (len > _CHUNK_SIZE)
2298      {
2299         wd->append_text_left = (char *) malloc(len + 1);
2300      }
2301
2302    /* If we decided to use the idler */
2303    if (wd->append_text_left)
2304      {
2305         /* Need to clear the entry first */
2306         edje_object_part_text_set(wd->ent, "elm.text", "");
2307         memcpy(wd->append_text_left, entry, len + 1);
2308         wd->append_text_position = 0;
2309         wd->append_text_len = len;
2310         wd->append_text_idler = ecore_idler_add(_text_append_idler, obj);
2311      }
2312    else
2313      {
2314         edje_object_part_text_set(wd->ent, "elm.text", entry);
2315      }
2316    evas_event_thaw(evas_object_evas_get(obj));
2317    evas_event_thaw_eval(evas_object_evas_get(obj));
2318 }
2319
2320 static const char *
2321 _elm_entry_text_get(const Evas_Object *obj, const char *item)
2322 {
2323    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2324    Widget_Data *wd = elm_widget_data_get(obj);
2325    if (item && strcmp(item, "default")) return NULL;
2326    const char *text;
2327    if (!wd) return NULL;
2328    if (wd->text) return wd->text;
2329    text = edje_object_part_text_get(wd->ent, "elm.text");
2330    if (!text)
2331      {
2332         ERR("text=NULL for edje %p, part 'elm.text'", wd->ent);
2333         return NULL;
2334      }
2335
2336    if (wd->append_text_len > 0)
2337      {
2338         char *tmpbuf;
2339         size_t tlen;
2340         tlen = strlen(text);
2341         tmpbuf = malloc(tlen + wd->append_text_len + 1);
2342         if (!tmpbuf)
2343           {
2344              ERR("Failed to allocate memory for entry's text %p", obj);
2345              return NULL;
2346           }
2347         memcpy(tmpbuf, text, tlen);
2348         memcpy(tmpbuf + tlen, wd->append_text_left, wd->append_text_len);
2349         tmpbuf[tlen + wd->append_text_len] = '\0';
2350         eina_stringshare_replace(&wd->text, tmpbuf);
2351         free(tmpbuf);
2352      }
2353    else
2354      {
2355         eina_stringshare_replace(&wd->text, text);
2356      }
2357    return wd->text;
2358 }
2359
2360 EAPI Evas_Object *
2361 elm_entry_add(Evas_Object *parent)
2362 {
2363    Evas_Object *obj, *top;
2364    Evas *e;
2365    Widget_Data *wd;
2366
2367    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
2368
2369    ELM_SET_WIDTYPE(widtype, "entry");
2370    elm_widget_type_set(obj, "entry");
2371    elm_widget_sub_object_add(parent, obj);
2372    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
2373    elm_widget_data_set(obj, wd);
2374    elm_widget_del_hook_set(obj, _del_hook);
2375    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
2376    elm_widget_theme_hook_set(obj, _theme_hook);
2377    elm_widget_disable_hook_set(obj, _disable_hook);
2378    elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
2379    elm_widget_focus_region_hook_set(obj, _focus_region_hook);
2380    elm_widget_on_focus_region_hook_set(obj, _on_focus_region_hook);
2381    elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
2382    elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
2383    elm_object_cursor_set(obj, ELM_CURSOR_XTERM);
2384    elm_widget_can_focus_set(obj, EINA_TRUE);
2385    elm_widget_highlight_ignore_set(obj, EINA_TRUE);
2386    elm_widget_text_set_hook_set(obj, _elm_entry_text_set);
2387    elm_widget_text_get_hook_set(obj, _elm_entry_text_get);
2388    elm_widget_content_set_hook_set(obj, _content_set_hook);
2389    elm_widget_content_unset_hook_set(obj, _content_unset_hook);
2390    elm_widget_content_get_hook_set(obj, _content_get_hook);
2391    elm_widget_translate_hook_set(obj, _translate_hook);
2392
2393    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, wd);
2394
2395    wd->linewrap     = ELM_WRAP_WORD;
2396    wd->editable     = EINA_TRUE;
2397    wd->disabled     = EINA_FALSE;
2398    wd->context_menu = EINA_TRUE;
2399    wd->autosave     = EINA_TRUE;
2400    wd->cnp_mode     = ELM_CNP_MODE_MARKUP;
2401    wd->scroll       = EINA_FALSE;
2402    wd->input_panel_imdata = NULL;
2403
2404    wd->ent = edje_object_add(e);
2405    edje_object_item_provider_set(wd->ent, _get_item, obj);
2406    edje_object_text_insert_filter_callback_add(wd->ent,"elm.text", _text_filter, obj);
2407    edje_object_text_markup_filter_callback_add(wd->ent,"elm.text", _markup_filter, obj);
2408    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOVE, _move, obj);
2409    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_DOWN,
2410                                   _mouse_down, obj);
2411    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_UP,
2412                                   _mouse_up, obj);
2413    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_MOVE,
2414                                   _mouse_move, obj);
2415    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
2416
2417    _elm_theme_object_set(obj, wd->ent, "entry", "base", "default");
2418    edje_object_signal_callback_add(wd->ent, "entry,changed", "elm.text",
2419                                    _signal_entry_changed, obj);
2420    edje_object_signal_callback_add(wd->ent, "entry,changed,user", "elm.text",
2421                                    _signal_entry_changed_user, obj);
2422    edje_object_signal_callback_add(wd->ent, "preedit,changed", "elm.text",
2423                                    _signal_preedit_changed, obj);
2424    edje_object_signal_callback_add(wd->ent, "selection,start", "elm.text",
2425                                    _signal_selection_start, obj);
2426    edje_object_signal_callback_add(wd->ent, "selection,changed", "elm.text",
2427                                    _signal_selection_changed, obj);
2428    edje_object_signal_callback_add(wd->ent, "entry,selection,all,request", "elm.text",
2429                                    _signal_selection_all, obj);
2430    edje_object_signal_callback_add(wd->ent, "entry,selection,none,request", "elm.text",
2431                                    _signal_selection_none, obj);
2432    edje_object_signal_callback_add(wd->ent, "selection,cleared", "elm.text",
2433                                    _signal_selection_cleared, obj);
2434    edje_object_signal_callback_add(wd->ent, "entry,paste,request,*", "elm.text",
2435                                    _signal_entry_paste_request, obj);
2436    edje_object_signal_callback_add(wd->ent, "entry,copy,notify", "elm.text",
2437                                    _signal_entry_copy_notify, obj);
2438    edje_object_signal_callback_add(wd->ent, "entry,cut,notify", "elm.text",
2439                                    _signal_entry_cut_notify, obj);
2440    edje_object_signal_callback_add(wd->ent, "cursor,changed", "elm.text",
2441                                    _signal_cursor_changed, obj);
2442    edje_object_signal_callback_add(wd->ent, "cursor,changed,manual", "elm.text",
2443                                    _signal_cursor_changed_manual, obj);
2444    edje_object_signal_callback_add(wd->ent, "anchor,mouse,down,*", "elm.text",
2445                                    _signal_anchor_down, obj);
2446    edje_object_signal_callback_add(wd->ent, "anchor,mouse,up,*", "elm.text",
2447                                    _signal_anchor_up, obj);
2448    edje_object_signal_callback_add(wd->ent, "anchor,mouse,clicked,*", "elm.text",
2449                                    _signal_anchor_clicked, obj);
2450    edje_object_signal_callback_add(wd->ent, "anchor,mouse,move,*", "elm.text",
2451                                    _signal_anchor_move, obj);
2452    edje_object_signal_callback_add(wd->ent, "anchor,mouse,in,*", "elm.text",
2453                                    _signal_anchor_in, obj);
2454    edje_object_signal_callback_add(wd->ent, "anchor,mouse,out,*", "elm.text",
2455                                    _signal_anchor_out, obj);
2456    edje_object_signal_callback_add(wd->ent, "entry,key,enter", "elm.text",
2457                                    _signal_key_enter, obj);
2458    edje_object_signal_callback_add(wd->ent, "mouse,down,1", "elm.text",
2459                                    _signal_mouse_down, obj);
2460    edje_object_signal_callback_add(wd->ent, "mouse,clicked,1", "elm.text",
2461                                    _signal_mouse_clicked, obj);
2462    edje_object_signal_callback_add(wd->ent, "mouse,down,1,double", "elm.text",
2463                                    _signal_mouse_double, obj);
2464    edje_object_signal_callback_add(wd->ent, "mouse,down,1,triple", "elm.text",
2465                                    _signal_mouse_triple, obj);
2466    edje_object_signal_callback_add(wd->ent, "entry,undo,request", "elm.text",
2467                                    _signal_undo_request, obj);
2468    edje_object_signal_callback_add(wd->ent, "entry,redo,request", "elm.text",
2469                                    _signal_redo_request, obj);
2470    edje_object_part_text_set(wd->ent, "elm.text", "");
2471    if (_elm_config->desktop_entry)
2472      edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_TRUE);
2473    elm_widget_resize_object_set(obj, wd->ent);
2474    _sizing_eval(obj);
2475
2476    elm_entry_input_panel_layout_set(obj, ELM_INPUT_PANEL_LAYOUT_NORMAL);
2477    elm_entry_input_panel_enabled_set(obj, EINA_TRUE);
2478    elm_entry_prediction_allow_set(obj, EINA_TRUE);
2479
2480    wd->autocapital_type = edje_object_part_text_autocapital_type_get(wd->ent, "elm.text");
2481
2482 #ifdef HAVE_ELEMENTARY_X
2483    top = elm_widget_top_get(obj);
2484    if ((top) && (elm_win_xwindow_get(top)))
2485      {
2486         wd->sel_notify_handler =
2487            ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY,
2488                                    _event_selection_notify, obj);
2489         wd->sel_clear_handler =
2490            ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR,
2491                                    _event_selection_clear, obj);
2492      }
2493
2494    elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE,
2495                        _drag_drop_cb, NULL);
2496 #endif
2497
2498    entries = eina_list_prepend(entries, obj);
2499
2500    // module - find module for entry
2501    wd->api = _module(obj);
2502    // if found - hook in
2503    if ((wd->api) && (wd->api->obj_hook)) wd->api->obj_hook(obj);
2504
2505    _mirrored_set(obj, elm_widget_mirrored_get(obj));
2506    // TODO: convert Elementary to subclassing of Evas_Smart_Class
2507    // TODO: and save some bytes, making descriptions per-class and not instance!
2508    evas_object_smart_callbacks_descriptions_set(obj, _signals);
2509    return obj;
2510 }
2511
2512 EAPI void
2513 elm_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
2514 {
2515    ELM_CHECK_WIDTYPE(obj, widtype);
2516    Widget_Data *wd = elm_widget_data_get(obj);
2517    if (!wd) return;
2518    if (wd->single_line == single_line) return;
2519    wd->single_line = single_line;
2520    wd->linewrap = ELM_WRAP_NONE;
2521    elm_entry_cnp_mode_set(obj, ELM_CNP_MODE_NO_IMAGE);
2522    _theme_hook(obj);
2523    if (wd->scroller)
2524      {
2525         if (wd->single_line)
2526           elm_smart_scroller_policy_set(wd->scroller,
2527                                         ELM_SMART_SCROLLER_POLICY_OFF,
2528                                         ELM_SMART_SCROLLER_POLICY_OFF);
2529         else
2530           {
2531              const Elm_Scroller_Policy map[3] =
2532                {
2533                   ELM_SMART_SCROLLER_POLICY_AUTO,
2534                   ELM_SMART_SCROLLER_POLICY_ON,
2535                   ELM_SMART_SCROLLER_POLICY_OFF
2536                };
2537              elm_smart_scroller_policy_set(wd->scroller,
2538                                            map[wd->policy_h],
2539                                            map[wd->policy_v]);
2540           }
2541         _sizing_eval(obj);
2542      }
2543 }
2544
2545 EAPI Eina_Bool
2546 elm_entry_single_line_get(const Evas_Object *obj)
2547 {
2548    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2549    Widget_Data *wd = elm_widget_data_get(obj);
2550    if (!wd) return EINA_FALSE;
2551    return wd->single_line;
2552 }
2553
2554 EAPI void
2555 elm_entry_password_set(Evas_Object *obj, Eina_Bool password)
2556 {
2557    ELM_CHECK_WIDTYPE(obj, widtype);
2558    Widget_Data *wd = elm_widget_data_get(obj);
2559    if (!wd) return;
2560    if (wd->password == password) return;
2561    wd->password = password;
2562    if (password)
2563      {
2564         wd->single_line = EINA_TRUE;
2565         wd->linewrap = ELM_WRAP_NONE;
2566 #ifdef HAVE_ELEMENTARY_X
2567         elm_drop_target_del(obj);
2568 #endif
2569         edje_object_signal_callback_del_full(wd->ent, "selection,start", "elm.text",
2570                                         _signal_selection_start, obj);
2571         edje_object_signal_callback_del_full(wd->ent, "selection,changed", "elm.text",
2572                                         _signal_selection_changed, obj);
2573         edje_object_signal_callback_del_full(wd->ent, "entry,selection,all,request", "elm.text",
2574                                         _signal_selection_all, obj);
2575         edje_object_signal_callback_del_full(wd->ent, "entry,selection,none,request", "elm.text",
2576                                         _signal_selection_none, obj);
2577         edje_object_signal_callback_del_full(wd->ent, "selection,cleared", "elm.text",
2578                                         _signal_selection_cleared, obj);
2579         edje_object_signal_callback_del_full(wd->ent, "entry,paste,request,*", "elm.text",
2580                                         _signal_entry_paste_request, obj);
2581         edje_object_signal_callback_del_full(wd->ent, "entry,copy,notify", "elm.text",
2582                                         _signal_entry_copy_notify, obj);
2583         edje_object_signal_callback_del_full(wd->ent, "entry,cut,notify", "elm.text",
2584                                         _signal_entry_cut_notify, obj);
2585      }
2586    else
2587      {
2588 #ifdef HAVE_ELEMENTARY_X
2589         elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP, _drag_drop_cb, NULL);
2590 #endif
2591         edje_object_signal_callback_add(wd->ent, "selection,start", "elm.text",
2592                                         _signal_selection_start, obj);
2593         edje_object_signal_callback_add(wd->ent, "selection,changed", "elm.text",
2594                                         _signal_selection_changed, obj);
2595         edje_object_signal_callback_add(wd->ent, "entry,selection,all,request", "elm.text",
2596                                         _signal_selection_all, obj);
2597         edje_object_signal_callback_add(wd->ent, "entry,selection,none,request", "elm.text",
2598                                         _signal_selection_none, obj);
2599         edje_object_signal_callback_add(wd->ent, "selection,cleared", "elm.text",
2600                                         _signal_selection_cleared, obj);
2601         edje_object_signal_callback_add(wd->ent, "entry,paste,request,*", "elm.text",
2602                                         _signal_entry_paste_request, obj);
2603         edje_object_signal_callback_add(wd->ent, "entry,copy,notify", "elm.text",
2604                                         _signal_entry_copy_notify, obj);
2605         edje_object_signal_callback_add(wd->ent, "entry,cut,notify", "elm.text",
2606                                         _signal_entry_cut_notify, obj);
2607      }
2608    _theme_hook(obj);
2609 }
2610
2611 EAPI Eina_Bool
2612 elm_entry_password_get(const Evas_Object *obj)
2613 {
2614    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2615    Widget_Data *wd = elm_widget_data_get(obj);
2616    if (!wd) return EINA_FALSE;
2617    return wd->password;
2618 }
2619
2620 EAPI void
2621 elm_entry_entry_set(Evas_Object *obj, const char *entry)
2622 {
2623    _elm_entry_text_set(obj, NULL, entry);
2624 }
2625
2626 EAPI const char *
2627 elm_entry_entry_get(const Evas_Object *obj)
2628 {
2629    return _elm_entry_text_get(obj, NULL);
2630 }
2631
2632 EAPI void
2633 elm_entry_entry_append(Evas_Object *obj, const char *entry)
2634 {
2635    int len = 0;
2636    ELM_CHECK_WIDTYPE(obj, widtype);
2637    Widget_Data *wd = elm_widget_data_get(obj);
2638    if (!wd) return;
2639    if (!entry) entry = "";
2640    wd->changed = EINA_TRUE;
2641
2642    len = strlen(entry);
2643    if (wd->append_text_left)
2644      {
2645         char *tmpbuf;
2646         tmpbuf = realloc(wd->append_text_left, wd->append_text_len + len + 1);
2647         if (!tmpbuf)
2648           {
2649              /* Do something */
2650              return;
2651           }
2652         wd->append_text_left = tmpbuf;
2653         memcpy(wd->append_text_left + wd->append_text_len, entry, len + 1);
2654         wd->append_text_len += len;
2655      }
2656    else
2657      {
2658         /* FIXME: Add chunked appending here (like in entry_set) */
2659         edje_object_part_text_append(wd->ent, "elm.text", entry);
2660      }
2661 }
2662
2663 EAPI Eina_Bool
2664 elm_entry_is_empty(const Evas_Object *obj)
2665 {
2666    /* FIXME: until there's support for that in textblock, we just check
2667     * to see if the there is text or not. */
2668    ELM_CHECK_WIDTYPE(obj, widtype) EINA_TRUE;
2669    Widget_Data *wd = elm_widget_data_get(obj);
2670    const Evas_Object *tb;
2671    Evas_Textblock_Cursor *cur;
2672    Eina_Bool ret;
2673    if (!wd) return EINA_TRUE;
2674    /* It's a hack until we get the support suggested above.
2675     * We just create a cursor, point it to the begining, and then
2676     * try to advance it, if it can advance, the tb is not empty,
2677     * otherwise it is. */
2678    tb = edje_object_part_object_get(wd->ent, "elm.text");
2679    cur = evas_object_textblock_cursor_new((Evas_Object *) tb); /* This is
2680                                                                   actually, ok for the time being, thsese hackish stuff will be removed
2681                                                                   once evas 1.0 is out*/
2682    evas_textblock_cursor_pos_set(cur, 0);
2683    ret = evas_textblock_cursor_char_next(cur);
2684    evas_textblock_cursor_free(cur);
2685
2686    return !ret;
2687 }
2688
2689 EAPI Evas_Object *
2690 elm_entry_textblock_get(Evas_Object *obj)
2691 {
2692    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2693    Widget_Data *wd = elm_widget_data_get(obj);
2694    if (!wd) return NULL;
2695
2696    return (Evas_Object *) edje_object_part_object_get(wd->ent, "elm.text");
2697 }
2698
2699 EAPI void
2700 elm_entry_calc_force(Evas_Object *obj)
2701 {
2702    ELM_CHECK_WIDTYPE(obj, widtype);
2703    Widget_Data *wd = elm_widget_data_get(obj);
2704    if (!wd) return;
2705
2706    edje_object_calc_force(wd->ent);
2707    wd->changed = EINA_TRUE;
2708    _sizing_eval(obj);
2709 }
2710
2711
2712 EAPI const char *
2713 elm_entry_selection_get(const Evas_Object *obj)
2714 {
2715    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2716    Widget_Data *wd = elm_widget_data_get(obj);
2717    if ((!wd) || (wd->password)) return NULL;
2718    return edje_object_part_text_selection_get(wd->ent, "elm.text");
2719 }
2720
2721 EAPI void
2722 elm_entry_entry_insert(Evas_Object *obj, const char *entry)
2723 {
2724    ELM_CHECK_WIDTYPE(obj, widtype);
2725    Widget_Data *wd = elm_widget_data_get(obj);
2726    if (!wd) return;
2727    edje_object_part_text_insert(wd->ent, "elm.text", entry);
2728    wd->changed = EINA_TRUE;
2729    _sizing_eval(obj);
2730 }
2731
2732 EAPI void
2733 elm_entry_line_wrap_set(Evas_Object *obj, Elm_Wrap_Type wrap)
2734 {
2735    ELM_CHECK_WIDTYPE(obj, widtype);
2736    Widget_Data *wd = elm_widget_data_get(obj);
2737    if (!wd) return;
2738    if (wd->linewrap == wrap) return;
2739    wd->lastw = -1;
2740    wd->linewrap = wrap;
2741    _theme_hook(obj);
2742 }
2743
2744 EAPI Elm_Wrap_Type
2745 elm_entry_line_wrap_get(const Evas_Object *obj)
2746 {
2747    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2748    Widget_Data *wd = elm_widget_data_get(obj);
2749    if (!wd) return EINA_FALSE;
2750    return wd->linewrap;
2751 }
2752
2753 EAPI void
2754 elm_entry_editable_set(Evas_Object *obj, Eina_Bool editable)
2755 {
2756    ELM_CHECK_WIDTYPE(obj, widtype);
2757    Widget_Data *wd = elm_widget_data_get(obj);
2758    if (!wd) return;
2759    if (wd->editable == editable) return;
2760    wd->editable = editable;
2761    _theme_hook(obj);
2762
2763 #ifdef HAVE_ELEMENTARY_X
2764    if (editable)
2765      elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP, _drag_drop_cb, NULL);
2766    else
2767      elm_drop_target_del(obj);
2768 #endif
2769 }
2770
2771 EAPI Eina_Bool
2772 elm_entry_editable_get(const Evas_Object *obj)
2773 {
2774    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2775    Widget_Data *wd = elm_widget_data_get(obj);
2776    if (!wd) return EINA_FALSE;
2777    return wd->editable;
2778 }
2779
2780 EAPI void
2781 elm_entry_select_none(Evas_Object *obj)
2782 {
2783    ELM_CHECK_WIDTYPE(obj, widtype);
2784    Widget_Data *wd = elm_widget_data_get(obj);
2785    if ((!wd) || (wd->password)) return;
2786    if (wd->selmode)
2787      {
2788         wd->selmode = EINA_FALSE;
2789         if (!_elm_config->desktop_entry)
2790           edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
2791         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
2792      }
2793    wd->have_selection = EINA_FALSE;
2794    edje_object_part_text_select_none(wd->ent, "elm.text");
2795 }
2796
2797 EAPI void
2798 elm_entry_select_all(Evas_Object *obj)
2799 {
2800    ELM_CHECK_WIDTYPE(obj, widtype);
2801    Widget_Data *wd = elm_widget_data_get(obj);
2802    if ((!wd) || (wd->password)) return;
2803    if (wd->selmode)
2804      {
2805         wd->selmode = EINA_FALSE;
2806         if (!_elm_config->desktop_entry)
2807           edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
2808         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
2809      }
2810    wd->have_selection = EINA_TRUE;
2811    edje_object_part_text_select_all(wd->ent, "elm.text");
2812 }
2813
2814 EAPI Eina_Bool
2815 elm_entry_cursor_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
2816 {
2817    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2818    Widget_Data *wd = elm_widget_data_get(obj);
2819    if (!wd) return EINA_FALSE;
2820    edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text", x, y, w, h);
2821    return EINA_TRUE;
2822 }
2823
2824 EAPI Eina_Bool
2825 elm_entry_cursor_next(Evas_Object *obj)
2826 {
2827    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2828    Widget_Data *wd = elm_widget_data_get(obj);
2829    if (!wd) return EINA_FALSE;
2830    return edje_object_part_text_cursor_next(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2831 }
2832
2833 EAPI Eina_Bool
2834 elm_entry_cursor_prev(Evas_Object *obj)
2835 {
2836    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2837    Widget_Data *wd = elm_widget_data_get(obj);
2838    if (!wd) return EINA_FALSE;
2839    return edje_object_part_text_cursor_prev(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2840 }
2841
2842 EAPI Eina_Bool
2843 elm_entry_cursor_up(Evas_Object *obj)
2844 {
2845    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2846    Widget_Data *wd = elm_widget_data_get(obj);
2847    if (!wd) return EINA_FALSE;
2848    return edje_object_part_text_cursor_up(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2849 }
2850
2851 EAPI Eina_Bool
2852 elm_entry_cursor_down(Evas_Object *obj)
2853 {
2854    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2855    Widget_Data *wd = elm_widget_data_get(obj);
2856    if (!wd) return EINA_FALSE;
2857    return edje_object_part_text_cursor_down(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2858 }
2859
2860 EAPI void
2861 elm_entry_cursor_begin_set(Evas_Object *obj)
2862 {
2863    ELM_CHECK_WIDTYPE(obj, widtype);
2864    Widget_Data *wd = elm_widget_data_get(obj);
2865    if (!wd) return;
2866    edje_object_part_text_cursor_begin_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2867 }
2868
2869 EAPI void
2870 elm_entry_cursor_end_set(Evas_Object *obj)
2871 {
2872    ELM_CHECK_WIDTYPE(obj, widtype);
2873    Widget_Data *wd = elm_widget_data_get(obj);
2874    if (!wd) return;
2875    edje_object_part_text_cursor_end_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2876 }
2877
2878 EAPI void
2879 elm_entry_cursor_line_begin_set(Evas_Object *obj)
2880 {
2881    ELM_CHECK_WIDTYPE(obj, widtype);
2882    Widget_Data *wd = elm_widget_data_get(obj);
2883    if (!wd) return;
2884    edje_object_part_text_cursor_line_begin_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2885 }
2886
2887 EAPI void
2888 elm_entry_cursor_line_end_set(Evas_Object *obj)
2889 {
2890    ELM_CHECK_WIDTYPE(obj, widtype);
2891    Widget_Data *wd = elm_widget_data_get(obj);
2892    if (!wd) return;
2893    edje_object_part_text_cursor_line_end_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2894 }
2895
2896 EAPI void
2897 elm_entry_cursor_selection_begin(Evas_Object *obj)
2898 {
2899    ELM_CHECK_WIDTYPE(obj, widtype);
2900    Widget_Data *wd = elm_widget_data_get(obj);
2901    if (!wd) return;
2902    edje_object_part_text_select_begin(wd->ent, "elm.text");
2903 }
2904
2905 EAPI void
2906 elm_entry_cursor_selection_end(Evas_Object *obj)
2907 {
2908    ELM_CHECK_WIDTYPE(obj, widtype);
2909    Widget_Data *wd = elm_widget_data_get(obj);
2910    if (!wd) return;
2911    edje_object_part_text_select_extend(wd->ent, "elm.text");
2912 }
2913
2914 EAPI Eina_Bool
2915 elm_entry_cursor_is_format_get(const Evas_Object *obj)
2916 {
2917    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2918    Widget_Data *wd = elm_widget_data_get(obj);
2919    if (!wd) return EINA_FALSE;
2920    return edje_object_part_text_cursor_is_format_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2921 }
2922
2923 EAPI Eina_Bool
2924 elm_entry_cursor_is_visible_format_get(const Evas_Object *obj)
2925 {
2926    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2927    Widget_Data *wd = elm_widget_data_get(obj);
2928    if (!wd) return EINA_FALSE;
2929    return edje_object_part_text_cursor_is_visible_format_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2930 }
2931
2932 EAPI char *
2933 elm_entry_cursor_content_get(const Evas_Object *obj)
2934 {
2935    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2936    Widget_Data *wd = elm_widget_data_get(obj);
2937    if (!wd) return NULL;
2938    return edje_object_part_text_cursor_content_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2939 }
2940
2941 EAPI void
2942 elm_entry_cursor_pos_set(Evas_Object *obj, int pos)
2943 {
2944    ELM_CHECK_WIDTYPE(obj, widtype);
2945    Widget_Data *wd = elm_widget_data_get(obj);
2946    if (!wd) return;
2947    edje_object_part_text_cursor_pos_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN, pos);
2948    edje_object_message_signal_process(wd->ent);
2949 }
2950
2951 EAPI int
2952 elm_entry_cursor_pos_get(const Evas_Object *obj)
2953 {
2954    ELM_CHECK_WIDTYPE(obj, widtype) 0;
2955    Widget_Data *wd = elm_widget_data_get(obj);
2956    if (!wd) return 0;
2957    return edje_object_part_text_cursor_pos_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2958 }
2959
2960 EAPI void
2961 elm_entry_selection_cut(Evas_Object *obj)
2962 {
2963    ELM_CHECK_WIDTYPE(obj, widtype);
2964    Widget_Data *wd = elm_widget_data_get(obj);
2965    if ((!wd) || (wd->password)) return;
2966    _cut(obj, NULL, NULL);
2967 }
2968
2969 EAPI void
2970 elm_entry_selection_copy(Evas_Object *obj)
2971 {
2972    ELM_CHECK_WIDTYPE(obj, widtype);
2973    Widget_Data *wd = elm_widget_data_get(obj);
2974    if ((!wd) || (wd->password)) return;
2975    _copy(obj, NULL, NULL);
2976 }
2977
2978 EAPI void
2979 elm_entry_selection_paste(Evas_Object *obj)
2980 {
2981    ELM_CHECK_WIDTYPE(obj, widtype);
2982    Widget_Data *wd = elm_widget_data_get(obj);
2983    if ((!wd) || (wd->password)) return;
2984    _paste(obj, NULL, NULL);
2985 }
2986
2987 EAPI void
2988 elm_entry_context_menu_clear(Evas_Object *obj)
2989 {
2990    ELM_CHECK_WIDTYPE(obj, widtype);
2991    Widget_Data *wd = elm_widget_data_get(obj);
2992    Elm_Entry_Context_Menu_Item *it;
2993    if (!wd) return;
2994    EINA_LIST_FREE(wd->items, it)
2995      {
2996         eina_stringshare_del(it->label);
2997         eina_stringshare_del(it->icon_file);
2998         eina_stringshare_del(it->icon_group);
2999         free(it);
3000      }
3001 }
3002
3003 EAPI void
3004 elm_entry_context_menu_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data)
3005 {
3006    ELM_CHECK_WIDTYPE(obj, widtype);
3007    Widget_Data *wd = elm_widget_data_get(obj);
3008    Elm_Entry_Context_Menu_Item *it;
3009    if (!wd) return;
3010    it = calloc(1, sizeof(Elm_Entry_Context_Menu_Item));
3011    if (!it) return;
3012    wd->items = eina_list_append(wd->items, it);
3013    it->obj = obj;
3014    it->label = eina_stringshare_add(label);
3015    it->icon_file = eina_stringshare_add(icon_file);
3016    it->icon_type = icon_type;
3017    it->func = func;
3018    it->data = (void *)data;
3019 }
3020
3021 EAPI void
3022 elm_entry_context_menu_disabled_set(Evas_Object *obj, Eina_Bool disabled)
3023 {
3024    ELM_CHECK_WIDTYPE(obj, widtype);
3025    Widget_Data *wd = elm_widget_data_get(obj);
3026    if (!wd) return;
3027    if (wd->context_menu == !disabled) return;
3028    wd->context_menu = !disabled;
3029 }
3030
3031 EAPI Eina_Bool
3032 elm_entry_context_menu_disabled_get(const Evas_Object *obj)
3033 {
3034    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3035    Widget_Data *wd = elm_widget_data_get(obj);
3036    if (!wd) return EINA_FALSE;
3037    return !wd->context_menu;
3038 }
3039
3040 EAPI void
3041 elm_entry_item_provider_append(Evas_Object *obj, Elm_Entry_Item_Provider_Cb func, void *data)
3042 {
3043    ELM_CHECK_WIDTYPE(obj, widtype);
3044    Widget_Data *wd = elm_widget_data_get(obj);
3045    if (!wd) return;
3046    EINA_SAFETY_ON_NULL_RETURN(func);
3047    Elm_Entry_Item_Provider *ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
3048    if (!ip) return;
3049    ip->func = func;
3050    ip->data = data;
3051    wd->item_providers = eina_list_append(wd->item_providers, ip);
3052 }
3053
3054 EAPI void
3055 elm_entry_item_provider_prepend(Evas_Object *obj, Elm_Entry_Item_Provider_Cb func, void *data)
3056 {
3057    ELM_CHECK_WIDTYPE(obj, widtype);
3058    Widget_Data *wd = elm_widget_data_get(obj);
3059    if (!wd) return;
3060    EINA_SAFETY_ON_NULL_RETURN(func);
3061    Elm_Entry_Item_Provider *ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
3062    if (!ip) return;
3063    ip->func = func;
3064    ip->data = data;
3065    wd->item_providers = eina_list_prepend(wd->item_providers, ip);
3066 }
3067
3068 EAPI void
3069 elm_entry_item_provider_remove(Evas_Object *obj, Elm_Entry_Item_Provider_Cb func, void *data)
3070 {
3071    ELM_CHECK_WIDTYPE(obj, widtype);
3072    Widget_Data *wd = elm_widget_data_get(obj);
3073    Eina_List *l;
3074    Elm_Entry_Item_Provider *ip;
3075    if (!wd) return;
3076    EINA_SAFETY_ON_NULL_RETURN(func);
3077    EINA_LIST_FOREACH(wd->item_providers, l, ip)
3078      {
3079         if ((ip->func == func) && ((!data) || (ip->data == data)))
3080           {
3081              wd->item_providers = eina_list_remove_list(wd->item_providers, l);
3082              free(ip);
3083              return;
3084           }
3085      }
3086 }
3087
3088 EAPI void
3089 elm_entry_markup_filter_append(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3090 {
3091    Widget_Data *wd;
3092    Elm_Entry_Markup_Filter *tf;
3093    ELM_CHECK_WIDTYPE(obj, widtype);
3094
3095    wd = elm_widget_data_get(obj);
3096
3097    EINA_SAFETY_ON_NULL_RETURN(func);
3098
3099    tf = _filter_new(func, data);
3100    if (!tf) return;
3101
3102    wd->markup_filters = eina_list_append(wd->markup_filters, tf);
3103 }
3104
3105 EAPI void
3106 elm_entry_markup_filter_prepend(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3107 {
3108    Widget_Data *wd;
3109    Elm_Entry_Markup_Filter *tf;
3110    ELM_CHECK_WIDTYPE(obj, widtype);
3111
3112    wd = elm_widget_data_get(obj);
3113
3114    EINA_SAFETY_ON_NULL_RETURN(func);
3115
3116    tf = _filter_new(func, data);
3117    if (!tf) return;
3118
3119    wd->markup_filters = eina_list_prepend(wd->markup_filters, tf);
3120 }
3121
3122 EAPI void
3123 elm_entry_markup_filter_remove(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3124 {
3125    Widget_Data *wd;
3126    Eina_List *l;
3127    Elm_Entry_Markup_Filter *tf;
3128    ELM_CHECK_WIDTYPE(obj, widtype);
3129
3130    wd = elm_widget_data_get(obj);
3131
3132    EINA_SAFETY_ON_NULL_RETURN(func);
3133
3134    EINA_LIST_FOREACH(wd->markup_filters, l, tf)
3135      {
3136         if ((tf->func == func) && ((!data) || (tf->data == data)))
3137           {
3138              wd->markup_filters = eina_list_remove_list(wd->markup_filters, l);
3139              _filter_free(tf);
3140              return;
3141           }
3142      }
3143 }
3144
3145 EAPI char *
3146 elm_entry_markup_to_utf8(const char *s)
3147 {
3148    char *ss = _elm_util_mkup_to_text(s);
3149    if (!ss) ss = strdup("");
3150    return ss;
3151 }
3152
3153 EAPI char *
3154 elm_entry_utf8_to_markup(const char *s)
3155 {
3156    char *ss = _elm_util_text_to_mkup(s);
3157    if (!ss) ss = strdup("");
3158    return ss;
3159 }
3160
3161 static const char *
3162 _text_get(const Evas_Object *obj)
3163 {
3164    return elm_object_text_get(obj);
3165 }
3166
3167 EAPI void
3168 elm_entry_filter_limit_size(void *data, Evas_Object *entry, char **text)
3169 {
3170    Elm_Entry_Filter_Limit_Size *lim = data;
3171    char *current, *utfstr;
3172    int len, newlen;
3173    const char *(*text_get)(const Evas_Object *);
3174
3175    EINA_SAFETY_ON_NULL_RETURN(data);
3176    EINA_SAFETY_ON_NULL_RETURN(entry);
3177    EINA_SAFETY_ON_NULL_RETURN(text);
3178
3179    /* hack. I don't want to copy the entire function to work with
3180     * scrolled_entry */
3181    text_get = _text_get;
3182
3183    current = elm_entry_markup_to_utf8(text_get(entry));
3184    utfstr = elm_entry_markup_to_utf8(*text);
3185
3186    if (lim->max_char_count > 0)
3187      {
3188         len = evas_string_char_len_get(current);
3189         if (len >= lim->max_char_count)
3190           {
3191              evas_object_smart_callback_call(entry, "maxlength,reached", NULL);
3192              free(*text);
3193              *text = NULL;
3194              free(current);
3195              free(utfstr);
3196              return;
3197           }
3198         newlen = evas_string_char_len_get(utfstr);
3199         if ((len + newlen) > lim->max_char_count)
3200           _add_chars_till_limit(entry, text, (lim->max_char_count - len), LENGTH_UNIT_CHAR);
3201      }
3202    else if (lim->max_byte_count > 0)
3203      {
3204         len = strlen(current);
3205         if (len >= lim->max_byte_count)
3206           {
3207              evas_object_smart_callback_call(entry, "maxlength,reached", NULL);
3208              free(*text);
3209              *text = NULL;
3210              free(current);
3211              free(utfstr);
3212              return;
3213           }
3214         newlen = strlen(utfstr);
3215         if ((len + newlen) > lim->max_byte_count)
3216           _add_chars_till_limit(entry, text, (lim->max_byte_count - len), LENGTH_UNIT_BYTE);
3217      }
3218    free(current);
3219    free(utfstr);
3220 }
3221
3222 EAPI void
3223 elm_entry_filter_accept_set(void *data, Evas_Object *entry __UNUSED__, char **text)
3224 {
3225    Elm_Entry_Filter_Accept_Set *as = data;
3226    const char *set;
3227    char *insert;
3228    Eina_Bool goes_in;
3229    int read_idx, last_read_idx = 0, read_char;
3230
3231    EINA_SAFETY_ON_NULL_RETURN(data);
3232    EINA_SAFETY_ON_NULL_RETURN(text);
3233
3234    if ((!as->accepted) && (!as->rejected))
3235      return;
3236
3237    if (as->accepted)
3238      {
3239         set = as->accepted;
3240         goes_in = EINA_TRUE;
3241      }
3242    else
3243      {
3244         set = as->rejected;
3245         goes_in = EINA_FALSE;
3246      }
3247
3248    insert = *text;
3249    read_idx = evas_string_char_next_get(*text, 0, &read_char);
3250    while (read_char)
3251      {
3252         int cmp_idx, cmp_char;
3253         Eina_Bool in_set = EINA_FALSE;
3254
3255         cmp_idx = evas_string_char_next_get(set, 0, &cmp_char);
3256         while (cmp_char)
3257           {
3258              if (read_char == cmp_char)
3259                {
3260                   in_set = EINA_TRUE;
3261                   break;
3262                }
3263              cmp_idx = evas_string_char_next_get(set, cmp_idx, &cmp_char);
3264           }
3265         if (in_set == goes_in)
3266           {
3267              int size = read_idx - last_read_idx;
3268              const char *src = (*text) + last_read_idx;
3269              if (src != insert)
3270                memcpy(insert, *text + last_read_idx, size);
3271              insert += size;
3272           }
3273         last_read_idx = read_idx;
3274         read_idx = evas_string_char_next_get(*text, read_idx, &read_char);
3275      }
3276    *insert = 0;
3277 }
3278
3279 EAPI Eina_Bool
3280 elm_entry_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format)
3281 {
3282    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3283    Widget_Data *wd = elm_widget_data_get(obj);
3284    if (!wd) return EINA_FALSE;
3285    if (wd->delay_write)
3286      {
3287         ecore_timer_del(wd->delay_write);
3288         wd->delay_write = NULL;
3289      }
3290    if (wd->autosave) _save(obj);
3291    eina_stringshare_replace(&wd->file, file);
3292    wd->format = format;
3293    return _load(obj);
3294 }
3295
3296 EAPI void
3297 elm_entry_file_get(const Evas_Object *obj, const char **file, Elm_Text_Format *format)
3298 {
3299    ELM_CHECK_WIDTYPE(obj, widtype);
3300    Widget_Data *wd = elm_widget_data_get(obj);
3301    if (!wd) return;
3302    if (file) *file = wd->file;
3303    if (format) *format = wd->format;
3304 }
3305
3306 EAPI void
3307 elm_entry_file_save(Evas_Object *obj)
3308 {
3309    ELM_CHECK_WIDTYPE(obj, widtype);
3310    Widget_Data *wd = elm_widget_data_get(obj);
3311    if (!wd) return;
3312    if (wd->delay_write)
3313      {
3314         ecore_timer_del(wd->delay_write);
3315         wd->delay_write = NULL;
3316      }
3317    _save(obj);
3318    wd->delay_write = ecore_timer_add(2.0, _delay_write, obj);
3319 }
3320
3321 EAPI void
3322 elm_entry_autosave_set(Evas_Object *obj, Eina_Bool autosave)
3323 {
3324    ELM_CHECK_WIDTYPE(obj, widtype);
3325    Widget_Data *wd = elm_widget_data_get(obj);
3326    if (!wd) return;
3327    wd->autosave = !!autosave;
3328 }
3329
3330 EAPI Eina_Bool
3331 elm_entry_autosave_get(const Evas_Object *obj)
3332 {
3333    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3334    Widget_Data *wd = elm_widget_data_get(obj);
3335    if (!wd) return EINA_FALSE;
3336    return wd->autosave;
3337 }
3338
3339 EINA_DEPRECATED EAPI void
3340 elm_entry_cnp_textonly_set(Evas_Object *obj, Eina_Bool textonly)
3341 {
3342    ELM_CHECK_WIDTYPE(obj, widtype);
3343    Elm_Cnp_Mode cnp_mode = ELM_CNP_MODE_MARKUP;
3344    if (textonly)
3345      cnp_mode = ELM_CNP_MODE_NO_IMAGE;
3346    elm_entry_cnp_mode_set(obj, cnp_mode);
3347 }
3348
3349 EINA_DEPRECATED EAPI Eina_Bool
3350 elm_entry_cnp_textonly_get(const Evas_Object *obj)
3351 {
3352    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3353    return elm_entry_cnp_mode_get(obj) != ELM_CNP_MODE_MARKUP;
3354 }
3355
3356 EAPI void
3357 elm_entry_cnp_mode_set(Evas_Object *obj, Elm_Cnp_Mode cnp_mode)
3358 {
3359    Elm_Sel_Format format = ELM_SEL_FORMAT_MARKUP;
3360    ELM_CHECK_WIDTYPE(obj, widtype);
3361    Widget_Data *wd = elm_widget_data_get(obj);
3362    if (!wd) return;
3363    if (wd->cnp_mode == cnp_mode) return;
3364    wd->cnp_mode = cnp_mode;
3365    if (wd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
3366      format = ELM_SEL_FORMAT_TEXT;
3367    else if (cnp_mode == ELM_CNP_MODE_MARKUP) format |= ELM_SEL_FORMAT_IMAGE;
3368 #ifdef HAVE_ELEMENTARY_X
3369    elm_drop_target_add(obj, format, _drag_drop_cb, NULL);
3370 #endif
3371 }
3372
3373 EAPI Elm_Cnp_Mode
3374 elm_entry_cnp_mode_get(const Evas_Object *obj)
3375 {
3376    ELM_CHECK_WIDTYPE(obj, widtype) ELM_CNP_MODE_MARKUP;
3377    Widget_Data *wd = elm_widget_data_get(obj);
3378    if (!wd) return ELM_CNP_MODE_MARKUP;
3379    return wd->cnp_mode;
3380 }
3381
3382 EAPI void
3383 elm_entry_scrollable_set(Evas_Object *obj, Eina_Bool scroll)
3384 {
3385    ELM_CHECK_WIDTYPE(obj, widtype);
3386    Widget_Data *wd = elm_widget_data_get(obj);
3387    const Elm_Scroller_Policy map[3] =
3388      {
3389         ELM_SMART_SCROLLER_POLICY_AUTO,
3390         ELM_SMART_SCROLLER_POLICY_ON,
3391         ELM_SMART_SCROLLER_POLICY_OFF
3392      };
3393    if (!wd) return;
3394    scroll = !!scroll;
3395    if (wd->scroll == scroll) return;
3396    wd->scroll = scroll;
3397    if (wd->scroll)
3398      {
3399         if (!wd->scroller)
3400           {
3401              wd->scroller = elm_smart_scroller_add(evas_object_evas_get(obj));
3402              elm_widget_resize_object_set(obj, wd->scroller);
3403              elm_smart_scroller_widget_set(wd->scroller, obj);
3404              elm_smart_scroller_object_theme_set(obj, wd->scroller, "scroller", "entry",
3405                                                  elm_widget_style_get(obj));
3406              evas_object_size_hint_weight_set(wd->scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
3407              evas_object_size_hint_align_set(wd->scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
3408              evas_object_propagate_events_set(wd->scroller, EINA_TRUE);
3409              evas_object_propagate_events_set(elm_smart_scroller_edje_object_get(wd->scroller),
3410                                               EINA_TRUE);
3411           }
3412         elm_smart_scroller_bounce_allow_set(wd->scroller, wd->h_bounce, wd->v_bounce);
3413         if (wd->single_line)
3414           elm_smart_scroller_policy_set(wd->scroller, ELM_SMART_SCROLLER_POLICY_OFF,
3415                                         ELM_SMART_SCROLLER_POLICY_OFF);
3416         else
3417           elm_smart_scroller_policy_set(wd->scroller, map[wd->policy_h], map[wd->policy_v]);
3418         elm_widget_sub_object_add(obj, wd->ent);
3419         elm_smart_scroller_child_set(wd->scroller, wd->ent);
3420         evas_object_show(wd->scroller);
3421         elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3422      }
3423    else
3424      {
3425         if (wd->scroller)
3426           {
3427              elm_smart_scroller_child_set(wd->scroller, NULL);
3428              evas_object_smart_member_add(wd->scroller, obj);
3429              elm_widget_sub_object_add(obj, wd->scroller);
3430              evas_object_hide(wd->scroller);
3431           }
3432         elm_widget_sub_object_del(obj, wd->ent);
3433         elm_widget_resize_object_set(obj, wd->ent);
3434         elm_widget_on_show_region_hook_set(obj, NULL, NULL);
3435      }
3436    wd->lastw = -1;
3437    _theme_hook(obj);
3438 }
3439
3440 EAPI Eina_Bool
3441 elm_entry_scrollable_get(const Evas_Object *obj)
3442 {
3443    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3444    Widget_Data *wd = elm_widget_data_get(obj);
3445    if (!wd) return EINA_FALSE;
3446    return wd->scroll;
3447 }
3448
3449 EAPI void
3450 elm_entry_icon_visible_set(Evas_Object *obj, Eina_Bool setting)
3451 {
3452    ELM_CHECK_WIDTYPE(obj, widtype);
3453    Widget_Data *wd = elm_widget_data_get(obj);
3454    Evas_Object *edje;
3455    if (!wd) return;
3456    if (wd->scroll)
3457       edje = elm_smart_scroller_edje_object_get(wd->scroller);
3458    else
3459       edje = wd->ent;
3460
3461    if ((!edje) || (!edje_object_part_swallow_get(edje, "elm.swallow.icon"))) return;
3462    if (setting)
3463      edje_object_signal_emit(edje, "elm,action,show,icon", "elm");
3464    else
3465      edje_object_signal_emit(edje, "elm,action,hide,icon", "elm");
3466    _sizing_eval(obj);
3467 }
3468
3469 EAPI void
3470 elm_entry_end_visible_set(Evas_Object *obj, Eina_Bool setting)
3471 {
3472    ELM_CHECK_WIDTYPE(obj, widtype);
3473    Widget_Data *wd = elm_widget_data_get(obj);
3474    Evas_Object *edje;
3475    if (!wd) return;
3476    if (wd->scroll)
3477       edje = elm_smart_scroller_edje_object_get(wd->scroller);
3478    else
3479       edje = wd->ent;
3480
3481    if ((!edje) || (!edje_object_part_swallow_get(edje, "elm.swallow.icon"))) return;
3482    if (setting)
3483      edje_object_signal_emit(edje, "elm,action,show,end", "elm");
3484    else
3485      edje_object_signal_emit(edje, "elm,action,hide,end", "elm");
3486    _sizing_eval(obj);
3487 }
3488
3489 EAPI void
3490 elm_entry_scrollbar_policy_set(Evas_Object *obj, Elm_Scroller_Policy h, Elm_Scroller_Policy v)
3491 {
3492    ELM_CHECK_WIDTYPE(obj, widtype);
3493    Widget_Data *wd = elm_widget_data_get(obj);
3494    const Elm_Scroller_Policy map[3] =
3495      {
3496         ELM_SMART_SCROLLER_POLICY_AUTO,
3497         ELM_SMART_SCROLLER_POLICY_ON,
3498         ELM_SMART_SCROLLER_POLICY_OFF
3499      };
3500    if (!wd) return;
3501    wd->policy_h = h;
3502    wd->policy_v = v;
3503    elm_smart_scroller_policy_set(wd->scroller,
3504                                  map[wd->policy_h],
3505                                  map[wd->policy_v]);
3506 }
3507
3508 EAPI void
3509 elm_entry_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
3510 {
3511    ELM_CHECK_WIDTYPE(obj, widtype);
3512    Widget_Data *wd = elm_widget_data_get(obj);
3513    if (!wd) return;
3514    wd->h_bounce = h_bounce;
3515    wd->v_bounce = v_bounce;
3516    elm_smart_scroller_bounce_allow_set(wd->scroller, h_bounce, v_bounce);
3517 }
3518
3519 EAPI void
3520 elm_entry_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
3521 {
3522    ELM_CHECK_WIDTYPE(obj, widtype);
3523    Widget_Data *wd = elm_widget_data_get(obj);
3524    if (!wd) return;
3525    elm_smart_scroller_bounce_allow_get(wd->scroller, h_bounce, v_bounce);
3526 }
3527
3528 EAPI void
3529 elm_entry_input_panel_layout_set(Evas_Object *obj, Elm_Input_Panel_Layout layout)
3530 {
3531    ELM_CHECK_WIDTYPE(obj, widtype);
3532    Widget_Data *wd = elm_widget_data_get(obj);
3533    if (!wd) return;
3534
3535    wd->input_panel_layout = layout;
3536
3537    edje_object_part_text_input_panel_layout_set(wd->ent, "elm.text", layout);
3538 }
3539
3540 EAPI Elm_Input_Panel_Layout
3541 elm_entry_input_panel_layout_get(const Evas_Object *obj)
3542 {
3543    ELM_CHECK_WIDTYPE(obj, widtype) ELM_INPUT_PANEL_LAYOUT_INVALID;
3544    Widget_Data *wd = elm_widget_data_get(obj);
3545    if (!wd) return ELM_INPUT_PANEL_LAYOUT_INVALID;
3546
3547    return wd->input_panel_layout;
3548 }
3549
3550 EAPI void
3551 elm_entry_autocapital_type_set(Evas_Object *obj, Elm_Autocapital_Type autocapital_type)
3552 {
3553    ELM_CHECK_WIDTYPE(obj, widtype);
3554    Widget_Data *wd = elm_widget_data_get(obj);
3555    if (!wd) return;
3556
3557    wd->autocapital_type = autocapital_type;
3558    edje_object_part_text_autocapital_type_set(wd->ent, "elm.text", autocapital_type);
3559 }
3560
3561 EAPI Elm_Autocapital_Type
3562 elm_entry_autocapital_type_get(const Evas_Object *obj)
3563 {
3564    ELM_CHECK_WIDTYPE(obj, widtype) ELM_AUTOCAPITAL_TYPE_NONE;
3565    Widget_Data *wd = elm_widget_data_get(obj);
3566    if (!wd) return ELM_AUTOCAPITAL_TYPE_NONE;
3567
3568    return wd->autocapital_type;
3569 }
3570
3571 EAPI void
3572 elm_entry_prediction_allow_set(Evas_Object *obj, Eina_Bool prediction)
3573 {
3574    ELM_CHECK_WIDTYPE(obj, widtype);
3575    Widget_Data *wd = elm_widget_data_get(obj);
3576    if (!wd) return;
3577
3578    wd->prediction_allow = prediction;
3579    edje_object_part_text_prediction_allow_set(wd->ent, "elm.text", prediction);
3580 }
3581
3582 EAPI Eina_Bool
3583 elm_entry_prediction_allow_get(const Evas_Object *obj)
3584 {
3585    ELM_CHECK_WIDTYPE(obj, widtype) EINA_TRUE;
3586    Widget_Data *wd = elm_widget_data_get(obj);
3587    if (!wd) return EINA_TRUE;
3588
3589    return wd->prediction_allow;
3590 }
3591
3592 EAPI void
3593 elm_entry_imf_context_reset(Evas_Object *obj)
3594 {
3595    ELM_CHECK_WIDTYPE(obj, widtype);
3596    Widget_Data *wd = elm_widget_data_get(obj);
3597    if (!wd) return;
3598
3599    edje_object_part_text_imf_context_reset(wd->ent, "elm.text");
3600 }
3601
3602 EAPI void
3603 elm_entry_input_panel_enabled_set(Evas_Object *obj, Eina_Bool enabled)
3604 {
3605    ELM_CHECK_WIDTYPE(obj, widtype);
3606    Widget_Data *wd = elm_widget_data_get(obj);
3607    if (!wd) return;
3608
3609    wd->input_panel_enable = enabled;
3610    edje_object_part_text_input_panel_enabled_set(wd->ent, "elm.text", enabled);
3611 }
3612
3613 EAPI Eina_Bool
3614 elm_entry_input_panel_enabled_get(const Evas_Object *obj)
3615 {
3616    ELM_CHECK_WIDTYPE(obj, widtype) EINA_TRUE;
3617    Widget_Data *wd = elm_widget_data_get(obj);
3618    if (!wd) return EINA_TRUE;
3619
3620    return wd->input_panel_enable;
3621 }
3622
3623 EAPI void
3624 elm_entry_input_panel_show(Evas_Object *obj)
3625 {
3626    ELM_CHECK_WIDTYPE(obj, widtype);
3627    Widget_Data *wd = elm_widget_data_get(obj);
3628    if (!wd) return;
3629
3630    edje_object_part_text_input_panel_show(wd->ent, "elm.text");
3631 }
3632
3633 EAPI void
3634 elm_entry_input_panel_hide(Evas_Object *obj)
3635 {
3636    ELM_CHECK_WIDTYPE(obj, widtype);
3637    Widget_Data *wd = elm_widget_data_get(obj);
3638    if (!wd) return;
3639
3640    edje_object_part_text_input_panel_hide(wd->ent, "elm.text");
3641 }
3642
3643 EAPI void
3644 elm_entry_input_panel_language_set(Evas_Object *obj, Elm_Input_Panel_Lang lang)
3645 {
3646    ELM_CHECK_WIDTYPE(obj, widtype);
3647    Widget_Data *wd = elm_widget_data_get(obj);
3648    if (!wd) return;
3649
3650    wd->input_panel_lang = lang;
3651    edje_object_part_text_input_panel_language_set(wd->ent, "elm.text", lang);
3652 }
3653
3654 EAPI Elm_Input_Panel_Lang
3655 elm_entry_input_panel_language_get(const Evas_Object *obj)
3656 {
3657    ELM_CHECK_WIDTYPE(obj, widtype) ELM_INPUT_PANEL_LANG_AUTOMATIC;
3658    Widget_Data *wd = elm_widget_data_get(obj);
3659    if (!wd) return ELM_INPUT_PANEL_LANG_AUTOMATIC;
3660
3661    return wd->input_panel_lang;
3662 }
3663
3664 EAPI void
3665 elm_entry_input_panel_imdata_set(Evas_Object *obj, const void *data, int len)
3666 {
3667    ELM_CHECK_WIDTYPE(obj, widtype);
3668    Widget_Data *wd = elm_widget_data_get(obj);
3669    if (!wd) return;
3670
3671    if (wd->input_panel_imdata)
3672      free(wd->input_panel_imdata);
3673
3674    wd->input_panel_imdata = calloc(1, len);
3675    wd->input_panel_imdata_len = len;
3676    memcpy(wd->input_panel_imdata, data, len);
3677
3678    edje_object_part_text_input_panel_imdata_set(wd->ent, "elm.text", wd->input_panel_imdata, wd->input_panel_imdata_len);
3679 }
3680
3681 EAPI void
3682 elm_entry_input_panel_imdata_get(const Evas_Object *obj, void *data, int *len)
3683 {
3684    ELM_CHECK_WIDTYPE(obj, widtype);
3685    Widget_Data *wd = elm_widget_data_get(obj);
3686    if (!wd) return;
3687
3688    edje_object_part_text_input_panel_imdata_get(wd->ent, "elm.text", data, len);
3689 }
3690
3691 EAPI void
3692 elm_entry_input_panel_return_key_type_set(Evas_Object *obj, Elm_Input_Panel_Return_Key_Type return_key_type)
3693 {
3694    ELM_CHECK_WIDTYPE(obj, widtype);
3695    Widget_Data *wd = elm_widget_data_get(obj);
3696    if (!wd) return;
3697
3698    wd->input_panel_return_key_type = return_key_type;
3699
3700    edje_object_part_text_input_panel_return_key_type_set(wd->ent, "elm.text", return_key_type);
3701 }
3702
3703 EAPI Elm_Input_Panel_Return_Key_Type
3704 elm_entry_input_panel_return_key_type_get(const Evas_Object *obj)
3705 {
3706    ELM_CHECK_WIDTYPE(obj, widtype) ELM_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3707    Widget_Data *wd = elm_widget_data_get(obj);
3708    if (!wd) return ELM_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3709
3710    return wd->input_panel_return_key_type;
3711 }
3712
3713 EAPI void
3714 elm_entry_input_panel_return_key_disabled_set(Evas_Object *obj, Eina_Bool disabled)
3715 {
3716    ELM_CHECK_WIDTYPE(obj, widtype);
3717    Widget_Data *wd = elm_widget_data_get(obj);
3718    if (!wd) return;
3719
3720    wd->input_panel_return_key_disabled = disabled;
3721
3722    edje_object_part_text_input_panel_return_key_disabled_set(wd->ent, "elm.text", disabled);
3723 }
3724
3725 EAPI Eina_Bool
3726 elm_entry_input_panel_return_key_disabled_get(const Evas_Object *obj)
3727 {
3728    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3729    Widget_Data *wd = elm_widget_data_get(obj);
3730    if (!wd) return EINA_FALSE;
3731
3732    return wd->input_panel_return_key_disabled;
3733 }
3734
3735 EAPI void
3736 elm_entry_input_panel_return_key_autoenabled_set(Evas_Object *obj, Eina_Bool enabled)
3737 {
3738    ELM_CHECK_WIDTYPE(obj, widtype);
3739    Widget_Data *wd = elm_widget_data_get(obj);
3740    if (!wd) return;
3741
3742    wd->autoreturnkey = enabled;
3743    _check_enable_return_key(obj);
3744 }
3745
3746 EAPI void*
3747 elm_entry_imf_context_get(Evas_Object *obj)
3748 {
3749    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3750    Widget_Data *wd = elm_widget_data_get(obj);
3751    if (!wd) return NULL;
3752
3753    return edje_object_part_text_imf_context_get(wd->ent, "elm.text");
3754 }
3755
3756 /* START - ANCHOR HOVER */
3757 static void
3758 _parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3759 {
3760    Widget_Data *wd = elm_widget_data_get(data);
3761    if (!wd) return;
3762    wd->anchor_hover.hover_parent = NULL;
3763 }
3764
3765 EAPI void
3766 elm_entry_anchor_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
3767 {
3768    ELM_CHECK_WIDTYPE(obj, widtype);
3769    Widget_Data *wd = elm_widget_data_get(obj);
3770    if (!wd) return;
3771    if (wd->anchor_hover.hover_parent)
3772      evas_object_event_callback_del_full(wd->anchor_hover.hover_parent, EVAS_CALLBACK_DEL, _parent_del, obj);
3773    wd->anchor_hover.hover_parent = parent;
3774    if (wd->anchor_hover.hover_parent)
3775      evas_object_event_callback_add(wd->anchor_hover.hover_parent, EVAS_CALLBACK_DEL, _parent_del, obj);
3776 }
3777
3778 EAPI Evas_Object *
3779 elm_entry_anchor_hover_parent_get(const Evas_Object *obj)
3780 {
3781    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3782    Widget_Data *wd = elm_widget_data_get(obj);
3783    if (!wd) return NULL;
3784    return wd->anchor_hover.hover_parent;
3785 }
3786
3787 EAPI void
3788 elm_entry_anchor_hover_style_set(Evas_Object *obj, const char *style)
3789 {
3790    ELM_CHECK_WIDTYPE(obj, widtype);
3791    Widget_Data *wd = elm_widget_data_get(obj);
3792    if (!wd) return;
3793    eina_stringshare_replace(&wd->anchor_hover.hover_style, style);
3794 }
3795
3796 EAPI const char *
3797 elm_entry_anchor_hover_style_get(const Evas_Object *obj)
3798 {
3799    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3800    Widget_Data *wd = elm_widget_data_get(obj);
3801    if (!wd) return NULL;
3802    return wd->anchor_hover.hover_style;
3803 }
3804
3805 EAPI void
3806 elm_entry_anchor_hover_end(Evas_Object *obj)
3807 {
3808    ELM_CHECK_WIDTYPE(obj, widtype);
3809    Widget_Data *wd = elm_widget_data_get(obj);
3810    if (!wd) return;
3811    if (wd->anchor_hover.hover) evas_object_del(wd->anchor_hover.hover);
3812    if (wd->anchor_hover.pop) evas_object_del(wd->anchor_hover.pop);
3813    wd->anchor_hover.hover = NULL;
3814    wd->anchor_hover.pop = NULL;
3815 }
3816
3817
3818 static void
3819 _anchor_hover_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3820 {
3821    elm_entry_anchor_hover_end(data);
3822 }
3823
3824 static void
3825 _entry_hover_anchor_clicked(void *data, Evas_Object *obj, void *event_info)
3826 {
3827    Widget_Data *wd = elm_widget_data_get(obj);
3828    Elm_Entry_Anchor_Info *info = event_info;
3829    Evas_Object *hover_parent;
3830    Elm_Entry_Anchor_Hover_Info ei;
3831    Evas_Coord x, w, y, h, px, py;
3832    if (!wd) return;
3833    ei.anchor_info = event_info;
3834    wd->anchor_hover.pop = elm_icon_add(obj);
3835    evas_object_move(wd->anchor_hover.pop, info->x, info->y);
3836    evas_object_resize(wd->anchor_hover.pop, info->w, info->h);
3837    wd->anchor_hover.hover = elm_hover_add(obj);
3838    elm_widget_mirrored_set(wd->anchor_hover.hover, elm_widget_mirrored_get(obj));
3839    if (wd->anchor_hover.hover_style)
3840      elm_object_style_set(wd->anchor_hover.hover, wd->anchor_hover.hover_style);
3841    hover_parent = wd->anchor_hover.hover_parent;
3842    if (!hover_parent) hover_parent = obj;
3843    elm_hover_parent_set(wd->anchor_hover.hover, hover_parent);
3844    elm_hover_target_set(wd->anchor_hover.hover, wd->anchor_hover.pop);
3845    ei.hover = wd->anchor_hover.hover;
3846    evas_object_geometry_get(hover_parent, &x, &y, &w, &h);
3847    ei.hover_parent.x = x;
3848    ei.hover_parent.y = y;
3849    ei.hover_parent.w = w;
3850    ei.hover_parent.h = h;
3851    px = info->x + (info->w / 2);
3852    py = info->y + (info->h / 2);
3853    ei.hover_left = 1;
3854    if (px < (x + (w / 3))) ei.hover_left = 0;
3855    ei.hover_right = 1;
3856    if (px > (x + ((w * 2) / 3))) ei.hover_right = 0;
3857    ei.hover_top = 1;
3858    if (py < (y + (h / 3))) ei.hover_top = 0;
3859    ei.hover_bottom = 1;
3860    if (py > (y + ((h * 2) / 3))) ei.hover_bottom = 0;
3861
3862    if (elm_widget_mirrored_get(wd->anchor_hover.hover))
3863      {  /* Swap right and left because they switch sides in RTL */
3864         Eina_Bool tmp = ei.hover_left;
3865         ei.hover_left = ei.hover_right;
3866         ei.hover_right = tmp;
3867      }
3868
3869    evas_object_smart_callback_call(data, SIG_ANCHOR_HOVER_OPENED, &ei);
3870    evas_object_smart_callback_add(wd->anchor_hover.hover, "clicked", _anchor_hover_clicked, data);
3871    evas_object_show(wd->anchor_hover.hover);
3872 }
3873 /* END - ANCHOR HOVER */
3874