update for beta release
[framework/uifw/e17.git] / src / bin / e_entry.c
1 #include "e.h"
2
3 #ifdef HAVE_ECORE_IMF
4 #include <Ecore_IMF.h>
5 #include <Ecore_IMF_Evas.h>
6 #endif
7
8 typedef struct _E_Entry_Smart_Data E_Entry_Smart_Data;
9
10 struct _E_Entry_Smart_Data
11 {
12    Evas_Object *entry_object;
13    Evas_Object *editable_object;
14    E_Menu *popup;
15    Ecore_Event_Handler *selection_handler;
16 #ifdef HAVE_ECORE_IMF
17    Ecore_IMF_Context *imf_context;
18 #endif
19    Ecore_Event_Handler *imf_ee_commit_handler;
20    Ecore_Event_Handler *imf_ee_preedit_changed_handler;
21    Ecore_Event_Handler *imf_ee_delete_handler;
22
23    int enabled;
24    int focused;
25    int selection_dragging;
26    int selection_mode;
27    float valign;
28    int min_width;
29    int height;
30    int preedit_start_pos;
31    int preedit_end_pos;
32    Eina_Bool have_preedit : 1;
33 };
34
35 /* local subsystem functions */
36 static void _e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
37 static void _e_entry_key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
38 static void _e_entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
39 static void _e_entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
40 static void _e_entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
41 static Eina_Bool _e_entry_x_selection_notify_handler(void *data, int type, void *event);
42
43 static void _e_entry_x_selection_update(Evas_Object *entry);
44 static void _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event);
45 static void _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event);
46
47 static void _e_entry_smart_add(Evas_Object *object);
48 static void _e_entry_smart_del(Evas_Object *object);
49 static void _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y);
50 static void _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h);
51 static void _e_entry_smart_show(Evas_Object *object);
52 static void _e_entry_smart_hide(Evas_Object *object);
53 static void _e_entry_color_set(Evas_Object *object, int r, int g, int b, int a);
54 static void _e_entry_clip_set(Evas_Object *object, Evas_Object *clip);
55 static void _e_entry_clip_unset(Evas_Object *object);
56 static void _e_entry_cb_menu_post(void *data, E_Menu *m);
57 static void _e_entry_cb_cut(void *data, E_Menu *m, E_Menu_Item *mi);
58 static void _e_entry_cb_copy(void *data, E_Menu *m, E_Menu_Item *mi);
59 static void _e_entry_cb_paste(void *data, E_Menu *m, E_Menu_Item *mi);
60 static void _e_entry_cb_select_all(void *data, E_Menu *m, E_Menu_Item *mi);
61 static void _e_entry_cb_delete(void *data, E_Menu *m, E_Menu_Item *mi);
62 static void _e_entry_imf_cursor_info_set(Evas_Object *object);
63 static void _e_entry_imf_context_reset(Evas_Object *object);
64 #ifdef HAVE_ECORE_IMF
65 static Eina_Bool _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos);
66 static Eina_Bool _e_entry_cb_imf_event_commit(void *data, int type, void *event);
67 static Eina_Bool _e_entry_cb_imf_event_preedit_changed(void *data, int type __UNUSED__, void *event);
68 static Eina_Bool _e_entry_cb_imf_event_delete_surrounding(void *data, int type, void *event);
69 #endif
70
71 /* local subsystem globals */
72 static Evas_Smart *_e_entry_smart = NULL;
73 static int _e_entry_smart_use = 0;
74 static int _e_entry_emacs_keybindings = 0;
75
76
77 /* externally accessible functions */
78
79 /**
80  * Creates a new entry object. An entry is a field where the user can type
81  * single-line text.
82  * Use the "changed" smart callback to know when the content of the entry is
83  * changed
84  *
85  * @param evas the evas where the entry object should be added
86  * @return Returns the new entry object
87  */
88 EAPI Evas_Object *
89 e_entry_add(Evas *evas)
90 {
91    if (!_e_entry_smart)
92      {
93         static const Evas_Smart_Class sc =
94           {
95              "e_entry",
96                EVAS_SMART_CLASS_VERSION,
97                _e_entry_smart_add,
98                _e_entry_smart_del,
99                _e_entry_smart_move,
100                _e_entry_smart_resize,
101                _e_entry_smart_show,
102                _e_entry_smart_hide,
103                _e_entry_color_set,
104                _e_entry_clip_set,
105                _e_entry_clip_unset,
106                NULL,
107                NULL,
108                NULL,
109                NULL,
110                NULL,
111                NULL,
112                NULL
113           };
114         _e_entry_smart = evas_smart_class_new(&sc);
115         _e_entry_smart_use = 0;
116      }
117    
118    _e_entry_smart_use++;
119    return evas_object_smart_add(evas, _e_entry_smart);
120 }
121
122 /**
123  * Sets the text of the entry object
124  *
125  * @param entry an entry object
126  * @param text the text to set
127  */
128 EAPI void
129 e_entry_text_set(Evas_Object *entry, const char *text)
130 {
131    E_Entry_Smart_Data *sd;
132    
133    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
134      return;
135    
136    e_editable_text_set(sd->editable_object, text);
137    evas_object_smart_callback_call(entry, "changed", NULL);
138 }
139
140 /**
141  * Gets the text of the entry object
142  *
143  * @param entry an entry object
144  * @return Returns the text of the entry object
145  */
146 EAPI const char *
147 e_entry_text_get(Evas_Object *entry)
148 {
149    E_Entry_Smart_Data *sd;
150    
151    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
152      return NULL;
153    return e_editable_text_get(sd->editable_object);
154 }
155
156 /**
157  * Clears the entry object
158  *
159  * @param entry an entry object
160  */
161 EAPI void
162 e_entry_clear(Evas_Object *entry)
163 {
164    e_entry_text_set(entry, "");
165 }
166
167 /**
168  * Gets the editable object used by the entry object. It will allow you to have
169  * better control on the text, the cursor or the selection of the entry with
170  * the e_editable_*() functions.
171  *
172  * @param entry an entry object
173  * @return Returns the editable object used by the entry object
174  */
175 EAPI Evas_Object *
176 e_entry_editable_object_get(Evas_Object *entry)
177 {
178    E_Entry_Smart_Data *sd;
179    
180    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
181      return NULL;
182    return sd->editable_object;
183 }
184
185 /**
186  * Sets whether or not the entry object is in password mode. In password mode,
187  * the entry displays '*' instead of the characters
188  *
189  * @param entry an entry object
190  * @param password_mode 1 to turn on password mode, 0 to turn it off
191  */
192 EAPI void
193 e_entry_password_set(Evas_Object *entry, int password_mode)
194 {
195    E_Entry_Smart_Data *sd;
196    
197    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
198      return;
199    e_editable_password_set(sd->editable_object, password_mode);
200 #ifdef HAVE_ECORE_IMF
201    if (sd->imf_context)
202      ecore_imf_context_input_mode_set(sd->imf_context,
203                                       password_mode ? ECORE_IMF_INPUT_MODE_FULL & ECORE_IMF_INPUT_MODE_INVISIBLE :
204                                                       ECORE_IMF_INPUT_MODE_FULL);
205 #endif
206 }
207
208 /**
209  * Gets the minimum size of the entry object
210  *
211  * @param entry an entry object
212  * @param minw the location where to store the minimun width of the entry
213  * @param minh the location where to store the minimun height of the entry
214  */
215 EAPI void
216 e_entry_size_min_get(Evas_Object *entry, Evas_Coord *minw, Evas_Coord *minh)
217 {
218    E_Entry_Smart_Data *sd;
219    
220    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
221      return;
222    
223    if (minw) *minw = sd->min_width;
224    if (minh) *minh = sd->height;
225 }
226
227 /**
228  * Focuses the entry object. It will receives keyboard events and the user could
229  * then type some text (the entry should also be enabled. The cursor and the
230  * selection will be shown
231  *
232  * @param entry the entry to focus
233  */
234 EAPI void
235 e_entry_focus(Evas_Object *entry)
236 {
237    E_Entry_Smart_Data *sd;
238    
239    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
240      return;
241    if (sd->focused)
242       return;
243    
244    evas_object_focus_set(entry, 1);
245    edje_object_signal_emit(sd->entry_object, "e,state,focused", "e");
246    if (!sd->selection_dragging)
247      {
248         e_editable_cursor_move_to_end(sd->editable_object);
249
250         _e_entry_imf_context_reset(entry);
251         _e_entry_imf_cursor_info_set(entry);
252
253         e_editable_selection_move_to_end(sd->editable_object);
254      }
255    if (sd->enabled)
256       e_editable_cursor_show(sd->editable_object);
257    e_editable_selection_show(sd->editable_object);
258 #ifdef HAVE_ECORE_IMF
259    if (sd->imf_context)
260      {
261         ecore_imf_context_reset(sd->imf_context);
262         ecore_imf_context_focus_in(sd->imf_context);
263      }
264 #endif
265    sd->focused = 1;
266 }
267
268 /**
269  * Unfocuses the entry object. It will no longer receives keyboard events so
270  * the user could no longer type some text. The cursor and the selection will
271  * be hidden
272  *
273  * @param entry the entry object to unfocus
274  */
275 EAPI void
276 e_entry_unfocus(Evas_Object *entry)
277 {
278    E_Entry_Smart_Data *sd;
279    
280    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
281      return;
282    if (!sd->focused)
283      return;
284    
285    evas_object_focus_set(entry, 0);
286    edje_object_signal_emit(sd->entry_object, "e,state,unfocused", "e");
287    e_editable_cursor_hide(sd->editable_object);
288    e_editable_selection_hide(sd->editable_object);
289 #ifdef HAVE_ECORE_IMF
290    if (sd->imf_context)
291      {
292         ecore_imf_context_reset(sd->imf_context);
293         ecore_imf_context_focus_out(sd->imf_context);
294      }
295 #endif
296    sd->focused = 0;
297 }
298
299 /**
300  * Enables the entry object: the user will be able to type text
301  *
302  * @param entry the entry object to enable
303  */
304 EAPI void
305 e_entry_enable(Evas_Object *entry)
306 {
307    E_Entry_Smart_Data *sd;
308    
309    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
310      return;
311    if (sd->enabled)
312      return;
313    
314    edje_object_signal_emit(sd->entry_object, "e,state,enabled", "e");
315    e_editable_enable(sd->editable_object);
316    if (sd->focused)
317      e_editable_cursor_show(sd->editable_object);
318    sd->enabled = 1;
319 }
320
321 /**
322  * Disables the entry object: the user won't be able to type anymore. Selection
323  * will still be possible (to copy the text)
324  *
325  * @param entry the entry object to disable
326  */
327 EAPI void
328 e_entry_disable(Evas_Object *entry)
329 {
330    E_Entry_Smart_Data *sd;
331    
332    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
333      return;
334    if (!sd->enabled)
335      return;
336    
337    edje_object_signal_emit(sd->entry_object, "e,state,disabled", "e");
338    e_editable_disable(sd->editable_object);
339    e_editable_cursor_hide(sd->editable_object);
340    sd->enabled = 0;
341 }
342
343
344 /* Private functions */
345
346 /* Called when a key has been pressed by the user */
347 static void
348 _e_entry_key_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
349 {
350    E_Entry_Smart_Data *sd;
351
352    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
353      return;
354
355 #ifdef HAVE_ECORE_IMF
356    if (sd->imf_context)
357      {
358         Ecore_IMF_Event_Key_Down ev;
359
360         ecore_imf_evas_event_key_down_wrap(event_info, &ev);
361         if (ecore_imf_context_filter_event(sd->imf_context,
362                                            ECORE_IMF_EVENT_KEY_DOWN,
363                                            (Ecore_IMF_Event *) &ev))
364           return;
365      }
366 #endif
367
368    if (_e_entry_emacs_keybindings)
369      _e_entry_key_down_emacs(obj, event_info);
370    else
371      _e_entry_key_down_windows(obj, event_info);
372 }
373
374 /* Called when a key has been released by the user */
375 static void
376 _e_entry_key_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
377 {
378    E_Entry_Smart_Data *sd;
379
380    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
381      return;
382
383 #ifdef HAVE_ECORE_IMF
384    if (sd->imf_context)
385      {
386         Ecore_IMF_Event_Key_Up ev;
387
388         ecore_imf_evas_event_key_up_wrap(event_info, &ev);
389         if (ecore_imf_context_filter_event(sd->imf_context,
390                                            ECORE_IMF_EVENT_KEY_UP,
391                                            (Ecore_IMF_Event *) &ev))
392           return;
393      }
394 #endif
395 }
396
397 /* Called when the entry object is pressed by the mouse */
398 static void
399 _e_entry_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
400 {
401    E_Entry_Smart_Data *sd;
402    Evas_Event_Mouse_Down *event;
403    Evas_Coord ox, oy;
404    int pos;
405    
406    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
407      return;
408    if (!(event = event_info))
409      return;
410
411 #ifdef HAVE_ECORE_IMF
412    if (sd->imf_context)
413      {
414         Ecore_IMF_Event_Mouse_Down ev;
415
416         ecore_imf_evas_event_mouse_down_wrap(event_info, &ev);
417         if (ecore_imf_context_filter_event(sd->imf_context,
418                                            ECORE_IMF_EVENT_MOUSE_DOWN,
419                                            (Ecore_IMF_Event *) &ev))
420           return;
421      }
422 #endif
423
424    evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL);
425    pos = e_editable_pos_get_from_coords(sd->editable_object,
426                                         event->canvas.x - ox,
427                                         event->canvas.y - oy);
428   
429    if (event->button == 1)
430      {
431         if (event->flags & EVAS_BUTTON_TRIPLE_CLICK)
432           {
433              e_editable_select_all(sd->editable_object);
434              _e_entry_x_selection_update(obj);
435           }
436         else if (event->flags & EVAS_BUTTON_DOUBLE_CLICK)
437           {
438              e_editable_select_word(sd->editable_object, pos);
439              _e_entry_x_selection_update(obj);
440           }
441         else
442           {
443              e_editable_cursor_pos_set(sd->editable_object, pos);
444              if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
445                e_editable_selection_pos_set(sd->editable_object, pos);
446              
447              sd->selection_dragging = 1;
448           }
449      }
450    else if (event->button == 2)
451      {
452         E_Win *win;
453         
454         e_editable_cursor_pos_set(sd->editable_object, pos);
455         e_editable_selection_pos_set(sd->editable_object, pos);
456         
457         if ((win = e_win_evas_object_win_get(obj)))
458           ecore_x_selection_primary_request(win->evas_win,
459                                             ECORE_X_SELECTION_TARGET_UTF8_STRING);
460      }
461    else if (event->button == 3) 
462      {
463         E_Menu_Item *mi;
464         E_Manager *man;
465         E_Container *con;
466         int x, y;
467         int cursor_pos, selection_pos;
468         int start_pos, end_pos;
469         int s_enabled, s_selecting, s_empty, s_passwd;
470
471         cursor_pos = e_editable_cursor_pos_get(sd->editable_object);
472         selection_pos = e_editable_selection_pos_get(sd->editable_object);
473         start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
474         end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
475
476         s_selecting = (start_pos != end_pos);
477         s_enabled = sd->enabled;
478         s_empty = !e_editable_text_length_get(sd->editable_object);
479         s_passwd = e_editable_password_get(sd->editable_object);
480         
481         if (!s_selecting && !s_enabled && s_empty) return;
482
483         man = e_manager_current_get();
484         con = e_container_current_get(man);
485         ecore_x_pointer_xy_get(con->win, &x, &y);
486
487         /* Popup a menu */
488         sd->popup = e_menu_new();
489         e_menu_post_deactivate_callback_set(sd->popup, 
490                                             _e_entry_cb_menu_post, sd);
491         if (s_selecting)
492           {
493              if (s_enabled)
494                {
495                   mi = e_menu_item_new(sd->popup);
496                   e_menu_item_label_set(mi, _("Delete"));
497                   e_util_menu_item_theme_icon_set(mi, "edit-delete");
498                   e_menu_item_callback_set(mi, _e_entry_cb_delete, sd);
499              
500                   mi = e_menu_item_new(sd->popup);
501                   e_menu_item_separator_set(mi, 1);
502
503                   if (!s_passwd)
504                     {
505                        mi = e_menu_item_new(sd->popup);
506                        e_menu_item_label_set(mi, _("Cut"));
507                        e_util_menu_item_theme_icon_set(mi, "edit-cut");
508                        e_menu_item_callback_set(mi, _e_entry_cb_cut, sd);
509                     }
510                }
511              if (!s_passwd)
512                {
513                   mi = e_menu_item_new(sd->popup);
514                   e_menu_item_label_set(mi, _("Copy"));
515                   e_util_menu_item_theme_icon_set(mi, "edit-copy");
516                   e_menu_item_callback_set(mi, _e_entry_cb_copy, sd);
517                }
518           }
519         if (sd->enabled)
520           {
521              mi = e_menu_item_new(sd->popup);
522              e_menu_item_label_set(mi, _("Paste"));
523              e_util_menu_item_theme_icon_set(mi, "edit-paste");
524              e_menu_item_callback_set(mi, _e_entry_cb_paste, sd);
525           }
526         if (!s_empty)
527           {
528              mi = e_menu_item_new(sd->popup);
529              e_menu_item_separator_set(mi, 1);
530              
531              mi = e_menu_item_new(sd->popup);
532              e_menu_item_label_set(mi, _("Select All"));
533              e_util_menu_item_theme_icon_set(mi, "edit-select-all");
534              e_menu_item_callback_set(mi, _e_entry_cb_select_all, sd);
535           }
536
537         e_menu_activate_mouse(sd->popup, e_util_zone_current_get(man),
538                               x, y, 1, 1, 
539                               E_MENU_POP_DIRECTION_DOWN, event->timestamp);
540      }
541
542    _e_entry_imf_context_reset(obj);
543    _e_entry_imf_cursor_info_set(obj);
544 }
545
546 /* Called when the entry object is released by the mouse */
547 static void
548 _e_entry_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
549 {
550    E_Entry_Smart_Data *sd;
551    
552    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
553      return;
554    
555 #ifdef HAVE_ECORE_IMF
556    if (sd->imf_context)
557      {
558         Ecore_IMF_Event_Mouse_Up ev;
559
560         ecore_imf_evas_event_mouse_up_wrap(event_info, &ev);
561         if (ecore_imf_context_filter_event(sd->imf_context,
562                                            ECORE_IMF_EVENT_MOUSE_UP,
563                                            (Ecore_IMF_Event *) &ev))
564           return;
565      }
566 #endif
567
568    if (sd->selection_dragging)
569      {
570         sd->selection_dragging = 0;
571         _e_entry_x_selection_update(obj);
572      }
573 }
574
575 /* Called when the mouse moves over the entry object */
576 static void
577 _e_entry_mouse_move_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
578 {
579    E_Entry_Smart_Data *sd;
580    Evas_Event_Mouse_Move *event;
581    Evas_Coord ox, oy;
582    int pos;
583    
584    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
585      return;
586    if (!(event = event_info))
587      return;
588
589 #ifdef HAVE_ECORE_IMF
590    if (sd->imf_context)
591      {
592         Ecore_IMF_Event_Mouse_Move ev;
593
594         ecore_imf_evas_event_mouse_move_wrap(event_info, &ev);
595         if (ecore_imf_context_filter_event(sd->imf_context,
596                                            ECORE_IMF_EVENT_MOUSE_MOVE,
597                                            (Ecore_IMF_Event *) &ev))
598           return;
599      }
600 #endif
601
602    if (sd->selection_dragging)
603      {
604         evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL);
605         pos = e_editable_pos_get_from_coords(sd->editable_object,
606                                              event->cur.canvas.x - ox,
607                                              event->cur.canvas.y - oy);
608         e_editable_cursor_pos_set(sd->editable_object, pos);
609
610         _e_entry_imf_context_reset(obj);
611         _e_entry_imf_cursor_info_set(obj);
612      }
613 }
614
615 /* Called when the the "selection_notify" event is emitted */
616 static Eina_Bool
617 _e_entry_x_selection_notify_handler(void *data, int type __UNUSED__, void *event)
618 {
619    Evas_Object *entry;
620    E_Entry_Smart_Data *sd;
621    Ecore_X_Event_Selection_Notify *ev;
622    Evas_Object *editable;
623    int cursor_pos, selection_pos;
624    int start_pos, end_pos;
625    int selecting;
626    int changed = 0;
627    
628    if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
629      return 1;
630    if (!sd->focused)
631      return 1;
632    
633    editable = sd->editable_object;
634    cursor_pos = e_editable_cursor_pos_get(editable);
635    selection_pos = e_editable_selection_pos_get(editable);
636    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
637    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
638    selecting = (start_pos != end_pos);
639    
640    ev = event;
641    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
642        (ev->selection == ECORE_X_SELECTION_PRIMARY))
643      {
644         if (strcmp(ev->target, ECORE_X_SELECTION_TARGET_UTF8_STRING) == 0)
645           {
646              Ecore_X_Selection_Data_Text *text_data;
647              
648              text_data = ev->data;
649              if (selecting && !_e_entry_emacs_keybindings)
650                changed |= e_editable_delete(editable, start_pos, end_pos);
651              changed |= e_editable_insert(editable, start_pos, text_data->text);
652           }
653      }
654    
655    if (changed)
656      evas_object_smart_callback_call(entry, "changed", NULL);
657    
658    return ECORE_CALLBACK_PASS_ON;
659 }
660
661 /* Updates the X selection with the selected text of the entry */
662 static void
663 _e_entry_x_selection_update(Evas_Object *entry)
664 {
665    E_Entry_Smart_Data *sd;
666    Evas_Object *editable;
667    E_Win *win;
668    int cursor_pos, selection_pos;
669    int start_pos, end_pos;
670    int selecting;
671    char *text;
672    
673    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
674      return;
675    if (!(win = e_win_evas_object_win_get(entry)))
676      return;
677    
678    editable = sd->editable_object;
679    if (e_editable_password_get(editable)) return;
680
681    cursor_pos = e_editable_cursor_pos_get(editable);
682    selection_pos = e_editable_selection_pos_get(editable);
683    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
684    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
685    selecting = (start_pos != end_pos);
686   
687    if ((!selecting) ||
688        (!(text = e_editable_text_range_get(editable, start_pos, end_pos))))
689      return;
690
691    ecore_x_selection_primary_set(win->evas_win, text, strlen(text) + 1);
692    free(text);
693 }
694
695 /* Treats the "key down" event to mimick the behavior of Windows/Gtk2/Qt */
696 static void 
697 _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event)
698 {
699    E_Entry_Smart_Data *sd;
700    Evas_Object *editable;
701    int cursor_pos, selection_pos;
702    int start_pos, end_pos;
703    int selecting;
704    int changed = 0;
705    int selection_changed = 0;
706    char *range;
707    E_Win *win;
708    
709    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
710      return;
711    if ((!event) || (!event->keyname))
712      return;
713
714    editable = sd->editable_object;
715    cursor_pos = e_editable_cursor_pos_get(editable);
716    selection_pos = e_editable_selection_pos_get(editable);
717    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
718    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
719    selecting = (start_pos != end_pos);
720    
721    /* Move the cursor/selection to the left */
722    if (strcmp(event->key, "Left") == 0)
723      {
724         if (evas_key_modifier_is_set(event->modifiers, "Shift"))
725           {
726              e_editable_cursor_move_left(editable);
727              selection_changed = 1;
728           }
729         else if (selecting)
730           {
731              if (cursor_pos < selection_pos)
732                e_editable_selection_pos_set(editable, cursor_pos);
733              else
734                e_editable_cursor_pos_set(editable, selection_pos);
735           }
736         else
737           {
738              e_editable_cursor_move_left(editable);
739              e_editable_selection_pos_set(editable,
740                                           e_editable_cursor_pos_get(editable));
741           }
742      }
743    /* Move the cursor/selection to the right */
744    else if (strcmp(event->key, "Right") == 0)
745      {
746         if (evas_key_modifier_is_set(event->modifiers, "Shift"))
747           {
748              e_editable_cursor_move_right(editable);
749              selection_changed = 1;
750           }
751         else if (selecting)
752           {
753              if (cursor_pos > selection_pos)
754                e_editable_selection_pos_set(editable, cursor_pos);
755              else
756                e_editable_cursor_pos_set(editable, selection_pos);
757           }
758         else
759           {
760              e_editable_cursor_move_right(editable);
761              e_editable_selection_pos_set(editable,
762                                           e_editable_cursor_pos_get(editable));
763           }
764      }
765    /* Move the cursor/selection to the start of the entry */
766    else if (strcmp(event->keyname, "Home") == 0)
767      {
768         e_editable_cursor_move_to_start(editable);
769         if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
770           e_editable_selection_pos_set(editable,
771                                        e_editable_cursor_pos_get(editable));
772         else
773           selection_changed = 1;
774      }
775    /* Move the cursor/selection to the end of the entry */
776    else if (strcmp(event->keyname, "End") == 0)
777      {
778         e_editable_cursor_move_to_end(editable);
779         if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
780           e_editable_selection_pos_set(editable,
781                                        e_editable_cursor_pos_get(editable));
782         else
783           selection_changed = 1;
784      }
785    /* Delete the previous character */
786    else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0))
787      {
788         if (selecting)
789           changed = e_editable_delete(editable, start_pos, end_pos);
790         else
791           changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos);
792      }
793    /* Delete the next character */
794    else if ((sd->enabled) && (strcmp(event->keyname, "Delete") == 0))
795      {
796         if (selecting)
797           changed = e_editable_delete(editable, start_pos, end_pos);
798         else
799           changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1);
800      }
801    /* Ctrl + A,C,X,V */
802    else if (evas_key_modifier_is_set(event->modifiers, "Control"))
803      {
804         if (strcmp(event->keyname, "a") == 0)
805           {
806              e_editable_select_all(editable);
807              selection_changed = 1;
808           }
809         else if ((strcmp(event->keyname, "x") == 0) ||
810                  (strcmp(event->keyname, "c") == 0))
811           {
812              if (!e_editable_password_get(editable) && selecting)
813                {
814                  range = e_editable_text_range_get(editable, start_pos, end_pos);
815                  if (range)
816                    {
817                       if ((win = e_win_evas_object_win_get(entry)))
818                         ecore_x_selection_clipboard_set(win->evas_win,
819                                                         range,
820                                                         strlen(range) + 1);
821                       free(range);
822                    }
823                  if ((sd->enabled) && (strcmp(event->keyname, "x") == 0))
824                    changed = e_editable_delete(editable, start_pos, end_pos);
825                }
826            }
827         else if ((sd->enabled) && (strcmp(event->keyname, "v") == 0))
828           {
829              if ((win = e_win_evas_object_win_get(entry)))
830                ecore_x_selection_clipboard_request(win->evas_win,
831                                                    ECORE_X_SELECTION_TARGET_UTF8_STRING);
832           }
833      }
834    /* Otherwise, we insert the corresponding character */
835    else if ((event->string) && ((sd->enabled)) &&
836           ((strlen(event->string) != 1) || (event->string[0] >= 0x20)))
837      {
838         if (selecting)
839           changed |= e_editable_delete(editable, start_pos, end_pos);
840         changed |= e_editable_insert(editable, start_pos, event->string);
841      }
842
843    _e_entry_imf_context_reset(entry);
844    _e_entry_imf_cursor_info_set(entry);
845
846    if (changed)
847      evas_object_smart_callback_call(entry, "changed", NULL);
848    if (selection_changed)
849      _e_entry_x_selection_update(entry);
850 }
851
852 /* Treats the "key down" event to mimick the behavior of Emacs */
853 static void 
854 _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event)
855 {
856    E_Entry_Smart_Data *sd;
857    Evas_Object *editable;
858    int cursor_pos, selection_pos;
859    int start_pos, end_pos;
860    int selecting;
861    int changed = 0;
862    int selection_changed = 0;
863    char *range;
864    E_Win *win;
865    
866    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
867      return;
868    if ((!event) || (!event->keyname))
869      return;
870
871    editable = sd->editable_object;
872    cursor_pos = e_editable_cursor_pos_get(editable);
873    selection_pos = e_editable_selection_pos_get(editable);
874    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
875    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
876    selecting = (start_pos != end_pos);
877    
878    /* Move the cursor/selection to the left */
879    if ((strcmp(event->key, "Left") == 0) ||
880       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
881        (strcmp(event->key, "b") == 0)))
882      {
883         e_editable_cursor_move_left(editable);
884         if (sd->selection_mode)
885           selection_changed = 1;
886         else
887           e_editable_selection_pos_set(editable,
888                                        e_editable_cursor_pos_get(editable));
889      }
890    /* Move the cursor/selection to the right */
891    else if ((strcmp(event->key, "Right") == 0) ||
892       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
893        (strcmp(event->key, "f") == 0)))
894      {
895         e_editable_cursor_move_right(editable);
896         if (sd->selection_mode)
897           selection_changed = 1;
898         else
899           e_editable_selection_pos_set(editable,
900                                        e_editable_cursor_pos_get(editable));
901      }
902    /* Move the cursor/selection to the start of the entry */
903    else if ((strcmp(event->keyname, "Home") == 0) ||
904       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
905        (strcmp(event->key, "a") == 0)))
906      {
907         e_editable_cursor_move_to_start(editable);
908         if (sd->selection_mode)
909           selection_changed = 1;
910         else
911           e_editable_selection_pos_set(editable,
912                                        e_editable_cursor_pos_get(editable));
913      }
914    /* Move the cursor/selection to the end of the entry */
915    else if ((strcmp(event->keyname, "End") == 0) ||
916       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
917        (strcmp(event->key, "e") == 0)))
918      {
919         e_editable_cursor_move_to_end(editable);
920         if (sd->selection_mode)
921           selection_changed = 1;
922         else
923           e_editable_selection_pos_set(editable,
924                                        e_editable_cursor_pos_get(editable));
925      }
926    /* Delete the previous character */
927    else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0))
928      changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos);
929    /* Delete the next character */
930    else if ((sd->enabled) && 
931       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
932        (strcmp(event->key, "d") == 0)))
933      changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1);
934    /* Delete until end of line */
935    else if ((sd->enabled) && 
936       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
937        (strcmp(event->key, "k") == 0)))
938      changed = e_editable_delete(editable, cursor_pos,
939                                  e_editable_text_length_get(editable));
940    /* Toggle the selection mode */
941    else if ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
942        (strcmp(event->key, "space") == 0))
943      {
944         if (sd->selection_mode)
945           {
946              e_editable_selection_pos_set(editable, cursor_pos);
947              sd->selection_mode = 0;
948           }
949         else
950           sd->selection_mode = 1;
951      }
952    /* Cut/Copy */
953    else if ((evas_key_modifier_is_set(event->modifiers, "Control") ||
954              evas_key_modifier_is_set(event->modifiers, "Shift")) &&
955             (strcmp(event->key, "w") == 0))
956      {
957         if (!e_editable_password_get(editable) && selecting)
958           {
959              range = e_editable_text_range_get(editable, start_pos, end_pos);
960              if (range)
961                {
962                   if ((win = e_win_evas_object_win_get(entry)))
963                     ecore_x_selection_clipboard_set(win->evas_win,
964                                                     range,
965                                                     strlen(range) + 1);
966                   free(range);
967                }
968              if ((sd->enabled) && (evas_key_modifier_is_set(event->modifiers, "Control")))
969                {
970                   changed = e_editable_delete(editable, start_pos, end_pos);
971                   sd->selection_mode = 0;
972                }
973           }
974      }
975    /* Paste */
976    else if ((sd->enabled) && 
977             ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
978              (strcmp(event->key, "y") == 0)))
979      {
980         if ((win = e_win_evas_object_win_get(entry)))
981           ecore_x_selection_clipboard_request(win->evas_win,
982                                               ECORE_X_SELECTION_TARGET_UTF8_STRING);
983      }
984    /* Otherwise, we insert the corresponding character */
985    else if ((event->string) &&
986             ((strlen(event->string) != 1) ||
987              (event->string[0] >= 0x20 && event->string[0] != 0x7f)))
988      changed = e_editable_insert(editable, cursor_pos, event->string);
989
990    _e_entry_imf_context_reset(entry);
991    _e_entry_imf_cursor_info_set(entry);
992
993    if (changed)
994      evas_object_smart_callback_call(entry, "changed", NULL);
995    if (selection_changed)
996      _e_entry_x_selection_update(entry);
997 }
998
999 /* Editable object's smart methods */
1000
1001 static void 
1002 _e_entry_smart_add(Evas_Object *object)
1003 {
1004    Evas *evas;
1005    E_Entry_Smart_Data *sd;
1006    Evas_Object *o;
1007    int cw, ch;
1008    const char *ctx_id;
1009 #ifdef HAVE_ECORE_IMF
1010    const Ecore_IMF_Context_Info *ctx_info;
1011 #endif
1012    
1013    if ((!object) || !(evas = evas_object_evas_get(object)))
1014      return;
1015
1016    sd = calloc(1, sizeof(E_Entry_Smart_Data));
1017    if (!sd) return;
1018    
1019    evas_object_smart_data_set(object, sd);
1020
1021 #ifdef HAVE_ECORE_IMF
1022    ctx_id = ecore_imf_context_default_id_get();
1023    if (ctx_id)
1024      {
1025         ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
1026         if (!ctx_info->canvas_type ||
1027             strcmp(ctx_info->canvas_type, "evas") == 0)
1028           sd->imf_context = ecore_imf_context_add(ctx_id);
1029         else
1030           {
1031              ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
1032              if (ctx_id)
1033                sd->imf_context = ecore_imf_context_add(ctx_id);
1034              else
1035                sd->imf_context = NULL;
1036           }
1037      }
1038    else
1039      sd->imf_context = NULL;
1040
1041    if (sd->imf_context)
1042      {
1043         ecore_imf_context_client_window_set(sd->imf_context,
1044                                             (long *)ecore_evas_window_get(ecore_evas_ecore_evas_get(evas)));
1045         ecore_imf_context_client_canvas_set(sd->imf_context, evas);
1046         ecore_imf_context_retrieve_surrounding_callback_set(sd->imf_context,
1047                                                             _e_entry_cb_imf_retrieve_surrounding,
1048                                                             sd);
1049         sd->imf_ee_commit_handler = 
1050           ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT,
1051                                   _e_entry_cb_imf_event_commit, object);
1052         sd->imf_ee_preedit_changed_handler =
1053            ecore_event_handler_add(ECORE_IMF_EVENT_PREEDIT_CHANGED,
1054                                    _e_entry_cb_imf_event_preedit_changed, object);
1055         sd->imf_ee_delete_handler = 
1056           ecore_event_handler_add(ECORE_IMF_EVENT_DELETE_SURROUNDING,
1057                                   _e_entry_cb_imf_event_delete_surrounding, sd);
1058      }
1059 #endif
1060
1061    sd->enabled = 1;
1062    sd->focused = 0;
1063    sd->selection_dragging = 0;
1064    sd->selection_mode = 0;
1065    sd->valign = 0.5;
1066    
1067    o = edje_object_add(evas);
1068    sd->entry_object = o;
1069    e_theme_edje_object_set(o, "base/theme/widgets", "e/widgets/entry");
1070    evas_object_smart_member_add(o, object);
1071    
1072    o = e_editable_add(evas);
1073    sd->editable_object = o;
1074    e_editable_theme_set(o, "base/theme/widgets", "e/widgets/entry");
1075    e_editable_cursor_hide(o);
1076    e_editable_char_size_get(o, &cw, &ch);
1077    edje_extern_object_min_size_set(o, cw, ch);
1078    edje_object_part_swallow(sd->entry_object, "e.swallow.text", o);
1079    edje_object_size_min_calc(sd->entry_object, &sd->min_width, &sd->height);
1080    evas_object_show(o);
1081    
1082    evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_DOWN,
1083                                   _e_entry_key_down_cb, NULL);
1084    evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_UP,
1085                                   _e_entry_key_up_cb, NULL);
1086    evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_DOWN,
1087                                   _e_entry_mouse_down_cb, NULL);
1088    evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_UP,
1089                                   _e_entry_mouse_up_cb, NULL);
1090    evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_MOVE,
1091                                   _e_entry_mouse_move_cb, NULL);
1092    sd->selection_handler = ecore_event_handler_add(
1093                                        ECORE_X_EVENT_SELECTION_NOTIFY,
1094                                        _e_entry_x_selection_notify_handler,
1095                                        object);
1096 }
1097
1098 static void 
1099 _e_entry_smart_del(Evas_Object *object)
1100 {
1101    E_Entry_Smart_Data *sd;
1102    
1103    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1104      return;
1105
1106 #ifdef HAVE_ECORE_IMF
1107    if (sd->imf_context)
1108      {
1109         if (sd->imf_ee_commit_handler) 
1110           ecore_event_handler_del(sd->imf_ee_commit_handler);
1111         if (sd->imf_ee_preedit_changed_handler)
1112           ecore_event_handler_del(sd->imf_ee_preedit_changed_handler);
1113         if (sd->imf_ee_delete_handler) 
1114           ecore_event_handler_del(sd->imf_ee_delete_handler);
1115         ecore_imf_context_del(sd->imf_context);
1116      }
1117 #endif
1118
1119    evas_object_event_callback_del(object, EVAS_CALLBACK_KEY_DOWN,
1120                                   _e_entry_key_down_cb);
1121    evas_object_event_callback_del(object, EVAS_CALLBACK_KEY_UP,
1122                                   _e_entry_key_up_cb);
1123    evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_DOWN,
1124                                   _e_entry_mouse_down_cb);
1125    evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_UP,
1126                                   _e_entry_mouse_up_cb);
1127    evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_MOVE,
1128                                   _e_entry_mouse_move_cb);
1129
1130    if (sd->selection_handler) 
1131      ecore_event_handler_del(sd->selection_handler);
1132    evas_object_del(sd->editable_object);
1133    evas_object_del(sd->entry_object);
1134    free(sd);
1135 }
1136
1137 static void 
1138 _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y)
1139 {
1140    E_Entry_Smart_Data *sd;
1141    Evas_Coord prev_x, prev_y;
1142    Evas_Coord ox, oy;
1143    
1144    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1145      return;
1146    
1147    evas_object_geometry_get(object, &prev_x, &prev_y, NULL, NULL);
1148    evas_object_geometry_get(sd->entry_object, &ox, &oy, NULL, NULL);
1149    evas_object_move(sd->entry_object, ox + (x - prev_x), oy + (y - prev_y));
1150 }
1151
1152 static void 
1153 _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h)
1154 {
1155    E_Entry_Smart_Data *sd;
1156    Evas_Coord x, y;
1157    
1158    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1159      return;
1160    
1161    evas_object_geometry_get(object, &x, &y, NULL, NULL);
1162    evas_object_move(sd->entry_object, x, y + ((h - sd->height) * sd->valign));
1163    evas_object_resize(sd->entry_object, w, sd->height);
1164 }
1165
1166 static void 
1167 _e_entry_smart_show(Evas_Object *object)
1168 {
1169    E_Entry_Smart_Data *sd;
1170    
1171    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1172      return;
1173    evas_object_show(sd->entry_object);
1174 }
1175
1176 static void 
1177 _e_entry_smart_hide(Evas_Object *object)
1178 {
1179    E_Entry_Smart_Data *sd;
1180    
1181    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1182      return;
1183    evas_object_hide(sd->entry_object);
1184 }
1185
1186 static void 
1187 _e_entry_color_set(Evas_Object *object, int r, int g, int b, int a)
1188 {
1189    E_Entry_Smart_Data *sd;
1190    
1191    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1192      return;
1193    evas_object_color_set(sd->entry_object, r, g, b, a);
1194 }
1195
1196 static void 
1197 _e_entry_clip_set(Evas_Object *object, Evas_Object *clip)
1198 {
1199    E_Entry_Smart_Data *sd;
1200    
1201    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1202      return;
1203    evas_object_clip_set(sd->entry_object, clip);
1204 }
1205
1206 static void 
1207 _e_entry_clip_unset(Evas_Object *object)
1208 {
1209    E_Entry_Smart_Data *sd;
1210    
1211    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1212      return;
1213    evas_object_clip_unset(sd->entry_object);
1214 }
1215
1216 static void 
1217 _e_entry_cb_menu_post(void *data, E_Menu *m __UNUSED__) 
1218 {
1219    E_Entry_Smart_Data *sd;
1220
1221    sd = data;
1222    if (!sd->popup) return;
1223    e_object_del(E_OBJECT(sd->popup));
1224    sd->popup = NULL;
1225 }
1226
1227 static void 
1228 _e_entry_cb_cut(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) 
1229 {
1230    E_Entry_Smart_Data *sd;
1231    Evas_Object *editable;
1232    int cursor_pos, selection_pos;
1233    int start_pos, end_pos;
1234    int selecting, changed;
1235    char *range;
1236    E_Win *win;
1237
1238    sd = data;
1239    if (!sd->enabled) return;
1240    
1241    editable = sd->editable_object;
1242    cursor_pos = e_editable_cursor_pos_get(editable);
1243    selection_pos = e_editable_selection_pos_get(editable);
1244    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1245    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1246    selecting = (start_pos != end_pos);
1247    if (!selecting) return;
1248    
1249    range = e_editable_text_range_get(editable, start_pos, end_pos);
1250    if (range)
1251      {
1252         if ((win = e_win_evas_object_win_get(sd->entry_object)))
1253           ecore_x_selection_clipboard_set(win->evas_win,
1254                                           range, strlen(range) + 1);
1255         free(range);
1256      }   
1257    changed = e_editable_delete(editable, start_pos, end_pos);
1258    if (changed)
1259      evas_object_smart_callback_call(sd->entry_object, "changed", NULL);
1260 }
1261
1262 static void 
1263 _e_entry_cb_copy(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) 
1264 {
1265    E_Entry_Smart_Data *sd;
1266    Evas_Object *editable;
1267    int cursor_pos, selection_pos;
1268    int start_pos, end_pos;
1269    int selecting;
1270    char *range;
1271    E_Win *win;
1272
1273    sd = data;
1274    
1275    editable = sd->editable_object;
1276    cursor_pos = e_editable_cursor_pos_get(editable);
1277    selection_pos = e_editable_selection_pos_get(editable);
1278    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1279    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1280    selecting = (start_pos != end_pos);
1281    if (!selecting) return;
1282    
1283    range = e_editable_text_range_get(editable, start_pos, end_pos);
1284    if (range)
1285      {
1286         if ((win = e_win_evas_object_win_get(sd->entry_object)))
1287           ecore_x_selection_clipboard_set(win->evas_win,
1288                                           range, strlen(range) + 1);
1289         free(range);
1290      }
1291 }
1292
1293 static void 
1294 _e_entry_cb_paste(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) 
1295 {
1296    E_Entry_Smart_Data *sd;
1297    E_Win *win;
1298    
1299    sd = data;
1300    if (!sd->enabled) return;
1301    
1302    if ((win = e_win_evas_object_win_get(sd->entry_object)))
1303      ecore_x_selection_clipboard_request(win->evas_win,
1304                                          ECORE_X_SELECTION_TARGET_UTF8_STRING);
1305 }
1306
1307 static void 
1308 _e_entry_cb_select_all(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) 
1309 {
1310    E_Entry_Smart_Data *sd;
1311
1312    sd = data;
1313    e_editable_select_all(sd->editable_object);
1314    _e_entry_x_selection_update(sd->entry_object);
1315 }
1316
1317 static void 
1318 _e_entry_cb_delete(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) 
1319 {
1320    E_Entry_Smart_Data *sd;
1321    Evas_Object *editable;
1322    int cursor_pos, selection_pos;
1323    int start_pos, end_pos;
1324    int selecting;
1325    char *range;
1326
1327    sd = data;
1328    if (!sd->enabled) return;
1329
1330    editable = sd->editable_object;
1331    cursor_pos = e_editable_cursor_pos_get(editable);
1332    selection_pos = e_editable_selection_pos_get(editable);
1333    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1334    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1335    selecting = (start_pos != end_pos);
1336    if (!selecting) return;
1337
1338    range = e_editable_text_range_get(editable, start_pos, end_pos);
1339    if (range)
1340      {
1341         e_editable_delete(editable, start_pos, end_pos);
1342         evas_object_smart_callback_call(sd->entry_object, "changed", NULL);
1343         free(range);
1344      }
1345 }
1346
1347 static void
1348 _e_entry_imf_context_reset(Evas_Object *object)
1349 {
1350    E_Entry_Smart_Data *sd;
1351
1352    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1353      return;
1354
1355 #ifdef HAVE_ECORE_IMF 
1356    if (sd->imf_context)
1357      ecore_imf_context_reset(sd->imf_context);
1358 #endif
1359 }
1360
1361 static void
1362 _e_entry_imf_cursor_info_set(Evas_Object *object)
1363 {
1364    E_Entry_Smart_Data *sd;
1365    Evas_Coord cx, cy, cw, ch;
1366    Evas_Object *editable;
1367
1368    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1369      return;
1370
1371 #ifdef HAVE_ECORE_IMF 
1372    if (!sd || !sd->imf_context) return;
1373
1374    editable = sd->editable_object;
1375
1376    e_editable_cursor_geometry_get(editable, &cx, &cy, &cw, &ch);
1377
1378    ecore_imf_context_cursor_position_set(sd->imf_context,
1379                                          e_editable_cursor_pos_get(editable));
1380    ecore_imf_context_cursor_location_set(sd->imf_context, cx, cy, cw, ch);
1381 #endif
1382 }
1383
1384 #ifdef HAVE_ECORE_IMF
1385 static Eina_Bool 
1386 _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx __UNUSED__, char **text, int *cursor_pos)
1387 {
1388    E_Entry_Smart_Data *sd;
1389
1390    sd = data;
1391
1392    if (text)
1393      {
1394         const char *str;
1395
1396         str = e_editable_text_get(sd->editable_object);
1397         *text = str ? strdup(str) : strdup("");
1398      }
1399
1400    if (cursor_pos)
1401      *cursor_pos = e_editable_cursor_pos_get(sd->editable_object);
1402
1403    return EINA_TRUE;
1404 }
1405
1406 static Eina_Bool
1407 _e_entry_cb_imf_event_commit(void *data, int type __UNUSED__, void *event)
1408 {
1409    Evas_Object *entry;
1410    E_Entry_Smart_Data *sd;
1411    Ecore_IMF_Event_Commit *ev = event;
1412    Evas_Object *editable;
1413    int cursor_pos, selection_pos;
1414    int start_pos, end_pos;
1415    int selecting;
1416    int changed = 0;
1417
1418    if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
1419      return ECORE_CALLBACK_PASS_ON;
1420
1421    if ((!sd->imf_context) || (sd->imf_context != ev->ctx))
1422      return ECORE_CALLBACK_PASS_ON;
1423
1424    editable = sd->editable_object;
1425    cursor_pos = e_editable_cursor_pos_get(editable);
1426    selection_pos = e_editable_selection_pos_get(editable);
1427    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1428    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1429    selecting = (start_pos != end_pos);
1430
1431    if (selecting)
1432      changed |= e_editable_delete(editable, start_pos, end_pos);
1433
1434    /* delete preedit characters */
1435    if (sd->have_preedit)
1436      {
1437         if (sd->preedit_start_pos != sd->preedit_end_pos)
1438           e_editable_delete(editable, sd->preedit_start_pos, sd->preedit_end_pos);
1439         sd->have_preedit = EINA_FALSE;
1440         start_pos = sd->preedit_start_pos;
1441      }
1442
1443    changed |= e_editable_insert(editable, start_pos, ev->str);
1444
1445    _e_entry_imf_cursor_info_set(entry);
1446
1447    if (changed)
1448      evas_object_smart_callback_call(entry, "changed", NULL);
1449
1450    return ECORE_CALLBACK_DONE;
1451 }
1452
1453 static Eina_Bool
1454 _e_entry_cb_imf_event_preedit_changed(void *data, int type __UNUSED__, void *event)
1455 {
1456    Evas_Object *entry;
1457    E_Entry_Smart_Data *sd;
1458    Ecore_IMF_Event_Preedit_Changed *ev = event;
1459    Evas_Object *editable;
1460    int cursor_pos, selection_pos;
1461    char *preedit_string = NULL;
1462    int start_pos, end_pos;
1463    int selecting;
1464    int changed = 0;
1465
1466    if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
1467      return ECORE_CALLBACK_PASS_ON;
1468
1469    if ((!sd->imf_context) || (sd->imf_context != ev->ctx))
1470      return ECORE_CALLBACK_PASS_ON;
1471
1472    /* Get the preedit string from IMF */
1473    ecore_imf_context_preedit_string_get(sd->imf_context, &preedit_string, &cursor_pos);
1474    if (!preedit_string) return ECORE_CALLBACK_PASS_ON;
1475
1476    editable = sd->editable_object;
1477    cursor_pos = e_editable_cursor_pos_get(editable);
1478    selection_pos = e_editable_selection_pos_get(editable);
1479    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1480    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1481    selecting = (start_pos != end_pos);
1482
1483    if (selecting)
1484      changed |= e_editable_delete(editable, start_pos, end_pos);
1485
1486    /* delete preedit characters */
1487    if (sd->have_preedit)
1488      {
1489         if (sd->preedit_start_pos != sd->preedit_end_pos)
1490           e_editable_delete(editable, sd->preedit_start_pos, sd->preedit_end_pos);
1491      }
1492
1493    cursor_pos = e_editable_cursor_pos_get(editable);
1494    sd->preedit_start_pos = cursor_pos;
1495
1496    /* insert preedit character(s) */
1497    changed |= e_editable_insert(editable, cursor_pos, preedit_string);
1498
1499    sd->preedit_end_pos = e_editable_cursor_pos_get(editable);
1500
1501    if (!strcmp(preedit_string, ""))
1502      sd->have_preedit = EINA_FALSE;
1503    else
1504      sd->have_preedit = EINA_TRUE;
1505
1506    _e_entry_imf_cursor_info_set(entry);
1507
1508    if (changed)
1509      evas_object_smart_callback_call(entry, "preedit,changed", NULL);
1510
1511    free(preedit_string);
1512
1513    return ECORE_CALLBACK_DONE;
1514 }
1515
1516 static Eina_Bool
1517 _e_entry_cb_imf_event_delete_surrounding(void *data, int type __UNUSED__, void *event)
1518 {
1519    E_Entry_Smart_Data *sd;
1520    Ecore_IMF_Event_Delete_Surrounding *ev = event;
1521    Evas_Object *editable;
1522    int cursor_pos;
1523
1524    sd = data;
1525
1526    if (sd->imf_context != ev->ctx)
1527      return ECORE_CALLBACK_PASS_ON;
1528
1529    editable = sd->editable_object;
1530    cursor_pos = e_editable_cursor_pos_get(editable);
1531    e_editable_delete(editable,
1532                      cursor_pos + ev->offset,
1533                      cursor_pos + ev->offset + ev->n_chars);
1534
1535    return ECORE_CALLBACK_DONE;
1536 }
1537 #endif