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