Merge "[*][elm_win] merge with 66174 for fixing focus problem"
[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_Sel_Format formats = ELM_SEL_FORMAT_MARKUP;
2252              if (wd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
2253                formats = ELM_SEL_FORMAT_TEXT;
2254              else if (wd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
2255                formats |= ELM_SEL_FORMAT_IMAGE;
2256              elm_selection_get(ELM_SEL_CLIPBOARD, formats ,data, NULL, NULL);
2257           }
2258 #endif
2259      }
2260 }
2261
2262 static void
2263 _signal_entry_copy_notify(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2264 {
2265    Widget_Data *wd = elm_widget_data_get(data);
2266    if (!wd) return;
2267    evas_object_smart_callback_call(data, SIG_SELECTION_COPY, NULL);
2268    elm_selection_set(ELM_SEL_CLIPBOARD, obj, ELM_SEL_FORMAT_MARKUP,
2269                      elm_entry_selection_get(data));
2270 }
2271
2272 static void
2273 _signal_entry_cut_notify(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2274 {
2275    Widget_Data *wd = elm_widget_data_get(data);
2276    if (!wd) return;
2277    evas_object_smart_callback_call(data, SIG_SELECTION_CUT, NULL);
2278    elm_selection_set(ELM_SEL_CLIPBOARD, obj, ELM_SEL_FORMAT_MARKUP,
2279                      elm_entry_selection_get(data));
2280    edje_object_part_text_insert(wd->ent, "elm.text", "");
2281    wd->changed = EINA_TRUE;
2282    _sizing_eval(data);
2283 }
2284
2285 static void
2286 _signal_cursor_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2287 {
2288    Widget_Data *wd = elm_widget_data_get(data);
2289    if (!wd) return;
2290    wd->cursor_pos = edje_object_part_text_cursor_pos_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
2291    wd->cur_changed = EINA_TRUE;
2292    _recalc_cursor_geometry(data);
2293 }
2294
2295 static void
2296 _signal_anchor_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2297 {
2298    Widget_Data *wd = elm_widget_data_get(data);
2299    if (!wd) return;
2300 }
2301
2302 static void
2303 _signal_anchor_up(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2304 {
2305    Widget_Data *wd = elm_widget_data_get(data);
2306    if (!wd) return;
2307 }
2308
2309 static void
2310 _signal_anchor_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission, const char *source __UNUSED__)
2311 {
2312    Widget_Data *wd = elm_widget_data_get(data);
2313    Elm_Entry_Anchor_Info ei;
2314    char *buf2, *p, *p2, *n;
2315    if (!wd) return;
2316    p = strrchr(emission, ',');
2317    if (p)
2318      {
2319         const Eina_List *geoms;
2320
2321         n = p + 1;
2322         p2 = p -1;
2323         while (p2 >= emission)
2324           {
2325              if (*p2 == ',') break;
2326              p2--;
2327           }
2328         p2++;
2329         buf2 = alloca(5 + p - p2);
2330         strncpy(buf2, p2, p - p2);
2331         buf2[p - p2] = 0;
2332         ei.name = n;
2333         ei.button = atoi(buf2);
2334         ei.x = ei.y = ei.w = ei.h = 0;
2335         geoms =
2336            edje_object_part_text_anchor_geometry_get(wd->ent, "elm.text", ei.name);
2337         if (geoms)
2338           {
2339              Evas_Textblock_Rectangle *r;
2340              const Eina_List *l;
2341              Evas_Coord px, py, x, y;
2342
2343              evas_object_geometry_get(wd->ent, &x, &y, NULL, NULL);
2344              evas_pointer_canvas_xy_get(evas_object_evas_get(wd->ent), &px, &py);
2345              EINA_LIST_FOREACH(geoms, l, r)
2346                {
2347                   if (((r->x + x) <= px) && ((r->y + y) <= py) &&
2348                       ((r->x + x + r->w) > px) && ((r->y + y + r->h) > py))
2349                     {
2350                        ei.x = r->x + x;
2351                        ei.y = r->y + y;
2352                        ei.w = r->w;
2353                        ei.h = r->h;
2354                        break;
2355                     }
2356                }
2357           }
2358         if (!wd->disabled)
2359           evas_object_smart_callback_call(data, SIG_ANCHOR_CLICKED, &ei);
2360      }
2361 }
2362
2363 static void
2364 _signal_anchor_move(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2365 {
2366    Widget_Data *wd = elm_widget_data_get(data);
2367    if (!wd) return;
2368 }
2369
2370 static void
2371 _signal_anchor_in(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2372 {
2373    Widget_Data *wd = elm_widget_data_get(data);
2374    if (!wd) return;
2375 }
2376
2377 static void
2378 _signal_anchor_out(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2379 {
2380    Widget_Data *wd = elm_widget_data_get(data);
2381    if (!wd) return;
2382 }
2383
2384 static void
2385 _signal_key_enter(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2386 {
2387    Widget_Data *wd = elm_widget_data_get(data);
2388    if (!wd) return;
2389    evas_object_smart_callback_call(data, SIG_ACTIVATED, NULL);
2390 }
2391
2392 static void
2393 _signal_mouse_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2394 {
2395    Widget_Data *wd = elm_widget_data_get(data);
2396    if (!wd) return;
2397    wd->double_clicked = EINA_FALSE;
2398    evas_object_smart_callback_call(data, SIG_PRESS, NULL);
2399
2400    if ((wd->api) && (wd->api->obj_hidemenu))
2401      wd->api->obj_hidemenu(data);
2402 }
2403
2404 static void
2405 _signal_mouse_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2406 {
2407    Widget_Data *wd = elm_widget_data_get(data);
2408    if (!wd) return;
2409    evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
2410
2411    if (!_elm_config->desktop_entry && !wd->double_clicked)
2412      _cancel(data, NULL, NULL);
2413 }
2414
2415 static void
2416 _signal_mouse_double(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2417 {
2418    Widget_Data *wd = elm_widget_data_get(data);
2419    if (!wd) return;
2420    wd->double_clicked = EINA_TRUE;
2421    evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
2422 }
2423
2424 #ifdef HAVE_ELEMENTARY_X
2425 static Eina_Bool
2426 _event_selection_notify(void *data, int type __UNUSED__, void *event)
2427 {
2428    Widget_Data *wd = elm_widget_data_get(data);
2429    Ecore_X_Event_Selection_Notify *ev = event;
2430    if (!wd) return ECORE_CALLBACK_PASS_ON;
2431    if ((!wd->selection_asked) && (!wd->drag_selection_asked))
2432      return ECORE_CALLBACK_PASS_ON;
2433
2434    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
2435        (ev->selection == ECORE_X_SELECTION_PRIMARY))
2436      {
2437         Ecore_X_Selection_Data_Text *text_data;
2438
2439         text_data = ev->data;
2440         if (text_data->data.content == ECORE_X_SELECTION_CONTENT_TEXT)
2441           {
2442              if (text_data->text)
2443                {
2444                   char *txt = _elm_util_text_to_mkup(text_data->text);
2445
2446                   if (txt)
2447                     {
2448                        elm_entry_entry_insert(data, txt);
2449                        free(txt);
2450                     }
2451                }
2452           }
2453         wd->selection_asked = EINA_FALSE;
2454      }
2455    else if (ev->selection == ECORE_X_SELECTION_XDND)
2456      {
2457         Ecore_X_Selection_Data_Text *text_data;
2458
2459         text_data = ev->data;
2460         if (text_data->data.content == ECORE_X_SELECTION_CONTENT_TEXT)
2461           {
2462              if (text_data->text)
2463                {
2464                   char *txt = _elm_util_text_to_mkup(text_data->text);
2465
2466                   if (txt)
2467                     {
2468                        /* Massive FIXME: this should be at the drag point */
2469                        elm_entry_entry_insert(data, txt);
2470                        free(txt);
2471                     }
2472                }
2473           }
2474         wd->drag_selection_asked = EINA_FALSE;
2475
2476         ecore_x_dnd_send_finished();
2477
2478      }
2479    return ECORE_CALLBACK_PASS_ON;
2480 }
2481
2482 static Eina_Bool
2483 _event_selection_clear(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
2484 {
2485 #if 0
2486    Widget_Data *wd = elm_widget_data_get(data);
2487    Ecore_X_Event_Selection_Clear *ev = event;
2488    if (!wd) return ECORE_CALLBACK_PASS_ON;
2489    if (!wd->have_selection) return ECORE_CALLBACK_PASS_ON;
2490    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
2491        (ev->selection == ECORE_X_SELECTION_PRIMARY))
2492      {
2493         elm_entry_select_none(data);
2494      }
2495 #else
2496
2497    // start for cbhm
2498    Evas_Object *top = elm_widget_top_get(data);
2499    Ecore_X_Event_Selection_Clear *ev = event;
2500
2501    if (!top)
2502       return ECORE_CALLBACK_PASS_ON;
2503
2504    if (ev->selection != ECORE_X_SELECTION_SECONDARY)
2505      {
2506         return ECORE_CALLBACK_PASS_ON;
2507      }
2508
2509    if (cnpwidgetdata == data)
2510      {
2511         Widget_Data *wd = elm_widget_data_get(data);
2512         Elm_Sel_Format formats = ELM_SEL_FORMAT_MARKUP;
2513         evas_object_smart_callback_call(data, SIG_SELECTION_PASTE, NULL);
2514         if (wd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
2515           formats = ELM_SEL_FORMAT_TEXT;
2516         else if (wd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
2517           formats |= ELM_SEL_FORMAT_IMAGE;
2518         elm_selection_get(ELM_SEL_SECONDARY, formats ,data, NULL, NULL);
2519      }
2520
2521    // end for cbhm
2522 #endif
2523    return ECORE_CALLBACK_PASS_ON;
2524 }
2525
2526 static Eina_Bool
2527 _drag_drop_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Selection_Data *drop)
2528 {
2529    Widget_Data *wd;
2530    Eina_Bool rv;
2531
2532    wd = elm_widget_data_get(obj);
2533    if (!wd) return EINA_FALSE;
2534    printf("Inserting at (%d,%d) %s\n",drop->x,drop->y,(char*)drop->data);
2535
2536    edje_object_part_text_cursor_copy(wd->ent, "elm.text",
2537                                      EDJE_CURSOR_MAIN,/*->*/EDJE_CURSOR_USER);
2538    rv = edje_object_part_text_cursor_coord_set(wd->ent,"elm.text",
2539                                                EDJE_CURSOR_MAIN,drop->x,drop->y);
2540    if (!rv) printf("Warning: Failed to position cursor: paste anyway\n");
2541    elm_entry_entry_insert(obj, drop->data);
2542    edje_object_part_text_cursor_copy(wd->ent, "elm.text",
2543                                      EDJE_CURSOR_USER,/*->*/EDJE_CURSOR_MAIN);
2544
2545    return EINA_TRUE;
2546 }
2547 #endif
2548
2549 static Evas_Object *
2550 _get_item(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, const char *item)
2551 {
2552    Widget_Data *wd = elm_widget_data_get(data);
2553    Evas_Object *o;
2554    Eina_List *l;
2555    Elm_Entry_Item_Provider *ip;
2556
2557    EINA_LIST_FOREACH(wd->item_providers, l, ip)
2558      {
2559         o = ip->func(ip->data, data, item);
2560         if (o) return o;
2561      }
2562    if (!strncmp(item, "file://", 7))
2563      {
2564         const char *fname = item + 7;
2565
2566         o = evas_object_image_filled_add(evas_object_evas_get(data));
2567         evas_object_image_file_set(o, fname, NULL);
2568         if (evas_object_image_load_error_get(o) == EVAS_LOAD_ERROR_NONE)
2569           {
2570              evas_object_show(o);
2571           }
2572         else
2573           {
2574              evas_object_del(o);
2575              o = edje_object_add(evas_object_evas_get(data));
2576              _elm_theme_object_set(data, o, "entry/emoticon", "wtf", elm_widget_style_get(data));
2577           }
2578         return o;
2579      }
2580    o = edje_object_add(evas_object_evas_get(data));
2581    if (!_elm_theme_object_set(data, o, "entry", item, elm_widget_style_get(data)))
2582      _elm_theme_object_set(data, o, "entry/emoticon", "wtf", elm_widget_style_get(data));
2583    return o;
2584 }
2585
2586 static int
2587 _strbuf_key_value_replace(Eina_Strbuf *srcbuf, char *key, const char *value, int deleteflag)
2588 {
2589    const char *srcstring = NULL;
2590    Eina_Strbuf *repbuf = NULL, *diffbuf = NULL;
2591    char *curlocater = NULL, *replocater;
2592    char *starttag, *endtag;
2593    int tagtxtlen = 0, insertflag = 0;
2594
2595    srcstring = eina_strbuf_string_get(srcbuf);
2596    if (srcstring)
2597      curlocater = strstr(srcstring, key);
2598    if (!curlocater || !srcstring)
2599      {
2600         insertflag = 1;
2601      }
2602    else
2603      {
2604        do
2605          {
2606            starttag = strchr(srcstring, '<');
2607            endtag = strchr(srcstring, '>');
2608            tagtxtlen = endtag - starttag;
2609            if (tagtxtlen <= 0) tagtxtlen = 0;
2610            if (starttag < curlocater && curlocater < endtag) break;
2611            if (endtag != NULL && endtag+1 != NULL)
2612              srcstring = endtag+1;
2613            else
2614              break;
2615          } while (strlen(srcstring) > 1);
2616
2617        if (starttag && endtag && tagtxtlen > strlen(key))
2618          {
2619            repbuf = eina_strbuf_new();
2620            diffbuf = eina_strbuf_new();
2621            eina_strbuf_append_n(repbuf, starttag, tagtxtlen);
2622            srcstring = eina_strbuf_string_get(repbuf);
2623            curlocater = strstr(srcstring, key);
2624
2625            if (curlocater != NULL)
2626              {
2627                replocater = curlocater + strlen(key) + 1;
2628
2629                while ((*replocater) && (*replocater != ' ') && (*replocater != '>'))
2630                  replocater++;
2631
2632                if (replocater-curlocater > strlen(key)+1)
2633                  {
2634                    eina_strbuf_append_n(diffbuf, curlocater, replocater-curlocater+1);
2635                  }
2636                else
2637                  insertflag = 1;
2638              }
2639            else
2640              {
2641                insertflag = 1;
2642              }
2643            eina_strbuf_reset(repbuf);
2644          }
2645        else
2646          {
2647            insertflag = 1;
2648          }
2649      }
2650
2651    if (repbuf == NULL) repbuf = eina_strbuf_new();
2652    if (diffbuf == NULL) diffbuf = eina_strbuf_new();
2653
2654    if (insertflag)
2655      {
2656        eina_strbuf_append_printf(repbuf, "<%s=%s>", key, value);
2657        eina_strbuf_prepend(srcbuf, eina_strbuf_string_get(repbuf));
2658      }
2659    else
2660      {
2661         if (deleteflag)
2662           {
2663             eina_strbuf_prepend(diffbuf, "<");
2664             eina_strbuf_append(diffbuf, ">");
2665             eina_strbuf_replace_first(srcbuf, eina_strbuf_string_get(diffbuf), "");
2666           }
2667         else
2668           {
2669             eina_strbuf_append_printf(repbuf, "%s=%s", key, value);
2670             eina_strbuf_replace_first(srcbuf, eina_strbuf_string_get(diffbuf), eina_strbuf_string_get(repbuf));
2671           }
2672      }
2673
2674    if (repbuf) eina_strbuf_free(repbuf);
2675    if (diffbuf) eina_strbuf_free(diffbuf);
2676
2677    return 0;
2678 }
2679
2680 static int
2681 _stringshare_key_value_replace(const char **srcstring, char *key, const char *value, int deleteflag)
2682 {
2683    Eina_Strbuf *sharebuf = NULL;
2684
2685    sharebuf = eina_strbuf_new();
2686    eina_strbuf_append(sharebuf, *srcstring);
2687    _strbuf_key_value_replace(sharebuf, key, value, deleteflag);
2688    eina_stringshare_del(*srcstring);
2689    *srcstring = eina_stringshare_add(eina_strbuf_string_get(sharebuf));
2690    eina_strbuf_free(sharebuf);
2691
2692    return 0;
2693 }
2694
2695 static void
2696 _text_filter(void *data, Evas_Object *edje __UNUSED__, const char *part __UNUSED__, Edje_Text_Filter_Type type, char **text)
2697 {
2698    Widget_Data *wd = elm_widget_data_get(data);
2699    Eina_List *l;
2700    Elm_Entry_Text_Filter *tf;
2701
2702    if (type == EDJE_TEXT_FILTER_FORMAT)
2703      return;
2704
2705    EINA_LIST_FOREACH(wd->text_filters, l, tf)
2706      {
2707         tf->func(tf->data, data, text);
2708         if (!*text)
2709           break;
2710      }
2711 }
2712
2713 /* This function is used to insert text by chunks in jobs */
2714 static Eina_Bool
2715 _text_append_idler(void *data)
2716 {
2717    int start;
2718    char backup;
2719    Evas_Object *obj = (Evas_Object *) data;
2720    Widget_Data *wd = elm_widget_data_get(obj);
2721    if (wd->text) eina_stringshare_del(wd->text);
2722    wd->text = NULL;
2723    if (wd->password_text) eina_stringshare_del(wd->password_text);
2724    wd->password_text = NULL;
2725    wd->changed = EINA_TRUE;
2726
2727    start = wd->append_text_position;
2728    if (start + _CHUNK_SIZE < wd->append_text_len)
2729      {
2730         int pos = start;
2731         int tag_start, esc_start;
2732
2733         tag_start = esc_start = -1;
2734         /* Find proper markup cut place */
2735         while (pos - start < _CHUNK_SIZE)
2736           {
2737              int prev_pos = pos;
2738              Eina_Unicode tmp =
2739                 eina_unicode_utf8_get_next(wd->append_text_left, &pos);
2740              if (esc_start == -1)
2741                {
2742                   if (tmp == '<')
2743                      tag_start = prev_pos;
2744                   else if (tmp == '>')
2745                      tag_start = -1;
2746                }
2747              else if (tag_start == -1)
2748                {
2749                   if (tmp == '&')
2750                      esc_start = prev_pos;
2751                   else if (tmp == ';')
2752                      esc_start = -1;
2753                }
2754           }
2755
2756         if (tag_start >= 0)
2757           {
2758              wd->append_text_position = tag_start;
2759           }
2760         else if (esc_start >= 0)
2761           {
2762              wd->append_text_position = esc_start;
2763           }
2764         else
2765           {
2766              wd->append_text_position = pos;
2767           }
2768      }
2769    else
2770      {
2771         wd->append_text_position = wd->append_text_len;
2772      }
2773
2774    backup = wd->append_text_left[wd->append_text_position];
2775    wd->append_text_left[wd->append_text_position] = '\0';
2776
2777    edje_object_part_text_append(wd->ent, "elm.text",
2778                                 wd->append_text_left + start);
2779
2780    wd->append_text_left[wd->append_text_position] = backup;
2781
2782    /* If there's still more to go, renew the idler, else, cleanup */
2783    if (wd->append_text_position < wd->append_text_len)
2784      {
2785         return ECORE_CALLBACK_RENEW;
2786      }
2787    else
2788      {
2789         free(wd->append_text_left);
2790         wd->append_text_left = NULL;
2791         wd->append_text_idler = NULL;
2792         return ECORE_CALLBACK_CANCEL;
2793      }
2794 }
2795
2796 static void
2797 _add_chars_till_limit(Evas_Object *obj, char **text, int can_add, Length_Unit unit)
2798 {
2799    int i = 0, current_len = 0;
2800    char *new_text;
2801
2802    if (!*text) return;
2803    if (unit >= LENGTH_UNIT_LAST) return;
2804    new_text = *text;
2805    current_len = strlen(*text);
2806    while (*new_text)
2807      {
2808         int idx = 0, unit_size = 0;
2809         char *markup, *utfstr;
2810         if (*new_text == '<')
2811           {
2812              while (*(new_text + idx) != '>')
2813                {
2814                   idx++;
2815                   if (!*(new_text + idx)) break;
2816                }
2817           }
2818         else if (*new_text == '&')
2819           {
2820              while (*(new_text + idx) != ';')
2821                {
2822                   idx++;
2823                   if (!*(new_text + idx)) break;
2824                }
2825           }
2826         idx = evas_string_char_next_get(new_text, idx, NULL);
2827         markup = malloc(idx + 1);
2828         if (markup)
2829           {
2830              strncpy(markup, new_text, idx);
2831              markup[idx] = 0;
2832              utfstr = elm_entry_markup_to_utf8(markup);
2833              if (utfstr)
2834                {
2835                   if (unit == LENGTH_UNIT_BYTE)
2836                     unit_size = strlen(utfstr);
2837                   else if (unit == LENGTH_UNIT_CHAR)
2838                     unit_size = evas_string_char_len_get(utfstr);
2839                   free(utfstr);
2840                   utfstr = NULL;
2841                }
2842              free(markup);
2843              markup = NULL;
2844           }
2845         if (can_add < unit_size)
2846           {
2847              if (!i)
2848                {
2849                   evas_object_smart_callback_call(obj, "maxlength,reached", NULL);
2850                   free(*text);
2851                   *text = NULL;
2852                   return;
2853                }
2854              can_add = 0;
2855              strncpy(new_text, new_text + idx, current_len - ((new_text + idx) - *text));
2856              current_len -= idx;
2857              (*text)[current_len] = 0;
2858           }
2859         else
2860           {
2861              new_text += idx;
2862              can_add -= unit_size;
2863           }
2864         i++;
2865      }
2866    evas_object_smart_callback_call(obj, "maxlength,reached", NULL);
2867 }
2868
2869 static void
2870 _elm_entry_text_set(Evas_Object *obj, const char *item, const char *entry)
2871 {
2872    int len = 0;
2873    ELM_CHECK_WIDTYPE(obj, widtype);
2874    Widget_Data *wd = elm_widget_data_get(obj);
2875    if (!wd) return;
2876    if (!entry) entry = "";
2877    if (item && strcmp(item, "default"))
2878      {
2879         edje_object_part_text_set(wd->ent, item, entry);
2880         return;
2881      }
2882
2883    if (wd->text) eina_stringshare_del(wd->text);
2884    wd->text = NULL;
2885    if (wd->password_text) eina_stringshare_del(wd->password_text);
2886    wd->password_text = NULL;
2887    wd->changed = EINA_TRUE;
2888
2889    /* Clear currently pending job if there is one */
2890    if (wd->append_text_idler)
2891      {
2892         ecore_idler_del(wd->append_text_idler);
2893         free(wd->append_text_left);
2894         wd->append_text_left = NULL;
2895         wd->append_text_idler = NULL;
2896      }
2897
2898    len = strlen(entry);
2899    /* Split to ~_CHUNK_SIZE chunks */
2900    if (len > _CHUNK_SIZE)
2901      {
2902         wd->append_text_left = (char *) malloc(len + 1);
2903      }
2904
2905    /* If we decided to use the idler */
2906    if (wd->append_text_left)
2907      {
2908         /* Need to clear the entry first */
2909         edje_object_part_text_set(wd->ent, "elm.text", "");
2910         memcpy(wd->append_text_left, entry, len + 1);
2911         wd->append_text_position = 0;
2912         wd->append_text_len = len;
2913         wd->append_text_idler = ecore_idler_add(_text_append_idler, obj);
2914      }
2915    else
2916      {
2917         edje_object_part_text_set(wd->ent, "elm.text", entry);
2918      }
2919 }
2920
2921 static const char *
2922 _elm_entry_text_get(const Evas_Object *obj, const char *item)
2923 {
2924    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2925    Widget_Data *wd = elm_widget_data_get(obj);
2926    if (item && strcmp(item, "default")) return NULL;
2927    const char *text;
2928    if (!wd) return NULL;
2929    if (wd->password)
2930      {
2931         if(wd->password_text) return wd->password_text;
2932      }
2933    else if (wd->text) 
2934      {
2935         return wd->text;
2936      }
2937    text = edje_object_part_text_get(wd->ent, "elm.text");
2938    if (!text)
2939      {
2940         ERR("text=NULL for edje %p, part 'elm.text'", wd->ent);
2941         return NULL;
2942      }
2943    eina_stringshare_replace(&wd->text, text);
2944    if (wd->password)
2945      {
2946         const char *pw_text;
2947         pw_text = elm_entry_markup_to_utf8(wd->text);
2948         if (pw_text)
2949           {
2950              eina_stringshare_replace(&wd->password_text, pw_text);
2951              free(pw_text);
2952              return wd->password_text;
2953           }
2954      }
2955    return wd->text;
2956 }
2957
2958 EAPI Evas_Object *
2959 elm_entry_add(Evas_Object *parent)
2960 {
2961    Evas_Object *obj, *top;
2962    Evas *e;
2963    Widget_Data *wd;
2964
2965    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
2966
2967    ELM_SET_WIDTYPE(widtype, "entry");
2968    elm_widget_type_set(obj, "entry");
2969    elm_widget_sub_object_add(parent, obj);
2970    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
2971    elm_widget_data_set(obj, wd);
2972    elm_widget_del_hook_set(obj, _del_hook);
2973    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
2974    elm_widget_theme_hook_set(obj, _theme_hook);
2975    elm_widget_disable_hook_set(obj, _disable_hook);
2976    elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
2977    elm_widget_focus_region_hook_set(obj, _focus_region_hook);
2978    elm_widget_on_focus_region_hook_set(obj, _on_focus_region_hook);
2979    elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
2980    elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
2981    elm_object_cursor_set(obj, ELM_CURSOR_XTERM);
2982    elm_widget_can_focus_set(obj, EINA_TRUE);
2983    elm_widget_highlight_ignore_set(obj, EINA_TRUE);
2984    elm_widget_text_set_hook_set(obj, _elm_entry_text_set);
2985    elm_widget_text_get_hook_set(obj, _elm_entry_text_get);
2986    elm_widget_content_set_hook_set(obj, _content_set_hook);
2987    elm_widget_content_unset_hook_set(obj, _content_unset_hook);
2988    elm_widget_content_get_hook_set(obj, _content_get_hook);
2989    elm_widget_translate_hook_set(obj, _translate_hook);
2990
2991    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, wd);
2992
2993    wd->linewrap     = ELM_WRAP_WORD;
2994    wd->editable     = EINA_TRUE;
2995    wd->disabled     = EINA_FALSE;
2996    wd->context_menu = EINA_TRUE;
2997    wd->magnifier_enabled = EINA_TRUE;
2998    wd->autosave     = EINA_TRUE;
2999    wd->scroll       = EINA_FALSE;
3000    wd->cnp_mode     = ELM_CNP_MODE_MARKUP;
3001    wd->autoperiod   = EINA_TRUE;
3002
3003    wd->ent = edje_object_add(e);
3004    elm_widget_sub_object_add(obj, wd->ent);
3005    edje_object_item_provider_set(wd->ent, _get_item, obj);
3006    edje_object_text_insert_filter_callback_add(wd->ent,"elm.text", _text_filter, obj);
3007    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOVE, _move, obj);
3008    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_DOWN,
3009                                   _mouse_down, obj);
3010    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_UP,
3011                                   _mouse_up, obj);
3012    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_MOVE,
3013                                   _mouse_move, obj);
3014    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
3015
3016    _elm_theme_object_set(obj, wd->ent, "entry", "base", "default");
3017    edje_object_signal_callback_add(wd->ent, "entry,changed", "elm.text",
3018                                    _signal_entry_changed, obj);
3019    edje_object_signal_callback_add(wd->ent, "preedit,changed", "elm.text",
3020                                    _signal_preedit_changed, obj);
3021    edje_object_signal_callback_add(wd->ent, "handler,move,start", "elm.text",
3022                                    _signal_handler_move_start, obj);
3023    edje_object_signal_callback_add(wd->ent, "handler,move,end", "elm.text",
3024                                    _signal_handler_move_end, obj);
3025    edje_object_signal_callback_add(wd->ent, "handler,moving", "elm.text",
3026                                    _signal_handler_moving, obj);
3027    edje_object_signal_callback_add(wd->ent, "selection,start", "elm.text",
3028                                    _signal_selection_start, obj);
3029    edje_object_signal_callback_add(wd->ent, "selection,end", "elm.text",
3030                                    _signal_selection_end, obj);
3031    edje_object_signal_callback_add(wd->ent, "long,pressed", "elm.text",
3032                                    _signal_long_pressed, obj);
3033    edje_object_signal_callback_add(wd->ent, "magnifier,changed", "elm.text",
3034                                    _signal_magnifier_changed, obj);
3035    edje_object_signal_callback_add(wd->ent, "selection,changed", "elm.text",
3036                                    _signal_selection_changed, obj);
3037    edje_object_signal_callback_add(wd->ent, "selection,cleared", "elm.text",
3038                                    _signal_selection_cleared, obj);
3039    edje_object_signal_callback_add(wd->ent, "entry,paste,request", "elm.text",
3040                                    _signal_entry_paste_request, obj);
3041    edje_object_signal_callback_add(wd->ent, "entry,copy,notify", "elm.text",
3042                                    _signal_entry_copy_notify, obj);
3043    edje_object_signal_callback_add(wd->ent, "entry,cut,notify", "elm.text",
3044                                    _signal_entry_cut_notify, obj);
3045    edje_object_signal_callback_add(wd->ent, "cursor,changed", "elm.text",
3046                                    _signal_cursor_changed, obj);
3047    edje_object_signal_callback_add(wd->ent, "anchor,mouse,down,*", "elm.text",
3048                                    _signal_anchor_down, obj);
3049    edje_object_signal_callback_add(wd->ent, "anchor,mouse,up,*", "elm.text",
3050                                    _signal_anchor_up, obj);
3051    edje_object_signal_callback_add(wd->ent, "anchor,mouse,clicked,*", "elm.text",
3052                                    _signal_anchor_clicked, obj);
3053    edje_object_signal_callback_add(wd->ent, "anchor,mouse,move,*", "elm.text",
3054                                    _signal_anchor_move, obj);
3055    edje_object_signal_callback_add(wd->ent, "anchor,mouse,in,*", "elm.text",
3056                                    _signal_anchor_in, obj);
3057    edje_object_signal_callback_add(wd->ent, "anchor,mouse,out,*", "elm.text",
3058                                    _signal_anchor_out, obj);
3059    edje_object_signal_callback_add(wd->ent, "entry,key,enter", "elm.text",
3060                                    _signal_key_enter, obj);
3061    edje_object_signal_callback_add(wd->ent, "mouse,down,1", "elm.text",
3062                                    _signal_mouse_down, obj);
3063    edje_object_signal_callback_add(wd->ent, "mouse,clicked,1", "elm.text",
3064                                    _signal_mouse_clicked, obj);
3065    edje_object_signal_callback_add(wd->ent, "mouse,down,1,double", "elm.text",
3066                                    _signal_mouse_double, obj);
3067    edje_object_part_text_set(wd->ent, "elm.text", "");
3068    if (_elm_config->desktop_entry)
3069      edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_TRUE);
3070    else
3071      {
3072         edje_object_part_text_copy_paste_disabled_set(wd->ent, "elm.text", EINA_FALSE);
3073         edje_object_part_text_viewport_region_set(wd->ent, "elm.text", -1, -1, -1, -1);
3074         edje_object_part_text_layout_region_set(wd->ent, "elm.text", -1, -1, -1, -1);
3075      }
3076    elm_widget_resize_object_set(obj, wd->ent);
3077    _sizing_eval(obj);
3078
3079    elm_entry_input_panel_layout_set(obj, ELM_INPUT_PANEL_LAYOUT_NORMAL);
3080
3081    wd->input_panel_enable = edje_object_part_text_input_panel_enabled_get(wd->ent, "elm.text");
3082    wd->autocapital_type = edje_object_part_text_autocapital_type_get(wd->ent, "elm.text");
3083
3084 #ifdef HAVE_ELEMENTARY_X
3085    top = elm_widget_top_get(obj);
3086    if ((top) && (elm_win_xwindow_get(top)))
3087      {
3088         wd->sel_notify_handler =
3089            ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY,
3090                                    _event_selection_notify, obj);
3091         wd->sel_clear_handler =
3092            ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR,
3093                                    _event_selection_clear, obj);
3094      }
3095
3096    elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE,
3097                        _drag_drop_cb, NULL);
3098 #endif
3099
3100    entries = eina_list_prepend(entries, obj);
3101
3102    // module - find module for entry
3103    wd->api = _module(obj);
3104    // if found - hook in
3105    if ((wd->api) && (wd->api->obj_hook)) wd->api->obj_hook(obj);
3106
3107    _mirrored_set(obj, elm_widget_mirrored_get(obj));
3108    // TODO: convert Elementary to subclassing of Evas_Smart_Class
3109    // TODO: and save some bytes, making descriptions per-class and not instance!
3110    evas_object_smart_callbacks_descriptions_set(obj, _signals);
3111    return obj;
3112 }
3113
3114 EAPI void elm_entry_extension_module_data_get(Evas_Object *obj,Elm_Entry_Extension_data *ext_mod)
3115 {
3116    ELM_CHECK_WIDTYPE(obj, widtype);
3117    Widget_Data *wd = elm_widget_data_get(obj);
3118    if (!wd) return;
3119    ext_mod->cancel = _cancel;
3120    ext_mod->copy = _copy;
3121    ext_mod->cut = _cut;
3122    ext_mod->paste = _paste;
3123    ext_mod->select = _select;
3124    ext_mod->selectall = _selectall;
3125    ext_mod->ent = wd->ent;
3126    ext_mod->items = wd->items;
3127    ext_mod->editable = wd->editable;
3128    ext_mod->have_selection = wd->have_selection;
3129    ext_mod->password = wd->password;
3130    ext_mod->selmode = wd->selmode;
3131    ext_mod->cnpinit = _cnpinit;
3132    ext_mod->context_menu = wd->context_menu;
3133    ext_mod->cnp_mode = wd->cnp_mode;
3134    ext_mod->viewport_rect = _viewport_region_get(obj);
3135 }
3136
3137 EAPI void
3138 elm_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
3139 {
3140    ELM_CHECK_WIDTYPE(obj, widtype);
3141    Widget_Data *wd = elm_widget_data_get(obj);
3142    if (!wd) return;
3143    if (wd->single_line == single_line) return;
3144    wd->single_line = single_line;
3145    wd->linewrap = ELM_WRAP_NONE;
3146    elm_entry_cnp_mode_set(obj, ELM_CNP_MODE_NO_IMAGE);
3147    _theme_hook(obj);
3148    if (wd->scroller)
3149      {
3150         if (wd->single_line)
3151           {
3152              elm_smart_scroller_policy_set(wd->scroller,
3153                                            ELM_SMART_SCROLLER_POLICY_OFF,
3154                                            ELM_SMART_SCROLLER_POLICY_OFF);
3155              elm_smart_scroller_bounce_allow_set(wd->scroller, EINA_FALSE, EINA_FALSE);
3156           }
3157         else
3158           {
3159              const Elm_Scroller_Policy map[3] =
3160                {
3161                   ELM_SMART_SCROLLER_POLICY_AUTO,
3162                   ELM_SMART_SCROLLER_POLICY_ON,
3163                   ELM_SMART_SCROLLER_POLICY_OFF
3164                };
3165              elm_smart_scroller_policy_set(wd->scroller,
3166                                            map[wd->policy_h],
3167                                            map[wd->policy_v]);
3168              elm_smart_scroller_bounce_allow_set(wd->scroller, EINA_FALSE, EINA_FALSE);
3169           }
3170         _sizing_eval(obj);
3171      }
3172 }
3173
3174 EAPI Eina_Bool
3175 elm_entry_single_line_get(const Evas_Object *obj)
3176 {
3177    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3178    Widget_Data *wd = elm_widget_data_get(obj);
3179    if (!wd) return EINA_FALSE;
3180    return wd->single_line;
3181 }
3182
3183 EAPI void
3184 elm_entry_password_set(Evas_Object *obj, Eina_Bool password)
3185 {
3186    ELM_CHECK_WIDTYPE(obj, widtype);
3187    Widget_Data *wd = elm_widget_data_get(obj);
3188    if (!wd) return;
3189    if (wd->password == password) return;
3190    wd->password = password;
3191    wd->single_line = EINA_TRUE;
3192    wd->linewrap = ELM_WRAP_NONE;
3193    _theme_hook(obj);
3194 }
3195
3196 EAPI Eina_Bool
3197 elm_entry_password_get(const Evas_Object *obj)
3198 {
3199    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3200    Widget_Data *wd = elm_widget_data_get(obj);
3201    if (!wd) return EINA_FALSE;
3202    return wd->password;
3203 }
3204
3205 EAPI void
3206 elm_entry_entry_set(Evas_Object *obj, const char *entry)
3207 {
3208    _elm_entry_text_set(obj, NULL, entry);
3209 }
3210
3211 EAPI void
3212 elm_entry_entry_append(Evas_Object *obj, const char *entry)
3213 {
3214    int len = 0;
3215    ELM_CHECK_WIDTYPE(obj, widtype);
3216    Widget_Data *wd = elm_widget_data_get(obj);
3217    if (!wd) return;
3218    if (!entry) entry = "";
3219    wd->changed = EINA_TRUE;
3220
3221    len = strlen(entry);
3222    if (wd->append_text_left)
3223      {
3224         char *tmpbuf;
3225         tmpbuf = realloc(wd->append_text_left, wd->append_text_len + len + 1);
3226         if (!tmpbuf)
3227           {
3228              /* Do something */
3229              return;
3230           }
3231         wd->append_text_left = tmpbuf;
3232         memcpy(wd->append_text_left + wd->append_text_len, entry, len + 1);
3233         wd->append_text_len += len;
3234      }
3235    else
3236      {
3237         /* FIXME: Add chunked appending here (like in entry_set) */
3238         edje_object_part_text_append(wd->ent, "elm.text", entry);
3239      }
3240 }
3241
3242 EAPI const char *
3243 elm_entry_entry_get(const Evas_Object *obj)
3244 {
3245    return _elm_entry_text_get(obj, NULL);
3246 }
3247
3248 EAPI Eina_Bool
3249 elm_entry_is_empty(const Evas_Object *obj)
3250 {
3251    /* FIXME: until there's support for that in textblock, we just check
3252     * to see if the there is text or not. */
3253    ELM_CHECK_WIDTYPE(obj, widtype) EINA_TRUE;
3254    Widget_Data *wd = elm_widget_data_get(obj);
3255    const Evas_Object *tb;
3256    Evas_Textblock_Cursor *cur;
3257    Eina_Bool ret;
3258    if (!wd) return EINA_TRUE;
3259
3260    if (0) {
3261    /* It's a hack until we get the support suggested above.
3262     * We just create a cursor, point it to the begining, and then
3263     * try to advance it, if it can advance, the tb is not empty,
3264     * otherwise it is. */
3265    tb = edje_object_part_object_get(wd->ent, "elm.text");
3266    cur = evas_object_textblock_cursor_new((Evas_Object *) tb); /* This is
3267                                                                   actually, ok for the time being, thsese hackish stuff will be removed
3268                                                                   once evas 1.0 is out*/
3269    evas_textblock_cursor_pos_set(cur, 0);
3270    ret = evas_textblock_cursor_char_next(cur);
3271    evas_textblock_cursor_free(cur);
3272
3273    return !ret;
3274    }
3275
3276    char *str = elm_entry_markup_to_utf8(elm_entry_entry_get(obj));
3277    if (!str) return EINA_TRUE;
3278
3279    ret = (strlen(str) == 0);
3280
3281    free(str);
3282    return ret;
3283 }
3284
3285 EAPI const Evas_Object *
3286 elm_entry_textblock_get(const Evas_Object *obj)
3287 {
3288    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3289    Widget_Data *wd = elm_widget_data_get(obj);
3290    if (!wd) return NULL;
3291
3292    return edje_object_part_object_get(wd->ent, "elm.text");
3293 }
3294
3295 EAPI void
3296 elm_entry_calc_force(const Evas_Object *obj)
3297 {
3298    ELM_CHECK_WIDTYPE(obj, widtype);
3299    Widget_Data *wd = elm_widget_data_get(obj);
3300    if (!wd) return;
3301
3302    edje_object_calc_force(wd->ent);
3303 }
3304
3305
3306 EAPI const char *
3307 elm_entry_selection_get(const Evas_Object *obj)
3308 {
3309    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3310    Widget_Data *wd = elm_widget_data_get(obj);
3311    if (!wd) return NULL;
3312    return edje_object_part_text_selection_get(wd->ent, "elm.text");
3313 }
3314
3315 EAPI void
3316 elm_entry_entry_insert(Evas_Object *obj, const char *entry)
3317 {
3318    ELM_CHECK_WIDTYPE(obj, widtype);
3319    Widget_Data *wd = elm_widget_data_get(obj);
3320    if (!wd) return;
3321    edje_object_part_text_insert(wd->ent, "elm.text", entry);
3322    // start for cbhm
3323 #ifdef HAVE_ELEMENTARY_X
3324    if (cnpwidgetdata == obj)
3325       ecore_x_selection_secondary_set(elm_win_xwindow_get(obj), "",1);
3326 #endif
3327    // end for cbhm
3328    wd->changed = EINA_TRUE;
3329    _sizing_eval(obj);
3330 }
3331
3332 EAPI void
3333 elm_entry_line_wrap_set(Evas_Object *obj, Elm_Wrap_Type wrap)
3334 {
3335    ELM_CHECK_WIDTYPE(obj, widtype);
3336    Widget_Data *wd = elm_widget_data_get(obj);
3337    if (!wd) return;
3338    if (wd->linewrap == wrap) return;
3339    wd->lastw = -1;
3340    wd->linewrap = wrap;
3341    _theme_hook(obj);
3342 }
3343
3344 EAPI Elm_Wrap_Type
3345 elm_entry_line_wrap_get(const Evas_Object *obj)
3346 {
3347    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3348    Widget_Data *wd = elm_widget_data_get(obj);
3349    if (!wd) return EINA_FALSE;
3350    return wd->linewrap;
3351 }
3352
3353 EAPI void
3354 elm_entry_editable_set(Evas_Object *obj, Eina_Bool editable)
3355 {
3356    ELM_CHECK_WIDTYPE(obj, widtype);
3357    Widget_Data *wd = elm_widget_data_get(obj);
3358    if (!wd) return;
3359    if (wd->editable == editable) return;
3360    wd->editable = editable;
3361    _theme_hook(obj);
3362
3363 #ifdef HAVE_ELEMENTARY_X
3364    if (editable)
3365      elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP, _drag_drop_cb, NULL);
3366    else
3367      elm_drop_target_del(obj);
3368 #endif
3369 }
3370
3371 EAPI Eina_Bool
3372 elm_entry_editable_get(const Evas_Object *obj)
3373 {
3374    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3375    Widget_Data *wd = elm_widget_data_get(obj);
3376    if (!wd) return EINA_FALSE;
3377    return wd->editable;
3378 }
3379
3380 EAPI void
3381 elm_entry_select_none(Evas_Object *obj)
3382 {
3383    ELM_CHECK_WIDTYPE(obj, widtype);
3384    Widget_Data *wd = elm_widget_data_get(obj);
3385    if (!wd) return;
3386    if (wd->selmode)
3387      {
3388         wd->selmode = EINA_FALSE;
3389         if (!_elm_config->desktop_entry)
3390           edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
3391         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
3392      }
3393    wd->have_selection = EINA_FALSE;
3394    edje_object_part_text_select_none(wd->ent, "elm.text");
3395 }
3396
3397 EAPI void
3398 elm_entry_select_all(Evas_Object *obj)
3399 {
3400    ELM_CHECK_WIDTYPE(obj, widtype);
3401    Widget_Data *wd = elm_widget_data_get(obj);
3402    if (!wd) return;
3403    if (wd->selmode)
3404      {
3405         wd->selmode = EINA_FALSE;
3406         if (!_elm_config->desktop_entry)
3407           edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
3408         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
3409      }
3410    wd->have_selection = EINA_TRUE;
3411    edje_object_part_text_select_all(wd->ent, "elm.text");
3412 }
3413
3414 EAPI Eina_Bool
3415 elm_entry_cursor_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
3416 {
3417    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3418    Widget_Data *wd = elm_widget_data_get(obj);
3419    if (!wd) return EINA_FALSE;
3420    edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text", x, y, w, h);
3421    return EINA_TRUE;
3422 }
3423
3424 EAPI Eina_Bool
3425 elm_entry_cursor_next(Evas_Object *obj)
3426 {
3427    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3428    Widget_Data *wd = elm_widget_data_get(obj);
3429    if (!wd) return EINA_FALSE;
3430    return edje_object_part_text_cursor_next(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3431 }
3432
3433 EAPI Eina_Bool
3434 elm_entry_cursor_prev(Evas_Object *obj)
3435 {
3436    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3437    Widget_Data *wd = elm_widget_data_get(obj);
3438    if (!wd) return EINA_FALSE;
3439    return edje_object_part_text_cursor_prev(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3440 }
3441
3442 EAPI Eina_Bool
3443 elm_entry_cursor_up(Evas_Object *obj)
3444 {
3445    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3446    Widget_Data *wd = elm_widget_data_get(obj);
3447    if (!wd) return EINA_FALSE;
3448    return edje_object_part_text_cursor_up(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3449 }
3450
3451 EAPI Eina_Bool
3452 elm_entry_cursor_down(Evas_Object *obj)
3453 {
3454    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3455    Widget_Data *wd = elm_widget_data_get(obj);
3456    if (!wd) return EINA_FALSE;
3457    return edje_object_part_text_cursor_down(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3458 }
3459
3460 EAPI void
3461 elm_entry_cursor_begin_set(Evas_Object *obj)
3462 {
3463    ELM_CHECK_WIDTYPE(obj, widtype);
3464    Widget_Data *wd = elm_widget_data_get(obj);
3465    if (!wd) return;
3466    edje_object_part_text_cursor_begin_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3467 }
3468
3469 EAPI void
3470 elm_entry_cursor_end_set(Evas_Object *obj)
3471 {
3472    ELM_CHECK_WIDTYPE(obj, widtype);
3473    Widget_Data *wd = elm_widget_data_get(obj);
3474    if (!wd) return;
3475    edje_object_part_text_cursor_end_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3476    edje_object_message_signal_process(wd->ent);
3477 }
3478
3479 EAPI void
3480 elm_entry_cursor_line_begin_set(Evas_Object *obj)
3481 {
3482    ELM_CHECK_WIDTYPE(obj, widtype);
3483    Widget_Data *wd = elm_widget_data_get(obj);
3484    if (!wd) return;
3485    edje_object_part_text_cursor_line_begin_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3486 }
3487
3488 EAPI void
3489 elm_entry_cursor_line_end_set(Evas_Object *obj)
3490 {
3491    ELM_CHECK_WIDTYPE(obj, widtype);
3492    Widget_Data *wd = elm_widget_data_get(obj);
3493    if (!wd) return;
3494    edje_object_part_text_cursor_line_end_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3495 }
3496
3497 EAPI void
3498 elm_entry_cursor_selection_begin(Evas_Object *obj)
3499 {
3500    ELM_CHECK_WIDTYPE(obj, widtype);
3501    Widget_Data *wd = elm_widget_data_get(obj);
3502    if (!wd) return;
3503    edje_object_part_text_select_begin(wd->ent, "elm.text");
3504 }
3505
3506 EAPI void
3507 elm_entry_cursor_selection_end(Evas_Object *obj)
3508 {
3509    ELM_CHECK_WIDTYPE(obj, widtype);
3510    Widget_Data *wd = elm_widget_data_get(obj);
3511    if (!wd) return;
3512    edje_object_part_text_select_extend(wd->ent, "elm.text");
3513 }
3514
3515 EAPI Eina_Bool
3516 elm_entry_cursor_is_format_get(const Evas_Object *obj)
3517 {
3518    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3519    Widget_Data *wd = elm_widget_data_get(obj);
3520    if (!wd) return EINA_FALSE;
3521    return edje_object_part_text_cursor_is_format_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3522 }
3523
3524 EAPI Eina_Bool
3525 elm_entry_cursor_is_visible_format_get(const Evas_Object *obj)
3526 {
3527    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3528    Widget_Data *wd = elm_widget_data_get(obj);
3529    if (!wd) return EINA_FALSE;
3530    return edje_object_part_text_cursor_is_visible_format_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3531 }
3532
3533 EAPI const char *
3534 elm_entry_cursor_content_get(const Evas_Object *obj)
3535 {
3536    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3537    Widget_Data *wd = elm_widget_data_get(obj);
3538    if (!wd) return NULL;
3539    return edje_object_part_text_cursor_content_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3540 }
3541
3542 EAPI void
3543 elm_entry_cursor_pos_set(Evas_Object *obj, int pos)
3544 {
3545    ELM_CHECK_WIDTYPE(obj, widtype);
3546    Widget_Data *wd = elm_widget_data_get(obj);
3547    if (!wd) return;
3548    edje_object_part_text_cursor_pos_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN, pos);
3549    edje_object_message_signal_process(wd->ent);
3550 }
3551
3552 EAPI int
3553 elm_entry_cursor_pos_get(const Evas_Object *obj)
3554 {
3555    ELM_CHECK_WIDTYPE(obj, widtype) 0;
3556    Widget_Data *wd = elm_widget_data_get(obj);
3557    if (!wd) return 0;
3558    return edje_object_part_text_cursor_pos_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
3559 }
3560
3561 EAPI void
3562 elm_entry_selection_cut(Evas_Object *obj)
3563 {
3564    ELM_CHECK_WIDTYPE(obj, widtype);
3565    Widget_Data *wd = elm_widget_data_get(obj);
3566    if (!wd) return;
3567    _cut(obj, NULL, NULL);
3568 }
3569
3570 EAPI void
3571 elm_entry_selection_copy(Evas_Object *obj)
3572 {
3573    ELM_CHECK_WIDTYPE(obj, widtype);
3574    Widget_Data *wd = elm_widget_data_get(obj);
3575    if (!wd) return;
3576    _copy(obj, NULL, NULL);
3577 }
3578
3579 EAPI void
3580 elm_entry_selection_paste(Evas_Object *obj)
3581 {
3582    ELM_CHECK_WIDTYPE(obj, widtype);
3583    Widget_Data *wd = elm_widget_data_get(obj);
3584    if (!wd) return;
3585    _paste(obj, NULL, NULL);
3586 }
3587
3588 EAPI void
3589 elm_entry_context_menu_clear(Evas_Object *obj)
3590 {
3591    ELM_CHECK_WIDTYPE(obj, widtype);
3592    Widget_Data *wd = elm_widget_data_get(obj);
3593    Elm_Entry_Context_Menu_Item *it;
3594    if (!wd) return;
3595    EINA_LIST_FREE(wd->items, it)
3596      {
3597         eina_stringshare_del(it->label);
3598         eina_stringshare_del(it->icon_file);
3599         eina_stringshare_del(it->icon_group);
3600         free(it);
3601      }
3602 }
3603
3604 EAPI void
3605 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)
3606 {
3607    ELM_CHECK_WIDTYPE(obj, widtype);
3608    Widget_Data *wd = elm_widget_data_get(obj);
3609    Elm_Entry_Context_Menu_Item *it;
3610    if (!wd) return;
3611    it = calloc(1, sizeof(Elm_Entry_Context_Menu_Item));
3612    if (!it) return;
3613    wd->items = eina_list_append(wd->items, it);
3614    it->obj = obj;
3615    it->label = eina_stringshare_add(label);
3616    it->icon_file = eina_stringshare_add(icon_file);
3617    it->icon_type = icon_type;
3618    it->func = func;
3619    it->data = (void *)data;
3620 }
3621
3622 EAPI void
3623 elm_entry_context_menu_disabled_set(Evas_Object *obj, Eina_Bool disabled)
3624 {
3625    ELM_CHECK_WIDTYPE(obj, widtype);
3626    Widget_Data *wd = elm_widget_data_get(obj);
3627    if (!wd) return;
3628    if (wd->context_menu == !disabled) return;
3629    wd->context_menu = !disabled;
3630
3631    if (!_elm_config->desktop_entry)
3632      edje_object_part_text_copy_paste_disabled_set(wd->ent, "elm.text", disabled);
3633 }
3634
3635 EAPI Eina_Bool
3636 elm_entry_context_menu_disabled_get(const Evas_Object *obj)
3637 {
3638    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3639    Widget_Data *wd = elm_widget_data_get(obj);
3640    if (!wd) return EINA_FALSE;
3641    return !wd->context_menu;
3642 }
3643
3644 EAPI void
3645 elm_entry_magnifier_disabled_set(Evas_Object *obj, Eina_Bool disabled)
3646 {
3647    ELM_CHECK_WIDTYPE(obj, widtype);
3648    Widget_Data *wd = elm_widget_data_get(obj);
3649    if (!wd) return;
3650    if (wd->magnifier_enabled == !disabled) return;
3651    wd->magnifier_enabled = !disabled;
3652 }
3653
3654 EAPI Eina_Bool
3655 elm_entry_magnifier_disabled_get(const Evas_Object *obj)
3656 {
3657    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3658    Widget_Data *wd = elm_widget_data_get(obj);
3659    if (!wd) return EINA_FALSE;
3660    return !wd->magnifier_enabled;
3661 }
3662
3663 EAPI void
3664 elm_entry_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data)
3665 {
3666    ELM_CHECK_WIDTYPE(obj, widtype);
3667    Widget_Data *wd = elm_widget_data_get(obj);
3668    if (!wd) return;
3669    EINA_SAFETY_ON_NULL_RETURN(func);
3670    Elm_Entry_Item_Provider *ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
3671    if (!ip) return;
3672    ip->func = func;
3673    ip->data = data;
3674    wd->item_providers = eina_list_append(wd->item_providers, ip);
3675 }
3676
3677 EAPI void
3678 elm_entry_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data)
3679 {
3680    ELM_CHECK_WIDTYPE(obj, widtype);
3681    Widget_Data *wd = elm_widget_data_get(obj);
3682    if (!wd) return;
3683    EINA_SAFETY_ON_NULL_RETURN(func);
3684    Elm_Entry_Item_Provider *ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
3685    if (!ip) return;
3686    ip->func = func;
3687    ip->data = data;
3688    wd->item_providers = eina_list_prepend(wd->item_providers, ip);
3689 }
3690
3691 EAPI void
3692 elm_entry_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data)
3693 {
3694    ELM_CHECK_WIDTYPE(obj, widtype);
3695    Widget_Data *wd = elm_widget_data_get(obj);
3696    Eina_List *l;
3697    Elm_Entry_Item_Provider *ip;
3698    if (!wd) return;
3699    EINA_SAFETY_ON_NULL_RETURN(func);
3700    EINA_LIST_FOREACH(wd->item_providers, l, ip)
3701      {
3702         if ((ip->func == func) && ((!data) || (ip->data == data)))
3703           {
3704              wd->item_providers = eina_list_remove_list(wd->item_providers, l);
3705              free(ip);
3706              return;
3707           }
3708      }
3709 }
3710
3711 EAPI void
3712 elm_entry_text_filter_append(Evas_Object *obj, void (*func) (void *data, Evas_Object *entry, char **text), void *data)
3713 {
3714    Widget_Data *wd;
3715    Elm_Entry_Text_Filter *tf;
3716    ELM_CHECK_WIDTYPE(obj, widtype);
3717
3718    wd = elm_widget_data_get(obj);
3719
3720    EINA_SAFETY_ON_NULL_RETURN(func);
3721
3722    tf = _filter_new(func, data);
3723    if (!tf) return;
3724
3725    wd->text_filters = eina_list_append(wd->text_filters, tf);
3726 }
3727
3728 EAPI void
3729 elm_entry_text_filter_prepend(Evas_Object *obj, void (*func) (void *data, Evas_Object *entry, char **text), void *data)
3730 {
3731    Widget_Data *wd;
3732    Elm_Entry_Text_Filter *tf;
3733    ELM_CHECK_WIDTYPE(obj, widtype);
3734
3735    wd = elm_widget_data_get(obj);
3736
3737    EINA_SAFETY_ON_NULL_RETURN(func);
3738
3739    tf = _filter_new(func, data);
3740    if (!tf) return;
3741
3742    wd->text_filters = eina_list_prepend(wd->text_filters, tf);
3743 }
3744
3745 EAPI void
3746 elm_entry_text_filter_remove(Evas_Object *obj, void (*func) (void *data, Evas_Object *entry, char **text), void *data)
3747 {
3748    Widget_Data *wd;
3749    Eina_List *l;
3750    Elm_Entry_Text_Filter *tf;
3751    ELM_CHECK_WIDTYPE(obj, widtype);
3752
3753    wd = elm_widget_data_get(obj);
3754
3755    EINA_SAFETY_ON_NULL_RETURN(func);
3756
3757    EINA_LIST_FOREACH(wd->text_filters, l, tf)
3758      {
3759         if ((tf->func == func) && ((!data) || (tf->data == data)))
3760           {
3761              wd->text_filters = eina_list_remove_list(wd->text_filters, l);
3762              _filter_free(tf);
3763              return;
3764           }
3765      }
3766 }
3767
3768 EAPI char *
3769 elm_entry_markup_to_utf8(const char *s)
3770 {
3771    char *ss = _elm_util_mkup_to_text(s);
3772    if (!ss) ss = strdup("");
3773    return ss;
3774 }
3775
3776 EAPI char *
3777 elm_entry_utf8_to_markup(const char *s)
3778 {
3779    char *ss = _elm_util_text_to_mkup(s);
3780    if (!ss) ss = strdup("");
3781    return ss;
3782 }
3783
3784 EAPI void
3785 elm_entry_filter_limit_size(void *data, Evas_Object *entry, char **text)
3786 {
3787    Elm_Entry_Filter_Limit_Size *lim = data;
3788    char *current;
3789    int len, newlen;
3790    const char *(*text_get)(const Evas_Object *);
3791    const char *widget_type;
3792
3793    EINA_SAFETY_ON_NULL_RETURN(data);
3794    EINA_SAFETY_ON_NULL_RETURN(entry);
3795    EINA_SAFETY_ON_NULL_RETURN(text);
3796
3797    /* hack. I don't want to copy the entire function to work with
3798     * scrolled_entry */
3799    widget_type = elm_widget_type_get(entry);
3800    if (!strcmp(widget_type, "entry"))
3801      text_get = elm_entry_entry_get;
3802    else /* huh? */
3803      return;
3804
3805    current = elm_entry_markup_to_utf8(text_get(entry));
3806
3807    if (lim->max_char_count > 0)
3808      {
3809         len = evas_string_char_len_get(current);
3810         if (len >= lim->max_char_count)
3811           {
3812              evas_object_smart_callback_call(entry, "maxlength,reached", NULL);
3813              free(*text);
3814              free(current);
3815              *text = NULL;
3816              return;
3817           }
3818         newlen = evas_string_char_len_get(elm_entry_markup_to_utf8(*text));
3819         if ((len + newlen) > lim->max_char_count)
3820           _add_chars_till_limit(entry, text, (lim->max_char_count - len), LENGTH_UNIT_CHAR);
3821      }
3822    else if (lim->max_byte_count > 0)
3823      {
3824         len = strlen(current);
3825         if (len >= lim->max_byte_count)
3826           {
3827              evas_object_smart_callback_call(entry, "maxlength,reached", NULL);
3828              free(*text);
3829              free(current);
3830              *text = NULL;
3831              return;
3832           }
3833         newlen = strlen(elm_entry_markup_to_utf8(*text));
3834         if ((len + newlen) > lim->max_byte_count)
3835           _add_chars_till_limit(entry, text, (lim->max_byte_count - len), LENGTH_UNIT_BYTE);
3836      }
3837    free(current);
3838 }
3839
3840 EAPI void
3841 elm_entry_filter_accept_set(void *data, Evas_Object *entry __UNUSED__, char **text)
3842 {
3843    Elm_Entry_Filter_Accept_Set *as = data;
3844    const char *set;
3845    char *insert;
3846    Eina_Bool goes_in;
3847    int read_idx, last_read_idx = 0, read_char;
3848
3849    EINA_SAFETY_ON_NULL_RETURN(data);
3850    EINA_SAFETY_ON_NULL_RETURN(text);
3851
3852    if ((!as->accepted) && (!as->rejected))
3853      return;
3854
3855    if (as->accepted)
3856      {
3857         set = as->accepted;
3858         goes_in = EINA_TRUE;
3859      }
3860    else
3861      {
3862         set = as->rejected;
3863         goes_in = EINA_FALSE;
3864      }
3865
3866    insert = *text;
3867    read_idx = evas_string_char_next_get(*text, 0, &read_char);
3868    while (read_char)
3869      {
3870         int cmp_idx, cmp_char;
3871         Eina_Bool in_set = EINA_FALSE;
3872
3873         cmp_idx = evas_string_char_next_get(set, 0, &cmp_char);
3874         while (cmp_char)
3875           {
3876              if (read_char == cmp_char)
3877                {
3878                   in_set = EINA_TRUE;
3879                   break;
3880                }
3881              cmp_idx = evas_string_char_next_get(set, cmp_idx, &cmp_char);
3882           }
3883         if (in_set == goes_in)
3884           {
3885              int size = read_idx - last_read_idx;
3886              const char *src = (*text) + last_read_idx;
3887              if (src != insert)
3888                memcpy(insert, *text + last_read_idx, size);
3889              insert += size;
3890           }
3891         last_read_idx = read_idx;
3892         read_idx = evas_string_char_next_get(*text, read_idx, &read_char);
3893      }
3894    *insert = 0;
3895 }
3896
3897 EAPI void
3898 elm_entry_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format)
3899 {
3900    ELM_CHECK_WIDTYPE(obj, widtype);
3901    Widget_Data *wd = elm_widget_data_get(obj);
3902    if (!wd) return;
3903    if (wd->delay_write)
3904      {
3905         ecore_timer_del(wd->delay_write);
3906         wd->delay_write = NULL;
3907      }
3908    if (wd->autosave) _save(obj);
3909    eina_stringshare_replace(&wd->file, file);
3910    wd->format = format;
3911    _load(obj);
3912 }
3913
3914 EAPI void
3915 elm_entry_file_get(const Evas_Object *obj, const char **file, Elm_Text_Format *format)
3916 {
3917    ELM_CHECK_WIDTYPE(obj, widtype);
3918    Widget_Data *wd = elm_widget_data_get(obj);
3919    if (!wd) return;
3920    if (file) *file = wd->file;
3921    if (format) *format = wd->format;
3922 }
3923
3924 EAPI void
3925 elm_entry_file_save(Evas_Object *obj)
3926 {
3927    ELM_CHECK_WIDTYPE(obj, widtype);
3928    Widget_Data *wd = elm_widget_data_get(obj);
3929    if (!wd) return;
3930    if (wd->delay_write)
3931      {
3932         ecore_timer_del(wd->delay_write);
3933         wd->delay_write = NULL;
3934      }
3935    _save(obj);
3936    wd->delay_write = ecore_timer_add(2.0, _delay_write, obj);
3937 }
3938
3939 EAPI void
3940 elm_entry_autosave_set(Evas_Object *obj, Eina_Bool autosave)
3941 {
3942    ELM_CHECK_WIDTYPE(obj, widtype);
3943    Widget_Data *wd = elm_widget_data_get(obj);
3944    if (!wd) return;
3945    wd->autosave = !!autosave;
3946 }
3947
3948 EAPI Eina_Bool
3949 elm_entry_autosave_get(const Evas_Object *obj)
3950 {
3951    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3952    Widget_Data *wd = elm_widget_data_get(obj);
3953    if (!wd) return EINA_FALSE;
3954    return wd->autosave;
3955 }
3956
3957 EAPI void
3958 elm_entry_cnp_textonly_set(Evas_Object *obj, Eina_Bool textonly)
3959 {
3960    ELM_CHECK_WIDTYPE(obj, widtype);
3961    elm_entry_cnp_mode_set(obj, textonly ? ELM_CNP_MODE_NO_IMAGE : ELM_CNP_MODE_MARKUP);
3962 }
3963
3964 EAPI Eina_Bool
3965 elm_entry_cnp_textonly_get(const Evas_Object *obj)
3966 {
3967    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3968    return elm_entry_cnp_mode_get(obj) != ELM_CNP_MODE_MARKUP;
3969 }
3970
3971 EAPI void
3972 elm_entry_cnp_mode_set(Evas_Object *obj, Elm_CNP_Mode cnp_mode)
3973 {
3974    Elm_Sel_Format format = ELM_SEL_FORMAT_MARKUP;
3975    ELM_CHECK_WIDTYPE(obj, widtype);
3976    Widget_Data *wd = elm_widget_data_get(obj);
3977    if (!wd) return;
3978    if (wd->cnp_mode == cnp_mode) return;
3979    wd->cnp_mode = cnp_mode;
3980    if (wd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
3981      format = ELM_SEL_FORMAT_TEXT;
3982    else if (cnp_mode == ELM_CNP_MODE_MARKUP) format |= ELM_SEL_FORMAT_IMAGE;
3983 #ifdef HAVE_ELEMENTARY_X
3984    elm_drop_target_add(obj, format, _drag_drop_cb, NULL);
3985 #endif
3986 }
3987
3988 EAPI Elm_CNP_Mode
3989 elm_entry_cnp_mode_get(const Evas_Object *obj)
3990 {
3991    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3992    Widget_Data *wd = elm_widget_data_get(obj);
3993    if (!wd) return EINA_FALSE;
3994    return wd->cnp_mode;
3995 }
3996
3997 EAPI void
3998 elm_entry_scrollable_set(Evas_Object *obj, Eina_Bool scroll)
3999 {
4000    ELM_CHECK_WIDTYPE(obj, widtype);
4001    Widget_Data *wd = elm_widget_data_get(obj);
4002    const Elm_Scroller_Policy map[3] =
4003      {
4004         ELM_SMART_SCROLLER_POLICY_AUTO,
4005         ELM_SMART_SCROLLER_POLICY_ON,
4006         ELM_SMART_SCROLLER_POLICY_OFF
4007      };
4008    if (!wd) return;
4009    scroll = !!scroll;
4010    if (wd->scroll == scroll) return;
4011    wd->scroll = scroll;
4012    if (wd->scroll)
4013      {
4014         if (!wd->scroller)
4015           {
4016              wd->scroller = elm_smart_scroller_add(evas_object_evas_get(obj));
4017              elm_widget_resize_object_set(obj, wd->scroller);
4018              elm_smart_scroller_widget_set(wd->scroller, obj);
4019              elm_smart_scroller_object_theme_set(obj, wd->scroller, "scroller", "entry",
4020                                                  elm_widget_style_get(obj));
4021              evas_object_size_hint_weight_set(wd->scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
4022              evas_object_size_hint_align_set(wd->scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
4023              evas_object_propagate_events_set(wd->scroller, EINA_TRUE);
4024              evas_object_propagate_events_set(elm_smart_scroller_edje_object_get(wd->scroller),
4025                                               EINA_TRUE);
4026           }
4027         elm_smart_scroller_bounce_allow_set(wd->scroller, wd->h_bounce, wd->v_bounce);
4028         if (wd->single_line)
4029           elm_smart_scroller_policy_set(wd->scroller, ELM_SMART_SCROLLER_POLICY_OFF,
4030                                         ELM_SMART_SCROLLER_POLICY_OFF);
4031         else
4032           elm_smart_scroller_policy_set(wd->scroller, map[wd->policy_h], map[wd->policy_v]);
4033         elm_widget_sub_object_add(obj, wd->ent);
4034         elm_smart_scroller_child_set(wd->scroller, wd->ent);
4035         evas_object_show(wd->scroller);
4036         elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
4037      }
4038    else
4039      {
4040         if (wd->scroller)
4041           {
4042              elm_smart_scroller_child_set(wd->scroller, NULL);
4043              evas_object_smart_member_add(wd->scroller, obj);
4044              elm_widget_sub_object_add(obj, wd->scroller);
4045              evas_object_hide(wd->scroller);
4046           }
4047         elm_widget_sub_object_del(obj, wd->ent);
4048         elm_widget_resize_object_set(obj, wd->ent);
4049         elm_widget_on_show_region_hook_set(obj, NULL, NULL);
4050      }
4051    wd->lastw = -1;
4052    _theme_hook(obj);
4053 }
4054
4055 EAPI Eina_Bool
4056 elm_entry_scrollable_get(const Evas_Object *obj)
4057 {
4058    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4059    Widget_Data *wd = elm_widget_data_get(obj);
4060    if (!wd) return EINA_FALSE;
4061    return wd->scroll;
4062 }
4063
4064 EAPI void
4065 elm_entry_icon_set(Evas_Object *obj, Evas_Object *icon)
4066 {
4067    ELM_CHECK_WIDTYPE(obj, widtype);
4068    Widget_Data *wd = elm_widget_data_get(obj);
4069    Evas_Object *edje;
4070    if (!wd) return;
4071    EINA_SAFETY_ON_NULL_RETURN(icon);
4072    if (wd->icon == icon) return;
4073    if (wd->icon) evas_object_del(wd->icon);
4074    wd->icon = icon;
4075    edje = elm_smart_scroller_edje_object_get(wd->scroller);
4076    if (!edje) return;
4077    edje_object_part_swallow(edje, "elm.swallow.icon", wd->icon);
4078    edje_object_signal_emit(edje, "elm,action,show,icon", "elm");
4079    _sizing_eval(obj);
4080 }
4081
4082 EAPI Evas_Object *
4083 elm_entry_icon_get(const Evas_Object *obj)
4084 {
4085    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4086    Widget_Data *wd = elm_widget_data_get(obj);
4087    if (!wd) return NULL;
4088    return wd->icon;
4089 }
4090
4091 EAPI Evas_Object *
4092 elm_entry_icon_unset(Evas_Object *obj)
4093 {
4094    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4095    Widget_Data *wd = elm_widget_data_get(obj);
4096    Evas_Object *ret = NULL;
4097    if (!wd) return NULL;
4098    if (wd->icon)
4099      {
4100         Evas_Object *edje = elm_smart_scroller_edje_object_get(wd->scroller);
4101         if (!edje) return NULL;
4102         ret = wd->icon;
4103         edje_object_part_unswallow(edje, wd->icon);
4104         edje_object_signal_emit(edje, "elm,action,hide,icon", "elm");
4105         wd->icon = NULL;
4106         _sizing_eval(obj);
4107      }
4108    return ret;
4109 }
4110
4111 EAPI void
4112 elm_entry_icon_visible_set(Evas_Object *obj, Eina_Bool setting)
4113 {
4114    ELM_CHECK_WIDTYPE(obj, widtype);
4115    Widget_Data *wd = elm_widget_data_get(obj);
4116    if ((!wd) || (!wd->icon)) return;
4117    if (setting)
4118       evas_object_hide(wd->icon);
4119    else
4120       evas_object_show(wd->icon);
4121    _sizing_eval(obj);
4122 }
4123
4124 EAPI void
4125 elm_entry_end_set(Evas_Object *obj, Evas_Object *end)
4126 {
4127    ELM_CHECK_WIDTYPE(obj, widtype);
4128    Widget_Data *wd = elm_widget_data_get(obj);
4129    Evas_Object *edje;
4130    if (!wd) return;
4131    EINA_SAFETY_ON_NULL_RETURN(end);
4132    if (wd->end == end) return;
4133    if (wd->end) evas_object_del(wd->end);
4134    wd->end = end;
4135    edje = elm_smart_scroller_edje_object_get(wd->scroller);
4136    if (!edje) return;
4137    edje_object_part_swallow(edje, "elm.swallow.end", wd->end);
4138    edje_object_signal_emit(edje, "elm,action,show,end", "elm");
4139    _sizing_eval(obj);
4140 }
4141
4142 EAPI Evas_Object *
4143 elm_entry_end_get(const Evas_Object *obj)
4144 {
4145    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4146    Widget_Data *wd = elm_widget_data_get(obj);
4147    if (!wd) return NULL;
4148    return wd->end;
4149 }
4150
4151 EAPI Evas_Object *
4152 elm_entry_end_unset(Evas_Object *obj)
4153 {
4154    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4155    Widget_Data *wd = elm_widget_data_get(obj);
4156    Evas_Object *ret = NULL;
4157    if (!wd) return NULL;
4158    if (wd->end)
4159      {
4160         Evas_Object *edje = elm_smart_scroller_edje_object_get(wd->scroller);
4161         if (!edje) return NULL;
4162         ret = wd->end;
4163         edje_object_part_unswallow(edje, wd->end);
4164         edje_object_signal_emit(edje, "elm,action,hide,end", "elm");
4165         wd->end = NULL;
4166         _sizing_eval(obj);
4167      }
4168    return ret;
4169 }
4170
4171 EAPI void
4172 elm_entry_end_visible_set(Evas_Object *obj, Eina_Bool setting)
4173 {
4174    ELM_CHECK_WIDTYPE(obj, widtype);
4175    Widget_Data *wd = elm_widget_data_get(obj);
4176    if ((!wd) || (!wd->end)) return;
4177    if (setting)
4178       evas_object_hide(wd->end);
4179    else
4180       evas_object_show(wd->end);
4181    _sizing_eval(obj);
4182 }
4183
4184 EAPI void
4185 elm_entry_scrollbar_policy_set(Evas_Object *obj, Elm_Scroller_Policy h, Elm_Scroller_Policy v)
4186 {
4187    ELM_CHECK_WIDTYPE(obj, widtype);
4188    Widget_Data *wd = elm_widget_data_get(obj);
4189    const Elm_Scroller_Policy map[3] =
4190      {
4191         ELM_SMART_SCROLLER_POLICY_AUTO,
4192         ELM_SMART_SCROLLER_POLICY_ON,
4193         ELM_SMART_SCROLLER_POLICY_OFF
4194      };
4195    if (!wd) return;
4196    wd->policy_h = h;
4197    wd->policy_v = v;
4198    elm_smart_scroller_policy_set(wd->scroller,
4199                                  map[wd->policy_h],
4200                                  map[wd->policy_v]);
4201 }
4202
4203 EAPI void
4204 elm_entry_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
4205 {
4206    ELM_CHECK_WIDTYPE(obj, widtype);
4207    Widget_Data *wd = elm_widget_data_get(obj);
4208    if (!wd) return;
4209    wd->h_bounce = h_bounce;
4210    wd->v_bounce = v_bounce;
4211    elm_smart_scroller_bounce_allow_set(wd->scroller, h_bounce, v_bounce);
4212 }
4213
4214 EAPI void
4215 elm_entry_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
4216 {
4217    ELM_CHECK_WIDTYPE(obj, widtype);
4218    Widget_Data *wd = elm_widget_data_get(obj);
4219    if (!wd) return;
4220    elm_smart_scroller_bounce_allow_get(wd->scroller, h_bounce, v_bounce);
4221 }
4222
4223 EAPI void
4224 elm_entry_input_panel_layout_set(Evas_Object *obj, Elm_Input_Panel_Layout layout)
4225 {
4226    ELM_CHECK_WIDTYPE(obj, widtype);
4227    Widget_Data *wd = elm_widget_data_get(obj);
4228    if (!wd) return;
4229
4230    wd->input_panel_layout = layout;
4231
4232    edje_object_part_text_input_panel_layout_set(wd->ent, "elm.text", layout);
4233 }
4234
4235 EAPI Elm_Input_Panel_Layout
4236 elm_entry_input_panel_layout_get(Evas_Object *obj)
4237 {
4238    ELM_CHECK_WIDTYPE(obj, widtype) ELM_INPUT_PANEL_LAYOUT_INVALID;
4239    Widget_Data *wd = elm_widget_data_get(obj);
4240    if (!wd) return ELM_INPUT_PANEL_LAYOUT_INVALID;
4241
4242    return wd->input_panel_layout;
4243 }
4244
4245 EAPI void
4246 elm_entry_autocapital_type_set(Evas_Object *obj, Elm_Autocapital_Type autocapital_type)
4247 {
4248    ELM_CHECK_WIDTYPE(obj, widtype);
4249    Widget_Data *wd = elm_widget_data_get(obj);
4250    if (!wd) return;
4251
4252    wd->autocapital_type = autocapital_type;
4253    edje_object_part_text_autocapital_type_set(wd->ent, "elm.text", autocapital_type);
4254 }
4255
4256 EAPI Elm_Autocapital_Type
4257 elm_entry_autocapital_type_get(Evas_Object *obj)
4258 {
4259    ELM_CHECK_WIDTYPE(obj, widtype) ELM_AUTOCAPITAL_TYPE_NONE;
4260    Widget_Data *wd = elm_widget_data_get(obj);
4261    if (!wd) return ELM_AUTOCAPITAL_TYPE_NONE;
4262
4263    return wd->autocapital_type;
4264 }
4265
4266 EAPI void
4267 elm_entry_input_panel_enabled_set(Evas_Object *obj, Eina_Bool enabled)
4268 {
4269    ELM_CHECK_WIDTYPE(obj, widtype);
4270    Widget_Data *wd = elm_widget_data_get(obj);
4271    if (!wd) return;
4272
4273    wd->input_panel_enable = enabled;
4274    edje_object_part_text_input_panel_enabled_set(wd->ent, "elm.text", enabled);
4275 }
4276
4277 EINA_DEPRECATED EAPI void
4278 elm_entry_line_char_wrap_set(Evas_Object *obj, Eina_Bool wrap)
4279 {
4280    if (wrap) elm_entry_line_wrap_set(obj, ELM_WRAP_CHAR);
4281 }
4282
4283 EAPI void
4284 elm_entry_autocapitalization_set(Evas_Object *obj, Eina_Bool autocap)
4285 {
4286    ELM_CHECK_WIDTYPE(obj, widtype);
4287    Widget_Data *wd = elm_widget_data_get(obj);
4288    if (!wd) return;
4289
4290    if (autocap)
4291      wd->autocapital_type = ELM_AUTOCAPITAL_TYPE_SENTENCE;
4292    else
4293      wd->autocapital_type = ELM_AUTOCAPITAL_TYPE_NONE;
4294
4295    if (wd->input_panel_layout == ELM_INPUT_PANEL_LAYOUT_URL ||
4296        wd->input_panel_layout == ELM_INPUT_PANEL_LAYOUT_EMAIL)
4297      wd->autocapital_type = ELM_AUTOCAPITAL_TYPE_NONE;
4298
4299    edje_object_part_text_autocapital_type_set(wd->ent, "elm.text", wd->autocapital_type);
4300 }
4301
4302 EAPI void
4303 elm_entry_autoperiod_set(Evas_Object *obj, Eina_Bool autoperiod)
4304 {
4305    ELM_CHECK_WIDTYPE(obj, widtype);
4306    Widget_Data *wd = elm_widget_data_get(obj);
4307    if (!wd) return;
4308
4309    if (wd->password)
4310      wd->autoperiod = EINA_FALSE;
4311    else
4312      wd->autoperiod = autoperiod;
4313
4314    if (wd->input_panel_layout == ELM_INPUT_PANEL_LAYOUT_URL ||
4315        wd->input_panel_layout == ELM_INPUT_PANEL_LAYOUT_EMAIL)
4316      wd->autoperiod = EINA_FALSE;
4317
4318    edje_object_part_text_autoperiod_set(wd->ent, "elm.text", wd->autoperiod);
4319 }
4320
4321 EAPI void
4322 elm_entry_autoenable_returnkey_set(Evas_Object *obj, Eina_Bool on)
4323 {
4324    ELM_CHECK_WIDTYPE(obj, widtype);
4325    Widget_Data *wd = elm_widget_data_get(obj);
4326    if (!wd) return;
4327
4328    wd->autoreturnkey = on;
4329    _check_enable_returnkey(obj);
4330 }
4331
4332 EAPI Ecore_IMF_Context *elm_entry_imf_context_get(Evas_Object *obj)
4333 {
4334    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4335    Widget_Data *wd = elm_widget_data_get(obj);
4336    if (!wd || !wd->ent) return NULL;
4337
4338    return edje_object_part_text_imf_context_get(wd->ent, "elm.text");
4339 }
4340
4341 EAPI void
4342 elm_entry_matchlist_set(Evas_Object *obj, Eina_List *match_list, Eina_Bool case_sensitive)
4343 {
4344    Widget_Data *wd = elm_widget_data_get(obj);
4345    if (!wd) return;
4346
4347    if (match_list)
4348      {
4349         Evas_Coord max_w = 9999, max_h = 9999;
4350         const char* key_data = NULL;
4351
4352         wd->matchlist_threshold = 1;
4353         wd->hover = elm_hover_add(elm_widget_parent_get(obj));
4354         elm_hover_parent_set(wd->hover, elm_widget_parent_get(obj));
4355         elm_hover_target_set(wd->hover, obj);
4356         elm_object_style_set(wd->hover, "matchlist");
4357
4358         wd->layout = elm_layout_add(wd->hover);
4359         elm_layout_theme_set(wd->layout, "entry", "matchlist", "default");
4360         wd->list = elm_list_add(wd->layout);
4361         evas_object_size_hint_weight_set(wd->list, EVAS_HINT_EXPAND, 0.0);
4362         evas_object_size_hint_align_set(wd->list, EVAS_HINT_FILL, EVAS_HINT_FILL);
4363         elm_list_mode_set(wd->list, ELM_LIST_EXPAND);
4364         elm_object_style_set(wd->list, "matchlist");
4365
4366         key_data = edje_object_data_get(elm_layout_edje_get(wd->layout), "max_width");
4367         if (key_data) max_w = atoi(key_data);
4368         key_data = edje_object_data_get(elm_layout_edje_get(wd->layout), "max_height");
4369         if (key_data) max_h = atoi(key_data);
4370
4371         elm_list_go(wd->list);
4372         evas_object_size_hint_max_set(wd->list, max_w, max_h);
4373         evas_object_smart_callback_add(wd->list, "selected", _matchlist_list_clicked, obj);
4374         elm_layout_content_set(wd->layout, "elm.swallow.content", wd->list);
4375         elm_hover_content_set(wd->hover, "bottom", wd->layout);
4376
4377         wd->match_list = match_list;
4378      }
4379    else
4380      {
4381         if (wd->hover)
4382           evas_object_del(wd->hover);
4383
4384         wd->match_list = NULL;
4385      }
4386
4387    wd->matchlist_case_sensitive = case_sensitive;
4388 }
4389
4390 EAPI void
4391 elm_entry_magnifier_type_set(Evas_Object *obj, int type)
4392 {
4393    ELM_CHECK_WIDTYPE(obj, widtype);
4394    Widget_Data *wd = elm_widget_data_get(obj);
4395    if (!wd) return;
4396
4397    wd->mgf_type = type;
4398    _magnifier_create(obj);
4399 }