5 #include <Ecore_IMF_Evas.h>
8 typedef struct _E_Entry_Smart_Data E_Entry_Smart_Data;
10 struct _E_Entry_Smart_Data
12 Evas_Object *entry_object;
13 Evas_Object *editable_object;
15 Ecore_Event_Handler *selection_handler;
17 Ecore_IMF_Context *imf_context;
19 Ecore_Event_Handler *imf_ee_commit_handler;
20 Ecore_Event_Handler *imf_ee_delete_handler;
24 int selection_dragging;
31 /* local subsystem functions */
32 static void _e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
33 static void _e_entry_key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
34 static void _e_entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
35 static void _e_entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
36 static void _e_entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
37 static Eina_Bool _e_entry_x_selection_notify_handler(void *data, int type, void *event);
39 static void _e_entry_x_selection_update(Evas_Object *entry);
40 static void _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event);
41 static void _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event);
43 static void _e_entry_smart_add(Evas_Object *object);
44 static void _e_entry_smart_del(Evas_Object *object);
45 static void _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y);
46 static void _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h);
47 static void _e_entry_smart_show(Evas_Object *object);
48 static void _e_entry_smart_hide(Evas_Object *object);
49 static void _e_entry_color_set(Evas_Object *object, int r, int g, int b, int a);
50 static void _e_entry_clip_set(Evas_Object *object, Evas_Object *clip);
51 static void _e_entry_clip_unset(Evas_Object *object);
52 static void _e_entry_cb_menu_post(void *data, E_Menu *m);
53 static void _e_entry_cb_cut(void *data, E_Menu *m, E_Menu_Item *mi);
54 static void _e_entry_cb_copy(void *data, E_Menu *m, E_Menu_Item *mi);
55 static void _e_entry_cb_paste(void *data, E_Menu *m, E_Menu_Item *mi);
56 static void _e_entry_cb_select_all(void *data, E_Menu *m, E_Menu_Item *mi);
57 static void _e_entry_cb_delete(void *data, E_Menu *m, E_Menu_Item *mi);
59 static Eina_Bool _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos);
60 static Eina_Bool _e_entry_cb_imf_event_commit(void *data, int type, void *event);
61 static Eina_Bool _e_entry_cb_imf_event_delete_surrounding(void *data, int type, void *event);
64 /* local subsystem globals */
65 static Evas_Smart *_e_entry_smart = NULL;
66 static int _e_entry_smart_use = 0;
67 static int _e_entry_emacs_keybindings = 0;
70 /* externally accessible functions */
73 * Creates a new entry object. An entry is a field where the user can type
75 * Use the "changed" smart callback to know when the content of the entry is
78 * @param evas the evas where the entry object should be added
79 * @return Returns the new entry object
82 e_entry_add(Evas *evas)
86 static const Evas_Smart_Class sc =
89 EVAS_SMART_CLASS_VERSION,
93 _e_entry_smart_resize,
107 _e_entry_smart = evas_smart_class_new(&sc);
108 _e_entry_smart_use = 0;
111 _e_entry_smart_use++;
112 return evas_object_smart_add(evas, _e_entry_smart);
116 * Sets the text of the entry object
118 * @param entry an entry object
119 * @param text the text to set
122 e_entry_text_set(Evas_Object *entry, const char *text)
124 E_Entry_Smart_Data *sd;
126 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
129 e_editable_text_set(sd->editable_object, text);
130 evas_object_smart_callback_call(entry, "changed", NULL);
134 * Gets the text of the entry object
136 * @param entry an entry object
137 * @return Returns the text of the entry object
140 e_entry_text_get(Evas_Object *entry)
142 E_Entry_Smart_Data *sd;
144 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
146 return e_editable_text_get(sd->editable_object);
150 * Clears the entry object
152 * @param entry an entry object
155 e_entry_clear(Evas_Object *entry)
157 e_entry_text_set(entry, "");
161 * Gets the editable object used by the entry object. It will allow you to have
162 * better control on the text, the cursor or the selection of the entry with
163 * the e_editable_*() functions.
165 * @param entry an entry object
166 * @return Returns the editable object used by the entry object
169 e_entry_editable_object_get(Evas_Object *entry)
171 E_Entry_Smart_Data *sd;
173 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
175 return sd->editable_object;
179 * Sets whether or not the entry object is in password mode. In password mode,
180 * the entry displays '*' instead of the characters
182 * @param entry an entry object
183 * @param password_mode 1 to turn on password mode, 0 to turn it off
186 e_entry_password_set(Evas_Object *entry, int password_mode)
188 E_Entry_Smart_Data *sd;
190 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
192 e_editable_password_set(sd->editable_object, password_mode);
193 #ifdef HAVE_ECORE_IMF
195 ecore_imf_context_input_mode_set(sd->imf_context,
196 password_mode ? ECORE_IMF_INPUT_MODE_FULL & ECORE_IMF_INPUT_MODE_INVISIBLE :
197 ECORE_IMF_INPUT_MODE_FULL);
202 * Gets the minimum size of the entry object
204 * @param entry an entry object
205 * @param minw the location where to store the minimun width of the entry
206 * @param minh the location where to store the minimun height of the entry
209 e_entry_size_min_get(Evas_Object *entry, Evas_Coord *minw, Evas_Coord *minh)
211 E_Entry_Smart_Data *sd;
213 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
216 if (minw) *minw = sd->min_width;
217 if (minh) *minh = sd->height;
221 * Focuses the entry object. It will receives keyboard events and the user could
222 * then type some text (the entry should also be enabled. The cursor and the
223 * selection will be shown
225 * @param entry the entry to focus
228 e_entry_focus(Evas_Object *entry)
230 E_Entry_Smart_Data *sd;
232 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
237 evas_object_focus_set(entry, 1);
238 edje_object_signal_emit(sd->entry_object, "e,state,focused", "e");
239 if (!sd->selection_dragging)
241 e_editable_cursor_move_to_end(sd->editable_object);
242 #ifdef HAVE_ECORE_IMF
245 ecore_imf_context_reset(sd->imf_context);
246 ecore_imf_context_cursor_position_set(sd->imf_context,
247 e_editable_cursor_pos_get(sd->editable_object));
250 e_editable_selection_move_to_end(sd->editable_object);
253 e_editable_cursor_show(sd->editable_object);
254 e_editable_selection_show(sd->editable_object);
255 #ifdef HAVE_ECORE_IMF
258 ecore_imf_context_reset(sd->imf_context);
259 ecore_imf_context_focus_in(sd->imf_context);
266 * Unfocuses the entry object. It will no longer receives keyboard events so
267 * the user could no longer type some text. The cursor and the selection will
270 * @param entry the entry object to unfocus
273 e_entry_unfocus(Evas_Object *entry)
275 E_Entry_Smart_Data *sd;
277 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
282 evas_object_focus_set(entry, 0);
283 edje_object_signal_emit(sd->entry_object, "e,state,unfocused", "e");
284 e_editable_cursor_hide(sd->editable_object);
285 e_editable_selection_hide(sd->editable_object);
286 #ifdef HAVE_ECORE_IMF
289 ecore_imf_context_reset(sd->imf_context);
290 ecore_imf_context_focus_out(sd->imf_context);
297 * Enables the entry object: the user will be able to type text
299 * @param entry the entry object to enable
302 e_entry_enable(Evas_Object *entry)
304 E_Entry_Smart_Data *sd;
306 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
311 edje_object_signal_emit(sd->entry_object, "e,state,enabled", "e");
312 e_editable_enable(sd->editable_object);
314 e_editable_cursor_show(sd->editable_object);
319 * Disables the entry object: the user won't be able to type anymore. Selection
320 * will still be possible (to copy the text)
322 * @param entry the entry object to disable
325 e_entry_disable(Evas_Object *entry)
327 E_Entry_Smart_Data *sd;
329 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
334 edje_object_signal_emit(sd->entry_object, "e,state,disabled", "e");
335 e_editable_disable(sd->editable_object);
336 e_editable_cursor_hide(sd->editable_object);
341 /* Private functions */
343 /* Called when a key has been pressed by the user */
345 _e_entry_key_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
347 E_Entry_Smart_Data *sd;
349 if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
352 #ifdef HAVE_ECORE_IMF
355 Ecore_IMF_Event_Key_Down ev;
357 ecore_imf_evas_event_key_down_wrap(event_info, &ev);
358 if (ecore_imf_context_filter_event(sd->imf_context,
359 ECORE_IMF_EVENT_KEY_DOWN,
360 (Ecore_IMF_Event *) &ev))
365 if (_e_entry_emacs_keybindings)
366 _e_entry_key_down_emacs(obj, event_info);
368 _e_entry_key_down_windows(obj, event_info);
371 /* Called when a key has been released by the user */
373 _e_entry_key_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
375 E_Entry_Smart_Data *sd;
377 if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
380 #ifdef HAVE_ECORE_IMF
383 Ecore_IMF_Event_Key_Up ev;
385 ecore_imf_evas_event_key_up_wrap(event_info, &ev);
386 if (ecore_imf_context_filter_event(sd->imf_context,
387 ECORE_IMF_EVENT_KEY_UP,
388 (Ecore_IMF_Event *) &ev))
394 /* Called when the entry object is pressed by the mouse */
396 _e_entry_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
398 E_Entry_Smart_Data *sd;
399 Evas_Event_Mouse_Down *event;
403 if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
405 if (!(event = event_info))
408 #ifdef HAVE_ECORE_IMF
411 Ecore_IMF_Event_Mouse_Down ev;
413 ecore_imf_evas_event_mouse_down_wrap(event_info, &ev);
414 if (ecore_imf_context_filter_event(sd->imf_context,
415 ECORE_IMF_EVENT_MOUSE_DOWN,
416 (Ecore_IMF_Event *) &ev))
421 evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL);
422 pos = e_editable_pos_get_from_coords(sd->editable_object,
423 event->canvas.x - ox,
424 event->canvas.y - oy);
426 if (event->button == 1)
428 if (event->flags & EVAS_BUTTON_TRIPLE_CLICK)
430 e_editable_select_all(sd->editable_object);
431 _e_entry_x_selection_update(obj);
433 else if (event->flags & EVAS_BUTTON_DOUBLE_CLICK)
435 e_editable_select_word(sd->editable_object, pos);
436 _e_entry_x_selection_update(obj);
440 e_editable_cursor_pos_set(sd->editable_object, pos);
441 if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
442 e_editable_selection_pos_set(sd->editable_object, pos);
444 sd->selection_dragging = 1;
447 else if (event->button == 2)
451 e_editable_cursor_pos_set(sd->editable_object, pos);
452 e_editable_selection_pos_set(sd->editable_object, pos);
454 if ((win = e_win_evas_object_win_get(obj)))
455 ecore_x_selection_primary_request(win->evas_win,
456 ECORE_X_SELECTION_TARGET_UTF8_STRING);
458 else if (event->button == 3)
464 int cursor_pos, selection_pos;
465 int start_pos, end_pos;
466 int s_enabled, s_selecting, s_empty, s_passwd;
468 cursor_pos = e_editable_cursor_pos_get(sd->editable_object);
469 selection_pos = e_editable_selection_pos_get(sd->editable_object);
470 start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
471 end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
473 s_selecting = (start_pos != end_pos);
474 s_enabled = sd->enabled;
475 s_empty = !e_editable_text_length_get(sd->editable_object);
476 s_passwd = e_editable_password_get(sd->editable_object);
478 if (!s_selecting && !s_enabled && s_empty) return;
480 man = e_manager_current_get();
481 con = e_container_current_get(man);
482 ecore_x_pointer_xy_get(con->win, &x, &y);
485 sd->popup = e_menu_new();
486 e_menu_post_deactivate_callback_set(sd->popup,
487 _e_entry_cb_menu_post, sd);
492 mi = e_menu_item_new(sd->popup);
493 e_menu_item_label_set(mi, _("Delete"));
494 e_util_menu_item_theme_icon_set(mi, "edit-delete");
495 e_menu_item_callback_set(mi, _e_entry_cb_delete, sd);
497 mi = e_menu_item_new(sd->popup);
498 e_menu_item_separator_set(mi, 1);
502 mi = e_menu_item_new(sd->popup);
503 e_menu_item_label_set(mi, _("Cut"));
504 e_util_menu_item_theme_icon_set(mi, "edit-cut");
505 e_menu_item_callback_set(mi, _e_entry_cb_cut, sd);
510 mi = e_menu_item_new(sd->popup);
511 e_menu_item_label_set(mi, _("Copy"));
512 e_util_menu_item_theme_icon_set(mi, "edit-copy");
513 e_menu_item_callback_set(mi, _e_entry_cb_copy, sd);
518 mi = e_menu_item_new(sd->popup);
519 e_menu_item_label_set(mi, _("Paste"));
520 e_util_menu_item_theme_icon_set(mi, "edit-paste");
521 e_menu_item_callback_set(mi, _e_entry_cb_paste, sd);
525 mi = e_menu_item_new(sd->popup);
526 e_menu_item_separator_set(mi, 1);
528 mi = e_menu_item_new(sd->popup);
529 e_menu_item_label_set(mi, _("Select All"));
530 e_util_menu_item_theme_icon_set(mi, "edit-select-all");
531 e_menu_item_callback_set(mi, _e_entry_cb_select_all, sd);
534 e_menu_activate_mouse(sd->popup, e_util_zone_current_get(man),
536 E_MENU_POP_DIRECTION_DOWN, event->timestamp);
539 #ifdef HAVE_ECORE_IMF
542 ecore_imf_context_reset(sd->imf_context);
543 ecore_imf_context_cursor_position_set(sd->imf_context,
544 e_editable_cursor_pos_get(sd->editable_object));
549 /* Called when the entry object is released by the mouse */
551 _e_entry_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
553 E_Entry_Smart_Data *sd;
555 if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
558 #ifdef HAVE_ECORE_IMF
561 Ecore_IMF_Event_Mouse_Up ev;
563 ecore_imf_evas_event_mouse_up_wrap(event_info, &ev);
564 if (ecore_imf_context_filter_event(sd->imf_context,
565 ECORE_IMF_EVENT_MOUSE_UP,
566 (Ecore_IMF_Event *) &ev))
571 if (sd->selection_dragging)
573 sd->selection_dragging = 0;
574 _e_entry_x_selection_update(obj);
578 /* Called when the mouse moves over the entry object */
580 _e_entry_mouse_move_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
582 E_Entry_Smart_Data *sd;
583 Evas_Event_Mouse_Move *event;
587 if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
589 if (!(event = event_info))
592 #ifdef HAVE_ECORE_IMF
595 Ecore_IMF_Event_Mouse_Move ev;
597 ecore_imf_evas_event_mouse_move_wrap(event_info, &ev);
598 if (ecore_imf_context_filter_event(sd->imf_context,
599 ECORE_IMF_EVENT_MOUSE_MOVE,
600 (Ecore_IMF_Event *) &ev))
605 if (sd->selection_dragging)
607 evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL);
608 pos = e_editable_pos_get_from_coords(sd->editable_object,
609 event->cur.canvas.x - ox,
610 event->cur.canvas.y - oy);
611 e_editable_cursor_pos_set(sd->editable_object, pos);
612 #ifdef HAVE_ECORE_IMF
615 ecore_imf_context_reset(sd->imf_context);
616 ecore_imf_context_cursor_position_set(sd->imf_context,
623 /* Called when the the "selection_notify" event is emitted */
625 _e_entry_x_selection_notify_handler(void *data, int type __UNUSED__, void *event)
628 E_Entry_Smart_Data *sd;
629 Ecore_X_Event_Selection_Notify *ev;
630 Evas_Object *editable;
631 int cursor_pos, selection_pos;
632 int start_pos, end_pos;
636 if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
641 editable = sd->editable_object;
642 cursor_pos = e_editable_cursor_pos_get(editable);
643 selection_pos = e_editable_selection_pos_get(editable);
644 start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
645 end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
646 selecting = (start_pos != end_pos);
649 if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
650 (ev->selection == ECORE_X_SELECTION_PRIMARY))
652 if (strcmp(ev->target, ECORE_X_SELECTION_TARGET_UTF8_STRING) == 0)
654 Ecore_X_Selection_Data_Text *text_data;
656 text_data = ev->data;
657 if (selecting && !_e_entry_emacs_keybindings)
658 changed |= e_editable_delete(editable, start_pos, end_pos);
659 changed |= e_editable_insert(editable, start_pos, text_data->text);
664 evas_object_smart_callback_call(entry, "changed", NULL);
666 return ECORE_CALLBACK_PASS_ON;
669 /* Updates the X selection with the selected text of the entry */
671 _e_entry_x_selection_update(Evas_Object *entry)
673 E_Entry_Smart_Data *sd;
674 Evas_Object *editable;
676 int cursor_pos, selection_pos;
677 int start_pos, end_pos;
681 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
683 if (!(win = e_win_evas_object_win_get(entry)))
686 editable = sd->editable_object;
687 if (e_editable_password_get(editable)) return;
689 cursor_pos = e_editable_cursor_pos_get(editable);
690 selection_pos = e_editable_selection_pos_get(editable);
691 start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
692 end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
693 selecting = (start_pos != end_pos);
696 (!(text = e_editable_text_range_get(editable, start_pos, end_pos))))
699 ecore_x_selection_primary_set(win->evas_win, text, strlen(text) + 1);
703 /* Treats the "key down" event to mimick the behavior of Windows/Gtk2/Qt */
705 _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event)
707 E_Entry_Smart_Data *sd;
708 Evas_Object *editable;
709 int cursor_pos, selection_pos;
710 int start_pos, end_pos;
713 int selection_changed = 0;
717 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
719 if ((!event) || (!event->keyname))
722 editable = sd->editable_object;
723 cursor_pos = e_editable_cursor_pos_get(editable);
724 selection_pos = e_editable_selection_pos_get(editable);
725 start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
726 end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
727 selecting = (start_pos != end_pos);
729 /* Move the cursor/selection to the left */
730 if (strcmp(event->key, "Left") == 0)
732 if (evas_key_modifier_is_set(event->modifiers, "Shift"))
734 e_editable_cursor_move_left(editable);
735 selection_changed = 1;
739 if (cursor_pos < selection_pos)
740 e_editable_selection_pos_set(editable, cursor_pos);
742 e_editable_cursor_pos_set(editable, selection_pos);
746 e_editable_cursor_move_left(editable);
747 e_editable_selection_pos_set(editable,
748 e_editable_cursor_pos_get(editable));
751 /* Move the cursor/selection to the right */
752 else if (strcmp(event->key, "Right") == 0)
754 if (evas_key_modifier_is_set(event->modifiers, "Shift"))
756 e_editable_cursor_move_right(editable);
757 selection_changed = 1;
761 if (cursor_pos > selection_pos)
762 e_editable_selection_pos_set(editable, cursor_pos);
764 e_editable_cursor_pos_set(editable, selection_pos);
768 e_editable_cursor_move_right(editable);
769 e_editable_selection_pos_set(editable,
770 e_editable_cursor_pos_get(editable));
773 /* Move the cursor/selection to the start of the entry */
774 else if (strcmp(event->keyname, "Home") == 0)
776 e_editable_cursor_move_to_start(editable);
777 if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
778 e_editable_selection_pos_set(editable,
779 e_editable_cursor_pos_get(editable));
781 selection_changed = 1;
783 /* Move the cursor/selection to the end of the entry */
784 else if (strcmp(event->keyname, "End") == 0)
786 e_editable_cursor_move_to_end(editable);
787 if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
788 e_editable_selection_pos_set(editable,
789 e_editable_cursor_pos_get(editable));
791 selection_changed = 1;
793 /* Delete the previous character */
794 else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0))
797 changed = e_editable_delete(editable, start_pos, end_pos);
799 changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos);
801 /* Delete the next character */
802 else if ((sd->enabled) && (strcmp(event->keyname, "Delete") == 0))
805 changed = e_editable_delete(editable, start_pos, end_pos);
807 changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1);
810 else if (evas_key_modifier_is_set(event->modifiers, "Control"))
812 if (strcmp(event->keyname, "a") == 0)
814 e_editable_select_all(editable);
815 selection_changed = 1;
817 else if ((strcmp(event->keyname, "x") == 0) ||
818 (strcmp(event->keyname, "c") == 0))
820 if (!e_editable_password_get(editable) && selecting)
822 range = e_editable_text_range_get(editable, start_pos, end_pos);
825 if ((win = e_win_evas_object_win_get(entry)))
826 ecore_x_selection_clipboard_set(win->evas_win,
831 if ((sd->enabled) && (strcmp(event->keyname, "x") == 0))
832 changed = e_editable_delete(editable, start_pos, end_pos);
835 else if ((sd->enabled) && (strcmp(event->keyname, "v") == 0))
837 if ((win = e_win_evas_object_win_get(entry)))
838 ecore_x_selection_clipboard_request(win->evas_win,
839 ECORE_X_SELECTION_TARGET_UTF8_STRING);
842 /* Otherwise, we insert the corresponding character */
843 else if ((event->string) && ((sd->enabled)) &&
844 ((strlen(event->string) != 1) || (event->string[0] >= 0x20)))
847 changed |= e_editable_delete(editable, start_pos, end_pos);
848 changed |= e_editable_insert(editable, start_pos, event->string);
851 #ifdef HAVE_ECORE_IMF
854 ecore_imf_context_reset(sd->imf_context);
855 ecore_imf_context_cursor_position_set(sd->imf_context,
856 e_editable_cursor_pos_get(editable));
861 evas_object_smart_callback_call(entry, "changed", NULL);
862 if (selection_changed)
863 _e_entry_x_selection_update(entry);
866 /* Treats the "key down" event to mimick the behavior of Emacs */
868 _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event)
870 E_Entry_Smart_Data *sd;
871 Evas_Object *editable;
872 int cursor_pos, selection_pos;
873 int start_pos, end_pos;
876 int selection_changed = 0;
880 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
882 if ((!event) || (!event->keyname))
885 editable = sd->editable_object;
886 cursor_pos = e_editable_cursor_pos_get(editable);
887 selection_pos = e_editable_selection_pos_get(editable);
888 start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
889 end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
890 selecting = (start_pos != end_pos);
892 /* Move the cursor/selection to the left */
893 if ((strcmp(event->key, "Left") == 0) ||
894 ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
895 (strcmp(event->key, "b") == 0)))
897 e_editable_cursor_move_left(editable);
898 if (sd->selection_mode)
899 selection_changed = 1;
901 e_editable_selection_pos_set(editable,
902 e_editable_cursor_pos_get(editable));
904 /* Move the cursor/selection to the right */
905 else if ((strcmp(event->key, "Right") == 0) ||
906 ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
907 (strcmp(event->key, "f") == 0)))
909 e_editable_cursor_move_right(editable);
910 if (sd->selection_mode)
911 selection_changed = 1;
913 e_editable_selection_pos_set(editable,
914 e_editable_cursor_pos_get(editable));
916 /* Move the cursor/selection to the start of the entry */
917 else if ((strcmp(event->keyname, "Home") == 0) ||
918 ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
919 (strcmp(event->key, "a") == 0)))
921 e_editable_cursor_move_to_start(editable);
922 if (sd->selection_mode)
923 selection_changed = 1;
925 e_editable_selection_pos_set(editable,
926 e_editable_cursor_pos_get(editable));
928 /* Move the cursor/selection to the end of the entry */
929 else if ((strcmp(event->keyname, "End") == 0) ||
930 ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
931 (strcmp(event->key, "e") == 0)))
933 e_editable_cursor_move_to_end(editable);
934 if (sd->selection_mode)
935 selection_changed = 1;
937 e_editable_selection_pos_set(editable,
938 e_editable_cursor_pos_get(editable));
940 /* Delete the previous character */
941 else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0))
942 changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos);
943 /* Delete the next character */
944 else if ((sd->enabled) &&
945 ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
946 (strcmp(event->key, "d") == 0)))
947 changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1);
948 /* Delete until end of line */
949 else if ((sd->enabled) &&
950 ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
951 (strcmp(event->key, "k") == 0)))
952 changed = e_editable_delete(editable, cursor_pos,
953 e_editable_text_length_get(editable));
954 /* Toggle the selection mode */
955 else if ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
956 (strcmp(event->key, "space") == 0))
958 if (sd->selection_mode)
960 e_editable_selection_pos_set(editable, cursor_pos);
961 sd->selection_mode = 0;
964 sd->selection_mode = 1;
967 else if ((evas_key_modifier_is_set(event->modifiers, "Control") ||
968 evas_key_modifier_is_set(event->modifiers, "Shift")) &&
969 (strcmp(event->key, "w") == 0))
971 if (!e_editable_password_get(editable) && selecting)
973 range = e_editable_text_range_get(editable, start_pos, end_pos);
976 if ((win = e_win_evas_object_win_get(entry)))
977 ecore_x_selection_clipboard_set(win->evas_win,
982 if ((sd->enabled) && (evas_key_modifier_is_set(event->modifiers, "Control")))
984 changed = e_editable_delete(editable, start_pos, end_pos);
985 sd->selection_mode = 0;
990 else if ((sd->enabled) &&
991 ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
992 (strcmp(event->key, "y") == 0)))
994 if ((win = e_win_evas_object_win_get(entry)))
995 ecore_x_selection_clipboard_request(win->evas_win,
996 ECORE_X_SELECTION_TARGET_UTF8_STRING);
998 /* Otherwise, we insert the corresponding character */
999 else if ((event->string) &&
1000 ((strlen(event->string) != 1) ||
1001 (event->string[0] >= 0x20 && event->string[0] != 0x7f)))
1002 changed = e_editable_insert(editable, cursor_pos, event->string);
1004 #ifdef HAVE_ECORE_IMF
1005 if (sd->imf_context)
1007 ecore_imf_context_reset(sd->imf_context);
1008 ecore_imf_context_cursor_position_set(sd->imf_context,
1009 e_editable_cursor_pos_get(editable));
1014 evas_object_smart_callback_call(entry, "changed", NULL);
1015 if (selection_changed)
1016 _e_entry_x_selection_update(entry);
1019 /* Editable object's smart methods */
1022 _e_entry_smart_add(Evas_Object *object)
1025 E_Entry_Smart_Data *sd;
1029 #ifdef HAVE_ECORE_IMF
1030 const Ecore_IMF_Context_Info *ctx_info;
1033 if ((!object) || !(evas = evas_object_evas_get(object)))
1036 sd = malloc(sizeof(E_Entry_Smart_Data));
1039 evas_object_smart_data_set(object, sd);
1041 #ifdef HAVE_ECORE_IMF
1042 ctx_id = ecore_imf_context_default_id_get();
1045 ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
1046 if (!ctx_info->canvas_type ||
1047 strcmp(ctx_info->canvas_type, "evas") == 0)
1048 sd->imf_context = ecore_imf_context_add(ctx_id);
1051 ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
1053 sd->imf_context = ecore_imf_context_add(ctx_id);
1055 sd->imf_context = NULL;
1059 sd->imf_context = NULL;
1061 if (sd->imf_context)
1063 ecore_imf_context_client_window_set(sd->imf_context,
1064 (long *)ecore_evas_window_get(ecore_evas_ecore_evas_get(evas)));
1065 ecore_imf_context_client_canvas_set(sd->imf_context, evas);
1066 ecore_imf_context_retrieve_surrounding_callback_set(sd->imf_context,
1067 _e_entry_cb_imf_retrieve_surrounding,
1069 sd->imf_ee_commit_handler =
1070 ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT,
1071 _e_entry_cb_imf_event_commit, object);
1072 sd->imf_ee_delete_handler =
1073 ecore_event_handler_add(ECORE_IMF_EVENT_DELETE_SURROUNDING,
1074 _e_entry_cb_imf_event_delete_surrounding, sd);
1080 sd->selection_dragging = 0;
1081 sd->selection_mode = 0;
1084 o = edje_object_add(evas);
1085 sd->entry_object = o;
1086 e_theme_edje_object_set(o, "base/theme/widgets", "e/widgets/entry");
1087 evas_object_smart_member_add(o, object);
1089 o = e_editable_add(evas);
1090 sd->editable_object = o;
1091 e_editable_theme_set(o, "base/theme/widgets", "e/widgets/entry");
1092 e_editable_cursor_hide(o);
1093 e_editable_char_size_get(o, &cw, &ch);
1094 edje_extern_object_min_size_set(o, cw, ch);
1095 edje_object_part_swallow(sd->entry_object, "e.swallow.text", o);
1096 edje_object_size_min_calc(sd->entry_object, &sd->min_width, &sd->height);
1097 evas_object_show(o);
1099 evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_DOWN,
1100 _e_entry_key_down_cb, NULL);
1101 evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_UP,
1102 _e_entry_key_up_cb, NULL);
1103 evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_DOWN,
1104 _e_entry_mouse_down_cb, NULL);
1105 evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_UP,
1106 _e_entry_mouse_up_cb, NULL);
1107 evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_MOVE,
1108 _e_entry_mouse_move_cb, NULL);
1109 sd->selection_handler = ecore_event_handler_add(
1110 ECORE_X_EVENT_SELECTION_NOTIFY,
1111 _e_entry_x_selection_notify_handler,
1116 _e_entry_smart_del(Evas_Object *object)
1118 E_Entry_Smart_Data *sd;
1120 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1123 #ifdef HAVE_ECORE_IMF
1124 if (sd->imf_context)
1126 if (sd->imf_ee_commit_handler)
1127 ecore_event_handler_del(sd->imf_ee_commit_handler);
1128 if (sd->imf_ee_delete_handler)
1129 ecore_event_handler_del(sd->imf_ee_delete_handler);
1130 ecore_imf_context_del(sd->imf_context);
1134 evas_object_event_callback_del(object, EVAS_CALLBACK_KEY_DOWN,
1135 _e_entry_key_down_cb);
1136 evas_object_event_callback_del(object, EVAS_CALLBACK_KEY_UP,
1137 _e_entry_key_up_cb);
1138 evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_DOWN,
1139 _e_entry_mouse_down_cb);
1140 evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_UP,
1141 _e_entry_mouse_up_cb);
1142 evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_MOVE,
1143 _e_entry_mouse_move_cb);
1145 if (sd->selection_handler)
1146 ecore_event_handler_del(sd->selection_handler);
1147 evas_object_del(sd->editable_object);
1148 evas_object_del(sd->entry_object);
1153 _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y)
1155 E_Entry_Smart_Data *sd;
1156 Evas_Coord prev_x, prev_y;
1159 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1162 evas_object_geometry_get(object, &prev_x, &prev_y, NULL, NULL);
1163 evas_object_geometry_get(sd->entry_object, &ox, &oy, NULL, NULL);
1164 evas_object_move(sd->entry_object, ox + (x - prev_x), oy + (y - prev_y));
1168 _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h)
1170 E_Entry_Smart_Data *sd;
1173 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1176 evas_object_geometry_get(object, &x, &y, NULL, NULL);
1177 evas_object_move(sd->entry_object, x, y + ((h - sd->height) * sd->valign));
1178 evas_object_resize(sd->entry_object, w, sd->height);
1182 _e_entry_smart_show(Evas_Object *object)
1184 E_Entry_Smart_Data *sd;
1186 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1188 evas_object_show(sd->entry_object);
1192 _e_entry_smart_hide(Evas_Object *object)
1194 E_Entry_Smart_Data *sd;
1196 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1198 evas_object_hide(sd->entry_object);
1202 _e_entry_color_set(Evas_Object *object, int r, int g, int b, int a)
1204 E_Entry_Smart_Data *sd;
1206 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1208 evas_object_color_set(sd->entry_object, r, g, b, a);
1212 _e_entry_clip_set(Evas_Object *object, Evas_Object *clip)
1214 E_Entry_Smart_Data *sd;
1216 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1218 evas_object_clip_set(sd->entry_object, clip);
1222 _e_entry_clip_unset(Evas_Object *object)
1224 E_Entry_Smart_Data *sd;
1226 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1228 evas_object_clip_unset(sd->entry_object);
1232 _e_entry_cb_menu_post(void *data, E_Menu *m __UNUSED__)
1234 E_Entry_Smart_Data *sd;
1237 if (!sd->popup) return;
1238 e_object_del(E_OBJECT(sd->popup));
1243 _e_entry_cb_cut(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1245 E_Entry_Smart_Data *sd;
1246 Evas_Object *editable;
1247 int cursor_pos, selection_pos;
1248 int start_pos, end_pos;
1249 int selecting, changed;
1254 if (!sd->enabled) return;
1256 editable = sd->editable_object;
1257 cursor_pos = e_editable_cursor_pos_get(editable);
1258 selection_pos = e_editable_selection_pos_get(editable);
1259 start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1260 end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1261 selecting = (start_pos != end_pos);
1262 if (!selecting) return;
1264 range = e_editable_text_range_get(editable, start_pos, end_pos);
1267 if ((win = e_win_evas_object_win_get(sd->entry_object)))
1268 ecore_x_selection_clipboard_set(win->evas_win,
1269 range, strlen(range) + 1);
1272 changed = e_editable_delete(editable, start_pos, end_pos);
1274 evas_object_smart_callback_call(sd->entry_object, "changed", NULL);
1278 _e_entry_cb_copy(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1280 E_Entry_Smart_Data *sd;
1281 Evas_Object *editable;
1282 int cursor_pos, selection_pos;
1283 int start_pos, end_pos;
1290 editable = sd->editable_object;
1291 cursor_pos = e_editable_cursor_pos_get(editable);
1292 selection_pos = e_editable_selection_pos_get(editable);
1293 start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1294 end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1295 selecting = (start_pos != end_pos);
1296 if (!selecting) return;
1298 range = e_editable_text_range_get(editable, start_pos, end_pos);
1301 if ((win = e_win_evas_object_win_get(sd->entry_object)))
1302 ecore_x_selection_clipboard_set(win->evas_win,
1303 range, strlen(range) + 1);
1309 _e_entry_cb_paste(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1311 E_Entry_Smart_Data *sd;
1315 if (!sd->enabled) return;
1317 if ((win = e_win_evas_object_win_get(sd->entry_object)))
1318 ecore_x_selection_clipboard_request(win->evas_win,
1319 ECORE_X_SELECTION_TARGET_UTF8_STRING);
1323 _e_entry_cb_select_all(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1325 E_Entry_Smart_Data *sd;
1328 e_editable_select_all(sd->editable_object);
1329 _e_entry_x_selection_update(sd->entry_object);
1333 _e_entry_cb_delete(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1335 E_Entry_Smart_Data *sd;
1336 Evas_Object *editable;
1337 int cursor_pos, selection_pos;
1338 int start_pos, end_pos;
1343 if (!sd->enabled) return;
1345 editable = sd->editable_object;
1346 cursor_pos = e_editable_cursor_pos_get(editable);
1347 selection_pos = e_editable_selection_pos_get(editable);
1348 start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1349 end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1350 selecting = (start_pos != end_pos);
1351 if (!selecting) return;
1353 range = e_editable_text_range_get(editable, start_pos, end_pos);
1356 e_editable_delete(editable, start_pos, end_pos);
1357 evas_object_smart_callback_call(sd->entry_object, "changed", NULL);
1362 #ifdef HAVE_ECORE_IMF
1364 _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx __UNUSED__, char **text, int *cursor_pos)
1366 E_Entry_Smart_Data *sd;
1374 str = e_editable_text_get(sd->editable_object);
1375 *text = str ? strdup(str) : strdup("");
1379 *cursor_pos = e_editable_cursor_pos_get(sd->editable_object);
1385 _e_entry_cb_imf_event_commit(void *data, int type __UNUSED__, void *event)
1388 E_Entry_Smart_Data *sd;
1389 Ecore_IMF_Event_Commit *ev = event;
1390 Evas_Object *editable;
1391 int cursor_pos, selection_pos;
1392 int start_pos, end_pos;
1396 if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
1397 return ECORE_CALLBACK_PASS_ON;
1399 if (sd->imf_context != ev->ctx)
1400 return ECORE_CALLBACK_PASS_ON;
1402 editable = sd->editable_object;
1403 cursor_pos = e_editable_cursor_pos_get(editable);
1404 selection_pos = e_editable_selection_pos_get(editable);
1405 start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1406 end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1407 selecting = (start_pos != end_pos);
1410 changed |= e_editable_delete(editable, start_pos, end_pos);
1411 changed |= e_editable_insert(editable, start_pos, ev->str);
1414 evas_object_smart_callback_call(entry, "changed", NULL);
1416 return ECORE_CALLBACK_DONE;
1420 _e_entry_cb_imf_event_delete_surrounding(void *data, int type __UNUSED__, void *event)
1422 E_Entry_Smart_Data *sd;
1423 Ecore_IMF_Event_Delete_Surrounding *ev = event;
1424 Evas_Object *editable;
1429 if (sd->imf_context != ev->ctx)
1430 return ECORE_CALLBACK_PASS_ON;
1432 editable = sd->editable_object;
1433 cursor_pos = e_editable_cursor_pos_get(editable);
1434 e_editable_delete(editable,
1435 cursor_pos + ev->offset,
1436 cursor_pos + ev->offset + ev->n_chars);
1438 return ECORE_CALLBACK_DONE;