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