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_preedit_changed_handler;
21 Ecore_Event_Handler *imf_ee_delete_handler;
25 int selection_dragging;
30 int preedit_start_pos;
32 Eina_Bool have_preedit : 1;
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);
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);
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);
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);
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;
77 /* externally accessible functions */
80 * Creates a new entry object. An entry is a field where the user can type
82 * Use the "changed" smart callback to know when the content of the entry is
85 * @param evas the evas where the entry object should be added
86 * @return Returns the new entry object
89 e_entry_add(Evas *evas)
93 static const Evas_Smart_Class sc =
96 EVAS_SMART_CLASS_VERSION,
100 _e_entry_smart_resize,
114 _e_entry_smart = evas_smart_class_new(&sc);
115 _e_entry_smart_use = 0;
118 _e_entry_smart_use++;
119 return evas_object_smart_add(evas, _e_entry_smart);
123 * Sets the text of the entry object
125 * @param entry an entry object
126 * @param text the text to set
129 e_entry_text_set(Evas_Object *entry, const char *text)
131 E_Entry_Smart_Data *sd;
133 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
136 e_editable_text_set(sd->editable_object, text);
137 evas_object_smart_callback_call(entry, "changed", NULL);
141 * Gets the text of the entry object
143 * @param entry an entry object
144 * @return Returns the text of the entry object
147 e_entry_text_get(Evas_Object *entry)
149 E_Entry_Smart_Data *sd;
151 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
153 return e_editable_text_get(sd->editable_object);
157 * Clears the entry object
159 * @param entry an entry object
162 e_entry_clear(Evas_Object *entry)
164 e_entry_text_set(entry, "");
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.
172 * @param entry an entry object
173 * @return Returns the editable object used by the entry object
176 e_entry_editable_object_get(Evas_Object *entry)
178 E_Entry_Smart_Data *sd;
180 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
182 return sd->editable_object;
186 * Sets whether or not the entry object is in password mode. In password mode,
187 * the entry displays '*' instead of the characters
189 * @param entry an entry object
190 * @param password_mode 1 to turn on password mode, 0 to turn it off
193 e_entry_password_set(Evas_Object *entry, int password_mode)
195 E_Entry_Smart_Data *sd;
197 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
199 e_editable_password_set(sd->editable_object, password_mode);
200 #ifdef HAVE_ECORE_IMF
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);
209 * Gets the minimum size of the entry object
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
216 e_entry_size_min_get(Evas_Object *entry, Evas_Coord *minw, Evas_Coord *minh)
218 E_Entry_Smart_Data *sd;
220 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
223 if (minw) *minw = sd->min_width;
224 if (minh) *minh = sd->height;
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
232 * @param entry the entry to focus
235 e_entry_focus(Evas_Object *entry)
237 E_Entry_Smart_Data *sd;
239 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
244 evas_object_focus_set(entry, 1);
245 edje_object_signal_emit(sd->entry_object, "e,state,focused", "e");
246 if (!sd->selection_dragging)
248 e_editable_cursor_move_to_end(sd->editable_object);
250 _e_entry_imf_context_reset(entry);
251 _e_entry_imf_cursor_info_set(entry);
253 e_editable_selection_move_to_end(sd->editable_object);
256 e_editable_cursor_show(sd->editable_object);
257 e_editable_selection_show(sd->editable_object);
258 #ifdef HAVE_ECORE_IMF
261 ecore_imf_context_reset(sd->imf_context);
262 ecore_imf_context_focus_in(sd->imf_context);
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
273 * @param entry the entry object to unfocus
276 e_entry_unfocus(Evas_Object *entry)
278 E_Entry_Smart_Data *sd;
280 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
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
292 ecore_imf_context_reset(sd->imf_context);
293 ecore_imf_context_focus_out(sd->imf_context);
300 * Enables the entry object: the user will be able to type text
302 * @param entry the entry object to enable
305 e_entry_enable(Evas_Object *entry)
307 E_Entry_Smart_Data *sd;
309 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
314 edje_object_signal_emit(sd->entry_object, "e,state,enabled", "e");
315 e_editable_enable(sd->editable_object);
317 e_editable_cursor_show(sd->editable_object);
322 * Disables the entry object: the user won't be able to type anymore. Selection
323 * will still be possible (to copy the text)
325 * @param entry the entry object to disable
328 e_entry_disable(Evas_Object *entry)
330 E_Entry_Smart_Data *sd;
332 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
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);
344 /* Private functions */
346 /* Called when a key has been pressed by the user */
348 _e_entry_key_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
350 E_Entry_Smart_Data *sd;
352 if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
355 #ifdef HAVE_ECORE_IMF
358 Ecore_IMF_Event_Key_Down ev;
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))
368 if (_e_entry_emacs_keybindings)
369 _e_entry_key_down_emacs(obj, event_info);
371 _e_entry_key_down_windows(obj, event_info);
374 /* Called when a key has been released by the user */
376 _e_entry_key_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
378 E_Entry_Smart_Data *sd;
380 if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
383 #ifdef HAVE_ECORE_IMF
386 Ecore_IMF_Event_Key_Up ev;
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))
397 /* Called when the entry object is pressed by the mouse */
399 _e_entry_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
401 E_Entry_Smart_Data *sd;
402 Evas_Event_Mouse_Down *event;
406 if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
408 if (!(event = event_info))
411 #ifdef HAVE_ECORE_IMF
414 Ecore_IMF_Event_Mouse_Down ev;
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))
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);
429 if (event->button == 1)
431 if (event->flags & EVAS_BUTTON_TRIPLE_CLICK)
433 e_editable_select_all(sd->editable_object);
434 _e_entry_x_selection_update(obj);
436 else if (event->flags & EVAS_BUTTON_DOUBLE_CLICK)
438 e_editable_select_word(sd->editable_object, pos);
439 _e_entry_x_selection_update(obj);
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);
447 sd->selection_dragging = 1;
450 else if (event->button == 2)
454 e_editable_cursor_pos_set(sd->editable_object, pos);
455 e_editable_selection_pos_set(sd->editable_object, pos);
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);
461 else if (event->button == 3)
467 int cursor_pos, selection_pos;
468 int start_pos, end_pos;
469 int s_enabled, s_selecting, s_empty, s_passwd;
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;
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);
481 if (!s_selecting && !s_enabled && s_empty) return;
483 man = e_manager_current_get();
484 con = e_container_current_get(man);
485 ecore_x_pointer_xy_get(con->win, &x, &y);
488 sd->popup = e_menu_new();
489 e_menu_post_deactivate_callback_set(sd->popup,
490 _e_entry_cb_menu_post, sd);
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);
500 mi = e_menu_item_new(sd->popup);
501 e_menu_item_separator_set(mi, 1);
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);
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);
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);
528 mi = e_menu_item_new(sd->popup);
529 e_menu_item_separator_set(mi, 1);
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);
537 e_menu_activate_mouse(sd->popup, e_util_zone_current_get(man),
539 E_MENU_POP_DIRECTION_DOWN, event->timestamp);
542 _e_entry_imf_context_reset(obj);
543 _e_entry_imf_cursor_info_set(obj);
546 /* Called when the entry object is released by the mouse */
548 _e_entry_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
550 E_Entry_Smart_Data *sd;
552 if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
555 #ifdef HAVE_ECORE_IMF
558 Ecore_IMF_Event_Mouse_Up ev;
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))
568 if (sd->selection_dragging)
570 sd->selection_dragging = 0;
571 _e_entry_x_selection_update(obj);
575 /* Called when the mouse moves over the entry object */
577 _e_entry_mouse_move_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
579 E_Entry_Smart_Data *sd;
580 Evas_Event_Mouse_Move *event;
584 if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
586 if (!(event = event_info))
589 #ifdef HAVE_ECORE_IMF
592 Ecore_IMF_Event_Mouse_Move ev;
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))
602 if (sd->selection_dragging)
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);
610 _e_entry_imf_context_reset(obj);
611 _e_entry_imf_cursor_info_set(obj);
615 /* Called when the the "selection_notify" event is emitted */
617 _e_entry_x_selection_notify_handler(void *data, int type __UNUSED__, void *event)
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;
628 if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
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);
641 if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
642 (ev->selection == ECORE_X_SELECTION_PRIMARY))
644 if (strcmp(ev->target, ECORE_X_SELECTION_TARGET_UTF8_STRING) == 0)
646 Ecore_X_Selection_Data_Text *text_data;
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);
656 evas_object_smart_callback_call(entry, "changed", NULL);
658 return ECORE_CALLBACK_PASS_ON;
661 /* Updates the X selection with the selected text of the entry */
663 _e_entry_x_selection_update(Evas_Object *entry)
665 E_Entry_Smart_Data *sd;
666 Evas_Object *editable;
668 int cursor_pos, selection_pos;
669 int start_pos, end_pos;
673 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
675 if (!(win = e_win_evas_object_win_get(entry)))
678 editable = sd->editable_object;
679 if (e_editable_password_get(editable)) return;
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);
688 (!(text = e_editable_text_range_get(editable, start_pos, end_pos))))
691 ecore_x_selection_primary_set(win->evas_win, text, strlen(text) + 1);
695 /* Treats the "key down" event to mimick the behavior of Windows/Gtk2/Qt */
697 _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event)
699 E_Entry_Smart_Data *sd;
700 Evas_Object *editable;
701 int cursor_pos, selection_pos;
702 int start_pos, end_pos;
705 int selection_changed = 0;
709 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
711 if ((!event) || (!event->keyname))
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);
721 /* Move the cursor/selection to the left */
722 if (strcmp(event->key, "Left") == 0)
724 if (evas_key_modifier_is_set(event->modifiers, "Shift"))
726 e_editable_cursor_move_left(editable);
727 selection_changed = 1;
731 if (cursor_pos < selection_pos)
732 e_editable_selection_pos_set(editable, cursor_pos);
734 e_editable_cursor_pos_set(editable, selection_pos);
738 e_editable_cursor_move_left(editable);
739 e_editable_selection_pos_set(editable,
740 e_editable_cursor_pos_get(editable));
743 /* Move the cursor/selection to the right */
744 else if (strcmp(event->key, "Right") == 0)
746 if (evas_key_modifier_is_set(event->modifiers, "Shift"))
748 e_editable_cursor_move_right(editable);
749 selection_changed = 1;
753 if (cursor_pos > selection_pos)
754 e_editable_selection_pos_set(editable, cursor_pos);
756 e_editable_cursor_pos_set(editable, selection_pos);
760 e_editable_cursor_move_right(editable);
761 e_editable_selection_pos_set(editable,
762 e_editable_cursor_pos_get(editable));
765 /* Move the cursor/selection to the start of the entry */
766 else if (strcmp(event->keyname, "Home") == 0)
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));
773 selection_changed = 1;
775 /* Move the cursor/selection to the end of the entry */
776 else if (strcmp(event->keyname, "End") == 0)
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));
783 selection_changed = 1;
785 /* Delete the previous character */
786 else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0))
789 changed = e_editable_delete(editable, start_pos, end_pos);
791 changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos);
793 /* Delete the next character */
794 else if ((sd->enabled) && (strcmp(event->keyname, "Delete") == 0))
797 changed = e_editable_delete(editable, start_pos, end_pos);
799 changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1);
802 else if (evas_key_modifier_is_set(event->modifiers, "Control"))
804 if (strcmp(event->keyname, "a") == 0)
806 e_editable_select_all(editable);
807 selection_changed = 1;
809 else if ((strcmp(event->keyname, "x") == 0) ||
810 (strcmp(event->keyname, "c") == 0))
812 if (!e_editable_password_get(editable) && selecting)
814 range = e_editable_text_range_get(editable, start_pos, end_pos);
817 if ((win = e_win_evas_object_win_get(entry)))
818 ecore_x_selection_clipboard_set(win->evas_win,
823 if ((sd->enabled) && (strcmp(event->keyname, "x") == 0))
824 changed = e_editable_delete(editable, start_pos, end_pos);
827 else if ((sd->enabled) && (strcmp(event->keyname, "v") == 0))
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);
834 /* Otherwise, we insert the corresponding character */
835 else if ((event->string) && ((sd->enabled)) &&
836 ((strlen(event->string) != 1) || (event->string[0] >= 0x20)))
839 changed |= e_editable_delete(editable, start_pos, end_pos);
840 changed |= e_editable_insert(editable, start_pos, event->string);
843 _e_entry_imf_context_reset(entry);
844 _e_entry_imf_cursor_info_set(entry);
847 evas_object_smart_callback_call(entry, "changed", NULL);
848 if (selection_changed)
849 _e_entry_x_selection_update(entry);
852 /* Treats the "key down" event to mimick the behavior of Emacs */
854 _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event)
856 E_Entry_Smart_Data *sd;
857 Evas_Object *editable;
858 int cursor_pos, selection_pos;
859 int start_pos, end_pos;
862 int selection_changed = 0;
866 if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
868 if ((!event) || (!event->keyname))
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);
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)))
883 e_editable_cursor_move_left(editable);
884 if (sd->selection_mode)
885 selection_changed = 1;
887 e_editable_selection_pos_set(editable,
888 e_editable_cursor_pos_get(editable));
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)))
895 e_editable_cursor_move_right(editable);
896 if (sd->selection_mode)
897 selection_changed = 1;
899 e_editable_selection_pos_set(editable,
900 e_editable_cursor_pos_get(editable));
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)))
907 e_editable_cursor_move_to_start(editable);
908 if (sd->selection_mode)
909 selection_changed = 1;
911 e_editable_selection_pos_set(editable,
912 e_editable_cursor_pos_get(editable));
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)))
919 e_editable_cursor_move_to_end(editable);
920 if (sd->selection_mode)
921 selection_changed = 1;
923 e_editable_selection_pos_set(editable,
924 e_editable_cursor_pos_get(editable));
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))
944 if (sd->selection_mode)
946 e_editable_selection_pos_set(editable, cursor_pos);
947 sd->selection_mode = 0;
950 sd->selection_mode = 1;
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))
957 if (!e_editable_password_get(editable) && selecting)
959 range = e_editable_text_range_get(editable, start_pos, end_pos);
962 if ((win = e_win_evas_object_win_get(entry)))
963 ecore_x_selection_clipboard_set(win->evas_win,
968 if ((sd->enabled) && (evas_key_modifier_is_set(event->modifiers, "Control")))
970 changed = e_editable_delete(editable, start_pos, end_pos);
971 sd->selection_mode = 0;
976 else if ((sd->enabled) &&
977 ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
978 (strcmp(event->key, "y") == 0)))
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);
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);
990 _e_entry_imf_context_reset(entry);
991 _e_entry_imf_cursor_info_set(entry);
994 evas_object_smart_callback_call(entry, "changed", NULL);
995 if (selection_changed)
996 _e_entry_x_selection_update(entry);
999 /* Editable object's smart methods */
1002 _e_entry_smart_add(Evas_Object *object)
1005 E_Entry_Smart_Data *sd;
1009 #ifdef HAVE_ECORE_IMF
1010 const Ecore_IMF_Context_Info *ctx_info;
1013 if ((!object) || !(evas = evas_object_evas_get(object)))
1016 sd = calloc(1, sizeof(E_Entry_Smart_Data));
1019 evas_object_smart_data_set(object, sd);
1021 #ifdef HAVE_ECORE_IMF
1022 ctx_id = ecore_imf_context_default_id_get();
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);
1031 ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
1033 sd->imf_context = ecore_imf_context_add(ctx_id);
1035 sd->imf_context = NULL;
1039 sd->imf_context = NULL;
1041 if (sd->imf_context)
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,
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);
1063 sd->selection_dragging = 0;
1064 sd->selection_mode = 0;
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);
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);
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,
1099 _e_entry_smart_del(Evas_Object *object)
1101 E_Entry_Smart_Data *sd;
1103 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1106 #ifdef HAVE_ECORE_IMF
1107 if (sd->imf_context)
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);
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);
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);
1138 _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y)
1140 E_Entry_Smart_Data *sd;
1141 Evas_Coord prev_x, prev_y;
1144 if ((!object) || !(sd = evas_object_smart_data_get(object)))
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));
1153 _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h)
1155 E_Entry_Smart_Data *sd;
1158 if ((!object) || !(sd = evas_object_smart_data_get(object)))
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);
1167 _e_entry_smart_show(Evas_Object *object)
1169 E_Entry_Smart_Data *sd;
1171 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1173 evas_object_show(sd->entry_object);
1177 _e_entry_smart_hide(Evas_Object *object)
1179 E_Entry_Smart_Data *sd;
1181 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1183 evas_object_hide(sd->entry_object);
1187 _e_entry_color_set(Evas_Object *object, int r, int g, int b, int a)
1189 E_Entry_Smart_Data *sd;
1191 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1193 evas_object_color_set(sd->entry_object, r, g, b, a);
1197 _e_entry_clip_set(Evas_Object *object, Evas_Object *clip)
1199 E_Entry_Smart_Data *sd;
1201 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1203 evas_object_clip_set(sd->entry_object, clip);
1207 _e_entry_clip_unset(Evas_Object *object)
1209 E_Entry_Smart_Data *sd;
1211 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1213 evas_object_clip_unset(sd->entry_object);
1217 _e_entry_cb_menu_post(void *data, E_Menu *m __UNUSED__)
1219 E_Entry_Smart_Data *sd;
1222 if (!sd->popup) return;
1223 e_object_del(E_OBJECT(sd->popup));
1228 _e_entry_cb_cut(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
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;
1239 if (!sd->enabled) return;
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;
1249 range = e_editable_text_range_get(editable, start_pos, end_pos);
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);
1257 changed = e_editable_delete(editable, start_pos, end_pos);
1259 evas_object_smart_callback_call(sd->entry_object, "changed", NULL);
1263 _e_entry_cb_copy(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1265 E_Entry_Smart_Data *sd;
1266 Evas_Object *editable;
1267 int cursor_pos, selection_pos;
1268 int start_pos, end_pos;
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;
1283 range = e_editable_text_range_get(editable, start_pos, end_pos);
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);
1294 _e_entry_cb_paste(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1296 E_Entry_Smart_Data *sd;
1300 if (!sd->enabled) return;
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);
1308 _e_entry_cb_select_all(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1310 E_Entry_Smart_Data *sd;
1313 e_editable_select_all(sd->editable_object);
1314 _e_entry_x_selection_update(sd->entry_object);
1318 _e_entry_cb_delete(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1320 E_Entry_Smart_Data *sd;
1321 Evas_Object *editable;
1322 int cursor_pos, selection_pos;
1323 int start_pos, end_pos;
1328 if (!sd->enabled) return;
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;
1338 range = e_editable_text_range_get(editable, start_pos, end_pos);
1341 e_editable_delete(editable, start_pos, end_pos);
1342 evas_object_smart_callback_call(sd->entry_object, "changed", NULL);
1348 _e_entry_imf_context_reset(Evas_Object *object)
1350 E_Entry_Smart_Data *sd;
1352 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1355 #ifdef HAVE_ECORE_IMF
1356 if (sd->imf_context)
1357 ecore_imf_context_reset(sd->imf_context);
1362 _e_entry_imf_cursor_info_set(Evas_Object *object)
1364 E_Entry_Smart_Data *sd;
1365 Evas_Coord cx, cy, cw, ch;
1366 Evas_Object *editable;
1368 if ((!object) || !(sd = evas_object_smart_data_get(object)))
1371 #ifdef HAVE_ECORE_IMF
1372 if (!sd || !sd->imf_context) return;
1374 editable = sd->editable_object;
1376 e_editable_cursor_geometry_get(editable, &cx, &cy, &cw, &ch);
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);
1384 #ifdef HAVE_ECORE_IMF
1386 _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx __UNUSED__, char **text, int *cursor_pos)
1388 E_Entry_Smart_Data *sd;
1396 str = e_editable_text_get(sd->editable_object);
1397 *text = str ? strdup(str) : strdup("");
1401 *cursor_pos = e_editable_cursor_pos_get(sd->editable_object);
1407 _e_entry_cb_imf_event_commit(void *data, int type __UNUSED__, void *event)
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;
1418 if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
1419 return ECORE_CALLBACK_PASS_ON;
1421 if ((!sd->imf_context) || (sd->imf_context != ev->ctx))
1422 return ECORE_CALLBACK_PASS_ON;
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);
1432 changed |= e_editable_delete(editable, start_pos, end_pos);
1434 /* delete preedit characters */
1435 if (sd->have_preedit)
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;
1443 changed |= e_editable_insert(editable, start_pos, ev->str);
1445 _e_entry_imf_cursor_info_set(entry);
1448 evas_object_smart_callback_call(entry, "changed", NULL);
1450 return ECORE_CALLBACK_DONE;
1454 _e_entry_cb_imf_event_preedit_changed(void *data, int type __UNUSED__, void *event)
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;
1466 if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
1467 return ECORE_CALLBACK_PASS_ON;
1469 if ((!sd->imf_context) || (sd->imf_context != ev->ctx))
1470 return ECORE_CALLBACK_PASS_ON;
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;
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);
1484 changed |= e_editable_delete(editable, start_pos, end_pos);
1486 /* delete preedit characters */
1487 if (sd->have_preedit)
1489 if (sd->preedit_start_pos != sd->preedit_end_pos)
1490 e_editable_delete(editable, sd->preedit_start_pos, sd->preedit_end_pos);
1493 cursor_pos = e_editable_cursor_pos_get(editable);
1494 sd->preedit_start_pos = cursor_pos;
1496 /* insert preedit character(s) */
1497 changed |= e_editable_insert(editable, cursor_pos, preedit_string);
1499 sd->preedit_end_pos = e_editable_cursor_pos_get(editable);
1501 if (!strcmp(preedit_string, ""))
1502 sd->have_preedit = EINA_FALSE;
1504 sd->have_preedit = EINA_TRUE;
1506 _e_entry_imf_cursor_info_set(entry);
1509 evas_object_smart_callback_call(entry, "preedit,changed", NULL);
1511 free(preedit_string);
1513 return ECORE_CALLBACK_DONE;
1517 _e_entry_cb_imf_event_delete_surrounding(void *data, int type __UNUSED__, void *event)
1519 E_Entry_Smart_Data *sd;
1520 Ecore_IMF_Event_Delete_Surrounding *ev = event;
1521 Evas_Object *editable;
1526 if (sd->imf_context != ev->ctx)
1527 return ECORE_CALLBACK_PASS_ON;
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);
1535 return ECORE_CALLBACK_DONE;