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