From: Jérémy Zurcher <jeremy@asynk.ch>
[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    evas_object_smart_callback_call(data, SIG_SELECTION_PASTE, NULL);
1723    if (wd->sel_notify_handler)
1724      {
1725 #ifdef HAVE_ELEMENTARY_X
1726         Evas_Object *top;
1727
1728         top = elm_widget_top_get(data);
1729         if ((top) && (elm_win_xwindow_get(top)))
1730           {
1731              wd->selection_asked = EINA_TRUE;
1732              Elm_Sel_Format formats = ELM_SEL_FORMAT_MARKUP;
1733              if (wd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
1734                formats = ELM_SEL_FORMAT_TEXT;
1735              else if (wd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
1736                formats |= ELM_SEL_FORMAT_IMAGE;
1737              elm_cnp_selection_get(data, type, formats,
1738                                    NULL, NULL);
1739           }
1740 #endif
1741      }
1742 }
1743
1744 static void
1745 _signal_entry_copy_notify(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1746 {
1747    evas_object_smart_callback_call(data, SIG_SELECTION_COPY, NULL);
1748    _copy(data, NULL, NULL);
1749 }
1750
1751 static void
1752 _signal_entry_cut_notify(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1753 {
1754    evas_object_smart_callback_call(data, SIG_SELECTION_CUT, NULL);
1755    _cut(data, NULL, NULL);
1756 }
1757
1758 static void
1759 _signal_cursor_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1760 {
1761    Widget_Data *wd = elm_widget_data_get(data);
1762    if (!wd) return;
1763    wd->cursor_pos = edje_object_part_text_cursor_pos_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
1764    wd->cur_changed = EINA_TRUE;
1765    _recalc_cursor_geometry(data);
1766 }
1767
1768 static void
1769 _signal_cursor_changed_manual(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1770 {
1771    evas_object_smart_callback_call(data, SIG_CURSOR_CHANGED_MANUAL, NULL);
1772 }
1773
1774
1775 static void
1776 _signal_anchor_geoms_do_things_with(Widget_Data *wd, Elm_Entry_Anchor_Info *ei)
1777 {
1778    const Eina_List *geoms, *l;
1779    Evas_Textblock_Rectangle *r;
1780    Evas_Coord px, py, x, y;
1781
1782    geoms = edje_object_part_text_anchor_geometry_get(wd->ent, "elm.text", ei->name);
1783    if (!geoms) return;
1784
1785
1786    evas_object_geometry_get(wd->ent, &x, &y, NULL, NULL);
1787    evas_pointer_canvas_xy_get(evas_object_evas_get(wd->ent), &px, &py);
1788    EINA_LIST_FOREACH(geoms, l, r)
1789      {
1790         if (((r->x + x) <= px) && ((r->y + y) <= py) &&
1791             ((r->x + x + r->w) > px) && ((r->y + y + r->h) > py))
1792           {
1793              ei->x = r->x + x;
1794              ei->y = r->y + y;
1795              ei->w = r->w;
1796              ei->h = r->h;
1797              break;
1798           }
1799      }
1800 }
1801
1802 static void
1803 _signal_anchor_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1804 {
1805    Widget_Data *wd = elm_widget_data_get(data);
1806    Elm_Entry_Anchor_Info ei;
1807    const char *p;
1808    char *p2;
1809    if (!wd) return;
1810    p = emission + sizeof("nchor,mouse,down,");
1811    ei.button = strtol(p, &p2, 10);
1812    ei.name = p2 + 1;
1813    ei.x = ei.y = ei.w = ei.h = 0;
1814
1815    _signal_anchor_geoms_do_things_with(wd, &ei);
1816
1817    if (!wd->disabled)
1818      evas_object_smart_callback_call(data, SIG_ANCHOR_DOWN, &ei);
1819 }
1820
1821 static void
1822 _signal_anchor_up(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1823 {
1824    Widget_Data *wd = elm_widget_data_get(data);
1825    Elm_Entry_Anchor_Info ei;
1826    const char *p;
1827    char *p2;
1828    if (!wd) return;
1829    p = emission + sizeof("nchor,mouse,up,");
1830    ei.button = strtol(p, &p2, 10);
1831    ei.name = p2 + 1;
1832    ei.x = ei.y = ei.w = ei.h = 0;
1833
1834    _signal_anchor_geoms_do_things_with(wd, &ei);
1835
1836    if (!wd->disabled)
1837      evas_object_smart_callback_call(data, SIG_ANCHOR_UP, &ei);
1838 }
1839
1840 static void
1841 _signal_anchor_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission, const char *source __UNUSED__)
1842 {
1843    Widget_Data *wd = elm_widget_data_get(data);
1844    Elm_Entry_Anchor_Info ei;
1845    const char *p;
1846    char *p2;
1847    if (!wd) return;
1848    p = emission + sizeof("nchor,mouse,clicked,");
1849    ei.button = strtol(p, &p2, 10);
1850    ei.name = p2 + 1;
1851    ei.x = ei.y = ei.w = ei.h = 0;
1852
1853    _signal_anchor_geoms_do_things_with(wd, &ei);
1854
1855    if (!wd->disabled)
1856      {
1857         evas_object_smart_callback_call(data, SIG_ANCHOR_CLICKED, &ei);
1858
1859         _entry_hover_anchor_clicked(data, data, &ei);
1860      }
1861 }
1862
1863 static void
1864 _signal_anchor_move(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1865 {
1866    Widget_Data *wd = elm_widget_data_get(data);
1867    if (!wd) return;
1868 }
1869
1870 static void
1871 _signal_anchor_in(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1872 {
1873    Widget_Data *wd = elm_widget_data_get(data);
1874    Elm_Entry_Anchor_Info ei;
1875    if (!wd) return;
1876    ei.name = emission + sizeof("nchor,mouse,in,");
1877    ei.button = 0;
1878    ei.x = ei.y = ei.w = ei.h = 0;
1879
1880    _signal_anchor_geoms_do_things_with(wd, &ei);
1881
1882    if (!wd->disabled)
1883      evas_object_smart_callback_call(data, SIG_ANCHOR_IN, &ei);
1884 }
1885
1886 static void
1887 _signal_anchor_out(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1888 {
1889    Widget_Data *wd = elm_widget_data_get(data);
1890    Elm_Entry_Anchor_Info ei;
1891    if (!wd) return;
1892    ei.name = emission + sizeof("nchor,mouse,out,");
1893    ei.button = 0;
1894    ei.x = ei.y = ei.w = ei.h = 0;
1895
1896    _signal_anchor_geoms_do_things_with(wd, &ei);
1897
1898    if (!wd->disabled)
1899      evas_object_smart_callback_call(data, SIG_ANCHOR_OUT, &ei);
1900 }
1901
1902 static void
1903 _signal_key_enter(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1904 {
1905    Widget_Data *wd = elm_widget_data_get(data);
1906    if (!wd) return;
1907    evas_object_smart_callback_call(data, SIG_ACTIVATED, NULL);
1908 }
1909
1910 static void
1911 _signal_mouse_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1912 {
1913    Widget_Data *wd = elm_widget_data_get(data);
1914    if (!wd) return;
1915    evas_object_smart_callback_call(data, SIG_PRESS, NULL);
1916 }
1917
1918 static void
1919 _signal_mouse_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1920 {
1921    Widget_Data *wd = elm_widget_data_get(data);
1922    if (!wd) return;
1923    evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
1924 }
1925
1926 static void
1927 _signal_mouse_double(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1928 {
1929    Widget_Data *wd = elm_widget_data_get(data);
1930    if (!wd) return;
1931    evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
1932 }
1933
1934 static void
1935 _signal_mouse_triple(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1936 {
1937    Widget_Data *wd = elm_widget_data_get(data);
1938    if (!wd) return;
1939    evas_object_smart_callback_call(data, SIG_CLICKED_TRIPLE, NULL);
1940 }
1941
1942 #ifdef HAVE_ELEMENTARY_X
1943 static Eina_Bool
1944 _event_selection_notify(void *data, int type __UNUSED__, void *event)
1945 {
1946    Widget_Data *wd = elm_widget_data_get(data);
1947    Ecore_X_Event_Selection_Notify *ev = event;
1948    if (!wd) return ECORE_CALLBACK_PASS_ON;
1949    if ((!wd->selection_asked) && (!wd->drag_selection_asked))
1950      return ECORE_CALLBACK_PASS_ON;
1951
1952    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
1953        (ev->selection == ECORE_X_SELECTION_PRIMARY))
1954      {
1955         Ecore_X_Selection_Data_Text *text_data;
1956
1957         text_data = ev->data;
1958         if (text_data->data.content == ECORE_X_SELECTION_CONTENT_TEXT)
1959           {
1960              if (text_data->text)
1961                {
1962                   char *txt = _elm_util_text_to_mkup(text_data->text);
1963
1964                   if (txt)
1965                     {
1966                        elm_entry_entry_insert(data, txt);
1967                        free(txt);
1968                     }
1969                }
1970           }
1971         wd->selection_asked = EINA_FALSE;
1972      }
1973    else if (ev->selection == ECORE_X_SELECTION_XDND)
1974      {
1975         Ecore_X_Selection_Data_Text *text_data;
1976
1977         text_data = ev->data;
1978         if (text_data->data.content == ECORE_X_SELECTION_CONTENT_TEXT)
1979           {
1980              if (text_data->text)
1981                {
1982                   char *txt = _elm_util_text_to_mkup(text_data->text);
1983
1984                   if (txt)
1985                     {
1986                        /* Massive FIXME: this should be at the drag point */
1987                        elm_entry_entry_insert(data, txt);
1988                        free(txt);
1989                     }
1990                }
1991           }
1992         wd->drag_selection_asked = EINA_FALSE;
1993
1994         ecore_x_dnd_send_finished();
1995
1996      }
1997    return ECORE_CALLBACK_PASS_ON;
1998 }
1999
2000 static Eina_Bool
2001 _event_selection_clear(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
2002 {
2003    Widget_Data *wd = elm_widget_data_get(data);
2004    Ecore_X_Event_Selection_Clear *ev = event;
2005    if (!wd) return ECORE_CALLBACK_PASS_ON;
2006    if (!wd->have_selection) return ECORE_CALLBACK_PASS_ON;
2007    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
2008        (ev->selection == ECORE_X_SELECTION_PRIMARY))
2009      {
2010         elm_entry_select_none(data);
2011      }
2012    return ECORE_CALLBACK_PASS_ON;
2013 }
2014
2015 static Eina_Bool
2016 _drag_drop_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Selection_Data *drop)
2017 {
2018    Widget_Data *wd;
2019    Eina_Bool rv;
2020
2021    wd = elm_widget_data_get(obj);
2022    if (!wd) return EINA_FALSE;
2023    printf("Inserting at (%d,%d) %s\n",drop->x,drop->y,(char*)drop->data);
2024
2025    edje_object_part_text_cursor_copy(wd->ent, "elm.text",
2026                                      EDJE_CURSOR_MAIN,/*->*/EDJE_CURSOR_USER);
2027    rv = edje_object_part_text_cursor_coord_set(wd->ent,"elm.text",
2028                                                EDJE_CURSOR_MAIN,drop->x,drop->y);
2029    if (!rv) printf("Warning: Failed to position cursor: paste anyway\n");
2030    elm_entry_entry_insert(obj, drop->data);
2031    edje_object_part_text_cursor_copy(wd->ent, "elm.text",
2032                                      EDJE_CURSOR_USER,/*->*/EDJE_CURSOR_MAIN);
2033
2034    return EINA_TRUE;
2035 }
2036 #endif
2037
2038 static Evas_Object *
2039 _get_item(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, const char *item)
2040 {
2041    Widget_Data *wd = elm_widget_data_get(data);
2042    Evas_Object *o;
2043    Eina_List *l;
2044    Elm_Entry_Item_Provider *ip;
2045
2046    EINA_LIST_FOREACH(wd->item_providers, l, ip)
2047      {
2048         o = ip->func(ip->data, data, item);
2049         if (o) return o;
2050      }
2051    if (!strncmp(item, "file://", 7))
2052      {
2053         const char *fname = item + 7;
2054
2055         o = evas_object_image_filled_add(evas_object_evas_get(data));
2056         evas_object_image_file_set(o, fname, NULL);
2057         if (evas_object_image_load_error_get(o) == EVAS_LOAD_ERROR_NONE)
2058           {
2059              evas_object_show(o);
2060           }
2061         else
2062           {
2063              evas_object_del(o);
2064              o = edje_object_add(evas_object_evas_get(data));
2065              _elm_theme_object_set(data, o, "entry/emoticon", "wtf", elm_widget_style_get(data));
2066           }
2067         return o;
2068      }
2069    o = edje_object_add(evas_object_evas_get(data));
2070    if (!_elm_theme_object_set(data, o, "entry", item, elm_widget_style_get(data)))
2071      _elm_theme_object_set(data, o, "entry/emoticon", "wtf", elm_widget_style_get(data));
2072    return o;
2073 }
2074
2075 static void
2076 _text_filter(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, Edje_Text_Filter_Type type, char **text)
2077 {
2078    Widget_Data *wd = elm_widget_data_get(data);
2079    Eina_List *l;
2080    Elm_Entry_Markup_Filter *tf;
2081
2082    if (type == EDJE_TEXT_FILTER_FORMAT)
2083      return;
2084
2085    EINA_LIST_FOREACH(wd->text_filters, l, tf)
2086      {
2087         tf->func(tf->data, data, text);
2088         if (!*text)
2089           break;
2090      }
2091 }
2092
2093 static void
2094 _markup_filter(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, char **text)
2095 {
2096    Widget_Data *wd = elm_widget_data_get(data);
2097    Eina_List *l;
2098    Elm_Entry_Markup_Filter *tf;
2099
2100    EINA_LIST_FOREACH(wd->markup_filters, l, tf)
2101      {
2102         tf->func(tf->data, data, text);
2103         if (!*text)
2104           break;
2105      }
2106 }
2107
2108 /* This function is used to insert text by chunks in jobs */
2109 static Eina_Bool
2110 _text_append_idler(void *data)
2111 {
2112    int start;
2113    char backup;
2114    Evas_Object *obj = (Evas_Object *) data;
2115    Widget_Data *wd = elm_widget_data_get(obj);
2116    evas_event_freeze(evas_object_evas_get(obj));
2117    if (wd->text) eina_stringshare_del(wd->text);
2118    wd->text = NULL;
2119    wd->changed = EINA_TRUE;
2120
2121    start = wd->append_text_position;
2122    if (start + _CHUNK_SIZE < wd->append_text_len)
2123      {
2124         int pos = start;
2125         int tag_start, esc_start;
2126
2127         tag_start = esc_start = -1;
2128         /* Find proper markup cut place */
2129         while (pos - start < _CHUNK_SIZE)
2130           {
2131              int prev_pos = pos;
2132              Eina_Unicode tmp =
2133                 eina_unicode_utf8_get_next(wd->append_text_left, &pos);
2134              if (esc_start == -1)
2135                {
2136                   if (tmp == '<')
2137                      tag_start = prev_pos;
2138                   else if (tmp == '>')
2139                      tag_start = -1;
2140                }
2141              if (tag_start == -1)
2142                {
2143                   if (tmp == '&')
2144                      esc_start = prev_pos;
2145                   else if (tmp == ';')
2146                      esc_start = -1;
2147                }
2148           }
2149
2150         if (tag_start >= 0)
2151           {
2152              wd->append_text_position = tag_start;
2153           }
2154         else if (esc_start >= 0)
2155           {
2156              wd->append_text_position = esc_start;
2157           }
2158         else
2159           {
2160              wd->append_text_position = pos;
2161           }
2162      }
2163    else
2164      {
2165         wd->append_text_position = wd->append_text_len;
2166      }
2167
2168    backup = wd->append_text_left[wd->append_text_position];
2169    wd->append_text_left[wd->append_text_position] = '\0';
2170
2171    edje_object_part_text_append(wd->ent, "elm.text",
2172                                 wd->append_text_left + start);
2173
2174    wd->append_text_left[wd->append_text_position] = backup;
2175
2176    evas_event_thaw(evas_object_evas_get(obj));
2177    evas_event_thaw_eval(evas_object_evas_get(obj));
2178
2179    /* If there's still more to go, renew the idler, else, cleanup */
2180    if (wd->append_text_position < wd->append_text_len)
2181      {
2182         return ECORE_CALLBACK_RENEW;
2183      }
2184    else
2185      {
2186         free(wd->append_text_left);
2187         wd->append_text_left = NULL;
2188         wd->append_text_idler = NULL;
2189         return ECORE_CALLBACK_CANCEL;
2190      }
2191 }
2192
2193 static void
2194 _add_chars_till_limit(Evas_Object *obj, char **text, int can_add, Length_Unit unit)
2195 {
2196    int i = 0, current_len = 0;
2197    char *new_text;
2198
2199    if (!*text) return;
2200    if (unit >= LENGTH_UNIT_LAST) return;
2201    new_text = *text;
2202    current_len = strlen(*text);
2203    while (*new_text)
2204      {
2205         int idx = 0, unit_size = 0;
2206         char *markup, *utfstr;
2207         if (*new_text == '<')
2208           {
2209              while (*(new_text + idx) != '>')
2210                {
2211                   idx++;
2212                   if (!*(new_text + idx)) break;
2213                }
2214           }
2215         else if (*new_text == '&')
2216           {
2217              while (*(new_text + idx) != ';')
2218                {
2219                   idx++;
2220                   if (!*(new_text + idx)) break;
2221                }
2222           }
2223         idx = evas_string_char_next_get(new_text, idx, NULL);
2224         markup = malloc(idx + 1);
2225         if (markup)
2226           {
2227              strncpy(markup, new_text, idx);
2228              markup[idx] = 0;
2229              utfstr = elm_entry_markup_to_utf8(markup);
2230              if (utfstr)
2231                {
2232                   if (unit == LENGTH_UNIT_BYTE)
2233                     unit_size = strlen(utfstr);
2234                   else if (unit == LENGTH_UNIT_CHAR)
2235                     unit_size = evas_string_char_len_get(utfstr);
2236                   free(utfstr);
2237                   utfstr = NULL;
2238                }
2239              free(markup);
2240              markup = NULL;
2241           }
2242         if (can_add < unit_size)
2243           {
2244              if (!i)
2245                {
2246                   evas_object_smart_callback_call(obj, "maxlength,reached", NULL);
2247                   free(*text);
2248                   *text = NULL;
2249                   return;
2250                }
2251              can_add = 0;
2252              strncpy(new_text, new_text + idx, current_len - ((new_text + idx) - *text));
2253              current_len -= idx;
2254              (*text)[current_len] = 0;
2255           }
2256         else
2257           {
2258              new_text += idx;
2259              can_add -= unit_size;
2260           }
2261         i++;
2262      }
2263    evas_object_smart_callback_call(obj, "maxlength,reached", NULL);
2264 }
2265
2266 static void
2267 _elm_entry_text_set(Evas_Object *obj, const char *item, const char *entry)
2268 {
2269    int len = 0;
2270    ELM_CHECK_WIDTYPE(obj, widtype);
2271    Widget_Data *wd = elm_widget_data_get(obj);
2272    if (!wd) return;
2273    evas_event_freeze(evas_object_evas_get(obj));
2274    if (!entry) entry = "";
2275    if (item && strcmp(item, "default"))
2276      {
2277         edje_object_part_text_set(wd->ent, item, entry);
2278         return;
2279      }
2280
2281    if (wd->text) eina_stringshare_del(wd->text);
2282    wd->text = NULL;
2283    wd->changed = EINA_TRUE;
2284
2285    /* Clear currently pending job if there is one */
2286    if (wd->append_text_idler)
2287      {
2288         ecore_idler_del(wd->append_text_idler);
2289         free(wd->append_text_left);
2290         wd->append_text_left = NULL;
2291         wd->append_text_idler = NULL;
2292      }
2293
2294    len = strlen(entry);
2295    /* Split to ~_CHUNK_SIZE chunks */
2296    if (len > _CHUNK_SIZE)
2297      {
2298         wd->append_text_left = (char *) malloc(len + 1);
2299      }
2300
2301    /* If we decided to use the idler */
2302    if (wd->append_text_left)
2303      {
2304         /* Need to clear the entry first */
2305         edje_object_part_text_set(wd->ent, "elm.text", "");
2306         memcpy(wd->append_text_left, entry, len + 1);
2307         wd->append_text_position = 0;
2308         wd->append_text_len = len;
2309         wd->append_text_idler = ecore_idler_add(_text_append_idler, obj);
2310      }
2311    else
2312      {
2313         edje_object_part_text_set(wd->ent, "elm.text", entry);
2314      }
2315    evas_event_thaw(evas_object_evas_get(obj));
2316    evas_event_thaw_eval(evas_object_evas_get(obj));
2317 }
2318
2319 static const char *
2320 _elm_entry_text_get(const Evas_Object *obj, const char *item)
2321 {
2322    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2323    Widget_Data *wd = elm_widget_data_get(obj);
2324    if (item && strcmp(item, "default")) return NULL;
2325    const char *text;
2326    if (!wd) return NULL;
2327    if (wd->text) return wd->text;
2328    text = edje_object_part_text_get(wd->ent, "elm.text");
2329    if (!text)
2330      {
2331         ERR("text=NULL for edje %p, part 'elm.text'", wd->ent);
2332         return NULL;
2333      }
2334
2335    if (wd->append_text_len > 0)
2336      {
2337         char *tmpbuf;
2338         size_t tlen;
2339         tlen = strlen(text);
2340         tmpbuf = malloc(tlen + wd->append_text_len + 1);
2341         if (!tmpbuf)
2342           {
2343              ERR("Failed to allocate memory for entry's text %p", obj);
2344              return NULL;
2345           }
2346         memcpy(tmpbuf, text, tlen);
2347         memcpy(tmpbuf + tlen, wd->append_text_left, wd->append_text_len);
2348         tmpbuf[tlen + wd->append_text_len] = '\0';
2349         eina_stringshare_replace(&wd->text, tmpbuf);
2350         free(tmpbuf);
2351      }
2352    else
2353      {
2354         eina_stringshare_replace(&wd->text, text);
2355      }
2356    return wd->text;
2357 }
2358
2359 EAPI Evas_Object *
2360 elm_entry_add(Evas_Object *parent)
2361 {
2362    Evas_Object *obj, *top;
2363    Evas *e;
2364    Widget_Data *wd;
2365
2366    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
2367
2368    ELM_SET_WIDTYPE(widtype, "entry");
2369    elm_widget_type_set(obj, "entry");
2370    elm_widget_sub_object_add(parent, obj);
2371    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
2372    elm_widget_data_set(obj, wd);
2373    elm_widget_del_hook_set(obj, _del_hook);
2374    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
2375    elm_widget_theme_hook_set(obj, _theme_hook);
2376    elm_widget_disable_hook_set(obj, _disable_hook);
2377    elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
2378    elm_widget_focus_region_hook_set(obj, _focus_region_hook);
2379    elm_widget_on_focus_region_hook_set(obj, _on_focus_region_hook);
2380    elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
2381    elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
2382    elm_object_cursor_set(obj, ELM_CURSOR_XTERM);
2383    elm_widget_can_focus_set(obj, EINA_TRUE);
2384    elm_widget_highlight_ignore_set(obj, EINA_TRUE);
2385    elm_widget_text_set_hook_set(obj, _elm_entry_text_set);
2386    elm_widget_text_get_hook_set(obj, _elm_entry_text_get);
2387    elm_widget_content_set_hook_set(obj, _content_set_hook);
2388    elm_widget_content_unset_hook_set(obj, _content_unset_hook);
2389    elm_widget_content_get_hook_set(obj, _content_get_hook);
2390    elm_widget_translate_hook_set(obj, _translate_hook);
2391
2392    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, wd);
2393
2394    wd->linewrap     = ELM_WRAP_WORD;
2395    wd->editable     = EINA_TRUE;
2396    wd->disabled     = EINA_FALSE;
2397    wd->context_menu = EINA_TRUE;
2398    wd->autosave     = EINA_TRUE;
2399    wd->cnp_mode     = ELM_CNP_MODE_MARKUP;
2400    wd->scroll       = EINA_FALSE;
2401    wd->input_panel_imdata = NULL;
2402
2403    wd->ent = edje_object_add(e);
2404    edje_object_item_provider_set(wd->ent, _get_item, obj);
2405    edje_object_text_insert_filter_callback_add(wd->ent,"elm.text", _text_filter, obj);
2406    edje_object_text_markup_filter_callback_add(wd->ent,"elm.text", _markup_filter, obj);
2407    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOVE, _move, obj);
2408    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_DOWN,
2409                                   _mouse_down, obj);
2410    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_UP,
2411                                   _mouse_up, obj);
2412    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_MOVE,
2413                                   _mouse_move, obj);
2414    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
2415
2416    _elm_theme_object_set(obj, wd->ent, "entry", "base", "default");
2417    edje_object_signal_callback_add(wd->ent, "entry,changed", "elm.text",
2418                                    _signal_entry_changed, obj);
2419    edje_object_signal_callback_add(wd->ent, "entry,changed,user", "elm.text",
2420                                    _signal_entry_changed_user, obj);
2421    edje_object_signal_callback_add(wd->ent, "preedit,changed", "elm.text",
2422                                    _signal_preedit_changed, obj);
2423    edje_object_signal_callback_add(wd->ent, "selection,start", "elm.text",
2424                                    _signal_selection_start, obj);
2425    edje_object_signal_callback_add(wd->ent, "selection,changed", "elm.text",
2426                                    _signal_selection_changed, obj);
2427    edje_object_signal_callback_add(wd->ent, "entry,selection,all,request", "elm.text",
2428                                    _signal_selection_all, obj);
2429    edje_object_signal_callback_add(wd->ent, "entry,selection,none,request", "elm.text",
2430                                    _signal_selection_none, obj);
2431    edje_object_signal_callback_add(wd->ent, "selection,cleared", "elm.text",
2432                                    _signal_selection_cleared, obj);
2433    edje_object_signal_callback_add(wd->ent, "entry,paste,request,*", "elm.text",
2434                                    _signal_entry_paste_request, obj);
2435    edje_object_signal_callback_add(wd->ent, "entry,copy,notify", "elm.text",
2436                                    _signal_entry_copy_notify, obj);
2437    edje_object_signal_callback_add(wd->ent, "entry,cut,notify", "elm.text",
2438                                    _signal_entry_cut_notify, obj);
2439    edje_object_signal_callback_add(wd->ent, "cursor,changed", "elm.text",
2440                                    _signal_cursor_changed, obj);
2441    edje_object_signal_callback_add(wd->ent, "cursor,changed,manual", "elm.text",
2442                                    _signal_cursor_changed_manual, obj);
2443    edje_object_signal_callback_add(wd->ent, "anchor,mouse,down,*", "elm.text",
2444                                    _signal_anchor_down, obj);
2445    edje_object_signal_callback_add(wd->ent, "anchor,mouse,up,*", "elm.text",
2446                                    _signal_anchor_up, obj);
2447    edje_object_signal_callback_add(wd->ent, "anchor,mouse,clicked,*", "elm.text",
2448                                    _signal_anchor_clicked, obj);
2449    edje_object_signal_callback_add(wd->ent, "anchor,mouse,move,*", "elm.text",
2450                                    _signal_anchor_move, obj);
2451    edje_object_signal_callback_add(wd->ent, "anchor,mouse,in,*", "elm.text",
2452                                    _signal_anchor_in, obj);
2453    edje_object_signal_callback_add(wd->ent, "anchor,mouse,out,*", "elm.text",
2454                                    _signal_anchor_out, obj);
2455    edje_object_signal_callback_add(wd->ent, "entry,key,enter", "elm.text",
2456                                    _signal_key_enter, obj);
2457    edje_object_signal_callback_add(wd->ent, "mouse,down,1", "elm.text",
2458                                    _signal_mouse_down, obj);
2459    edje_object_signal_callback_add(wd->ent, "mouse,clicked,1", "elm.text",
2460                                    _signal_mouse_clicked, obj);
2461    edje_object_signal_callback_add(wd->ent, "mouse,down,1,double", "elm.text",
2462                                    _signal_mouse_double, obj);
2463    edje_object_signal_callback_add(wd->ent, "mouse,down,1,triple", "elm.text",
2464                                    _signal_mouse_triple, obj);
2465    edje_object_signal_callback_add(wd->ent, "entry,undo,request", "elm.text",
2466                                    _signal_undo_request, obj);
2467    edje_object_signal_callback_add(wd->ent, "entry,redo,request", "elm.text",
2468                                    _signal_redo_request, obj);
2469    edje_object_part_text_set(wd->ent, "elm.text", "");
2470    if (_elm_config->desktop_entry)
2471      edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_TRUE);
2472    elm_widget_resize_object_set(obj, wd->ent);
2473    _sizing_eval(obj);
2474
2475    elm_entry_input_panel_layout_set(obj, ELM_INPUT_PANEL_LAYOUT_NORMAL);
2476    elm_entry_input_panel_enabled_set(obj, EINA_TRUE);
2477    elm_entry_prediction_allow_set(obj, EINA_TRUE);
2478
2479    wd->autocapital_type = edje_object_part_text_autocapital_type_get(wd->ent, "elm.text");
2480
2481 #ifdef HAVE_ELEMENTARY_X
2482    top = elm_widget_top_get(obj);
2483    if ((top) && (elm_win_xwindow_get(top)))
2484      {
2485         wd->sel_notify_handler =
2486            ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY,
2487                                    _event_selection_notify, obj);
2488         wd->sel_clear_handler =
2489            ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR,
2490                                    _event_selection_clear, obj);
2491      }
2492
2493    elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE,
2494                        _drag_drop_cb, NULL);
2495 #endif
2496
2497    entries = eina_list_prepend(entries, obj);
2498
2499    // module - find module for entry
2500    wd->api = _module(obj);
2501    // if found - hook in
2502    if ((wd->api) && (wd->api->obj_hook)) wd->api->obj_hook(obj);
2503
2504    _mirrored_set(obj, elm_widget_mirrored_get(obj));
2505    // TODO: convert Elementary to subclassing of Evas_Smart_Class
2506    // TODO: and save some bytes, making descriptions per-class and not instance!
2507    evas_object_smart_callbacks_descriptions_set(obj, _signals);
2508    return obj;
2509 }
2510
2511 EAPI void
2512 elm_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
2513 {
2514    ELM_CHECK_WIDTYPE(obj, widtype);
2515    Widget_Data *wd = elm_widget_data_get(obj);
2516    if (!wd) return;
2517    if (wd->single_line == single_line) return;
2518    wd->single_line = single_line;
2519    wd->linewrap = ELM_WRAP_NONE;
2520    elm_entry_cnp_mode_set(obj, ELM_CNP_MODE_NO_IMAGE);
2521    _theme_hook(obj);
2522    if (wd->scroller)
2523      {
2524         if (wd->single_line)
2525           elm_smart_scroller_policy_set(wd->scroller,
2526                                         ELM_SMART_SCROLLER_POLICY_OFF,
2527                                         ELM_SMART_SCROLLER_POLICY_OFF);
2528         else
2529           {
2530              const Elm_Scroller_Policy map[3] =
2531                {
2532                   ELM_SMART_SCROLLER_POLICY_AUTO,
2533                   ELM_SMART_SCROLLER_POLICY_ON,
2534                   ELM_SMART_SCROLLER_POLICY_OFF
2535                };
2536              elm_smart_scroller_policy_set(wd->scroller,
2537                                            map[wd->policy_h],
2538                                            map[wd->policy_v]);
2539           }
2540         _sizing_eval(obj);
2541      }
2542 }
2543
2544 EAPI Eina_Bool
2545 elm_entry_single_line_get(const Evas_Object *obj)
2546 {
2547    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2548    Widget_Data *wd = elm_widget_data_get(obj);
2549    if (!wd) return EINA_FALSE;
2550    return wd->single_line;
2551 }
2552
2553 EAPI void
2554 elm_entry_password_set(Evas_Object *obj, Eina_Bool password)
2555 {
2556    ELM_CHECK_WIDTYPE(obj, widtype);
2557    Widget_Data *wd = elm_widget_data_get(obj);
2558    if (!wd) return;
2559    if (wd->password == password) return;
2560    wd->password = password;
2561    if (password)
2562      {
2563         wd->single_line = EINA_TRUE;
2564         wd->linewrap = ELM_WRAP_NONE;
2565 #ifdef HAVE_ELEMENTARY_X
2566         elm_drop_target_del(obj);
2567 #endif
2568         edje_object_signal_callback_del_full(wd->ent, "selection,start", "elm.text",
2569                                         _signal_selection_start, obj);
2570         edje_object_signal_callback_del_full(wd->ent, "selection,changed", "elm.text",
2571                                         _signal_selection_changed, obj);
2572         edje_object_signal_callback_del_full(wd->ent, "entry,selection,all,request", "elm.text",
2573                                         _signal_selection_all, obj);
2574         edje_object_signal_callback_del_full(wd->ent, "entry,selection,none,request", "elm.text",
2575                                         _signal_selection_none, obj);
2576         edje_object_signal_callback_del_full(wd->ent, "selection,cleared", "elm.text",
2577                                         _signal_selection_cleared, obj);
2578         edje_object_signal_callback_del_full(wd->ent, "entry,paste,request,*", "elm.text",
2579                                         _signal_entry_paste_request, obj);
2580         edje_object_signal_callback_del_full(wd->ent, "entry,copy,notify", "elm.text",
2581                                         _signal_entry_copy_notify, obj);
2582         edje_object_signal_callback_del_full(wd->ent, "entry,cut,notify", "elm.text",
2583                                         _signal_entry_cut_notify, obj);
2584      }
2585    else
2586      {
2587 #ifdef HAVE_ELEMENTARY_X
2588         elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP, _drag_drop_cb, NULL);
2589 #endif
2590         edje_object_signal_callback_add(wd->ent, "selection,start", "elm.text",
2591                                         _signal_selection_start, obj);
2592         edje_object_signal_callback_add(wd->ent, "selection,changed", "elm.text",
2593                                         _signal_selection_changed, obj);
2594         edje_object_signal_callback_add(wd->ent, "entry,selection,all,request", "elm.text",
2595                                         _signal_selection_all, obj);
2596         edje_object_signal_callback_add(wd->ent, "entry,selection,none,request", "elm.text",
2597                                         _signal_selection_none, obj);
2598         edje_object_signal_callback_add(wd->ent, "selection,cleared", "elm.text",
2599                                         _signal_selection_cleared, obj);
2600         edje_object_signal_callback_add(wd->ent, "entry,paste,request,*", "elm.text",
2601                                         _signal_entry_paste_request, obj);
2602         edje_object_signal_callback_add(wd->ent, "entry,copy,notify", "elm.text",
2603                                         _signal_entry_copy_notify, obj);
2604         edje_object_signal_callback_add(wd->ent, "entry,cut,notify", "elm.text",
2605                                         _signal_entry_cut_notify, obj);
2606      }
2607    _theme_hook(obj);
2608 }
2609
2610 EAPI Eina_Bool
2611 elm_entry_password_get(const Evas_Object *obj)
2612 {
2613    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2614    Widget_Data *wd = elm_widget_data_get(obj);
2615    if (!wd) return EINA_FALSE;
2616    return wd->password;
2617 }
2618
2619 EAPI void
2620 elm_entry_entry_set(Evas_Object *obj, const char *entry)
2621 {
2622    _elm_entry_text_set(obj, NULL, entry);
2623 }
2624
2625 EAPI const char *
2626 elm_entry_entry_get(const Evas_Object *obj)
2627 {
2628    return _elm_entry_text_get(obj, NULL);
2629 }
2630
2631 EAPI void
2632 elm_entry_entry_append(Evas_Object *obj, const char *entry)
2633 {
2634    int len = 0;
2635    ELM_CHECK_WIDTYPE(obj, widtype);
2636    Widget_Data *wd = elm_widget_data_get(obj);
2637    if (!wd) return;
2638    if (!entry) entry = "";
2639    wd->changed = EINA_TRUE;
2640
2641    len = strlen(entry);
2642    if (wd->append_text_left)
2643      {
2644         char *tmpbuf;
2645         tmpbuf = realloc(wd->append_text_left, wd->append_text_len + len + 1);
2646         if (!tmpbuf)
2647           {
2648              /* Do something */
2649              return;
2650           }
2651         wd->append_text_left = tmpbuf;
2652         memcpy(wd->append_text_left + wd->append_text_len, entry, len + 1);
2653         wd->append_text_len += len;
2654      }
2655    else
2656      {
2657         /* FIXME: Add chunked appending here (like in entry_set) */
2658         edje_object_part_text_append(wd->ent, "elm.text", entry);
2659      }
2660 }
2661
2662 EAPI Eina_Bool
2663 elm_entry_is_empty(const Evas_Object *obj)
2664 {
2665    /* FIXME: until there's support for that in textblock, we just check
2666     * to see if the there is text or not. */
2667    ELM_CHECK_WIDTYPE(obj, widtype) EINA_TRUE;
2668    Widget_Data *wd = elm_widget_data_get(obj);
2669    const Evas_Object *tb;
2670    Evas_Textblock_Cursor *cur;
2671    Eina_Bool ret;
2672    if (!wd) return EINA_TRUE;
2673    /* It's a hack until we get the support suggested above.
2674     * We just create a cursor, point it to the begining, and then
2675     * try to advance it, if it can advance, the tb is not empty,
2676     * otherwise it is. */
2677    tb = edje_object_part_object_get(wd->ent, "elm.text");
2678    cur = evas_object_textblock_cursor_new((Evas_Object *) tb); /* This is
2679                                                                   actually, ok for the time being, thsese hackish stuff will be removed
2680                                                                   once evas 1.0 is out*/
2681    evas_textblock_cursor_pos_set(cur, 0);
2682    ret = evas_textblock_cursor_char_next(cur);
2683    evas_textblock_cursor_free(cur);
2684
2685    return !ret;
2686 }
2687
2688 EAPI Evas_Object *
2689 elm_entry_textblock_get(Evas_Object *obj)
2690 {
2691    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2692    Widget_Data *wd = elm_widget_data_get(obj);
2693    if (!wd) return NULL;
2694
2695    return (Evas_Object *) edje_object_part_object_get(wd->ent, "elm.text");
2696 }
2697
2698 EAPI void
2699 elm_entry_calc_force(Evas_Object *obj)
2700 {
2701    ELM_CHECK_WIDTYPE(obj, widtype);
2702    Widget_Data *wd = elm_widget_data_get(obj);
2703    if (!wd) return;
2704
2705    edje_object_calc_force(wd->ent);
2706    wd->changed = EINA_TRUE;
2707    _sizing_eval(obj);
2708 }
2709
2710
2711 EAPI const char *
2712 elm_entry_selection_get(const Evas_Object *obj)
2713 {
2714    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2715    Widget_Data *wd = elm_widget_data_get(obj);
2716    if ((!wd) || (wd->password)) return NULL;
2717    return edje_object_part_text_selection_get(wd->ent, "elm.text");
2718 }
2719
2720 EAPI void
2721 elm_entry_entry_insert(Evas_Object *obj, const char *entry)
2722 {
2723    ELM_CHECK_WIDTYPE(obj, widtype);
2724    Widget_Data *wd = elm_widget_data_get(obj);
2725    if (!wd) return;
2726    edje_object_part_text_insert(wd->ent, "elm.text", entry);
2727    wd->changed = EINA_TRUE;
2728    _sizing_eval(obj);
2729 }
2730
2731 EAPI void
2732 elm_entry_line_wrap_set(Evas_Object *obj, Elm_Wrap_Type wrap)
2733 {
2734    ELM_CHECK_WIDTYPE(obj, widtype);
2735    Widget_Data *wd = elm_widget_data_get(obj);
2736    if (!wd) return;
2737    if (wd->linewrap == wrap) return;
2738    wd->lastw = -1;
2739    wd->linewrap = wrap;
2740    _theme_hook(obj);
2741 }
2742
2743 EAPI Elm_Wrap_Type
2744 elm_entry_line_wrap_get(const Evas_Object *obj)
2745 {
2746    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2747    Widget_Data *wd = elm_widget_data_get(obj);
2748    if (!wd) return EINA_FALSE;
2749    return wd->linewrap;
2750 }
2751
2752 EAPI void
2753 elm_entry_editable_set(Evas_Object *obj, Eina_Bool editable)
2754 {
2755    ELM_CHECK_WIDTYPE(obj, widtype);
2756    Widget_Data *wd = elm_widget_data_get(obj);
2757    if (!wd) return;
2758    if (wd->editable == editable) return;
2759    wd->editable = editable;
2760    _theme_hook(obj);
2761
2762 #ifdef HAVE_ELEMENTARY_X
2763    if (editable)
2764      elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP, _drag_drop_cb, NULL);
2765    else
2766      elm_drop_target_del(obj);
2767 #endif
2768 }
2769
2770 EAPI Eina_Bool
2771 elm_entry_editable_get(const Evas_Object *obj)
2772 {
2773    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2774    Widget_Data *wd = elm_widget_data_get(obj);
2775    if (!wd) return EINA_FALSE;
2776    return wd->editable;
2777 }
2778
2779 EAPI void
2780 elm_entry_select_none(Evas_Object *obj)
2781 {
2782    ELM_CHECK_WIDTYPE(obj, widtype);
2783    Widget_Data *wd = elm_widget_data_get(obj);
2784    if ((!wd) || (wd->password)) return;
2785    if (wd->selmode)
2786      {
2787         wd->selmode = EINA_FALSE;
2788         if (!_elm_config->desktop_entry)
2789           edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
2790         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
2791      }
2792    wd->have_selection = EINA_FALSE;
2793    edje_object_part_text_select_none(wd->ent, "elm.text");
2794 }
2795
2796 EAPI void
2797 elm_entry_select_all(Evas_Object *obj)
2798 {
2799    ELM_CHECK_WIDTYPE(obj, widtype);
2800    Widget_Data *wd = elm_widget_data_get(obj);
2801    if ((!wd) || (wd->password)) return;
2802    if (wd->selmode)
2803      {
2804         wd->selmode = EINA_FALSE;
2805         if (!_elm_config->desktop_entry)
2806           edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
2807         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
2808      }
2809    wd->have_selection = EINA_TRUE;
2810    edje_object_part_text_select_all(wd->ent, "elm.text");
2811 }
2812
2813 EAPI Eina_Bool
2814 elm_entry_cursor_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
2815 {
2816    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2817    Widget_Data *wd = elm_widget_data_get(obj);
2818    if (!wd) return EINA_FALSE;
2819    edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text", x, y, w, h);
2820    return EINA_TRUE;
2821 }
2822
2823 EAPI Eina_Bool
2824 elm_entry_cursor_next(Evas_Object *obj)
2825 {
2826    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2827    Widget_Data *wd = elm_widget_data_get(obj);
2828    if (!wd) return EINA_FALSE;
2829    return edje_object_part_text_cursor_next(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2830 }
2831
2832 EAPI Eina_Bool
2833 elm_entry_cursor_prev(Evas_Object *obj)
2834 {
2835    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2836    Widget_Data *wd = elm_widget_data_get(obj);
2837    if (!wd) return EINA_FALSE;
2838    return edje_object_part_text_cursor_prev(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2839 }
2840
2841 EAPI Eina_Bool
2842 elm_entry_cursor_up(Evas_Object *obj)
2843 {
2844    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2845    Widget_Data *wd = elm_widget_data_get(obj);
2846    if (!wd) return EINA_FALSE;
2847    return edje_object_part_text_cursor_up(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2848 }
2849
2850 EAPI Eina_Bool
2851 elm_entry_cursor_down(Evas_Object *obj)
2852 {
2853    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2854    Widget_Data *wd = elm_widget_data_get(obj);
2855    if (!wd) return EINA_FALSE;
2856    return edje_object_part_text_cursor_down(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2857 }
2858
2859 EAPI void
2860 elm_entry_cursor_begin_set(Evas_Object *obj)
2861 {
2862    ELM_CHECK_WIDTYPE(obj, widtype);
2863    Widget_Data *wd = elm_widget_data_get(obj);
2864    if (!wd) return;
2865    edje_object_part_text_cursor_begin_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2866 }
2867
2868 EAPI void
2869 elm_entry_cursor_end_set(Evas_Object *obj)
2870 {
2871    ELM_CHECK_WIDTYPE(obj, widtype);
2872    Widget_Data *wd = elm_widget_data_get(obj);
2873    if (!wd) return;
2874    edje_object_part_text_cursor_end_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2875 }
2876
2877 EAPI void
2878 elm_entry_cursor_line_begin_set(Evas_Object *obj)
2879 {
2880    ELM_CHECK_WIDTYPE(obj, widtype);
2881    Widget_Data *wd = elm_widget_data_get(obj);
2882    if (!wd) return;
2883    edje_object_part_text_cursor_line_begin_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2884 }
2885
2886 EAPI void
2887 elm_entry_cursor_line_end_set(Evas_Object *obj)
2888 {
2889    ELM_CHECK_WIDTYPE(obj, widtype);
2890    Widget_Data *wd = elm_widget_data_get(obj);
2891    if (!wd) return;
2892    edje_object_part_text_cursor_line_end_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2893 }
2894
2895 EAPI void
2896 elm_entry_cursor_selection_begin(Evas_Object *obj)
2897 {
2898    ELM_CHECK_WIDTYPE(obj, widtype);
2899    Widget_Data *wd = elm_widget_data_get(obj);
2900    if (!wd) return;
2901    edje_object_part_text_select_begin(wd->ent, "elm.text");
2902 }
2903
2904 EAPI void
2905 elm_entry_cursor_selection_end(Evas_Object *obj)
2906 {
2907    ELM_CHECK_WIDTYPE(obj, widtype);
2908    Widget_Data *wd = elm_widget_data_get(obj);
2909    if (!wd) return;
2910    edje_object_part_text_select_extend(wd->ent, "elm.text");
2911 }
2912
2913 EAPI Eina_Bool
2914 elm_entry_cursor_is_format_get(const Evas_Object *obj)
2915 {
2916    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2917    Widget_Data *wd = elm_widget_data_get(obj);
2918    if (!wd) return EINA_FALSE;
2919    return edje_object_part_text_cursor_is_format_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2920 }
2921
2922 EAPI Eina_Bool
2923 elm_entry_cursor_is_visible_format_get(const Evas_Object *obj)
2924 {
2925    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2926    Widget_Data *wd = elm_widget_data_get(obj);
2927    if (!wd) return EINA_FALSE;
2928    return edje_object_part_text_cursor_is_visible_format_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2929 }
2930
2931 EAPI char *
2932 elm_entry_cursor_content_get(const Evas_Object *obj)
2933 {
2934    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2935    Widget_Data *wd = elm_widget_data_get(obj);
2936    if (!wd) return NULL;
2937    return edje_object_part_text_cursor_content_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2938 }
2939
2940 EAPI void
2941 elm_entry_cursor_pos_set(Evas_Object *obj, int pos)
2942 {
2943    ELM_CHECK_WIDTYPE(obj, widtype);
2944    Widget_Data *wd = elm_widget_data_get(obj);
2945    if (!wd) return;
2946    edje_object_part_text_cursor_pos_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN, pos);
2947    edje_object_message_signal_process(wd->ent);
2948 }
2949
2950 EAPI int
2951 elm_entry_cursor_pos_get(const Evas_Object *obj)
2952 {
2953    ELM_CHECK_WIDTYPE(obj, widtype) 0;
2954    Widget_Data *wd = elm_widget_data_get(obj);
2955    if (!wd) return 0;
2956    return edje_object_part_text_cursor_pos_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2957 }
2958
2959 EAPI void
2960 elm_entry_selection_cut(Evas_Object *obj)
2961 {
2962    ELM_CHECK_WIDTYPE(obj, widtype);
2963    Widget_Data *wd = elm_widget_data_get(obj);
2964    if ((!wd) || (wd->password)) return;
2965    _cut(obj, NULL, NULL);
2966 }
2967
2968 EAPI void
2969 elm_entry_selection_copy(Evas_Object *obj)
2970 {
2971    ELM_CHECK_WIDTYPE(obj, widtype);
2972    Widget_Data *wd = elm_widget_data_get(obj);
2973    if ((!wd) || (wd->password)) return;
2974    _copy(obj, NULL, NULL);
2975 }
2976
2977 EAPI void
2978 elm_entry_selection_paste(Evas_Object *obj)
2979 {
2980    ELM_CHECK_WIDTYPE(obj, widtype);
2981    Widget_Data *wd = elm_widget_data_get(obj);
2982    if ((!wd) || (wd->password)) return;
2983    _paste(obj, NULL, NULL);
2984 }
2985
2986 EAPI void
2987 elm_entry_context_menu_clear(Evas_Object *obj)
2988 {
2989    ELM_CHECK_WIDTYPE(obj, widtype);
2990    Widget_Data *wd = elm_widget_data_get(obj);
2991    Elm_Entry_Context_Menu_Item *it;
2992    if (!wd) return;
2993    EINA_LIST_FREE(wd->items, it)
2994      {
2995         eina_stringshare_del(it->label);
2996         eina_stringshare_del(it->icon_file);
2997         eina_stringshare_del(it->icon_group);
2998         free(it);
2999      }
3000 }
3001
3002 EAPI void
3003 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)
3004 {
3005    ELM_CHECK_WIDTYPE(obj, widtype);
3006    Widget_Data *wd = elm_widget_data_get(obj);
3007    Elm_Entry_Context_Menu_Item *it;
3008    if (!wd) return;
3009    it = calloc(1, sizeof(Elm_Entry_Context_Menu_Item));
3010    if (!it) return;
3011    wd->items = eina_list_append(wd->items, it);
3012    it->obj = obj;
3013    it->label = eina_stringshare_add(label);
3014    it->icon_file = eina_stringshare_add(icon_file);
3015    it->icon_type = icon_type;
3016    it->func = func;
3017    it->data = (void *)data;
3018 }
3019
3020 EAPI void
3021 elm_entry_context_menu_disabled_set(Evas_Object *obj, Eina_Bool disabled)
3022 {
3023    ELM_CHECK_WIDTYPE(obj, widtype);
3024    Widget_Data *wd = elm_widget_data_get(obj);
3025    if (!wd) return;
3026    if (wd->context_menu == !disabled) return;
3027    wd->context_menu = !disabled;
3028 }
3029
3030 EAPI Eina_Bool
3031 elm_entry_context_menu_disabled_get(const Evas_Object *obj)
3032 {
3033    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3034    Widget_Data *wd = elm_widget_data_get(obj);
3035    if (!wd) return EINA_FALSE;
3036    return !wd->context_menu;
3037 }
3038
3039 EAPI void
3040 elm_entry_item_provider_append(Evas_Object *obj, Elm_Entry_Item_Provider_Cb func, void *data)
3041 {
3042    ELM_CHECK_WIDTYPE(obj, widtype);
3043    Widget_Data *wd = elm_widget_data_get(obj);
3044    if (!wd) return;
3045    EINA_SAFETY_ON_NULL_RETURN(func);
3046    Elm_Entry_Item_Provider *ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
3047    if (!ip) return;
3048    ip->func = func;
3049    ip->data = data;
3050    wd->item_providers = eina_list_append(wd->item_providers, ip);
3051 }
3052
3053 EAPI void
3054 elm_entry_item_provider_prepend(Evas_Object *obj, Elm_Entry_Item_Provider_Cb func, void *data)
3055 {
3056    ELM_CHECK_WIDTYPE(obj, widtype);
3057    Widget_Data *wd = elm_widget_data_get(obj);
3058    if (!wd) return;
3059    EINA_SAFETY_ON_NULL_RETURN(func);
3060    Elm_Entry_Item_Provider *ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
3061    if (!ip) return;
3062    ip->func = func;
3063    ip->data = data;
3064    wd->item_providers = eina_list_prepend(wd->item_providers, ip);
3065 }
3066
3067 EAPI void
3068 elm_entry_item_provider_remove(Evas_Object *obj, Elm_Entry_Item_Provider_Cb func, void *data)
3069 {
3070    ELM_CHECK_WIDTYPE(obj, widtype);
3071    Widget_Data *wd = elm_widget_data_get(obj);
3072    Eina_List *l;
3073    Elm_Entry_Item_Provider *ip;
3074    if (!wd) return;
3075    EINA_SAFETY_ON_NULL_RETURN(func);
3076    EINA_LIST_FOREACH(wd->item_providers, l, ip)
3077      {
3078         if ((ip->func == func) && ((!data) || (ip->data == data)))
3079           {
3080              wd->item_providers = eina_list_remove_list(wd->item_providers, l);
3081              free(ip);
3082              return;
3083           }
3084      }
3085 }
3086
3087 EAPI void
3088 elm_entry_text_filter_append(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3089 {
3090    Widget_Data *wd;
3091    Elm_Entry_Markup_Filter *tf;
3092    ELM_CHECK_WIDTYPE(obj, widtype);
3093
3094    wd = elm_widget_data_get(obj);
3095
3096    EINA_SAFETY_ON_NULL_RETURN(func);
3097
3098    tf = _filter_new(func, data);
3099    if (!tf) return;
3100
3101    wd->text_filters = eina_list_append(wd->text_filters, tf);
3102 }
3103
3104 EAPI void
3105 elm_entry_text_filter_prepend(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3106 {
3107    Widget_Data *wd;
3108    Elm_Entry_Markup_Filter *tf;
3109    ELM_CHECK_WIDTYPE(obj, widtype);
3110
3111    wd = elm_widget_data_get(obj);
3112
3113    EINA_SAFETY_ON_NULL_RETURN(func);
3114
3115    tf = _filter_new(func, data);
3116    if (!tf) return;
3117
3118    wd->text_filters = eina_list_prepend(wd->text_filters, tf);
3119 }
3120
3121 EAPI void
3122 elm_entry_text_filter_remove(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3123 {
3124    Widget_Data *wd;
3125    Eina_List *l;
3126    Elm_Entry_Markup_Filter *tf;
3127    ELM_CHECK_WIDTYPE(obj, widtype);
3128
3129    wd = elm_widget_data_get(obj);
3130
3131    EINA_SAFETY_ON_NULL_RETURN(func);
3132
3133    EINA_LIST_FOREACH(wd->text_filters, l, tf)
3134      {
3135         if ((tf->func == func) && ((!data) || (tf->data == data)))
3136           {
3137              wd->text_filters = eina_list_remove_list(wd->text_filters, l);
3138              _filter_free(tf);
3139              return;
3140           }
3141      }
3142 }
3143
3144 EAPI void
3145 elm_entry_markup_filter_append(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3146 {
3147    Widget_Data *wd;
3148    Elm_Entry_Markup_Filter *tf;
3149    ELM_CHECK_WIDTYPE(obj, widtype);
3150
3151    wd = elm_widget_data_get(obj);
3152
3153    EINA_SAFETY_ON_NULL_RETURN(func);
3154
3155    tf = _filter_new(func, data);
3156    if (!tf) return;
3157
3158    wd->markup_filters = eina_list_append(wd->markup_filters, tf);
3159 }
3160
3161 EAPI void
3162 elm_entry_markup_filter_prepend(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3163 {
3164    Widget_Data *wd;
3165    Elm_Entry_Markup_Filter *tf;
3166    ELM_CHECK_WIDTYPE(obj, widtype);
3167
3168    wd = elm_widget_data_get(obj);
3169
3170    EINA_SAFETY_ON_NULL_RETURN(func);
3171
3172    tf = _filter_new(func, data);
3173    if (!tf) return;
3174
3175    wd->markup_filters = eina_list_prepend(wd->markup_filters, tf);
3176 }
3177
3178 EAPI void
3179 elm_entry_markup_filter_remove(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3180 {
3181    Widget_Data *wd;
3182    Eina_List *l;
3183    Elm_Entry_Markup_Filter *tf;
3184    ELM_CHECK_WIDTYPE(obj, widtype);
3185
3186    wd = elm_widget_data_get(obj);
3187
3188    EINA_SAFETY_ON_NULL_RETURN(func);
3189
3190    EINA_LIST_FOREACH(wd->markup_filters, l, tf)
3191      {
3192         if ((tf->func == func) && ((!data) || (tf->data == data)))
3193           {
3194              wd->markup_filters = eina_list_remove_list(wd->markup_filters, l);
3195              _filter_free(tf);
3196              return;
3197           }
3198      }
3199 }
3200
3201 EAPI char *
3202 elm_entry_markup_to_utf8(const char *s)
3203 {
3204    char *ss = _elm_util_mkup_to_text(s);
3205    if (!ss) ss = strdup("");
3206    return ss;
3207 }
3208
3209 EAPI char *
3210 elm_entry_utf8_to_markup(const char *s)
3211 {
3212    char *ss = _elm_util_text_to_mkup(s);
3213    if (!ss) ss = strdup("");
3214    return ss;
3215 }
3216
3217 static const char *
3218 _text_get(const Evas_Object *obj)
3219 {
3220    return elm_object_text_get(obj);
3221 }
3222
3223 EAPI void
3224 elm_entry_filter_limit_size(void *data, Evas_Object *entry, char **text)
3225 {
3226    Elm_Entry_Filter_Limit_Size *lim = data;
3227    char *current, *utfstr;
3228    int len, newlen;
3229    const char *(*text_get)(const Evas_Object *);
3230
3231    EINA_SAFETY_ON_NULL_RETURN(data);
3232    EINA_SAFETY_ON_NULL_RETURN(entry);
3233    EINA_SAFETY_ON_NULL_RETURN(text);
3234
3235    /* hack. I don't want to copy the entire function to work with
3236     * scrolled_entry */
3237    text_get = _text_get;
3238
3239    current = elm_entry_markup_to_utf8(text_get(entry));
3240    utfstr = elm_entry_markup_to_utf8(*text);
3241
3242    if (lim->max_char_count > 0)
3243      {
3244         len = evas_string_char_len_get(current);
3245         if (len >= lim->max_char_count)
3246           {
3247              evas_object_smart_callback_call(entry, "maxlength,reached", NULL);
3248              free(*text);
3249              *text = NULL;
3250              free(current);
3251              free(utfstr);
3252              return;
3253           }
3254         newlen = evas_string_char_len_get(utfstr);
3255         if ((len + newlen) > lim->max_char_count)
3256           _add_chars_till_limit(entry, text, (lim->max_char_count - len), LENGTH_UNIT_CHAR);
3257      }
3258    else if (lim->max_byte_count > 0)
3259      {
3260         len = strlen(current);
3261         if (len >= lim->max_byte_count)
3262           {
3263              evas_object_smart_callback_call(entry, "maxlength,reached", NULL);
3264              free(*text);
3265              *text = NULL;
3266              free(current);
3267              free(utfstr);
3268              return;
3269           }
3270         newlen = strlen(utfstr);
3271         if ((len + newlen) > lim->max_byte_count)
3272           _add_chars_till_limit(entry, text, (lim->max_byte_count - len), LENGTH_UNIT_BYTE);
3273      }
3274    free(current);
3275    free(utfstr);
3276 }
3277
3278 EAPI void
3279 elm_entry_filter_accept_set(void *data, Evas_Object *entry __UNUSED__, char **text)
3280 {
3281    Elm_Entry_Filter_Accept_Set *as = data;
3282    const char *set;
3283    char *insert;
3284    Eina_Bool goes_in;
3285    int read_idx, last_read_idx = 0, read_char;
3286
3287    EINA_SAFETY_ON_NULL_RETURN(data);
3288    EINA_SAFETY_ON_NULL_RETURN(text);
3289
3290    if ((!as->accepted) && (!as->rejected))
3291      return;
3292
3293    if (as->accepted)
3294      {
3295         set = as->accepted;
3296         goes_in = EINA_TRUE;
3297      }
3298    else
3299      {
3300         set = as->rejected;
3301         goes_in = EINA_FALSE;
3302      }
3303
3304    insert = *text;
3305    read_idx = evas_string_char_next_get(*text, 0, &read_char);
3306    while (read_char)
3307      {
3308         int cmp_idx, cmp_char;
3309         Eina_Bool in_set = EINA_FALSE;
3310
3311         cmp_idx = evas_string_char_next_get(set, 0, &cmp_char);
3312         while (cmp_char)
3313           {
3314              if (read_char == cmp_char)
3315                {
3316                   in_set = EINA_TRUE;
3317                   break;
3318                }
3319              cmp_idx = evas_string_char_next_get(set, cmp_idx, &cmp_char);
3320           }
3321         if (in_set == goes_in)
3322           {
3323              int size = read_idx - last_read_idx;
3324              const char *src = (*text) + last_read_idx;
3325              if (src != insert)
3326                memcpy(insert, *text + last_read_idx, size);
3327              insert += size;
3328           }
3329         last_read_idx = read_idx;
3330         read_idx = evas_string_char_next_get(*text, read_idx, &read_char);
3331      }
3332    *insert = 0;
3333 }
3334
3335 EAPI Eina_Bool
3336 elm_entry_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format)
3337 {
3338    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3339    Widget_Data *wd = elm_widget_data_get(obj);
3340    if (!wd) return EINA_FALSE;
3341    if (wd->delay_write)
3342      {
3343         ecore_timer_del(wd->delay_write);
3344         wd->delay_write = NULL;
3345      }
3346    if (wd->autosave) _save(obj);
3347    eina_stringshare_replace(&wd->file, file);
3348    wd->format = format;
3349    return _load(obj);
3350 }
3351
3352 EAPI void
3353 elm_entry_file_get(const Evas_Object *obj, const char **file, Elm_Text_Format *format)
3354 {
3355    ELM_CHECK_WIDTYPE(obj, widtype);
3356    Widget_Data *wd = elm_widget_data_get(obj);
3357    if (!wd) return;
3358    if (file) *file = wd->file;
3359    if (format) *format = wd->format;
3360 }
3361
3362 EAPI void
3363 elm_entry_file_save(Evas_Object *obj)
3364 {
3365    ELM_CHECK_WIDTYPE(obj, widtype);
3366    Widget_Data *wd = elm_widget_data_get(obj);
3367    if (!wd) return;
3368    if (wd->delay_write)
3369      {
3370         ecore_timer_del(wd->delay_write);
3371         wd->delay_write = NULL;
3372      }
3373    _save(obj);
3374    wd->delay_write = ecore_timer_add(2.0, _delay_write, obj);
3375 }
3376
3377 EAPI void
3378 elm_entry_autosave_set(Evas_Object *obj, Eina_Bool autosave)
3379 {
3380    ELM_CHECK_WIDTYPE(obj, widtype);
3381    Widget_Data *wd = elm_widget_data_get(obj);
3382    if (!wd) return;
3383    wd->autosave = !!autosave;
3384 }
3385
3386 EAPI Eina_Bool
3387 elm_entry_autosave_get(const Evas_Object *obj)
3388 {
3389    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3390    Widget_Data *wd = elm_widget_data_get(obj);
3391    if (!wd) return EINA_FALSE;
3392    return wd->autosave;
3393 }
3394
3395 EINA_DEPRECATED EAPI void
3396 elm_entry_cnp_textonly_set(Evas_Object *obj, Eina_Bool textonly)
3397 {
3398    ELM_CHECK_WIDTYPE(obj, widtype);
3399    Elm_Cnp_Mode cnp_mode = ELM_CNP_MODE_MARKUP;
3400    if (textonly)
3401      cnp_mode = ELM_CNP_MODE_NO_IMAGE;
3402    elm_entry_cnp_mode_set(obj, cnp_mode);
3403 }
3404
3405 EINA_DEPRECATED EAPI Eina_Bool
3406 elm_entry_cnp_textonly_get(const Evas_Object *obj)
3407 {
3408    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3409    return elm_entry_cnp_mode_get(obj) != ELM_CNP_MODE_MARKUP;
3410 }
3411
3412 EAPI void
3413 elm_entry_cnp_mode_set(Evas_Object *obj, Elm_Cnp_Mode cnp_mode)
3414 {
3415    Elm_Sel_Format format = ELM_SEL_FORMAT_MARKUP;
3416    ELM_CHECK_WIDTYPE(obj, widtype);
3417    Widget_Data *wd = elm_widget_data_get(obj);
3418    if (!wd) return;
3419    if (wd->cnp_mode == cnp_mode) return;
3420    wd->cnp_mode = cnp_mode;
3421    if (wd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
3422      format = ELM_SEL_FORMAT_TEXT;
3423    else if (cnp_mode == ELM_CNP_MODE_MARKUP) format |= ELM_SEL_FORMAT_IMAGE;
3424 #ifdef HAVE_ELEMENTARY_X
3425    elm_drop_target_add(obj, format, _drag_drop_cb, NULL);
3426 #endif
3427 }
3428
3429 EAPI Elm_Cnp_Mode
3430 elm_entry_cnp_mode_get(const Evas_Object *obj)
3431 {
3432    ELM_CHECK_WIDTYPE(obj, widtype) ELM_CNP_MODE_MARKUP;
3433    Widget_Data *wd = elm_widget_data_get(obj);
3434    if (!wd) return ELM_CNP_MODE_MARKUP;
3435    return wd->cnp_mode;
3436 }
3437
3438 EAPI void
3439 elm_entry_scrollable_set(Evas_Object *obj, Eina_Bool scroll)
3440 {
3441    ELM_CHECK_WIDTYPE(obj, widtype);
3442    Widget_Data *wd = elm_widget_data_get(obj);
3443    const Elm_Scroller_Policy map[3] =
3444      {
3445         ELM_SMART_SCROLLER_POLICY_AUTO,
3446         ELM_SMART_SCROLLER_POLICY_ON,
3447         ELM_SMART_SCROLLER_POLICY_OFF
3448      };
3449    if (!wd) return;
3450    scroll = !!scroll;
3451    if (wd->scroll == scroll) return;
3452    wd->scroll = scroll;
3453    if (wd->scroll)
3454      {
3455         if (!wd->scroller)
3456           {
3457              wd->scroller = elm_smart_scroller_add(evas_object_evas_get(obj));
3458              elm_widget_resize_object_set(obj, wd->scroller);
3459              elm_smart_scroller_widget_set(wd->scroller, obj);
3460              elm_smart_scroller_object_theme_set(obj, wd->scroller, "scroller", "entry",
3461                                                  elm_widget_style_get(obj));
3462              evas_object_size_hint_weight_set(wd->scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
3463              evas_object_size_hint_align_set(wd->scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
3464              evas_object_propagate_events_set(wd->scroller, EINA_TRUE);
3465              evas_object_propagate_events_set(elm_smart_scroller_edje_object_get(wd->scroller),
3466                                               EINA_TRUE);
3467           }
3468         elm_smart_scroller_bounce_allow_set(wd->scroller, wd->h_bounce, wd->v_bounce);
3469         if (wd->single_line)
3470           elm_smart_scroller_policy_set(wd->scroller, ELM_SMART_SCROLLER_POLICY_OFF,
3471                                         ELM_SMART_SCROLLER_POLICY_OFF);
3472         else
3473           elm_smart_scroller_policy_set(wd->scroller, map[wd->policy_h], map[wd->policy_v]);
3474         elm_widget_sub_object_add(obj, wd->ent);
3475         elm_smart_scroller_child_set(wd->scroller, wd->ent);
3476         evas_object_show(wd->scroller);
3477         elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3478      }
3479    else
3480      {
3481         if (wd->scroller)
3482           {
3483              elm_smart_scroller_child_set(wd->scroller, NULL);
3484              evas_object_smart_member_add(wd->scroller, obj);
3485              elm_widget_sub_object_add(obj, wd->scroller);
3486              evas_object_hide(wd->scroller);
3487           }
3488         elm_widget_sub_object_del(obj, wd->ent);
3489         elm_widget_resize_object_set(obj, wd->ent);
3490         elm_widget_on_show_region_hook_set(obj, NULL, NULL);
3491      }
3492    wd->lastw = -1;
3493    _theme_hook(obj);
3494 }
3495
3496 EAPI Eina_Bool
3497 elm_entry_scrollable_get(const Evas_Object *obj)
3498 {
3499    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3500    Widget_Data *wd = elm_widget_data_get(obj);
3501    if (!wd) return EINA_FALSE;
3502    return wd->scroll;
3503 }
3504
3505 EAPI void
3506 elm_entry_icon_set(Evas_Object *obj, Evas_Object *icon)
3507 {
3508    ELM_CHECK_WIDTYPE(obj, widtype);
3509    EINA_SAFETY_ON_NULL_RETURN(icon);
3510    _content_set_hook(obj, NULL, icon);
3511 }
3512
3513 EAPI Evas_Object *
3514 elm_entry_icon_get(const Evas_Object *obj)
3515 {
3516    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3517    return _content_get_hook(obj, NULL);
3518 }
3519
3520 EAPI Evas_Object *
3521 elm_entry_icon_unset(Evas_Object *obj)
3522 {
3523    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3524    return _content_unset_hook(obj, NULL);
3525 }
3526
3527 EAPI void
3528 elm_entry_icon_visible_set(Evas_Object *obj, Eina_Bool setting)
3529 {
3530    ELM_CHECK_WIDTYPE(obj, widtype);
3531    Widget_Data *wd = elm_widget_data_get(obj);
3532    Evas_Object *edje;
3533    if (!wd) return;
3534    if (wd->scroll)
3535       edje = elm_smart_scroller_edje_object_get(wd->scroller);
3536    else
3537       edje = wd->ent;
3538
3539    if ((!edje) || (!edje_object_part_swallow_get(edje, "elm.swallow.icon"))) return;
3540    if (setting)
3541      edje_object_signal_emit(edje, "elm,action,show,icon", "elm");
3542    else
3543      edje_object_signal_emit(edje, "elm,action,hide,icon", "elm");
3544    _sizing_eval(obj);
3545 }
3546
3547 EAPI void
3548 elm_entry_end_set(Evas_Object *obj, Evas_Object *end)
3549 {
3550    ELM_CHECK_WIDTYPE(obj, widtype);
3551    EINA_SAFETY_ON_NULL_RETURN(end);
3552    _content_set_hook(obj, "end", end);
3553 }
3554
3555 EAPI Evas_Object *
3556 elm_entry_end_get(const Evas_Object *obj)
3557 {
3558    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3559    return _content_get_hook(obj, "end");
3560 }
3561
3562 EAPI Evas_Object *
3563 elm_entry_end_unset(Evas_Object *obj)
3564 {
3565    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3566    return _content_unset_hook(obj, "end");
3567 }
3568
3569 EAPI void
3570 elm_entry_end_visible_set(Evas_Object *obj, Eina_Bool setting)
3571 {
3572    ELM_CHECK_WIDTYPE(obj, widtype);
3573    Widget_Data *wd = elm_widget_data_get(obj);
3574    Evas_Object *edje;
3575    if (!wd) return;
3576    if (wd->scroll)
3577       edje = elm_smart_scroller_edje_object_get(wd->scroller);
3578    else
3579       edje = wd->ent;
3580
3581    if ((!edje) || (!edje_object_part_swallow_get(edje, "elm.swallow.icon"))) return;
3582    if (setting)
3583      edje_object_signal_emit(edje, "elm,action,show,end", "elm");
3584    else
3585      edje_object_signal_emit(edje, "elm,action,hide,end", "elm");
3586    _sizing_eval(obj);
3587 }
3588
3589 EAPI void
3590 elm_entry_scrollbar_policy_set(Evas_Object *obj, Elm_Scroller_Policy h, Elm_Scroller_Policy v)
3591 {
3592    ELM_CHECK_WIDTYPE(obj, widtype);
3593    Widget_Data *wd = elm_widget_data_get(obj);
3594    const Elm_Scroller_Policy map[3] =
3595      {
3596         ELM_SMART_SCROLLER_POLICY_AUTO,
3597         ELM_SMART_SCROLLER_POLICY_ON,
3598         ELM_SMART_SCROLLER_POLICY_OFF
3599      };
3600    if (!wd) return;
3601    wd->policy_h = h;
3602    wd->policy_v = v;
3603    elm_smart_scroller_policy_set(wd->scroller,
3604                                  map[wd->policy_h],
3605                                  map[wd->policy_v]);
3606 }
3607
3608 EAPI void
3609 elm_entry_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
3610 {
3611    ELM_CHECK_WIDTYPE(obj, widtype);
3612    Widget_Data *wd = elm_widget_data_get(obj);
3613    if (!wd) return;
3614    wd->h_bounce = h_bounce;
3615    wd->v_bounce = v_bounce;
3616    elm_smart_scroller_bounce_allow_set(wd->scroller, h_bounce, v_bounce);
3617 }
3618
3619 EAPI void
3620 elm_entry_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
3621 {
3622    ELM_CHECK_WIDTYPE(obj, widtype);
3623    Widget_Data *wd = elm_widget_data_get(obj);
3624    if (!wd) return;
3625    elm_smart_scroller_bounce_allow_get(wd->scroller, h_bounce, v_bounce);
3626 }
3627
3628 EAPI void
3629 elm_entry_input_panel_layout_set(Evas_Object *obj, Elm_Input_Panel_Layout layout)
3630 {
3631    ELM_CHECK_WIDTYPE(obj, widtype);
3632    Widget_Data *wd = elm_widget_data_get(obj);
3633    if (!wd) return;
3634
3635    wd->input_panel_layout = layout;
3636
3637    edje_object_part_text_input_panel_layout_set(wd->ent, "elm.text", layout);
3638 }
3639
3640 EAPI Elm_Input_Panel_Layout
3641 elm_entry_input_panel_layout_get(const Evas_Object *obj)
3642 {
3643    ELM_CHECK_WIDTYPE(obj, widtype) ELM_INPUT_PANEL_LAYOUT_INVALID;
3644    Widget_Data *wd = elm_widget_data_get(obj);
3645    if (!wd) return ELM_INPUT_PANEL_LAYOUT_INVALID;
3646
3647    return wd->input_panel_layout;
3648 }
3649
3650 EAPI void
3651 elm_entry_autocapital_type_set(Evas_Object *obj, Elm_Autocapital_Type autocapital_type)
3652 {
3653    ELM_CHECK_WIDTYPE(obj, widtype);
3654    Widget_Data *wd = elm_widget_data_get(obj);
3655    if (!wd) return;
3656
3657    wd->autocapital_type = autocapital_type;
3658    edje_object_part_text_autocapital_type_set(wd->ent, "elm.text", autocapital_type);
3659 }
3660
3661 EAPI Elm_Autocapital_Type
3662 elm_entry_autocapital_type_get(const Evas_Object *obj)
3663 {
3664    ELM_CHECK_WIDTYPE(obj, widtype) ELM_AUTOCAPITAL_TYPE_NONE;
3665    Widget_Data *wd = elm_widget_data_get(obj);
3666    if (!wd) return ELM_AUTOCAPITAL_TYPE_NONE;
3667
3668    return wd->autocapital_type;
3669 }
3670
3671 EAPI void
3672 elm_entry_prediction_allow_set(Evas_Object *obj, Eina_Bool prediction)
3673 {
3674    ELM_CHECK_WIDTYPE(obj, widtype);
3675    Widget_Data *wd = elm_widget_data_get(obj);
3676    if (!wd) return;
3677
3678    wd->prediction_allow = prediction;
3679    edje_object_part_text_prediction_allow_set(wd->ent, "elm.text", prediction);
3680 }
3681
3682 EAPI Eina_Bool
3683 elm_entry_prediction_allow_get(const Evas_Object *obj)
3684 {
3685    ELM_CHECK_WIDTYPE(obj, widtype) EINA_TRUE;
3686    Widget_Data *wd = elm_widget_data_get(obj);
3687    if (!wd) return EINA_TRUE;
3688
3689    return wd->prediction_allow;
3690 }
3691
3692 EAPI void
3693 elm_entry_imf_context_reset(Evas_Object *obj)
3694 {
3695    ELM_CHECK_WIDTYPE(obj, widtype);
3696    Widget_Data *wd = elm_widget_data_get(obj);
3697    if (!wd) return;
3698
3699    edje_object_part_text_imf_context_reset(wd->ent, "elm.text");
3700 }
3701
3702 EAPI void
3703 elm_entry_input_panel_enabled_set(Evas_Object *obj, Eina_Bool enabled)
3704 {
3705    ELM_CHECK_WIDTYPE(obj, widtype);
3706    Widget_Data *wd = elm_widget_data_get(obj);
3707    if (!wd) return;
3708
3709    wd->input_panel_enable = enabled;
3710    edje_object_part_text_input_panel_enabled_set(wd->ent, "elm.text", enabled);
3711 }
3712
3713 EAPI Eina_Bool
3714 elm_entry_input_panel_enabled_get(const Evas_Object *obj)
3715 {
3716    ELM_CHECK_WIDTYPE(obj, widtype) EINA_TRUE;
3717    Widget_Data *wd = elm_widget_data_get(obj);
3718    if (!wd) return EINA_TRUE;
3719
3720    return wd->input_panel_enable;
3721 }
3722
3723 EAPI void
3724 elm_entry_input_panel_show(Evas_Object *obj)
3725 {
3726    ELM_CHECK_WIDTYPE(obj, widtype);
3727    Widget_Data *wd = elm_widget_data_get(obj);
3728    if (!wd) return;
3729
3730    edje_object_part_text_input_panel_show(wd->ent, "elm.text");
3731 }
3732
3733 EAPI void
3734 elm_entry_input_panel_hide(Evas_Object *obj)
3735 {
3736    ELM_CHECK_WIDTYPE(obj, widtype);
3737    Widget_Data *wd = elm_widget_data_get(obj);
3738    if (!wd) return;
3739
3740    edje_object_part_text_input_panel_hide(wd->ent, "elm.text");
3741 }
3742
3743 EAPI void
3744 elm_entry_input_panel_language_set(Evas_Object *obj, Elm_Input_Panel_Lang lang)
3745 {
3746    ELM_CHECK_WIDTYPE(obj, widtype);
3747    Widget_Data *wd = elm_widget_data_get(obj);
3748    if (!wd) return;
3749
3750    wd->input_panel_lang = lang;
3751    edje_object_part_text_input_panel_language_set(wd->ent, "elm.text", lang);
3752 }
3753
3754 EAPI Elm_Input_Panel_Lang
3755 elm_entry_input_panel_language_get(const Evas_Object *obj)
3756 {
3757    ELM_CHECK_WIDTYPE(obj, widtype) ELM_INPUT_PANEL_LANG_AUTOMATIC;
3758    Widget_Data *wd = elm_widget_data_get(obj);
3759    if (!wd) return ELM_INPUT_PANEL_LANG_AUTOMATIC;
3760
3761    return wd->input_panel_lang;
3762 }
3763
3764 EAPI void
3765 elm_entry_input_panel_imdata_set(Evas_Object *obj, const void *data, int len)
3766 {
3767    ELM_CHECK_WIDTYPE(obj, widtype);
3768    Widget_Data *wd = elm_widget_data_get(obj);
3769    if (!wd) return;
3770
3771    if (wd->input_panel_imdata)
3772      free(wd->input_panel_imdata);
3773
3774    wd->input_panel_imdata = calloc(1, len);
3775    wd->input_panel_imdata_len = len;
3776    memcpy(wd->input_panel_imdata, data, len);
3777
3778    edje_object_part_text_input_panel_imdata_set(wd->ent, "elm.text", wd->input_panel_imdata, wd->input_panel_imdata_len);
3779 }
3780
3781 EAPI void
3782 elm_entry_input_panel_imdata_get(const Evas_Object *obj, void *data, int *len)
3783 {
3784    ELM_CHECK_WIDTYPE(obj, widtype);
3785    Widget_Data *wd = elm_widget_data_get(obj);
3786    if (!wd) return;
3787
3788    edje_object_part_text_input_panel_imdata_get(wd->ent, "elm.text", data, len);
3789 }
3790
3791 EAPI void
3792 elm_entry_input_panel_return_key_type_set(Evas_Object *obj, Elm_Input_Panel_Return_Key_Type return_key_type)
3793 {
3794    ELM_CHECK_WIDTYPE(obj, widtype);
3795    Widget_Data *wd = elm_widget_data_get(obj);
3796    if (!wd) return;
3797
3798    wd->input_panel_return_key_type = return_key_type;
3799
3800    edje_object_part_text_input_panel_return_key_type_set(wd->ent, "elm.text", return_key_type);
3801 }
3802
3803 EAPI Elm_Input_Panel_Return_Key_Type
3804 elm_entry_input_panel_return_key_type_get(const Evas_Object *obj)
3805 {
3806    ELM_CHECK_WIDTYPE(obj, widtype) ELM_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3807    Widget_Data *wd = elm_widget_data_get(obj);
3808    if (!wd) return ELM_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3809
3810    return wd->input_panel_return_key_type;
3811 }
3812
3813 EAPI void
3814 elm_entry_input_panel_return_key_disabled_set(Evas_Object *obj, Eina_Bool disabled)
3815 {
3816    ELM_CHECK_WIDTYPE(obj, widtype);
3817    Widget_Data *wd = elm_widget_data_get(obj);
3818    if (!wd) return;
3819
3820    wd->input_panel_return_key_disabled = disabled;
3821
3822    edje_object_part_text_input_panel_return_key_disabled_set(wd->ent, "elm.text", disabled);
3823 }
3824
3825 EAPI Eina_Bool
3826 elm_entry_input_panel_return_key_disabled_get(const Evas_Object *obj)
3827 {
3828    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3829    Widget_Data *wd = elm_widget_data_get(obj);
3830    if (!wd) return EINA_FALSE;
3831
3832    return wd->input_panel_return_key_disabled;
3833 }
3834
3835 EAPI void
3836 elm_entry_input_panel_return_key_autoenabled_set(Evas_Object *obj, Eina_Bool enabled)
3837 {
3838    ELM_CHECK_WIDTYPE(obj, widtype);
3839    Widget_Data *wd = elm_widget_data_get(obj);
3840    if (!wd) return;
3841
3842    wd->autoreturnkey = enabled;
3843    _check_enable_return_key(obj);
3844 }
3845
3846 EAPI void*
3847 elm_entry_imf_context_get(Evas_Object *obj)
3848 {
3849    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3850    Widget_Data *wd = elm_widget_data_get(obj);
3851    if (!wd) return NULL;
3852
3853    return edje_object_part_text_imf_context_get(wd->ent, "elm.text");
3854 }
3855
3856 /* START - ANCHOR HOVER */
3857 static void
3858 _parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3859 {
3860    Widget_Data *wd = elm_widget_data_get(data);
3861    if (!wd) return;
3862    wd->anchor_hover.hover_parent = NULL;
3863 }
3864
3865 EAPI void
3866 elm_entry_anchor_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
3867 {
3868    ELM_CHECK_WIDTYPE(obj, widtype);
3869    Widget_Data *wd = elm_widget_data_get(obj);
3870    if (!wd) return;
3871    if (wd->anchor_hover.hover_parent)
3872      evas_object_event_callback_del_full(wd->anchor_hover.hover_parent, EVAS_CALLBACK_DEL, _parent_del, obj);
3873    wd->anchor_hover.hover_parent = parent;
3874    if (wd->anchor_hover.hover_parent)
3875      evas_object_event_callback_add(wd->anchor_hover.hover_parent, EVAS_CALLBACK_DEL, _parent_del, obj);
3876 }
3877
3878 EAPI Evas_Object *
3879 elm_entry_anchor_hover_parent_get(const Evas_Object *obj)
3880 {
3881    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3882    Widget_Data *wd = elm_widget_data_get(obj);
3883    if (!wd) return NULL;
3884    return wd->anchor_hover.hover_parent;
3885 }
3886
3887 EAPI void
3888 elm_entry_anchor_hover_style_set(Evas_Object *obj, const char *style)
3889 {
3890    ELM_CHECK_WIDTYPE(obj, widtype);
3891    Widget_Data *wd = elm_widget_data_get(obj);
3892    if (!wd) return;
3893    eina_stringshare_replace(&wd->anchor_hover.hover_style, style);
3894 }
3895
3896 EAPI const char *
3897 elm_entry_anchor_hover_style_get(const Evas_Object *obj)
3898 {
3899    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3900    Widget_Data *wd = elm_widget_data_get(obj);
3901    if (!wd) return NULL;
3902    return wd->anchor_hover.hover_style;
3903 }
3904
3905 EAPI void
3906 elm_entry_anchor_hover_end(Evas_Object *obj)
3907 {
3908    ELM_CHECK_WIDTYPE(obj, widtype);
3909    Widget_Data *wd = elm_widget_data_get(obj);
3910    if (!wd) return;
3911    if (wd->anchor_hover.hover) evas_object_del(wd->anchor_hover.hover);
3912    if (wd->anchor_hover.pop) evas_object_del(wd->anchor_hover.pop);
3913    wd->anchor_hover.hover = NULL;
3914    wd->anchor_hover.pop = NULL;
3915 }
3916
3917
3918 static void
3919 _anchor_hover_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3920 {
3921    elm_entry_anchor_hover_end(data);
3922 }
3923
3924 static void
3925 _entry_hover_anchor_clicked(void *data, Evas_Object *obj, void *event_info)
3926 {
3927    Widget_Data *wd = elm_widget_data_get(obj);
3928    Elm_Entry_Anchor_Info *info = event_info;
3929    Evas_Object *hover_parent;
3930    Elm_Entry_Anchor_Hover_Info ei;
3931    Evas_Coord x, w, y, h, px, py;
3932    if (!wd) return;
3933    ei.anchor_info = event_info;
3934    wd->anchor_hover.pop = elm_icon_add(obj);
3935    evas_object_move(wd->anchor_hover.pop, info->x, info->y);
3936    evas_object_resize(wd->anchor_hover.pop, info->w, info->h);
3937    wd->anchor_hover.hover = elm_hover_add(obj);
3938    elm_widget_mirrored_set(wd->anchor_hover.hover, elm_widget_mirrored_get(obj));
3939    if (wd->anchor_hover.hover_style)
3940      elm_object_style_set(wd->anchor_hover.hover, wd->anchor_hover.hover_style);
3941    hover_parent = wd->anchor_hover.hover_parent;
3942    if (!hover_parent) hover_parent = obj;
3943    elm_hover_parent_set(wd->anchor_hover.hover, hover_parent);
3944    elm_hover_target_set(wd->anchor_hover.hover, wd->anchor_hover.pop);
3945    ei.hover = wd->anchor_hover.hover;
3946    evas_object_geometry_get(hover_parent, &x, &y, &w, &h);
3947    ei.hover_parent.x = x;
3948    ei.hover_parent.y = y;
3949    ei.hover_parent.w = w;
3950    ei.hover_parent.h = h;
3951    px = info->x + (info->w / 2);
3952    py = info->y + (info->h / 2);
3953    ei.hover_left = 1;
3954    if (px < (x + (w / 3))) ei.hover_left = 0;
3955    ei.hover_right = 1;
3956    if (px > (x + ((w * 2) / 3))) ei.hover_right = 0;
3957    ei.hover_top = 1;
3958    if (py < (y + (h / 3))) ei.hover_top = 0;
3959    ei.hover_bottom = 1;
3960    if (py > (y + ((h * 2) / 3))) ei.hover_bottom = 0;
3961
3962    if (elm_widget_mirrored_get(wd->anchor_hover.hover))
3963      {  /* Swap right and left because they switch sides in RTL */
3964         Eina_Bool tmp = ei.hover_left;
3965         ei.hover_left = ei.hover_right;
3966         ei.hover_right = tmp;
3967      }
3968
3969    evas_object_smart_callback_call(data, SIG_ANCHOR_HOVER_OPENED, &ei);
3970    evas_object_smart_callback_add(wd->anchor_hover.hover, "clicked", _anchor_hover_clicked, data);
3971    evas_object_show(wd->anchor_hover.hover);
3972 }
3973 /* END - ANCHOR HOVER */
3974