Elm entry: Use the new edje_object_part_text_user_insert API.
[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    Widget_Data *wd = elm_widget_data_get(obj);
1153    edje_object_part_text_user_insert(wd->ent, "elm.text", entry);
1154 }
1155
1156 static void
1157 _paste(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1158 {
1159    Widget_Data *wd = elm_widget_data_get(data);
1160    if (!wd) return;
1161    evas_object_smart_callback_call(data, SIG_SELECTION_PASTE, NULL);
1162    if (wd->sel_notify_handler)
1163      {
1164 #ifdef HAVE_ELEMENTARY_X
1165         Elm_Sel_Format formats;
1166         wd->selection_asked = EINA_TRUE;
1167         formats = ELM_SEL_FORMAT_MARKUP;
1168         if (!wd->textonly)
1169           formats |= ELM_SEL_FORMAT_IMAGE;
1170         elm_cnp_selection_get(data, ELM_SEL_TYPE_CLIPBOARD, formats, NULL, NULL);
1171 #endif
1172      }
1173 }
1174
1175 static void
1176 _store_selection(Elm_Sel_Type seltype, Evas_Object *obj)
1177 {
1178    Widget_Data *wd = elm_widget_data_get(obj);
1179    const char *sel;
1180
1181    if (!wd) return;
1182    sel = edje_object_part_text_selection_get(wd->ent, "elm.text");
1183    if ((!sel) || (!sel[0])) return; /* avoid deleting our own selection */
1184    elm_cnp_selection_set(obj, seltype, ELM_SEL_FORMAT_MARKUP, sel, strlen(sel));
1185    if (seltype == ELM_SEL_TYPE_CLIPBOARD)
1186      eina_stringshare_replace(&wd->cut_sel, sel);
1187 }
1188
1189 static void
1190 _cut(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1191 {
1192    Widget_Data *wd = elm_widget_data_get(data);
1193
1194    /* Store it */
1195    wd->selmode = EINA_FALSE;
1196    if (!_elm_config->desktop_entry)
1197      edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
1198    edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
1199    if (!_elm_config->desktop_entry)
1200      elm_widget_scroll_hold_pop(data);
1201    _store_selection(ELM_SEL_TYPE_CLIPBOARD, data);
1202    edje_object_part_text_user_insert(wd->ent, "elm.text", "");
1203    _sizing_eval(data);
1204 }
1205
1206 static void
1207 _copy(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1208 {
1209    Widget_Data *wd = elm_widget_data_get(data);
1210    if (!wd) return;
1211    wd->selmode = EINA_FALSE;
1212    if (!_elm_config->desktop_entry)
1213      {
1214         edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
1215         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
1216         elm_widget_scroll_hold_pop(data);
1217      }
1218    _store_selection(ELM_SEL_TYPE_CLIPBOARD, data);
1219    //   edje_object_part_text_select_none(wd->ent, "elm.text");
1220 }
1221
1222 static void
1223 _cancel(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      edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
1230    edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
1231    if (!_elm_config->desktop_entry)
1232      elm_widget_scroll_hold_pop(data);
1233    edje_object_part_text_select_none(wd->ent, "elm.text");
1234 }
1235
1236 static void
1237 _item_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1238 {
1239    Elm_Entry_Context_Menu_Item *it = data;
1240    Evas_Object *obj2 = it->obj;
1241    if (it->func) it->func(it->data, obj2, NULL);
1242 }
1243
1244 static void
1245 _menu_press(Evas_Object *obj)
1246 {
1247    Widget_Data *wd = elm_widget_data_get(obj);
1248    Evas_Object *top;
1249    const Eina_List *l;
1250    const Elm_Entry_Context_Menu_Item *it;
1251    if (!wd) return;
1252    if ((wd->api) && (wd->api->obj_longpress))
1253      {
1254         wd->api->obj_longpress(obj);
1255      }
1256    else if (wd->context_menu)
1257      {
1258         const char *context_menu_orientation;
1259
1260         if (wd->hoversel) evas_object_del(wd->hoversel);
1261         else elm_widget_scroll_freeze_push(obj);
1262         wd->hoversel = elm_hoversel_add(obj);
1263         context_menu_orientation = edje_object_data_get
1264            (wd->ent, "context_menu_orientation");
1265         if ((context_menu_orientation) &&
1266             (!strcmp(context_menu_orientation, "horizontal")))
1267           elm_hoversel_horizontal_set(wd->hoversel, EINA_TRUE);
1268         elm_object_style_set(wd->hoversel, "entry");
1269         elm_widget_sub_object_add(obj, wd->hoversel);
1270         elm_object_text_set(wd->hoversel, "Text");
1271         top = elm_widget_top_get(obj);
1272         if (top) elm_hoversel_hover_parent_set(wd->hoversel, top);
1273         evas_object_smart_callback_add(wd->hoversel, "dismissed", _dismissed, obj);
1274         if (wd->have_selection)
1275           {
1276              if (!wd->password)
1277                {
1278                   if (wd->have_selection)
1279                     {
1280                        elm_hoversel_item_add(wd->hoversel, E_("Copy"), NULL, ELM_ICON_NONE,
1281                                              _copy, obj);
1282                        if (wd->editable)
1283                          elm_hoversel_item_add(wd->hoversel, E_("Cut"), NULL, ELM_ICON_NONE,
1284                                                _cut, obj);
1285                     }
1286                   elm_hoversel_item_add(wd->hoversel, E_("Cancel"), NULL, ELM_ICON_NONE,
1287                                         _cancel, obj);
1288                }
1289           }
1290         else
1291           {
1292              if (!wd->selmode)
1293                {
1294                   if (!_elm_config->desktop_entry)
1295                     {
1296                        if (!wd->password)
1297                          elm_hoversel_item_add(wd->hoversel, E_("Select"), NULL, ELM_ICON_NONE,
1298                                                _select, obj);
1299                     }
1300                   if (elm_selection_selection_has_owner())
1301                     {
1302                        if (wd->editable)
1303                          elm_hoversel_item_add(wd->hoversel, E_("Paste"), NULL, ELM_ICON_NONE,
1304                                                _paste, obj);
1305                     }
1306                }
1307           }
1308         EINA_LIST_FOREACH(wd->items, l, it)
1309           {
1310              elm_hoversel_item_add(wd->hoversel, it->label, it->icon_file,
1311                                    it->icon_type, _item_clicked, it);
1312           }
1313         if (wd->hoversel)
1314           {
1315              _hoversel_position(obj);
1316              evas_object_show(wd->hoversel);
1317              elm_hoversel_hover_begin(wd->hoversel);
1318           }
1319         if (!_elm_config->desktop_entry)
1320           {
1321              edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
1322              edje_object_part_text_select_abort(wd->ent, "elm.text");
1323           }
1324      }
1325 }
1326
1327 static Eina_Bool
1328 _long_press(void *data)
1329 {
1330    Widget_Data *wd = elm_widget_data_get(data);
1331    if (!wd) return ECORE_CALLBACK_CANCEL;
1332    _menu_press(data);
1333    wd->longpress_timer = NULL;
1334    evas_object_smart_callback_call(data, SIG_LONGPRESSED, NULL);
1335    return ECORE_CALLBACK_CANCEL;
1336 }
1337
1338 static void
1339 _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1340 {
1341    Widget_Data *wd = elm_widget_data_get(data);
1342    Evas_Event_Mouse_Down *ev = event_info;
1343    if (!wd) return;
1344    if (wd->disabled) return;
1345    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1346    wd->downx = ev->canvas.x;
1347    wd->downy = ev->canvas.y;
1348    if (ev->button == 1)
1349      {
1350         if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
1351         wd->longpress_timer = ecore_timer_add(_elm_config->longpress_timeout, _long_press, data);
1352      }
1353 }
1354
1355 static void
1356 _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1357 {
1358    Widget_Data *wd = elm_widget_data_get(data);
1359    Evas_Event_Mouse_Up *ev = event_info;
1360    if (!wd) return;
1361    if (wd->disabled) return;
1362    if (ev->button == 1)
1363      {
1364         if (wd->longpress_timer)
1365           {
1366              ecore_timer_del(wd->longpress_timer);
1367              wd->longpress_timer = NULL;
1368           }
1369      }
1370    else if (ev->button == 3)
1371      {
1372         wd->usedown = 1;
1373         _menu_press(data);
1374      }
1375 }
1376
1377 static void
1378 _mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1379 {
1380    Widget_Data *wd = elm_widget_data_get(data);
1381    Evas_Event_Mouse_Move *ev = event_info;
1382    if (!wd) return;
1383    if (wd->disabled) return;
1384    if (!wd->selmode)
1385      {
1386         if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1387           {
1388              if (wd->longpress_timer)
1389                {
1390                   ecore_timer_del(wd->longpress_timer);
1391                   wd->longpress_timer = NULL;
1392                }
1393           }
1394         else if (wd->longpress_timer)
1395           {
1396              Evas_Coord dx, dy;
1397
1398              dx = wd->downx - ev->cur.canvas.x;
1399              dx *= dx;
1400              dy = wd->downy - ev->cur.canvas.y;
1401              dy *= dy;
1402              if ((dx + dy) >
1403                  ((_elm_config->finger_size / 2) *
1404                   (_elm_config->finger_size / 2)))
1405                {
1406                   ecore_timer_del(wd->longpress_timer);
1407                   wd->longpress_timer = NULL;
1408                }
1409           }
1410      }
1411    else if (wd->longpress_timer)
1412      {
1413         Evas_Coord dx, dy;
1414
1415         dx = wd->downx - ev->cur.canvas.x;
1416         dx *= dx;
1417         dy = wd->downy - ev->cur.canvas.y;
1418         dy *= dy;
1419         if ((dx + dy) >
1420             ((_elm_config->finger_size / 2) *
1421              (_elm_config->finger_size / 2)))
1422           {
1423              ecore_timer_del(wd->longpress_timer);
1424              wd->longpress_timer = NULL;
1425           }
1426      }
1427 }
1428
1429 static const char *
1430 _getbase(Evas_Object *obj)
1431 {
1432    Widget_Data *wd = elm_widget_data_get(obj);
1433    if (!wd) return "base";
1434    if (wd->editable)
1435      {
1436         if (wd->password) return "base-password";
1437         else
1438           {
1439              if (wd->single_line) return "base-single";
1440              else
1441                {
1442                   switch (wd->linewrap)
1443                     {
1444                      case ELM_WRAP_CHAR:
1445                         return "base-charwrap";
1446                      case ELM_WRAP_WORD:
1447                         return "base";
1448                      case ELM_WRAP_MIXED:
1449                         return "base-mixedwrap";
1450                      case ELM_WRAP_NONE:
1451                      default:
1452                         return "base-nowrap";
1453                     }
1454                }
1455           }
1456      }
1457    else
1458      {
1459         if (wd->password) return "base-password";
1460         else
1461           {
1462              if (wd->single_line) return "base-single-noedit";
1463              else
1464                {
1465                   switch (wd->linewrap)
1466                     {
1467                      case ELM_WRAP_CHAR:
1468                         return "base-noedit-charwrap";
1469                      case ELM_WRAP_WORD:
1470                         return "base-noedit";
1471                      case ELM_WRAP_MIXED:
1472                         return "base-noedit-mixedwrap";
1473                      case ELM_WRAP_NONE:
1474                      default:
1475                         return "base-nowrap-noedit";
1476                     }
1477                }
1478           }
1479      }
1480 }
1481
1482 static void
1483 _entry_changed_common_handling(void *data, const char *event)
1484 {
1485    Widget_Data *wd = elm_widget_data_get(data);
1486    Evas_Coord minh;
1487    if (!wd) return;
1488    evas_event_freeze(evas_object_evas_get(data));
1489    wd->changed = EINA_TRUE;
1490    /* Reset the size hints which are no more relevant.
1491     * Keep the height, this is a hack, but doesn't really matter
1492     * cause we'll re-eval in a moment. */
1493    evas_object_size_hint_min_get(data, NULL, &minh);
1494    evas_object_size_hint_min_set(data, -1, minh);
1495    _sizing_eval(data);
1496    if (wd->text) eina_stringshare_del(wd->text);
1497    wd->text = NULL;
1498    if (wd->delay_write)
1499      {
1500         ecore_timer_del(wd->delay_write);
1501         wd->delay_write = NULL;
1502      }
1503    evas_event_thaw(evas_object_evas_get(data));
1504    evas_event_thaw_eval(evas_object_evas_get(data));
1505    if ((wd->autosave) && (wd->file))
1506      wd->delay_write = ecore_timer_add(2.0, _delay_write, data);
1507    /* callback - this could call callbacks that delete the entry... thus...
1508     * any access to wd after this could be invalid */
1509    evas_object_smart_callback_call(data, event, NULL);
1510    _check_enable_return_key(data);
1511 }
1512
1513 static void
1514 _signal_entry_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1515 {
1516    _entry_changed_common_handling(data, SIG_CHANGED);
1517 }
1518
1519 static void
1520 _signal_entry_changed_user(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1521 {
1522    Elm_Entry_Change_Info info;
1523    Edje_Entry_Change_Info *edje_info = (Edje_Entry_Change_Info *)
1524       edje_object_signal_callback_extra_data_get();
1525    if (edje_info)
1526      {
1527         memcpy(&info, edje_info, sizeof(info));
1528         evas_object_smart_callback_call(data, SIG_CHANGED_USER, &info);
1529      }
1530    else
1531      {
1532         evas_object_smart_callback_call(data, SIG_CHANGED_USER, NULL);
1533      }
1534 }
1535
1536 static void
1537 _signal_preedit_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1538 {
1539    _entry_changed_common_handling(data, SIG_PREEDIT_CHANGED);
1540 }
1541
1542 static void
1543 _signal_undo_request(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1544 {
1545    evas_object_smart_callback_call(data, SIG_UNDO_REQUEST, NULL);
1546 }
1547
1548 static void
1549 _signal_redo_request(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1550 {
1551    evas_object_smart_callback_call(data, SIG_REDO_REQUEST, NULL);
1552 }
1553
1554 static void
1555 _signal_selection_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1556 {
1557    Widget_Data *wd = elm_widget_data_get(data);
1558    const Eina_List *l;
1559    Evas_Object *entry;
1560    if (!wd) return;
1561    EINA_LIST_FOREACH(entries, l, entry)
1562      {
1563         if (entry != data) elm_entry_select_none(entry);
1564      }
1565    wd->have_selection = EINA_TRUE;
1566    evas_object_smart_callback_call(data, SIG_SELECTION_START, NULL);
1567 #ifdef HAVE_ELEMENTARY_X
1568    if (wd->sel_notify_handler)
1569      {
1570         const char *txt = elm_entry_selection_get(data);
1571         Evas_Object *top;
1572
1573         top = elm_widget_top_get(data);
1574         if (txt && top && (elm_win_xwindow_get(top)))
1575           elm_cnp_selection_set(data, ELM_SEL_TYPE_PRIMARY,
1576                                 ELM_SEL_FORMAT_MARKUP, txt, strlen(txt));
1577      }
1578 #endif
1579 }
1580
1581 static void
1582 _signal_selection_all(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1583 {
1584    Widget_Data *wd = elm_widget_data_get(data);
1585    if (!wd) return;
1586    elm_entry_select_all(data);
1587 }
1588
1589 static void
1590 _signal_selection_none(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1591 {
1592    Widget_Data *wd = elm_widget_data_get(data);
1593    if (!wd) return;
1594    elm_entry_select_none(data);
1595 }
1596
1597 static void
1598 _signal_selection_changed(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    wd->have_selection = EINA_TRUE;
1603    evas_object_smart_callback_call(data, SIG_SELECTION_CHANGED, NULL);
1604    _store_selection(ELM_SEL_TYPE_PRIMARY, data);
1605 }
1606
1607 static void
1608 _signal_selection_cleared(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1609 {
1610    Widget_Data *wd = elm_widget_data_get(data);
1611    if (!wd) return;
1612    if (!wd->have_selection) return;
1613    wd->have_selection = EINA_FALSE;
1614    evas_object_smart_callback_call(data, SIG_SELECTION_CLEARED, NULL);
1615    if (wd->sel_notify_handler)
1616      {
1617         if (wd->cut_sel)
1618           {
1619 #ifdef HAVE_ELEMENTARY_X
1620              Evas_Object *top;
1621
1622              top = elm_widget_top_get(data);
1623              if ((top) && (elm_win_xwindow_get(top)))
1624                elm_cnp_selection_set(data, ELM_SEL_TYPE_PRIMARY,
1625                                      ELM_SEL_FORMAT_MARKUP, wd->cut_sel,
1626                                      strlen(wd->cut_sel));
1627 #endif
1628              eina_stringshare_del(wd->cut_sel);
1629              wd->cut_sel = NULL;
1630           }
1631         else
1632           {
1633 #ifdef HAVE_ELEMENTARY_X
1634              Evas_Object *top;
1635
1636              top = elm_widget_top_get(data);
1637              if ((top) && (elm_win_xwindow_get(top)))
1638                elm_object_cnp_selection_clear(data, ELM_SEL_TYPE_PRIMARY);
1639 #endif
1640           }
1641      }
1642 }
1643
1644 static void
1645 _signal_entry_paste_request(void *data, Evas_Object *obj __UNUSED__, const char *emission, const char *source __UNUSED__)
1646 {
1647    Widget_Data *wd = elm_widget_data_get(data);
1648    Elm_Sel_Type type = (emission[sizeof("ntry,paste,request,")] == '1') ?
1649      ELM_SEL_TYPE_PRIMARY : ELM_SEL_TYPE_CLIPBOARD;
1650    if (!wd) return;
1651    evas_object_smart_callback_call(data, SIG_SELECTION_PASTE, NULL);
1652    if (wd->sel_notify_handler)
1653      {
1654 #ifdef HAVE_ELEMENTARY_X
1655         Evas_Object *top;
1656
1657         top = elm_widget_top_get(data);
1658         if ((top) && (elm_win_xwindow_get(top)))
1659           {
1660              wd->selection_asked = EINA_TRUE;
1661              elm_cnp_selection_get(data, type, ELM_SEL_FORMAT_MARKUP,
1662                                NULL, NULL);
1663           }
1664 #endif
1665      }
1666 }
1667
1668 static void
1669 _signal_entry_copy_notify(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1670 {
1671    evas_object_smart_callback_call(data, SIG_SELECTION_COPY, NULL);
1672    _copy(data, NULL, NULL);
1673 }
1674
1675 static void
1676 _signal_entry_cut_notify(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1677 {
1678    evas_object_smart_callback_call(data, SIG_SELECTION_CUT, NULL);
1679    _cut(data, NULL, NULL);
1680 }
1681
1682 static void
1683 _signal_cursor_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1684 {
1685    Widget_Data *wd = elm_widget_data_get(data);
1686    if (!wd) return;
1687    wd->cursor_pos = edje_object_part_text_cursor_pos_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
1688    wd->cur_changed = EINA_TRUE;
1689    _recalc_cursor_geometry(data);
1690 }
1691
1692 static void
1693 _signal_cursor_changed_manual(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1694 {
1695    evas_object_smart_callback_call(data, SIG_CURSOR_CHANGED_MANUAL, NULL);
1696 }
1697
1698
1699 static void
1700 _signal_anchor_geoms_do_things_with(Widget_Data *wd, Elm_Entry_Anchor_Info *ei)
1701 {
1702    const Eina_List *geoms, *l;
1703    Evas_Textblock_Rectangle *r;
1704    Evas_Coord px, py, x, y;
1705
1706    geoms = edje_object_part_text_anchor_geometry_get(wd->ent, "elm.text", ei->name);
1707    if (!geoms) return;
1708
1709
1710    evas_object_geometry_get(wd->ent, &x, &y, NULL, NULL);
1711    evas_pointer_canvas_xy_get(evas_object_evas_get(wd->ent), &px, &py);
1712    EINA_LIST_FOREACH(geoms, l, r)
1713      {
1714         if (((r->x + x) <= px) && ((r->y + y) <= py) &&
1715             ((r->x + x + r->w) > px) && ((r->y + y + r->h) > py))
1716           {
1717              ei->x = r->x + x;
1718              ei->y = r->y + y;
1719              ei->w = r->w;
1720              ei->h = r->h;
1721              break;
1722           }
1723      }
1724 }
1725
1726 static void
1727 _signal_anchor_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1728 {
1729    Widget_Data *wd = elm_widget_data_get(data);
1730    Elm_Entry_Anchor_Info ei;
1731    const char *p;
1732    char *p2;
1733    if (!wd) return;
1734    p = emission + sizeof("nchor,mouse,down,");
1735    ei.button = strtol(p, &p2, 10);
1736    ei.name = p2 + 1;
1737    ei.x = ei.y = ei.w = ei.h = 0;
1738
1739    _signal_anchor_geoms_do_things_with(wd, &ei);
1740
1741    if (!wd->disabled)
1742      evas_object_smart_callback_call(data, SIG_ANCHOR_DOWN, &ei);
1743 }
1744
1745 static void
1746 _signal_anchor_up(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1747 {
1748    Widget_Data *wd = elm_widget_data_get(data);
1749    Elm_Entry_Anchor_Info ei;
1750    const char *p;
1751    char *p2;
1752    if (!wd) return;
1753    p = emission + sizeof("nchor,mouse,up,");
1754    ei.button = strtol(p, &p2, 10);
1755    ei.name = p2 + 1;
1756    ei.x = ei.y = ei.w = ei.h = 0;
1757
1758    _signal_anchor_geoms_do_things_with(wd, &ei);
1759
1760    if (!wd->disabled)
1761      evas_object_smart_callback_call(data, SIG_ANCHOR_UP, &ei);
1762 }
1763
1764 static void
1765 _signal_anchor_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission, const char *source __UNUSED__)
1766 {
1767    Widget_Data *wd = elm_widget_data_get(data);
1768    Elm_Entry_Anchor_Info ei;
1769    const char *p;
1770    char *p2;
1771    if (!wd) return;
1772    p = emission + sizeof("nchor,mouse,clicked,");
1773    ei.button = strtol(p, &p2, 10);
1774    ei.name = p2 + 1;
1775    ei.x = ei.y = ei.w = ei.h = 0;
1776
1777    _signal_anchor_geoms_do_things_with(wd, &ei);
1778
1779    if (!wd->disabled)
1780      evas_object_smart_callback_call(data, SIG_ANCHOR_CLICKED, &ei);
1781 }
1782
1783 static void
1784 _signal_anchor_move(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1785 {
1786    Widget_Data *wd = elm_widget_data_get(data);
1787    if (!wd) return;
1788 }
1789
1790 static void
1791 _signal_anchor_in(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1792 {
1793    Widget_Data *wd = elm_widget_data_get(data);
1794    Elm_Entry_Anchor_Info ei;
1795    if (!wd) return;
1796    ei.name = emission + sizeof("nchor,mouse,in,");
1797    ei.button = 0;
1798    ei.x = ei.y = ei.w = ei.h = 0;
1799
1800    _signal_anchor_geoms_do_things_with(wd, &ei);
1801
1802    if (!wd->disabled)
1803      evas_object_smart_callback_call(data, SIG_ANCHOR_IN, &ei);
1804 }
1805
1806 static void
1807 _signal_anchor_out(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,out,");
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_OUT, &ei);
1820 }
1821
1822 static void
1823 _signal_key_enter(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    if (!wd) return;
1827    evas_object_smart_callback_call(data, SIG_ACTIVATED, NULL);
1828 }
1829
1830 static void
1831 _signal_mouse_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1832 {
1833    Widget_Data *wd = elm_widget_data_get(data);
1834    if (!wd) return;
1835    evas_object_smart_callback_call(data, SIG_PRESS, NULL);
1836 }
1837
1838 static void
1839 _signal_mouse_clicked(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_CLICKED, NULL);
1844 }
1845
1846 static void
1847 _signal_mouse_double(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_CLICKED_DOUBLE, NULL);
1852 }
1853
1854 static void
1855 _signal_mouse_triple(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_TRIPLE, NULL);
1860 }
1861
1862 #ifdef HAVE_ELEMENTARY_X
1863 static Eina_Bool
1864 _event_selection_notify(void *data, int type __UNUSED__, void *event)
1865 {
1866    Widget_Data *wd = elm_widget_data_get(data);
1867    Ecore_X_Event_Selection_Notify *ev = event;
1868    if (!wd) return ECORE_CALLBACK_PASS_ON;
1869    if ((!wd->selection_asked) && (!wd->drag_selection_asked))
1870      return ECORE_CALLBACK_PASS_ON;
1871
1872    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
1873        (ev->selection == ECORE_X_SELECTION_PRIMARY))
1874      {
1875         Ecore_X_Selection_Data_Text *text_data;
1876
1877         text_data = ev->data;
1878         if (text_data->data.content == ECORE_X_SELECTION_CONTENT_TEXT)
1879           {
1880              if (text_data->text)
1881                {
1882                   char *txt = _elm_util_text_to_mkup(text_data->text);
1883
1884                   if (txt)
1885                     {
1886                        elm_entry_entry_insert(data, txt);
1887                        free(txt);
1888                     }
1889                }
1890           }
1891         wd->selection_asked = EINA_FALSE;
1892      }
1893    else if (ev->selection == ECORE_X_SELECTION_XDND)
1894      {
1895         Ecore_X_Selection_Data_Text *text_data;
1896
1897         text_data = ev->data;
1898         if (text_data->data.content == ECORE_X_SELECTION_CONTENT_TEXT)
1899           {
1900              if (text_data->text)
1901                {
1902                   char *txt = _elm_util_text_to_mkup(text_data->text);
1903
1904                   if (txt)
1905                     {
1906                        /* Massive FIXME: this should be at the drag point */
1907                        elm_entry_entry_insert(data, txt);
1908                        free(txt);
1909                     }
1910                }
1911           }
1912         wd->drag_selection_asked = EINA_FALSE;
1913
1914         ecore_x_dnd_send_finished();
1915
1916      }
1917    return ECORE_CALLBACK_PASS_ON;
1918 }
1919
1920 static Eina_Bool
1921 _event_selection_clear(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
1922 {
1923    Widget_Data *wd = elm_widget_data_get(data);
1924    Ecore_X_Event_Selection_Clear *ev = event;
1925    if (!wd) return ECORE_CALLBACK_PASS_ON;
1926    if (!wd->have_selection) return ECORE_CALLBACK_PASS_ON;
1927    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
1928        (ev->selection == ECORE_X_SELECTION_PRIMARY))
1929      {
1930         elm_entry_select_none(data);
1931      }
1932    return ECORE_CALLBACK_PASS_ON;
1933 }
1934
1935 static Eina_Bool
1936 _drag_drop_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Selection_Data *drop)
1937 {
1938    Widget_Data *wd;
1939    Eina_Bool rv;
1940
1941    wd = elm_widget_data_get(obj);
1942    if (!wd) return EINA_FALSE;
1943    printf("Inserting at (%d,%d) %s\n",drop->x,drop->y,(char*)drop->data);
1944
1945    edje_object_part_text_cursor_copy(wd->ent, "elm.text",
1946                                      EDJE_CURSOR_MAIN,/*->*/EDJE_CURSOR_USER);
1947    rv = edje_object_part_text_cursor_coord_set(wd->ent,"elm.text",
1948                                                EDJE_CURSOR_MAIN,drop->x,drop->y);
1949    if (!rv) printf("Warning: Failed to position cursor: paste anyway\n");
1950    elm_entry_entry_insert(obj, drop->data);
1951    edje_object_part_text_cursor_copy(wd->ent, "elm.text",
1952                                      EDJE_CURSOR_USER,/*->*/EDJE_CURSOR_MAIN);
1953
1954    return EINA_TRUE;
1955 }
1956 #endif
1957
1958 static Evas_Object *
1959 _get_item(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, const char *item)
1960 {
1961    Widget_Data *wd = elm_widget_data_get(data);
1962    Evas_Object *o;
1963    Eina_List *l;
1964    Elm_Entry_Item_Provider *ip;
1965
1966    EINA_LIST_FOREACH(wd->item_providers, l, ip)
1967      {
1968         o = ip->func(ip->data, data, item);
1969         if (o) return o;
1970      }
1971    if (!strncmp(item, "file://", 7))
1972      {
1973         const char *fname = item + 7;
1974
1975         o = evas_object_image_filled_add(evas_object_evas_get(data));
1976         evas_object_image_file_set(o, fname, NULL);
1977         if (evas_object_image_load_error_get(o) == EVAS_LOAD_ERROR_NONE)
1978           {
1979              evas_object_show(o);
1980           }
1981         else
1982           {
1983              evas_object_del(o);
1984              o = edje_object_add(evas_object_evas_get(data));
1985              _elm_theme_object_set(data, o, "entry/emoticon", "wtf", elm_widget_style_get(data));
1986           }
1987         return o;
1988      }
1989    o = edje_object_add(evas_object_evas_get(data));
1990    if (!_elm_theme_object_set(data, o, "entry", item, elm_widget_style_get(data)))
1991      _elm_theme_object_set(data, o, "entry/emoticon", "wtf", elm_widget_style_get(data));
1992    return o;
1993 }
1994
1995 static void
1996 _text_filter(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, Edje_Text_Filter_Type type, char **text)
1997 {
1998    Widget_Data *wd = elm_widget_data_get(data);
1999    Eina_List *l;
2000    Elm_Entry_Markup_Filter *tf;
2001
2002    if (type == EDJE_TEXT_FILTER_FORMAT)
2003      return;
2004
2005    EINA_LIST_FOREACH(wd->text_filters, l, tf)
2006      {
2007         tf->func(tf->data, data, text);
2008         if (!*text)
2009           break;
2010      }
2011 }
2012
2013 static void
2014 _markup_filter(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, char **text)
2015 {
2016    Widget_Data *wd = elm_widget_data_get(data);
2017    Eina_List *l;
2018    Elm_Entry_Markup_Filter *tf;
2019
2020    EINA_LIST_FOREACH(wd->markup_filters, l, tf)
2021      {
2022         tf->func(tf->data, data, text);
2023         if (!*text)
2024           break;
2025      }
2026 }
2027
2028 /* This function is used to insert text by chunks in jobs */
2029 static Eina_Bool
2030 _text_append_idler(void *data)
2031 {
2032    int start;
2033    char backup;
2034    Evas_Object *obj = (Evas_Object *) data;
2035    Widget_Data *wd = elm_widget_data_get(obj);
2036    evas_event_freeze(evas_object_evas_get(obj));
2037    if (wd->text) eina_stringshare_del(wd->text);
2038    wd->text = NULL;
2039    wd->changed = EINA_TRUE;
2040
2041    start = wd->append_text_position;
2042    if (start + _CHUNK_SIZE < wd->append_text_len)
2043      {
2044         int pos = start;
2045         int tag_start, esc_start;
2046
2047         tag_start = esc_start = -1;
2048         /* Find proper markup cut place */
2049         while (pos - start < _CHUNK_SIZE)
2050           {
2051              int prev_pos = pos;
2052              Eina_Unicode tmp =
2053                 eina_unicode_utf8_get_next(wd->append_text_left, &pos);
2054              if (esc_start == -1)
2055                {
2056                   if (tmp == '<')
2057                      tag_start = prev_pos;
2058                   else if (tmp == '>')
2059                      tag_start = -1;
2060                }
2061              if (tag_start == -1)
2062                {
2063                   if (tmp == '&')
2064                      esc_start = prev_pos;
2065                   else if (tmp == ';')
2066                      esc_start = -1;
2067                }
2068           }
2069
2070         if (tag_start >= 0)
2071           {
2072              wd->append_text_position = tag_start;
2073           }
2074         else if (esc_start >= 0)
2075           {
2076              wd->append_text_position = esc_start;
2077           }
2078         else
2079           {
2080              wd->append_text_position = pos;
2081           }
2082      }
2083    else
2084      {
2085         wd->append_text_position = wd->append_text_len;
2086      }
2087
2088    backup = wd->append_text_left[wd->append_text_position];
2089    wd->append_text_left[wd->append_text_position] = '\0';
2090
2091    edje_object_part_text_append(wd->ent, "elm.text",
2092                                 wd->append_text_left + start);
2093
2094    wd->append_text_left[wd->append_text_position] = backup;
2095
2096    evas_event_thaw(evas_object_evas_get(obj));
2097    evas_event_thaw_eval(evas_object_evas_get(obj));
2098
2099    /* If there's still more to go, renew the idler, else, cleanup */
2100    if (wd->append_text_position < wd->append_text_len)
2101      {
2102         return ECORE_CALLBACK_RENEW;
2103      }
2104    else
2105      {
2106         free(wd->append_text_left);
2107         wd->append_text_left = NULL;
2108         wd->append_text_idler = NULL;
2109         return ECORE_CALLBACK_CANCEL;
2110      }
2111 }
2112
2113 static void
2114 _add_chars_till_limit(Evas_Object *obj, char **text, int can_add, Length_Unit unit)
2115 {
2116    int i = 0, current_len = 0;
2117    char *new_text;
2118
2119    if (!*text) return;
2120    if (unit >= LENGTH_UNIT_LAST) return;
2121    new_text = *text;
2122    current_len = strlen(*text);
2123    while (*new_text)
2124      {
2125         int idx = 0, unit_size = 0;
2126         char *markup, *utfstr;
2127         if (*new_text == '<')
2128           {
2129              while (*(new_text + idx) != '>')
2130                {
2131                   idx++;
2132                   if (!*(new_text + idx)) break;
2133                }
2134           }
2135         else if (*new_text == '&')
2136           {
2137              while (*(new_text + idx) != ';')
2138                {
2139                   idx++;
2140                   if (!*(new_text + idx)) break;
2141                }
2142           }
2143         idx = evas_string_char_next_get(new_text, idx, NULL);
2144         markup = malloc(idx + 1);
2145         if (markup)
2146           {
2147              strncpy(markup, new_text, idx);
2148              markup[idx] = 0;
2149              utfstr = elm_entry_markup_to_utf8(markup);
2150              if (utfstr)
2151                {
2152                   if (unit == LENGTH_UNIT_BYTE)
2153                     unit_size = strlen(utfstr);
2154                   else if (unit == LENGTH_UNIT_CHAR)
2155                     unit_size = evas_string_char_len_get(utfstr);
2156                   free(utfstr);
2157                   utfstr = NULL;
2158                }
2159              free(markup);
2160              markup = NULL;
2161           }
2162         if (can_add < unit_size)
2163           {
2164              if (!i)
2165                {
2166                   evas_object_smart_callback_call(obj, "maxlength,reached", NULL);
2167                   free(*text);
2168                   *text = NULL;
2169                   return;
2170                }
2171              can_add = 0;
2172              strncpy(new_text, new_text + idx, current_len - ((new_text + idx) - *text));
2173              current_len -= idx;
2174              (*text)[current_len] = 0;
2175           }
2176         else
2177           {
2178              new_text += idx;
2179              can_add -= unit_size;
2180           }
2181         i++;
2182      }
2183    evas_object_smart_callback_call(obj, "maxlength,reached", NULL);
2184 }
2185
2186 static void
2187 _elm_entry_text_set(Evas_Object *obj, const char *item, const char *entry)
2188 {
2189    int len = 0;
2190    ELM_CHECK_WIDTYPE(obj, widtype);
2191    Widget_Data *wd = elm_widget_data_get(obj);
2192    if (!wd) return;
2193    evas_event_freeze(evas_object_evas_get(obj));
2194    if (!entry) entry = "";
2195    if (item && strcmp(item, "default"))
2196      {
2197         edje_object_part_text_set(wd->ent, item, entry);
2198         return;
2199      }
2200
2201    if (wd->text) eina_stringshare_del(wd->text);
2202    wd->text = NULL;
2203    wd->changed = EINA_TRUE;
2204
2205    /* Clear currently pending job if there is one */
2206    if (wd->append_text_idler)
2207      {
2208         ecore_idler_del(wd->append_text_idler);
2209         free(wd->append_text_left);
2210         wd->append_text_left = NULL;
2211         wd->append_text_idler = NULL;
2212      }
2213
2214    len = strlen(entry);
2215    /* Split to ~_CHUNK_SIZE chunks */
2216    if (len > _CHUNK_SIZE)
2217      {
2218         wd->append_text_left = (char *) malloc(len + 1);
2219      }
2220
2221    /* If we decided to use the idler */
2222    if (wd->append_text_left)
2223      {
2224         /* Need to clear the entry first */
2225         edje_object_part_text_set(wd->ent, "elm.text", "");
2226         memcpy(wd->append_text_left, entry, len + 1);
2227         wd->append_text_position = 0;
2228         wd->append_text_len = len;
2229         wd->append_text_idler = ecore_idler_add(_text_append_idler, obj);
2230      }
2231    else
2232      {
2233         edje_object_part_text_set(wd->ent, "elm.text", entry);
2234      }
2235    evas_event_thaw(evas_object_evas_get(obj));
2236    evas_event_thaw_eval(evas_object_evas_get(obj));
2237 }
2238
2239 static const char *
2240 _elm_entry_text_get(const Evas_Object *obj, const char *item)
2241 {
2242    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2243    Widget_Data *wd = elm_widget_data_get(obj);
2244    if (item && strcmp(item, "default")) return NULL;
2245    const char *text;
2246    if (!wd) return NULL;
2247    if (wd->text) return wd->text;
2248    text = edje_object_part_text_get(wd->ent, "elm.text");
2249    if (!text)
2250      {
2251         ERR("text=NULL for edje %p, part 'elm.text'", wd->ent);
2252         return NULL;
2253      }
2254
2255    if (wd->append_text_len > 0)
2256      {
2257         char *tmpbuf;
2258         size_t tlen;
2259         tlen = strlen(text);
2260         tmpbuf = malloc(tlen + wd->append_text_len + 1);
2261         if (!tmpbuf)
2262           {
2263              ERR("Failed to allocate memory for entry's text %p", obj);
2264              return NULL;
2265           }
2266         memcpy(tmpbuf, text, tlen);
2267         memcpy(tmpbuf + tlen, wd->append_text_left, wd->append_text_len);
2268         tmpbuf[tlen + wd->append_text_len] = '\0';
2269         eina_stringshare_replace(&wd->text, tmpbuf);
2270         free(tmpbuf);
2271      }
2272    else
2273      {
2274         eina_stringshare_replace(&wd->text, text);
2275      }
2276    return wd->text;
2277 }
2278
2279 EAPI Evas_Object *
2280 elm_entry_add(Evas_Object *parent)
2281 {
2282    Evas_Object *obj, *top;
2283    Evas *e;
2284    Widget_Data *wd;
2285
2286    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
2287
2288    ELM_SET_WIDTYPE(widtype, "entry");
2289    elm_widget_type_set(obj, "entry");
2290    elm_widget_sub_object_add(parent, obj);
2291    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
2292    elm_widget_data_set(obj, wd);
2293    elm_widget_del_hook_set(obj, _del_hook);
2294    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
2295    elm_widget_theme_hook_set(obj, _theme_hook);
2296    elm_widget_disable_hook_set(obj, _disable_hook);
2297    elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
2298    elm_widget_focus_region_hook_set(obj, _focus_region_hook);
2299    elm_widget_on_focus_region_hook_set(obj, _on_focus_region_hook);
2300    elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
2301    elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
2302    elm_object_cursor_set(obj, ELM_CURSOR_XTERM);
2303    elm_widget_can_focus_set(obj, EINA_TRUE);
2304    elm_widget_highlight_ignore_set(obj, EINA_TRUE);
2305    elm_widget_text_set_hook_set(obj, _elm_entry_text_set);
2306    elm_widget_text_get_hook_set(obj, _elm_entry_text_get);
2307    elm_widget_content_set_hook_set(obj, _content_set_hook);
2308    elm_widget_content_unset_hook_set(obj, _content_unset_hook);
2309    elm_widget_content_get_hook_set(obj, _content_get_hook);
2310    elm_widget_translate_hook_set(obj, _translate_hook);
2311
2312    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, wd);
2313
2314    wd->linewrap     = ELM_WRAP_WORD;
2315    wd->editable     = EINA_TRUE;
2316    wd->disabled     = EINA_FALSE;
2317    wd->context_menu = EINA_TRUE;
2318    wd->autosave     = EINA_TRUE;
2319    wd->textonly     = EINA_FALSE;
2320    wd->scroll       = EINA_FALSE;
2321    wd->input_panel_imdata = NULL;
2322
2323    wd->ent = edje_object_add(e);
2324    edje_object_item_provider_set(wd->ent, _get_item, obj);
2325    edje_object_text_insert_filter_callback_add(wd->ent,"elm.text", _text_filter, obj);
2326    edje_object_text_markup_filter_callback_add(wd->ent,"elm.text", _markup_filter, obj);
2327    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOVE, _move, obj);
2328    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_DOWN,
2329                                   _mouse_down, obj);
2330    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_UP,
2331                                   _mouse_up, obj);
2332    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_MOVE,
2333                                   _mouse_move, obj);
2334    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
2335
2336    _elm_theme_object_set(obj, wd->ent, "entry", "base", "default");
2337    edje_object_signal_callback_add(wd->ent, "entry,changed", "elm.text",
2338                                    _signal_entry_changed, obj);
2339    edje_object_signal_callback_add(wd->ent, "entry,changed,user", "elm.text",
2340                                    _signal_entry_changed_user, obj);
2341    edje_object_signal_callback_add(wd->ent, "preedit,changed", "elm.text",
2342                                    _signal_preedit_changed, obj);
2343    edje_object_signal_callback_add(wd->ent, "selection,start", "elm.text",
2344                                    _signal_selection_start, obj);
2345    edje_object_signal_callback_add(wd->ent, "selection,changed", "elm.text",
2346                                    _signal_selection_changed, obj);
2347    edje_object_signal_callback_add(wd->ent, "entry,selection,all,request", "elm.text",
2348                                    _signal_selection_all, obj);
2349    edje_object_signal_callback_add(wd->ent, "entry,selection,none,request", "elm.text",
2350                                    _signal_selection_none, obj);
2351    edje_object_signal_callback_add(wd->ent, "selection,cleared", "elm.text",
2352                                    _signal_selection_cleared, obj);
2353    edje_object_signal_callback_add(wd->ent, "entry,paste,request,*", "elm.text",
2354                                    _signal_entry_paste_request, obj);
2355    edje_object_signal_callback_add(wd->ent, "entry,copy,notify", "elm.text",
2356                                    _signal_entry_copy_notify, obj);
2357    edje_object_signal_callback_add(wd->ent, "entry,cut,notify", "elm.text",
2358                                    _signal_entry_cut_notify, obj);
2359    edje_object_signal_callback_add(wd->ent, "cursor,changed", "elm.text",
2360                                    _signal_cursor_changed, obj);
2361    edje_object_signal_callback_add(wd->ent, "cursor,changed,manual", "elm.text",
2362                                    _signal_cursor_changed_manual, obj);
2363    edje_object_signal_callback_add(wd->ent, "anchor,mouse,down,*", "elm.text",
2364                                    _signal_anchor_down, obj);
2365    edje_object_signal_callback_add(wd->ent, "anchor,mouse,up,*", "elm.text",
2366                                    _signal_anchor_up, obj);
2367    edje_object_signal_callback_add(wd->ent, "anchor,mouse,clicked,*", "elm.text",
2368                                    _signal_anchor_clicked, obj);
2369    edje_object_signal_callback_add(wd->ent, "anchor,mouse,move,*", "elm.text",
2370                                    _signal_anchor_move, obj);
2371    edje_object_signal_callback_add(wd->ent, "anchor,mouse,in,*", "elm.text",
2372                                    _signal_anchor_in, obj);
2373    edje_object_signal_callback_add(wd->ent, "anchor,mouse,out,*", "elm.text",
2374                                    _signal_anchor_out, obj);
2375    edje_object_signal_callback_add(wd->ent, "entry,key,enter", "elm.text",
2376                                    _signal_key_enter, obj);
2377    edje_object_signal_callback_add(wd->ent, "mouse,down,1", "elm.text",
2378                                    _signal_mouse_down, obj);
2379    edje_object_signal_callback_add(wd->ent, "mouse,clicked,1", "elm.text",
2380                                    _signal_mouse_clicked, obj);
2381    edje_object_signal_callback_add(wd->ent, "mouse,down,1,double", "elm.text",
2382                                    _signal_mouse_double, obj);
2383    edje_object_signal_callback_add(wd->ent, "mouse,down,1,triple", "elm.text",
2384                                    _signal_mouse_triple, obj);
2385    edje_object_signal_callback_add(wd->ent, "entry,undo,request", "elm.text",
2386                                    _signal_undo_request, obj);
2387    edje_object_signal_callback_add(wd->ent, "entry,redo,request", "elm.text",
2388                                    _signal_redo_request, obj);
2389    edje_object_part_text_set(wd->ent, "elm.text", "");
2390    if (_elm_config->desktop_entry)
2391      edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_TRUE);
2392    elm_widget_resize_object_set(obj, wd->ent);
2393    _sizing_eval(obj);
2394
2395    elm_entry_input_panel_layout_set(obj, ELM_INPUT_PANEL_LAYOUT_NORMAL);
2396    elm_entry_input_panel_enabled_set(obj, EINA_TRUE);
2397    elm_entry_prediction_allow_set(obj, EINA_TRUE);
2398
2399    wd->autocapital_type = edje_object_part_text_autocapital_type_get(wd->ent, "elm.text");
2400
2401 #ifdef HAVE_ELEMENTARY_X
2402    top = elm_widget_top_get(obj);
2403    if ((top) && (elm_win_xwindow_get(top)))
2404      {
2405         wd->sel_notify_handler =
2406            ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY,
2407                                    _event_selection_notify, obj);
2408         wd->sel_clear_handler =
2409            ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR,
2410                                    _event_selection_clear, obj);
2411      }
2412
2413    elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE,
2414                        _drag_drop_cb, NULL);
2415 #endif
2416
2417    entries = eina_list_prepend(entries, obj);
2418
2419    // module - find module for entry
2420    wd->api = _module(obj);
2421    // if found - hook in
2422    if ((wd->api) && (wd->api->obj_hook)) wd->api->obj_hook(obj);
2423
2424    _mirrored_set(obj, elm_widget_mirrored_get(obj));
2425    // TODO: convert Elementary to subclassing of Evas_Smart_Class
2426    // TODO: and save some bytes, making descriptions per-class and not instance!
2427    evas_object_smart_callbacks_descriptions_set(obj, _signals);
2428    return obj;
2429 }
2430
2431 EAPI void
2432 elm_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
2433 {
2434    ELM_CHECK_WIDTYPE(obj, widtype);
2435    Widget_Data *wd = elm_widget_data_get(obj);
2436    if (!wd) return;
2437    if (wd->single_line == single_line) return;
2438    wd->single_line = single_line;
2439    wd->linewrap = ELM_WRAP_NONE;
2440    elm_entry_cnp_textonly_set(obj, EINA_TRUE);
2441    _theme_hook(obj);
2442    if (wd->scroller)
2443      {
2444         if (wd->single_line)
2445           elm_smart_scroller_policy_set(wd->scroller,
2446                                         ELM_SMART_SCROLLER_POLICY_OFF,
2447                                         ELM_SMART_SCROLLER_POLICY_OFF);
2448         else
2449           {
2450              const Elm_Scroller_Policy map[3] =
2451                {
2452                   ELM_SMART_SCROLLER_POLICY_AUTO,
2453                   ELM_SMART_SCROLLER_POLICY_ON,
2454                   ELM_SMART_SCROLLER_POLICY_OFF
2455                };
2456              elm_smart_scroller_policy_set(wd->scroller,
2457                                            map[wd->policy_h],
2458                                            map[wd->policy_v]);
2459           }
2460         _sizing_eval(obj);
2461      }
2462 }
2463
2464 EAPI Eina_Bool
2465 elm_entry_single_line_get(const Evas_Object *obj)
2466 {
2467    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2468    Widget_Data *wd = elm_widget_data_get(obj);
2469    if (!wd) return EINA_FALSE;
2470    return wd->single_line;
2471 }
2472
2473 EAPI void
2474 elm_entry_password_set(Evas_Object *obj, Eina_Bool password)
2475 {
2476    ELM_CHECK_WIDTYPE(obj, widtype);
2477    Widget_Data *wd = elm_widget_data_get(obj);
2478    if (!wd) return;
2479    if (wd->password == password) return;
2480    wd->password = password;
2481    if (password)
2482      {
2483         wd->single_line = EINA_TRUE;
2484         wd->linewrap = ELM_WRAP_NONE;
2485 #ifdef HAVE_ELEMENTARY_X
2486         elm_drop_target_del(obj);
2487 #endif
2488         edje_object_signal_callback_del_full(wd->ent, "selection,start", "elm.text",
2489                                         _signal_selection_start, obj);
2490         edje_object_signal_callback_del_full(wd->ent, "selection,changed", "elm.text",
2491                                         _signal_selection_changed, obj);
2492         edje_object_signal_callback_del_full(wd->ent, "entry,selection,all,request", "elm.text",
2493                                         _signal_selection_all, obj);
2494         edje_object_signal_callback_del_full(wd->ent, "entry,selection,none,request", "elm.text",
2495                                         _signal_selection_none, obj);
2496         edje_object_signal_callback_del_full(wd->ent, "selection,cleared", "elm.text",
2497                                         _signal_selection_cleared, obj);
2498         edje_object_signal_callback_del_full(wd->ent, "entry,paste,request,*", "elm.text",
2499                                         _signal_entry_paste_request, obj);
2500         edje_object_signal_callback_del_full(wd->ent, "entry,copy,notify", "elm.text",
2501                                         _signal_entry_copy_notify, obj);
2502         edje_object_signal_callback_del_full(wd->ent, "entry,cut,notify", "elm.text",
2503                                         _signal_entry_cut_notify, obj);
2504      }
2505    else
2506      {
2507 #ifdef HAVE_ELEMENTARY_X
2508         elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP, _drag_drop_cb, NULL);
2509 #endif
2510         edje_object_signal_callback_add(wd->ent, "selection,start", "elm.text",
2511                                         _signal_selection_start, obj);
2512         edje_object_signal_callback_add(wd->ent, "selection,changed", "elm.text",
2513                                         _signal_selection_changed, obj);
2514         edje_object_signal_callback_add(wd->ent, "entry,selection,all,request", "elm.text",
2515                                         _signal_selection_all, obj);
2516         edje_object_signal_callback_add(wd->ent, "entry,selection,none,request", "elm.text",
2517                                         _signal_selection_none, obj);
2518         edje_object_signal_callback_add(wd->ent, "selection,cleared", "elm.text",
2519                                         _signal_selection_cleared, obj);
2520         edje_object_signal_callback_add(wd->ent, "entry,paste,request,*", "elm.text",
2521                                         _signal_entry_paste_request, obj);
2522         edje_object_signal_callback_add(wd->ent, "entry,copy,notify", "elm.text",
2523                                         _signal_entry_copy_notify, obj);
2524         edje_object_signal_callback_add(wd->ent, "entry,cut,notify", "elm.text",
2525                                         _signal_entry_cut_notify, obj);
2526      }
2527    _theme_hook(obj);
2528 }
2529
2530 EAPI Eina_Bool
2531 elm_entry_password_get(const Evas_Object *obj)
2532 {
2533    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2534    Widget_Data *wd = elm_widget_data_get(obj);
2535    if (!wd) return EINA_FALSE;
2536    return wd->password;
2537 }
2538
2539 EAPI void
2540 elm_entry_entry_set(Evas_Object *obj, const char *entry)
2541 {
2542    _elm_entry_text_set(obj, NULL, entry);
2543 }
2544
2545 EAPI const char *
2546 elm_entry_entry_get(const Evas_Object *obj)
2547 {
2548    return _elm_entry_text_get(obj, NULL);
2549 }
2550
2551 EAPI void
2552 elm_entry_entry_append(Evas_Object *obj, const char *entry)
2553 {
2554    int len = 0;
2555    ELM_CHECK_WIDTYPE(obj, widtype);
2556    Widget_Data *wd = elm_widget_data_get(obj);
2557    if (!wd) return;
2558    if (!entry) entry = "";
2559    wd->changed = EINA_TRUE;
2560
2561    len = strlen(entry);
2562    if (wd->append_text_left)
2563      {
2564         char *tmpbuf;
2565         tmpbuf = realloc(wd->append_text_left, wd->append_text_len + len + 1);
2566         if (!tmpbuf)
2567           {
2568              /* Do something */
2569              return;
2570           }
2571         wd->append_text_left = tmpbuf;
2572         memcpy(wd->append_text_left + wd->append_text_len, entry, len + 1);
2573         wd->append_text_len += len;
2574      }
2575    else
2576      {
2577         /* FIXME: Add chunked appending here (like in entry_set) */
2578         edje_object_part_text_append(wd->ent, "elm.text", entry);
2579      }
2580 }
2581
2582 EAPI Eina_Bool
2583 elm_entry_is_empty(const Evas_Object *obj)
2584 {
2585    /* FIXME: until there's support for that in textblock, we just check
2586     * to see if the there is text or not. */
2587    ELM_CHECK_WIDTYPE(obj, widtype) EINA_TRUE;
2588    Widget_Data *wd = elm_widget_data_get(obj);
2589    const Evas_Object *tb;
2590    Evas_Textblock_Cursor *cur;
2591    Eina_Bool ret;
2592    if (!wd) return EINA_TRUE;
2593    /* It's a hack until we get the support suggested above.
2594     * We just create a cursor, point it to the begining, and then
2595     * try to advance it, if it can advance, the tb is not empty,
2596     * otherwise it is. */
2597    tb = edje_object_part_object_get(wd->ent, "elm.text");
2598    cur = evas_object_textblock_cursor_new((Evas_Object *) tb); /* This is
2599                                                                   actually, ok for the time being, thsese hackish stuff will be removed
2600                                                                   once evas 1.0 is out*/
2601    evas_textblock_cursor_pos_set(cur, 0);
2602    ret = evas_textblock_cursor_char_next(cur);
2603    evas_textblock_cursor_free(cur);
2604
2605    return !ret;
2606 }
2607
2608 EAPI Evas_Object *
2609 elm_entry_textblock_get(Evas_Object *obj)
2610 {
2611    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2612    Widget_Data *wd = elm_widget_data_get(obj);
2613    if (!wd) return NULL;
2614
2615    return (Evas_Object *) edje_object_part_object_get(wd->ent, "elm.text");
2616 }
2617
2618 EAPI void
2619 elm_entry_calc_force(Evas_Object *obj)
2620 {
2621    ELM_CHECK_WIDTYPE(obj, widtype);
2622    Widget_Data *wd = elm_widget_data_get(obj);
2623    if (!wd) return;
2624
2625    edje_object_calc_force(wd->ent);
2626    wd->changed = EINA_TRUE;
2627    _sizing_eval(obj);
2628 }
2629
2630
2631 EAPI const char *
2632 elm_entry_selection_get(const Evas_Object *obj)
2633 {
2634    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2635    Widget_Data *wd = elm_widget_data_get(obj);
2636    if ((!wd) || (wd->password)) return NULL;
2637    return edje_object_part_text_selection_get(wd->ent, "elm.text");
2638 }
2639
2640 EAPI void
2641 elm_entry_entry_insert(Evas_Object *obj, const char *entry)
2642 {
2643    ELM_CHECK_WIDTYPE(obj, widtype);
2644    Widget_Data *wd = elm_widget_data_get(obj);
2645    if (!wd) return;
2646    edje_object_part_text_insert(wd->ent, "elm.text", entry);
2647    wd->changed = EINA_TRUE;
2648    _sizing_eval(obj);
2649 }
2650
2651 EAPI void
2652 elm_entry_line_wrap_set(Evas_Object *obj, Elm_Wrap_Type wrap)
2653 {
2654    ELM_CHECK_WIDTYPE(obj, widtype);
2655    Widget_Data *wd = elm_widget_data_get(obj);
2656    if (!wd) return;
2657    if (wd->linewrap == wrap) return;
2658    wd->lastw = -1;
2659    wd->linewrap = wrap;
2660    _theme_hook(obj);
2661 }
2662
2663 EAPI Elm_Wrap_Type
2664 elm_entry_line_wrap_get(const Evas_Object *obj)
2665 {
2666    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2667    Widget_Data *wd = elm_widget_data_get(obj);
2668    if (!wd) return EINA_FALSE;
2669    return wd->linewrap;
2670 }
2671
2672 EAPI void
2673 elm_entry_editable_set(Evas_Object *obj, Eina_Bool editable)
2674 {
2675    ELM_CHECK_WIDTYPE(obj, widtype);
2676    Widget_Data *wd = elm_widget_data_get(obj);
2677    if (!wd) return;
2678    if (wd->editable == editable) return;
2679    wd->editable = editable;
2680    _theme_hook(obj);
2681
2682 #ifdef HAVE_ELEMENTARY_X
2683    if (editable)
2684      elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP, _drag_drop_cb, NULL);
2685    else
2686      elm_drop_target_del(obj);
2687 #endif
2688 }
2689
2690 EAPI Eina_Bool
2691 elm_entry_editable_get(const Evas_Object *obj)
2692 {
2693    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2694    Widget_Data *wd = elm_widget_data_get(obj);
2695    if (!wd) return EINA_FALSE;
2696    return wd->editable;
2697 }
2698
2699 EAPI void
2700 elm_entry_select_none(Evas_Object *obj)
2701 {
2702    ELM_CHECK_WIDTYPE(obj, widtype);
2703    Widget_Data *wd = elm_widget_data_get(obj);
2704    if ((!wd) || (wd->password)) return;
2705    if (wd->selmode)
2706      {
2707         wd->selmode = EINA_FALSE;
2708         if (!_elm_config->desktop_entry)
2709           edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
2710         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
2711      }
2712    wd->have_selection = EINA_FALSE;
2713    edje_object_part_text_select_none(wd->ent, "elm.text");
2714 }
2715
2716 EAPI void
2717 elm_entry_select_all(Evas_Object *obj)
2718 {
2719    ELM_CHECK_WIDTYPE(obj, widtype);
2720    Widget_Data *wd = elm_widget_data_get(obj);
2721    if ((!wd) || (wd->password)) return;
2722    if (wd->selmode)
2723      {
2724         wd->selmode = EINA_FALSE;
2725         if (!_elm_config->desktop_entry)
2726           edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
2727         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
2728      }
2729    wd->have_selection = EINA_TRUE;
2730    edje_object_part_text_select_all(wd->ent, "elm.text");
2731 }
2732
2733 EAPI Eina_Bool
2734 elm_entry_cursor_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
2735 {
2736    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2737    Widget_Data *wd = elm_widget_data_get(obj);
2738    if (!wd) return EINA_FALSE;
2739    edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text", x, y, w, h);
2740    return EINA_TRUE;
2741 }
2742
2743 EAPI Eina_Bool
2744 elm_entry_cursor_next(Evas_Object *obj)
2745 {
2746    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2747    Widget_Data *wd = elm_widget_data_get(obj);
2748    if (!wd) return EINA_FALSE;
2749    return edje_object_part_text_cursor_next(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2750 }
2751
2752 EAPI Eina_Bool
2753 elm_entry_cursor_prev(Evas_Object *obj)
2754 {
2755    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2756    Widget_Data *wd = elm_widget_data_get(obj);
2757    if (!wd) return EINA_FALSE;
2758    return edje_object_part_text_cursor_prev(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2759 }
2760
2761 EAPI Eina_Bool
2762 elm_entry_cursor_up(Evas_Object *obj)
2763 {
2764    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2765    Widget_Data *wd = elm_widget_data_get(obj);
2766    if (!wd) return EINA_FALSE;
2767    return edje_object_part_text_cursor_up(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2768 }
2769
2770 EAPI Eina_Bool
2771 elm_entry_cursor_down(Evas_Object *obj)
2772 {
2773    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2774    Widget_Data *wd = elm_widget_data_get(obj);
2775    if (!wd) return EINA_FALSE;
2776    return edje_object_part_text_cursor_down(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2777 }
2778
2779 EAPI void
2780 elm_entry_cursor_begin_set(Evas_Object *obj)
2781 {
2782    ELM_CHECK_WIDTYPE(obj, widtype);
2783    Widget_Data *wd = elm_widget_data_get(obj);
2784    if (!wd) return;
2785    edje_object_part_text_cursor_begin_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2786 }
2787
2788 EAPI void
2789 elm_entry_cursor_end_set(Evas_Object *obj)
2790 {
2791    ELM_CHECK_WIDTYPE(obj, widtype);
2792    Widget_Data *wd = elm_widget_data_get(obj);
2793    if (!wd) return;
2794    edje_object_part_text_cursor_end_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2795 }
2796
2797 EAPI void
2798 elm_entry_cursor_line_begin_set(Evas_Object *obj)
2799 {
2800    ELM_CHECK_WIDTYPE(obj, widtype);
2801    Widget_Data *wd = elm_widget_data_get(obj);
2802    if (!wd) return;
2803    edje_object_part_text_cursor_line_begin_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2804 }
2805
2806 EAPI void
2807 elm_entry_cursor_line_end_set(Evas_Object *obj)
2808 {
2809    ELM_CHECK_WIDTYPE(obj, widtype);
2810    Widget_Data *wd = elm_widget_data_get(obj);
2811    if (!wd) return;
2812    edje_object_part_text_cursor_line_end_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2813 }
2814
2815 EAPI void
2816 elm_entry_cursor_selection_begin(Evas_Object *obj)
2817 {
2818    ELM_CHECK_WIDTYPE(obj, widtype);
2819    Widget_Data *wd = elm_widget_data_get(obj);
2820    if (!wd) return;
2821    edje_object_part_text_select_begin(wd->ent, "elm.text");
2822 }
2823
2824 EAPI void
2825 elm_entry_cursor_selection_end(Evas_Object *obj)
2826 {
2827    ELM_CHECK_WIDTYPE(obj, widtype);
2828    Widget_Data *wd = elm_widget_data_get(obj);
2829    if (!wd) return;
2830    edje_object_part_text_select_extend(wd->ent, "elm.text");
2831 }
2832
2833 EAPI Eina_Bool
2834 elm_entry_cursor_is_format_get(const Evas_Object *obj)
2835 {
2836    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2837    Widget_Data *wd = elm_widget_data_get(obj);
2838    if (!wd) return EINA_FALSE;
2839    return edje_object_part_text_cursor_is_format_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2840 }
2841
2842 EAPI Eina_Bool
2843 elm_entry_cursor_is_visible_format_get(const Evas_Object *obj)
2844 {
2845    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2846    Widget_Data *wd = elm_widget_data_get(obj);
2847    if (!wd) return EINA_FALSE;
2848    return edje_object_part_text_cursor_is_visible_format_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2849 }
2850
2851 EAPI char *
2852 elm_entry_cursor_content_get(const Evas_Object *obj)
2853 {
2854    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2855    Widget_Data *wd = elm_widget_data_get(obj);
2856    if (!wd) return NULL;
2857    return edje_object_part_text_cursor_content_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2858 }
2859
2860 EAPI void
2861 elm_entry_cursor_pos_set(Evas_Object *obj, int pos)
2862 {
2863    ELM_CHECK_WIDTYPE(obj, widtype);
2864    Widget_Data *wd = elm_widget_data_get(obj);
2865    if (!wd) return;
2866    edje_object_part_text_cursor_pos_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN, pos);
2867    edje_object_message_signal_process(wd->ent);
2868 }
2869
2870 EAPI int
2871 elm_entry_cursor_pos_get(const Evas_Object *obj)
2872 {
2873    ELM_CHECK_WIDTYPE(obj, widtype) 0;
2874    Widget_Data *wd = elm_widget_data_get(obj);
2875    if (!wd) return 0;
2876    return edje_object_part_text_cursor_pos_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2877 }
2878
2879 EAPI void
2880 elm_entry_selection_cut(Evas_Object *obj)
2881 {
2882    ELM_CHECK_WIDTYPE(obj, widtype);
2883    Widget_Data *wd = elm_widget_data_get(obj);
2884    if ((!wd) || (wd->password)) return;
2885    _cut(obj, NULL, NULL);
2886 }
2887
2888 EAPI void
2889 elm_entry_selection_copy(Evas_Object *obj)
2890 {
2891    ELM_CHECK_WIDTYPE(obj, widtype);
2892    Widget_Data *wd = elm_widget_data_get(obj);
2893    if ((!wd) || (wd->password)) return;
2894    _copy(obj, NULL, NULL);
2895 }
2896
2897 EAPI void
2898 elm_entry_selection_paste(Evas_Object *obj)
2899 {
2900    ELM_CHECK_WIDTYPE(obj, widtype);
2901    Widget_Data *wd = elm_widget_data_get(obj);
2902    if ((!wd) || (wd->password)) return;
2903    _paste(obj, NULL, NULL);
2904 }
2905
2906 EAPI void
2907 elm_entry_context_menu_clear(Evas_Object *obj)
2908 {
2909    ELM_CHECK_WIDTYPE(obj, widtype);
2910    Widget_Data *wd = elm_widget_data_get(obj);
2911    Elm_Entry_Context_Menu_Item *it;
2912    if (!wd) return;
2913    EINA_LIST_FREE(wd->items, it)
2914      {
2915         eina_stringshare_del(it->label);
2916         eina_stringshare_del(it->icon_file);
2917         eina_stringshare_del(it->icon_group);
2918         free(it);
2919      }
2920 }
2921
2922 EAPI void
2923 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)
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    it = calloc(1, sizeof(Elm_Entry_Context_Menu_Item));
2930    if (!it) return;
2931    wd->items = eina_list_append(wd->items, it);
2932    it->obj = obj;
2933    it->label = eina_stringshare_add(label);
2934    it->icon_file = eina_stringshare_add(icon_file);
2935    it->icon_type = icon_type;
2936    it->func = func;
2937    it->data = (void *)data;
2938 }
2939
2940 EAPI void
2941 elm_entry_context_menu_disabled_set(Evas_Object *obj, Eina_Bool disabled)
2942 {
2943    ELM_CHECK_WIDTYPE(obj, widtype);
2944    Widget_Data *wd = elm_widget_data_get(obj);
2945    if (!wd) return;
2946    if (wd->context_menu == !disabled) return;
2947    wd->context_menu = !disabled;
2948 }
2949
2950 EAPI Eina_Bool
2951 elm_entry_context_menu_disabled_get(const Evas_Object *obj)
2952 {
2953    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2954    Widget_Data *wd = elm_widget_data_get(obj);
2955    if (!wd) return EINA_FALSE;
2956    return !wd->context_menu;
2957 }
2958
2959 EAPI void
2960 elm_entry_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data)
2961 {
2962    ELM_CHECK_WIDTYPE(obj, widtype);
2963    Widget_Data *wd = elm_widget_data_get(obj);
2964    if (!wd) return;
2965    EINA_SAFETY_ON_NULL_RETURN(func);
2966    Elm_Entry_Item_Provider *ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
2967    if (!ip) return;
2968    ip->func = func;
2969    ip->data = data;
2970    wd->item_providers = eina_list_append(wd->item_providers, ip);
2971 }
2972
2973 EAPI void
2974 elm_entry_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data)
2975 {
2976    ELM_CHECK_WIDTYPE(obj, widtype);
2977    Widget_Data *wd = elm_widget_data_get(obj);
2978    if (!wd) return;
2979    EINA_SAFETY_ON_NULL_RETURN(func);
2980    Elm_Entry_Item_Provider *ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
2981    if (!ip) return;
2982    ip->func = func;
2983    ip->data = data;
2984    wd->item_providers = eina_list_prepend(wd->item_providers, ip);
2985 }
2986
2987 EAPI void
2988 elm_entry_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data)
2989 {
2990    ELM_CHECK_WIDTYPE(obj, widtype);
2991    Widget_Data *wd = elm_widget_data_get(obj);
2992    Eina_List *l;
2993    Elm_Entry_Item_Provider *ip;
2994    if (!wd) return;
2995    EINA_SAFETY_ON_NULL_RETURN(func);
2996    EINA_LIST_FOREACH(wd->item_providers, l, ip)
2997      {
2998         if ((ip->func == func) && ((!data) || (ip->data == data)))
2999           {
3000              wd->item_providers = eina_list_remove_list(wd->item_providers, l);
3001              free(ip);
3002              return;
3003           }
3004      }
3005 }
3006
3007 EAPI void
3008 elm_entry_text_filter_append(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3009 {
3010    Widget_Data *wd;
3011    Elm_Entry_Markup_Filter *tf;
3012    ELM_CHECK_WIDTYPE(obj, widtype);
3013
3014    wd = elm_widget_data_get(obj);
3015
3016    EINA_SAFETY_ON_NULL_RETURN(func);
3017
3018    tf = _filter_new(func, data);
3019    if (!tf) return;
3020
3021    wd->text_filters = eina_list_append(wd->text_filters, tf);
3022 }
3023
3024 EAPI void
3025 elm_entry_text_filter_prepend(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3026 {
3027    Widget_Data *wd;
3028    Elm_Entry_Markup_Filter *tf;
3029    ELM_CHECK_WIDTYPE(obj, widtype);
3030
3031    wd = elm_widget_data_get(obj);
3032
3033    EINA_SAFETY_ON_NULL_RETURN(func);
3034
3035    tf = _filter_new(func, data);
3036    if (!tf) return;
3037
3038    wd->text_filters = eina_list_prepend(wd->text_filters, tf);
3039 }
3040
3041 EAPI void
3042 elm_entry_text_filter_remove(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3043 {
3044    Widget_Data *wd;
3045    Eina_List *l;
3046    Elm_Entry_Markup_Filter *tf;
3047    ELM_CHECK_WIDTYPE(obj, widtype);
3048
3049    wd = elm_widget_data_get(obj);
3050
3051    EINA_SAFETY_ON_NULL_RETURN(func);
3052
3053    EINA_LIST_FOREACH(wd->text_filters, l, tf)
3054      {
3055         if ((tf->func == func) && ((!data) || (tf->data == data)))
3056           {
3057              wd->text_filters = eina_list_remove_list(wd->text_filters, l);
3058              _filter_free(tf);
3059              return;
3060           }
3061      }
3062 }
3063
3064 EAPI void
3065 elm_entry_markup_filter_append(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3066 {
3067    Widget_Data *wd;
3068    Elm_Entry_Markup_Filter *tf;
3069    ELM_CHECK_WIDTYPE(obj, widtype);
3070
3071    wd = elm_widget_data_get(obj);
3072
3073    EINA_SAFETY_ON_NULL_RETURN(func);
3074
3075    tf = _filter_new(func, data);
3076    if (!tf) return;
3077
3078    wd->markup_filters = eina_list_append(wd->markup_filters, tf);
3079 }
3080
3081 EAPI void
3082 elm_entry_markup_filter_prepend(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3083 {
3084    Widget_Data *wd;
3085    Elm_Entry_Markup_Filter *tf;
3086    ELM_CHECK_WIDTYPE(obj, widtype);
3087
3088    wd = elm_widget_data_get(obj);
3089
3090    EINA_SAFETY_ON_NULL_RETURN(func);
3091
3092    tf = _filter_new(func, data);
3093    if (!tf) return;
3094
3095    wd->markup_filters = eina_list_prepend(wd->markup_filters, tf);
3096 }
3097
3098 EAPI void
3099 elm_entry_markup_filter_remove(Evas_Object *obj, Elm_Entry_Filter_Cb func, void *data)
3100 {
3101    Widget_Data *wd;
3102    Eina_List *l;
3103    Elm_Entry_Markup_Filter *tf;
3104    ELM_CHECK_WIDTYPE(obj, widtype);
3105
3106    wd = elm_widget_data_get(obj);
3107
3108    EINA_SAFETY_ON_NULL_RETURN(func);
3109
3110    EINA_LIST_FOREACH(wd->markup_filters, l, tf)
3111      {
3112         if ((tf->func == func) && ((!data) || (tf->data == data)))
3113           {
3114              wd->markup_filters = eina_list_remove_list(wd->markup_filters, l);
3115              _filter_free(tf);
3116              return;
3117           }
3118      }
3119 }
3120
3121 EAPI char *
3122 elm_entry_markup_to_utf8(const char *s)
3123 {
3124    char *ss = _elm_util_mkup_to_text(s);
3125    if (!ss) ss = strdup("");
3126    return ss;
3127 }
3128
3129 EAPI char *
3130 elm_entry_utf8_to_markup(const char *s)
3131 {
3132    char *ss = _elm_util_text_to_mkup(s);
3133    if (!ss) ss = strdup("");
3134    return ss;
3135 }
3136
3137 static const char *
3138 _text_get(const Evas_Object *obj)
3139 {
3140    return elm_object_text_get(obj);
3141 }
3142
3143 EAPI void
3144 elm_entry_filter_limit_size(void *data, Evas_Object *entry, char **text)
3145 {
3146    Elm_Entry_Filter_Limit_Size *lim = data;
3147    char *current, *utfstr;
3148    int len, newlen;
3149    const char *(*text_get)(const Evas_Object *);
3150
3151    EINA_SAFETY_ON_NULL_RETURN(data);
3152    EINA_SAFETY_ON_NULL_RETURN(entry);
3153    EINA_SAFETY_ON_NULL_RETURN(text);
3154
3155    /* hack. I don't want to copy the entire function to work with
3156     * scrolled_entry */
3157    text_get = _text_get;
3158
3159    current = elm_entry_markup_to_utf8(text_get(entry));
3160    utfstr = elm_entry_markup_to_utf8(*text);
3161
3162    if (lim->max_char_count > 0)
3163      {
3164         len = evas_string_char_len_get(current);
3165         if (len >= lim->max_char_count)
3166           {
3167              evas_object_smart_callback_call(entry, "maxlength,reached", NULL);
3168              free(*text);
3169              *text = NULL;
3170              free(current);
3171              free(utfstr);
3172              return;
3173           }
3174         newlen = evas_string_char_len_get(utfstr);
3175         if ((len + newlen) > lim->max_char_count)
3176           _add_chars_till_limit(entry, text, (lim->max_char_count - len), LENGTH_UNIT_CHAR);
3177      }
3178    else if (lim->max_byte_count > 0)
3179      {
3180         len = strlen(current);
3181         if (len >= lim->max_byte_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 = strlen(utfstr);
3191         if ((len + newlen) > lim->max_byte_count)
3192           _add_chars_till_limit(entry, text, (lim->max_byte_count - len), LENGTH_UNIT_BYTE);
3193      }
3194    free(current);
3195    free(utfstr);
3196 }
3197
3198 EAPI void
3199 elm_entry_filter_accept_set(void *data, Evas_Object *entry __UNUSED__, char **text)
3200 {
3201    Elm_Entry_Filter_Accept_Set *as = data;
3202    const char *set;
3203    char *insert;
3204    Eina_Bool goes_in;
3205    int read_idx, last_read_idx = 0, read_char;
3206
3207    EINA_SAFETY_ON_NULL_RETURN(data);
3208    EINA_SAFETY_ON_NULL_RETURN(text);
3209
3210    if ((!as->accepted) && (!as->rejected))
3211      return;
3212
3213    if (as->accepted)
3214      {
3215         set = as->accepted;
3216         goes_in = EINA_TRUE;
3217      }
3218    else
3219      {
3220         set = as->rejected;
3221         goes_in = EINA_FALSE;
3222      }
3223
3224    insert = *text;
3225    read_idx = evas_string_char_next_get(*text, 0, &read_char);
3226    while (read_char)
3227      {
3228         int cmp_idx, cmp_char;
3229         Eina_Bool in_set = EINA_FALSE;
3230
3231         cmp_idx = evas_string_char_next_get(set, 0, &cmp_char);
3232         while (cmp_char)
3233           {
3234              if (read_char == cmp_char)
3235                {
3236                   in_set = EINA_TRUE;
3237                   break;
3238                }
3239              cmp_idx = evas_string_char_next_get(set, cmp_idx, &cmp_char);
3240           }
3241         if (in_set == goes_in)
3242           {
3243              int size = read_idx - last_read_idx;
3244              const char *src = (*text) + last_read_idx;
3245              if (src != insert)
3246                memcpy(insert, *text + last_read_idx, size);
3247              insert += size;
3248           }
3249         last_read_idx = read_idx;
3250         read_idx = evas_string_char_next_get(*text, read_idx, &read_char);
3251      }
3252    *insert = 0;
3253 }
3254
3255 EAPI void
3256 elm_entry_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format)
3257 {
3258    ELM_CHECK_WIDTYPE(obj, widtype);
3259    Widget_Data *wd = elm_widget_data_get(obj);
3260    if (!wd) return;
3261    if (wd->delay_write)
3262      {
3263         ecore_timer_del(wd->delay_write);
3264         wd->delay_write = NULL;
3265      }
3266    if (wd->autosave) _save(obj);
3267    eina_stringshare_replace(&wd->file, file);
3268    wd->format = format;
3269    _load(obj);
3270 }
3271
3272 EAPI void
3273 elm_entry_file_get(const Evas_Object *obj, const char **file, Elm_Text_Format *format)
3274 {
3275    ELM_CHECK_WIDTYPE(obj, widtype);
3276    Widget_Data *wd = elm_widget_data_get(obj);
3277    if (!wd) return;
3278    if (file) *file = wd->file;
3279    if (format) *format = wd->format;
3280 }
3281
3282 EAPI void
3283 elm_entry_file_save(Evas_Object *obj)
3284 {
3285    ELM_CHECK_WIDTYPE(obj, widtype);
3286    Widget_Data *wd = elm_widget_data_get(obj);
3287    if (!wd) return;
3288    if (wd->delay_write)
3289      {
3290         ecore_timer_del(wd->delay_write);
3291         wd->delay_write = NULL;
3292      }
3293    _save(obj);
3294    wd->delay_write = ecore_timer_add(2.0, _delay_write, obj);
3295 }
3296
3297 EAPI void
3298 elm_entry_autosave_set(Evas_Object *obj, Eina_Bool autosave)
3299 {
3300    ELM_CHECK_WIDTYPE(obj, widtype);
3301    Widget_Data *wd = elm_widget_data_get(obj);
3302    if (!wd) return;
3303    wd->autosave = !!autosave;
3304 }
3305
3306 EAPI Eina_Bool
3307 elm_entry_autosave_get(const Evas_Object *obj)
3308 {
3309    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3310    Widget_Data *wd = elm_widget_data_get(obj);
3311    if (!wd) return EINA_FALSE;
3312    return wd->autosave;
3313 }
3314
3315 EAPI void
3316 elm_entry_cnp_textonly_set(Evas_Object *obj, Eina_Bool textonly)
3317 {
3318    Elm_Sel_Format format = ELM_SEL_FORMAT_MARKUP;
3319    ELM_CHECK_WIDTYPE(obj, widtype);
3320    Widget_Data *wd = elm_widget_data_get(obj);
3321    if (!wd) return;
3322    textonly = !!textonly;
3323    if (wd->textonly == textonly) return;
3324    wd->textonly = !!textonly;
3325    if (!textonly) format |= ELM_SEL_FORMAT_IMAGE;
3326 #ifdef HAVE_ELEMENTARY_X
3327    elm_drop_target_add(obj, format, _drag_drop_cb, NULL);
3328 #endif
3329 }
3330
3331 EAPI Eina_Bool
3332 elm_entry_cnp_textonly_get(const Evas_Object *obj)
3333 {
3334    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3335    Widget_Data *wd = elm_widget_data_get(obj);
3336    if (!wd) return EINA_FALSE;
3337    return wd->textonly;
3338 }
3339
3340 EAPI void
3341 elm_entry_scrollable_set(Evas_Object *obj, Eina_Bool scroll)
3342 {
3343    ELM_CHECK_WIDTYPE(obj, widtype);
3344    Widget_Data *wd = elm_widget_data_get(obj);
3345    const Elm_Scroller_Policy map[3] =
3346      {
3347         ELM_SMART_SCROLLER_POLICY_AUTO,
3348         ELM_SMART_SCROLLER_POLICY_ON,
3349         ELM_SMART_SCROLLER_POLICY_OFF
3350      };
3351    if (!wd) return;
3352    scroll = !!scroll;
3353    if (wd->scroll == scroll) return;
3354    wd->scroll = scroll;
3355    if (wd->scroll)
3356      {
3357         if (!wd->scroller)
3358           {
3359              wd->scroller = elm_smart_scroller_add(evas_object_evas_get(obj));
3360              elm_widget_resize_object_set(obj, wd->scroller);
3361              elm_smart_scroller_widget_set(wd->scroller, obj);
3362              elm_smart_scroller_object_theme_set(obj, wd->scroller, "scroller", "entry",
3363                                                  elm_widget_style_get(obj));
3364              evas_object_size_hint_weight_set(wd->scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
3365              evas_object_size_hint_align_set(wd->scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
3366              evas_object_propagate_events_set(wd->scroller, EINA_TRUE);
3367              evas_object_propagate_events_set(elm_smart_scroller_edje_object_get(wd->scroller),
3368                                               EINA_TRUE);
3369           }
3370         elm_smart_scroller_bounce_allow_set(wd->scroller, wd->h_bounce, wd->v_bounce);
3371         if (wd->single_line)
3372           elm_smart_scroller_policy_set(wd->scroller, ELM_SMART_SCROLLER_POLICY_OFF,
3373                                         ELM_SMART_SCROLLER_POLICY_OFF);
3374         else
3375           elm_smart_scroller_policy_set(wd->scroller, map[wd->policy_h], map[wd->policy_v]);
3376         elm_widget_sub_object_add(obj, wd->ent);
3377         elm_smart_scroller_child_set(wd->scroller, wd->ent);
3378         evas_object_show(wd->scroller);
3379         elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3380      }
3381    else
3382      {
3383         if (wd->scroller)
3384           {
3385              elm_smart_scroller_child_set(wd->scroller, NULL);
3386              evas_object_smart_member_add(wd->scroller, obj);
3387              elm_widget_sub_object_add(obj, wd->scroller);
3388              evas_object_hide(wd->scroller);
3389           }
3390         elm_widget_sub_object_del(obj, wd->ent);
3391         elm_widget_resize_object_set(obj, wd->ent);
3392         elm_widget_on_show_region_hook_set(obj, NULL, NULL);
3393      }
3394    wd->lastw = -1;
3395    _theme_hook(obj);
3396 }
3397
3398 EAPI Eina_Bool
3399 elm_entry_scrollable_get(const Evas_Object *obj)
3400 {
3401    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3402    Widget_Data *wd = elm_widget_data_get(obj);
3403    if (!wd) return EINA_FALSE;
3404    return wd->scroll;
3405 }
3406
3407 EAPI void
3408 elm_entry_icon_set(Evas_Object *obj, Evas_Object *icon)
3409 {
3410    ELM_CHECK_WIDTYPE(obj, widtype);
3411    EINA_SAFETY_ON_NULL_RETURN(icon);
3412    _content_set_hook(obj, NULL, icon);
3413 }
3414
3415 EAPI Evas_Object *
3416 elm_entry_icon_get(const Evas_Object *obj)
3417 {
3418    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3419    return _content_get_hook(obj, NULL);
3420 }
3421
3422 EAPI Evas_Object *
3423 elm_entry_icon_unset(Evas_Object *obj)
3424 {
3425    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3426    return _content_unset_hook(obj, NULL);
3427 }
3428
3429 EAPI void
3430 elm_entry_icon_visible_set(Evas_Object *obj, Eina_Bool setting)
3431 {
3432    ELM_CHECK_WIDTYPE(obj, widtype);
3433    Widget_Data *wd = elm_widget_data_get(obj);
3434    Evas_Object *edje;
3435    if (!wd) return;
3436    if (wd->scroll)
3437       edje = elm_smart_scroller_edje_object_get(wd->scroller);
3438    else
3439       edje = wd->ent;
3440
3441    if ((!edje) || (!edje_object_part_swallow_get(edje, "elm.swallow.icon"))) return;
3442    if (setting)
3443      edje_object_signal_emit(edje, "elm,action,show,icon", "elm");
3444    else
3445      edje_object_signal_emit(edje, "elm,action,hide,icon", "elm");
3446    _sizing_eval(obj);
3447 }
3448
3449 EAPI void
3450 elm_entry_end_set(Evas_Object *obj, Evas_Object *end)
3451 {
3452    ELM_CHECK_WIDTYPE(obj, widtype);
3453    EINA_SAFETY_ON_NULL_RETURN(end);
3454    _content_set_hook(obj, "end", end);
3455 }
3456
3457 EAPI Evas_Object *
3458 elm_entry_end_get(const Evas_Object *obj)
3459 {
3460    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3461    return _content_get_hook(obj, "end");
3462 }
3463
3464 EAPI Evas_Object *
3465 elm_entry_end_unset(Evas_Object *obj)
3466 {
3467    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3468    return _content_unset_hook(obj, "end");
3469 }
3470
3471 EAPI void
3472 elm_entry_end_visible_set(Evas_Object *obj, Eina_Bool setting)
3473 {
3474    ELM_CHECK_WIDTYPE(obj, widtype);
3475    Widget_Data *wd = elm_widget_data_get(obj);
3476    Evas_Object *edje;
3477    if (!wd) return;
3478    if (wd->scroll)
3479       edje = elm_smart_scroller_edje_object_get(wd->scroller);
3480    else
3481       edje = wd->ent;
3482
3483    if ((!edje) || (!edje_object_part_swallow_get(edje, "elm.swallow.icon"))) return;
3484    if (setting)
3485      edje_object_signal_emit(edje, "elm,action,show,end", "elm");
3486    else
3487      edje_object_signal_emit(edje, "elm,action,hide,end", "elm");
3488    _sizing_eval(obj);
3489 }
3490
3491 EAPI void
3492 elm_entry_scrollbar_policy_set(Evas_Object *obj, Elm_Scroller_Policy h, Elm_Scroller_Policy v)
3493 {
3494    ELM_CHECK_WIDTYPE(obj, widtype);
3495    Widget_Data *wd = elm_widget_data_get(obj);
3496    const Elm_Scroller_Policy map[3] =
3497      {
3498         ELM_SMART_SCROLLER_POLICY_AUTO,
3499         ELM_SMART_SCROLLER_POLICY_ON,
3500         ELM_SMART_SCROLLER_POLICY_OFF
3501      };
3502    if (!wd) return;
3503    wd->policy_h = h;
3504    wd->policy_v = v;
3505    elm_smart_scroller_policy_set(wd->scroller,
3506                                  map[wd->policy_h],
3507                                  map[wd->policy_v]);
3508 }
3509
3510 EAPI void
3511 elm_entry_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
3512 {
3513    ELM_CHECK_WIDTYPE(obj, widtype);
3514    Widget_Data *wd = elm_widget_data_get(obj);
3515    if (!wd) return;
3516    wd->h_bounce = h_bounce;
3517    wd->v_bounce = v_bounce;
3518    elm_smart_scroller_bounce_allow_set(wd->scroller, h_bounce, v_bounce);
3519 }
3520
3521 EAPI void
3522 elm_entry_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
3523 {
3524    ELM_CHECK_WIDTYPE(obj, widtype);
3525    Widget_Data *wd = elm_widget_data_get(obj);
3526    if (!wd) return;
3527    elm_smart_scroller_bounce_allow_get(wd->scroller, h_bounce, v_bounce);
3528 }
3529
3530 EAPI void
3531 elm_entry_input_panel_layout_set(Evas_Object *obj, Elm_Input_Panel_Layout layout)
3532 {
3533    ELM_CHECK_WIDTYPE(obj, widtype);
3534    Widget_Data *wd = elm_widget_data_get(obj);
3535    if (!wd) return;
3536
3537    wd->input_panel_layout = layout;
3538
3539    edje_object_part_text_input_panel_layout_set(wd->ent, "elm.text", layout);
3540 }
3541
3542 EAPI Elm_Input_Panel_Layout
3543 elm_entry_input_panel_layout_get(const Evas_Object *obj)
3544 {
3545    ELM_CHECK_WIDTYPE(obj, widtype) ELM_INPUT_PANEL_LAYOUT_INVALID;
3546    Widget_Data *wd = elm_widget_data_get(obj);
3547    if (!wd) return ELM_INPUT_PANEL_LAYOUT_INVALID;
3548
3549    return wd->input_panel_layout;
3550 }
3551
3552 EAPI void
3553 elm_entry_autocapital_type_set(Evas_Object *obj, Elm_Autocapital_Type autocapital_type)
3554 {
3555    ELM_CHECK_WIDTYPE(obj, widtype);
3556    Widget_Data *wd = elm_widget_data_get(obj);
3557    if (!wd) return;
3558
3559    wd->autocapital_type = autocapital_type;
3560    edje_object_part_text_autocapital_type_set(wd->ent, "elm.text", autocapital_type);
3561 }
3562
3563 EAPI Elm_Autocapital_Type
3564 elm_entry_autocapital_type_get(const Evas_Object *obj)
3565 {
3566    ELM_CHECK_WIDTYPE(obj, widtype) ELM_AUTOCAPITAL_TYPE_NONE;
3567    Widget_Data *wd = elm_widget_data_get(obj);
3568    if (!wd) return ELM_AUTOCAPITAL_TYPE_NONE;
3569
3570    return wd->autocapital_type;
3571 }
3572
3573 EAPI void
3574 elm_entry_prediction_allow_set(Evas_Object *obj, Eina_Bool prediction)
3575 {
3576    ELM_CHECK_WIDTYPE(obj, widtype);
3577    Widget_Data *wd = elm_widget_data_get(obj);
3578    if (!wd) return;
3579
3580    wd->prediction_allow = prediction;
3581    edje_object_part_text_prediction_allow_set(wd->ent, "elm.text", prediction);
3582 }
3583
3584 EAPI Eina_Bool
3585 elm_entry_prediction_allow_get(const Evas_Object *obj)
3586 {
3587    ELM_CHECK_WIDTYPE(obj, widtype) EINA_TRUE;
3588    Widget_Data *wd = elm_widget_data_get(obj);
3589    if (!wd) return EINA_TRUE;
3590
3591    return wd->prediction_allow;
3592 }
3593
3594 EAPI void
3595 elm_entry_imf_context_reset(Evas_Object *obj)
3596 {
3597    ELM_CHECK_WIDTYPE(obj, widtype);
3598    Widget_Data *wd = elm_widget_data_get(obj);
3599    if (!wd) return;
3600
3601    edje_object_part_text_imf_context_reset(wd->ent, "elm.text");
3602 }
3603
3604 EAPI void
3605 elm_entry_input_panel_enabled_set(Evas_Object *obj, Eina_Bool enabled)
3606 {
3607    ELM_CHECK_WIDTYPE(obj, widtype);
3608    Widget_Data *wd = elm_widget_data_get(obj);
3609    if (!wd) return;
3610
3611    wd->input_panel_enable = enabled;
3612    edje_object_part_text_input_panel_enabled_set(wd->ent, "elm.text", enabled);
3613 }
3614
3615 EAPI Eina_Bool
3616 elm_entry_input_panel_enabled_get(const Evas_Object *obj)
3617 {
3618    ELM_CHECK_WIDTYPE(obj, widtype) EINA_TRUE;
3619    Widget_Data *wd = elm_widget_data_get(obj);
3620    if (!wd) return EINA_TRUE;
3621
3622    return wd->input_panel_enable;
3623 }
3624
3625 EAPI void
3626 elm_entry_input_panel_show(Evas_Object *obj)
3627 {
3628    ELM_CHECK_WIDTYPE(obj, widtype);
3629    Widget_Data *wd = elm_widget_data_get(obj);
3630    if (!wd) return;
3631
3632    edje_object_part_text_input_panel_show(wd->ent, "elm.text");
3633 }
3634
3635 EAPI void
3636 elm_entry_input_panel_hide(Evas_Object *obj)
3637 {
3638    ELM_CHECK_WIDTYPE(obj, widtype);
3639    Widget_Data *wd = elm_widget_data_get(obj);
3640    if (!wd) return;
3641
3642    edje_object_part_text_input_panel_hide(wd->ent, "elm.text");
3643 }
3644
3645 EAPI void
3646 elm_entry_input_panel_language_set(Evas_Object *obj, Elm_Input_Panel_Lang lang)
3647 {
3648    ELM_CHECK_WIDTYPE(obj, widtype);
3649    Widget_Data *wd = elm_widget_data_get(obj);
3650    if (!wd) return;
3651
3652    wd->input_panel_lang = lang;
3653    edje_object_part_text_input_panel_language_set(wd->ent, "elm.text", lang);
3654 }
3655
3656 EAPI Elm_Input_Panel_Lang
3657 elm_entry_input_panel_language_get(const Evas_Object *obj)
3658 {
3659    ELM_CHECK_WIDTYPE(obj, widtype) ELM_INPUT_PANEL_LANG_AUTOMATIC;
3660    Widget_Data *wd = elm_widget_data_get(obj);
3661    if (!wd) return ELM_INPUT_PANEL_LANG_AUTOMATIC;
3662
3663    return wd->input_panel_lang;
3664 }
3665
3666 EAPI void
3667 elm_entry_input_panel_imdata_set(Evas_Object *obj, const void *data, int len)
3668 {
3669    ELM_CHECK_WIDTYPE(obj, widtype);
3670    Widget_Data *wd = elm_widget_data_get(obj);
3671    if (!wd) return;
3672
3673    if (wd->input_panel_imdata)
3674      free(wd->input_panel_imdata);
3675
3676    wd->input_panel_imdata = calloc(1, len);
3677    wd->input_panel_imdata_len = len;
3678    memcpy(wd->input_panel_imdata, data, len);
3679
3680    edje_object_part_text_input_panel_imdata_set(wd->ent, "elm.text", wd->input_panel_imdata, wd->input_panel_imdata_len);
3681 }
3682
3683 EAPI void
3684 elm_entry_input_panel_imdata_get(const Evas_Object *obj, void *data, int *len)
3685 {
3686    ELM_CHECK_WIDTYPE(obj, widtype);
3687    Widget_Data *wd = elm_widget_data_get(obj);
3688    if (!wd) return;
3689
3690    edje_object_part_text_input_panel_imdata_get(wd->ent, "elm.text", data, len);
3691 }
3692
3693 EAPI void
3694 elm_entry_input_panel_return_key_type_set(Evas_Object *obj, Elm_Input_Panel_Return_Key_Type return_key_type)
3695 {
3696    ELM_CHECK_WIDTYPE(obj, widtype);
3697    Widget_Data *wd = elm_widget_data_get(obj);
3698    if (!wd) return;
3699
3700    wd->input_panel_return_key_type = return_key_type;
3701
3702    edje_object_part_text_input_panel_return_key_type_set(wd->ent, "elm.text", return_key_type);
3703 }
3704
3705 EAPI Elm_Input_Panel_Return_Key_Type
3706 elm_entry_input_panel_return_key_type_get(const Evas_Object *obj)
3707 {
3708    ELM_CHECK_WIDTYPE(obj, widtype) ELM_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3709    Widget_Data *wd = elm_widget_data_get(obj);
3710    if (!wd) return ELM_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3711
3712    return wd->input_panel_return_key_type;
3713 }
3714
3715 EAPI void
3716 elm_entry_input_panel_return_key_disabled_set(Evas_Object *obj, Eina_Bool disabled)
3717 {
3718    ELM_CHECK_WIDTYPE(obj, widtype);
3719    Widget_Data *wd = elm_widget_data_get(obj);
3720    if (!wd) return;
3721
3722    wd->input_panel_return_key_disabled = disabled;
3723
3724    edje_object_part_text_input_panel_return_key_disabled_set(wd->ent, "elm.text", disabled);
3725 }
3726
3727 EAPI Eina_Bool
3728 elm_entry_input_panel_return_key_disabled_get(const Evas_Object *obj)
3729 {
3730    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3731    Widget_Data *wd = elm_widget_data_get(obj);
3732    if (!wd) return EINA_FALSE;
3733
3734    return wd->input_panel_return_key_disabled;
3735 }
3736
3737 EAPI void
3738 elm_entry_input_panel_return_key_autoenabled_set(Evas_Object *obj, Eina_Bool enabled)
3739 {
3740    ELM_CHECK_WIDTYPE(obj, widtype);
3741    Widget_Data *wd = elm_widget_data_get(obj);
3742    if (!wd) return;
3743
3744    wd->autoreturnkey = enabled;
3745    _check_enable_return_key(obj);
3746 }
3747