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