#include <Elementary_Cursor.h>
#include "elm_priv.h"
#include "elm_widget_entry.h"
+#include "elm_module_priv.h"
#define MY_CLASS ELM_ENTRY_CLASS
void (*obj_hook)(Evas_Object *obj);
void (*obj_unhook)(Evas_Object *obj);
void (*obj_longpress)(Evas_Object *obj);
+ // TIZEN ONLY (20150205): Support CopyPasteUI
+ void (*obj_hidemenu) (Evas_Object *obj);
+ void (*obj_mouseup) (Evas_Object *obj);
+ void (*obj_update_popup_pos) (Evas_Object *obj);
+ Eina_Bool (*obj_popup_showing_get) (Evas_Object *obj);
+ //
};
-static void _create_selection_handlers(Evas_Object *obj, Elm_Entry_Data *sd);
+static void _create_selection_handlers(Evas_Object *obj, Elm_Entry_Data *sd);
+
+/////////////////////////////////////////////////////////////////
+// TIZEN ONLY : START
+// 20150129: Add more control when drop happens.
+// 20150129: Add drag feature.
+// 20150201: Add cursor handler.
+// 20150205: Add support for CopyPaste module.
+// 20150310: Hide cbhm when unfocus.
+// 20150807: Apply user stye in drag and drop
+// 20150811: Apply scale in drag and drop
+// 20150820: Adjust end of line cursor to prevent zero selection
+// 20150829: Keep selection over text only on long press and move
+// 20150909: Update cursor position on mouse up, not mouse down (with edje)
+// 20151012: Modify scale in drag and drop
+/////////////////////////////////////////////////////////////////
+
+static void _magnifier_create(void *data);
+static void _magnifier_show(void *data);
+static void _magnifier_hide(void *data);
+static void _magnifier_move(void *data, Evas_Coord x, Evas_Coord y);
+static void _menu_call(Evas_Object *obj);
+static void _hover_cancel_cb(void *data, Evas_Object *obj, void *event_info);
+static void _copy_cb(void *data, Evas_Object *obj, void *event_info);
+static void _cut_cb(void *data, Evas_Object *obj, void *event_info);
+static void _paste_cb(void *data, Evas_Object *obj, void *event_info);
+static Eina_Rectangle *_viewport_region_get(Evas_Object *obj);
+static Evas_Coord_Rectangle _layout_region_get(Evas_Object *obj);
+
+static inline Eina_Iterator *
+_selection_range_geometry_get(Evas_Object *obj)
+{
+ ELM_ENTRY_DATA_GET(obj, sd);
+
+ Eina_Iterator *range = NULL;
+ Evas_Coord start_pos, end_pos;
+ Evas_Textblock_Cursor *start_cur = NULL, *end_cur = NULL;
+ const Evas_Object *tb = NULL;
+
+ start_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje,
+ "elm.text", EDJE_CURSOR_SELECTION_BEGIN);
+ end_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje,
+ "elm.text", EDJE_CURSOR_SELECTION_END);
+ tb = edje_object_part_object_get(sd->entry_edje, "elm.text");
+ start_cur = evas_object_textblock_cursor_new(tb);
+ evas_textblock_cursor_pos_set(start_cur, start_pos);
+ end_cur = evas_object_textblock_cursor_new(tb);
+ evas_textblock_cursor_pos_set(end_cur, end_pos);
+
+ range = evas_textblock_cursor_range_simple_geometry_get(
+ start_cur, end_cur);
+
+ evas_textblock_cursor_free(start_cur);
+ evas_textblock_cursor_free(end_cur);
+
+ return range;
+}
+
+static Evas_Coord_Rectangle
+_selection_geometry_get(Evas_Object *obj)
+{
+ Evas_Coord_Rectangle rect;
+ Eina_Iterator *range = NULL;
+ Evas_Textblock_Rectangle *r = NULL;
+ Evas_Coord min_x = 0, min_y = 0, max_x = 0, max_y = 0;
+ Evas_Coord xo = 0, yo = 0;
+ int i = 0;
+
+ ELM_ENTRY_DATA_GET(obj, sd);
+ evas_object_geometry_get(edje_object_part_object_get
+ (sd->entry_edje, "elm.text"),
+ &xo, &yo, NULL, NULL);
+ range = _selection_range_geometry_get(obj);
+ EINA_ITERATOR_FOREACH(range, r)
+ {
+ if (i == 0)
+ {
+ min_x = r->x;
+ min_y = r->y;
+ }
+ if (r->x < min_x) min_x = r->x;
+ if (r->y < min_y) min_y = r->y;
+ if ((r->x + r->w) > max_x)
+ max_x = r->x + r->w;
+ if ((r->y + r->h) > max_y)
+ max_y = r->y + r->h;
+ i++;
+ }
+ eina_iterator_free(range);
+
+ rect.x = min_x + xo;
+ rect.y = min_y + yo;
+ rect.w = max_x - min_x;
+ rect.h = max_y - min_y;
+
+ return rect;
+}
+
+static Eina_Bool
+_hit_selection_check(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+ Eina_Iterator *range = NULL;
+ Evas_Textblock_Rectangle *r = NULL;
+ Eina_Bool hit = EINA_FALSE;
+ Evas_Coord xo = 0, yo = 0;
+
+ ELM_ENTRY_DATA_GET(obj, sd);
+ evas_object_geometry_get(edje_object_part_object_get
+ (sd->entry_edje, "elm.text"),
+ &xo, &yo, NULL, NULL);
+ x -= xo;
+ y -= yo;
+ range = _selection_range_geometry_get(obj);
+ EINA_ITERATOR_FOREACH(range, r)
+ {
+ if ((x >= r->x) && (x <= r->x + r->w) &&
+ (y >= r->y) && (y <= r->y + r->h))
+ {
+ hit = EINA_TRUE;
+ break;
+ }
+ }
+ eina_iterator_free(range);
+
+ return hit;
+}
+
+static Evas_Object *
+_entry_icon_create_cb(void *data, Evas_Object *parent, Evas_Coord *xoff, Evas_Coord *yoff)
+{
+ int xm, ym;
+ Evas_Object *icon;
+ int r, g, b, a;
+ const char *text;
+ Evas_Coord margin_w = 0, margin_h = 0;
+ Evas_Coord_Rectangle rect;
+ ELM_ENTRY_DATA_GET(data, sd);
+
+ icon = evas_object_textblock_add(evas_object_evas_get(parent));
+ text = edje_object_part_text_selection_get(sd->entry_edje, "elm.text");
+
+ evas_object_color_get(data, &r, &g, &b, &a);
+ evas_object_color_set(icon, r, g, b, a);
+
+ // Copy style
+ Evas_Textblock_Style *tb_style =
+ (Evas_Textblock_Style *)evas_object_textblock_style_get
+ (elm_entry_textblock_get(data));
+ evas_object_textblock_style_set(icon, tb_style);
+
+ Evas_Textblock_Style *tb_style_user =
+ (Evas_Textblock_Style *)evas_object_textblock_style_user_peek
+ (elm_entry_textblock_get(data));
+ if (tb_style_user)
+ {
+ const char *tb_style_text;
+ tb_style_text = evas_textblock_style_get(tb_style_user);
+ tb_style_user = evas_textblock_style_new();
+ evas_textblock_style_set(tb_style_user, tb_style_text);
+ evas_object_textblock_style_user_push(icon, tb_style_user);
+ evas_textblock_style_free(tb_style_user);
+ }
+
+ evas_object_scale_set(icon,
+ elm_config_scale_get()
+ * elm_object_scale_get(data)
+ / edje_object_base_scale_get(sd->entry_edje));
+
+ evas_object_textblock_size_formatted_get(icon, &margin_w, &margin_h);
+ evas_object_textblock_text_markup_set(icon, text);
+
+ rect = _selection_geometry_get(data);
+
+ evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_move(icon, rect.x, rect.y);
+ evas_object_resize(icon, rect.w + margin_w, rect.h + margin_h);
+ evas_object_show(icon);
+
+ evas_pointer_canvas_xy_get(evas_object_evas_get(data), &xm, &ym);
+ if (xoff) *xoff = xm - (rect.w / 2);
+ if (yoff) *yoff = ym - (rect.h / 2);
+
+ return icon;
+}
+
+static void
+_dnd_enter_cb(void *data,
+ Evas_Object *obj EINA_UNUSED)
+{
+ elm_object_focus_set(data, EINA_TRUE);
+}
+
+static void
+_dnd_leave_cb(void *data,
+ Evas_Object *obji EINA_UNUSED)
+{
+ if (_elm_config->desktop_entry)
+ elm_object_focus_set(data, EINA_FALSE);
+}
+
+static void
+_dnd_pos_cb(void *data, Evas_Object *obj EINA_UNUSED, Evas_Coord x, Evas_Coord y,
+ Elm_Xdnd_Action action EINA_UNUSED)
+{
+ elm_object_focus_set(data, EINA_TRUE);
+
+ ELM_ENTRY_DATA_GET(data, sd);
+
+ Evas_Coord ox, oy, ex, ey;
+ evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
+ evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+ x = x + ox - ex;
+ y = y + oy - ey;
+
+ edje_object_part_text_cursor_coord_set
+ (sd->entry_edje, "elm.text", EDJE_CURSOR_USER, x, y);
+ int pos = edje_object_part_text_cursor_pos_get
+ (sd->entry_edje, "elm.text", EDJE_CURSOR_USER);
+ elm_entry_cursor_pos_set(data, pos);
+}
+
+
+static Eina_Bool
+_cursor_handler_long_press_cb(void *data)
+{
+ ELM_ENTRY_DATA_GET(data, sd);
+
+ Evas_Coord ex, ey;
+ Evas_Coord cx, cy, cw, ch;
+
+ edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
+ &cx, &cy, &cw, &ch);
+ evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+ if (sd->has_text)
+ {
+ _magnifier_create(data);
+ _magnifier_show(data);
+ _magnifier_move(data, ex + cx, ey + cy);
+ }
+ sd->cursor_handler_longpress_timer = NULL;
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_cursor_handler_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ ELM_ENTRY_DATA_GET(data, sd);
+
+ Evas_Event_Mouse_Down *ev = event_info;
+ Evas_Coord ex, ey;
+ Evas_Coord cx, cy, cw, ch;
+
+ if ((sd->api) && (sd->api->obj_hidemenu))
+ sd->api->obj_hidemenu(data);
+ sd->cursor_handler_down = EINA_TRUE;
+ edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
+ &cx, &cy, &cw, &ch);
+ evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+ sd->ox = ev->canvas.x - (ex + cx + (cw / 2));
+ sd->oy = ev->canvas.y - (ey + cy + (ch / 2));
+ if (_elm_config->magnifier_enable)
+ {
+ sd->cursor_handler_down_pos = sd->cursor_pos;
+
+ ELM_SAFE_FREE(sd->cursor_handler_longpress_timer, ecore_timer_del);
+ sd->cursor_handler_longpress_timer = ecore_timer_add
+ (_elm_config->longpress_timeout, _cursor_handler_long_press_cb, data);
+
+ }
+}
+
+static void
+_cursor_handler_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ ELM_ENTRY_DATA_GET(data, sd);
+
+ if (!sd->cursor_handler_down) return;
+
+ ELM_SAFE_FREE(sd->cursor_handler_longpress_timer, ecore_timer_del);
+ sd->cursor_handler_down = EINA_FALSE;
+ if (_elm_config->magnifier_enable)
+ _magnifier_hide(data);
+ if (!_elm_config->desktop_entry)
+ _menu_call(data);
+}
+
+static void
+_cursor_handler_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ ELM_ENTRY_DATA_GET(data, sd);
+
+ Evas_Event_Mouse_Move *ev = event_info;
+ Evas_Coord ex, ey;
+ Evas_Coord cx, cy, cw, ch, chx, chy, chh;
+ Evas_Coord lh, th;
+ const Evas_Textblock *tb;
+ Evas_Textblock_Cursor *cur;
+ Evas_Coord_Rectangle layrect;
+ int pos = 0;
+
+ if (!sd->cursor_handler_down) return;
+ pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_MAIN);
+ tb = edje_object_part_object_get(sd->entry_edje, "elm.text");
+ evas_object_textblock_size_formatted_get(tb, NULL, &th);
+ cur = evas_object_textblock_cursor_new((Evas_Object *)tb);
+ evas_textblock_cursor_pos_set(cur, pos);
+ evas_textblock_cursor_line_geometry_get(cur, NULL, NULL, NULL, &lh);
+ evas_textblock_cursor_free(cur);
+
+ evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+ cx = ev->cur.canvas.x - sd->ox - ex;
+ cy = ev->cur.canvas.y - sd->oy - ey;
+ if (cx <= 0) cx = 1;
+ if (cy < (lh / 2)) cy = lh / 2;
+ if (cy >= th) cy = th - 1;
+
+ edje_object_part_text_cursor_coord_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_USER, cx, cy);
+ pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_USER);
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_MAIN, pos);
+
+ evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+ edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
+ &cx, &cy, &cw, &ch);
+ chx = ex + cx + (cw / 2);
+ chy = ey + cy + ch;
+ evas_object_move(sd->cursor_handler, chx, chy);
+ layrect = _layout_region_get(data);
+ edje_object_parts_extends_calc(sd->cursor_handler, NULL, NULL, NULL, &chh);
+ if (chy + chh > layrect.y + layrect.h)
+ {
+ evas_object_move(sd->cursor_handler, chx, chy - ch);
+ edje_object_signal_emit(sd->cursor_handler, "edje,cursor,handle,top", "edje");
+ }
+ else
+ {
+ edje_object_signal_emit(sd->cursor_handler, "edje,cursor,handle,show", "edje");
+ }
+ edje_object_message_signal_process(sd->cursor_handler);
+
+ if (_elm_config->magnifier_enable)
+ {
+ if (sd->has_text)
+ {
+ if (sd->cursor_handler_down_pos != sd->cursor_pos)
+ {
+ if (sd->cursor_handler_longpress_timer)
+ {
+ ELM_SAFE_FREE(sd->cursor_handler_longpress_timer, ecore_timer_del);
+ _magnifier_create(data);
+ _magnifier_show(data);
+ }
+ _magnifier_move(data, ex + cx, ey + cy);
+ }
+ }
+ }
+}
+
+static void
+_create_cursor_handler(Evas_Object *obj, Elm_Entry_Data *sd)
+{
+ if (sd->cursor_handler) return;
+ Evas_Object *handle;
+
+ handle = edje_object_add(evas_object_evas_get(obj));
+ sd->cursor_handler = handle;
+ _elm_theme_object_set(obj, handle, "entry", "cursor_handle", "default");
+ evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_DOWN,
+ _cursor_handler_mouse_down_cb, obj);
+ evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_MOVE,
+ _cursor_handler_mouse_move_cb, obj);
+ evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_UP,
+ _cursor_handler_mouse_up_cb, obj);
+ evas_object_layer_set(handle, EVAS_LAYER_MAX - 1);
+ edje_object_signal_emit(handle, "edje,cursor,handle,show", "edje"); // FOR 2.3 theme
+}
+
+static void
+_update_cursor_handler(Evas_Object *obj, Elm_Entry_Data *sd)
+{
+ Evas_Coord ex, ey;
+ Evas_Coord cx, cy, cw, ch, chx, chy, chh;
+ Evas_Coord_Rectangle layrect;
+ Eina_Rectangle *rect;
+
+ evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+ edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
+ &cx, &cy, &cw, &ch);
+ chx = ex + cx + (cw / 2);
+ chy = ey + cy + ch;
+ evas_object_move(sd->cursor_handler, chx, chy);
+ layrect = _layout_region_get(obj);
+ edje_object_parts_extends_calc(sd->cursor_handler, NULL, NULL, NULL, &chh);
+ if (chy + chh > layrect.y + layrect.h)
+ {
+ evas_object_move(sd->cursor_handler, chx, chy - ch);
+ edje_object_signal_emit(sd->cursor_handler, "edje,cursor,handle,top", "edje");
+ }
+ else
+ {
+ edje_object_signal_emit(sd->cursor_handler, "edje,cursor,handle,show", "edje");
+ }
+ edje_object_message_signal_process(sd->cursor_handler);
+
+ rect = _viewport_region_get(obj);
+ if (!eina_rectangle_xcoord_inside(rect, chx) ||
+ !eina_rectangle_ycoord_inside(rect, chy))
+ {
+ evas_object_hide(sd->cursor_handler);
+ }
+ else
+ {
+ evas_object_show(sd->cursor_handler);
+ }
+}
+
+static void
+_select_all(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ ELM_ENTRY_DATA_GET(data, sd);
+
+ sd->sel_mode = EINA_TRUE;
+
+ if (edje_object_part_text_selection_get(sd->entry_edje, "elm.text") == NULL)
+ {
+ edje_object_part_text_select_none(sd->entry_edje, "elm.text");
+ edje_object_signal_emit(sd->entry_edje, "elm,state,select,on", "elm");
+ edje_object_part_text_select_all(sd->entry_edje, "elm.text");
+ }
+ else
+ {
+ edje_object_part_text_cursor_begin_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN);
+ edje_object_part_text_cursor_begin_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_END);
+ edje_object_part_text_cursor_end_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_MAIN);
+ edje_object_part_text_select_extend(sd->entry_edje, "elm.text");
+ }
+ sd->have_selection = EINA_TRUE;
+ _menu_call(data);
+}
+
+static void
+_adjust_eol_cursor(Evas_Object *obj)
+{
+ const Evas_Object *tb = NULL;
+ Evas_Textblock_Cursor *c = NULL;
+ Eina_Bool eol;
+
+ ELM_ENTRY_DATA_GET(obj, sd);
+
+ tb = edje_object_part_object_get(sd->entry_edje, "elm.text");
+ c = evas_object_textblock_cursor_get(tb);
+ eol = evas_textblock_cursor_eol_get(c);
+ if (eol)
+ {
+ Evas_Textblock_Cursor *cp;
+ Evas_Coord ly, lpy;
+
+ cp = evas_object_textblock_cursor_new(tb);
+ evas_textblock_cursor_copy(c, cp);
+ evas_textblock_cursor_cluster_prev(cp);
+ evas_textblock_cursor_line_geometry_get(c, NULL, &ly, NULL, NULL);
+ evas_textblock_cursor_line_geometry_get(cp, NULL, &lpy, NULL, NULL);
+ if (ly != lpy)
+ evas_textblock_cursor_cluster_prev(c);
+ evas_textblock_cursor_free(cp);
+ }
+}
+
+static Eina_Bool
+_cursor_coordinate_check(Evas_Object *obj, Evas_Coord canvasx)
+{
+ const Evas_Textblock *tb = NULL;
+ const Evas_Textblock_Cursor *c = NULL;
+ Evas_Coord x, cx, clx = 0, clw = 0;
+
+ ELM_ENTRY_DATA_GET(obj, sd);
+
+ tb = edje_object_part_object_get(sd->entry_edje, "elm.text");
+ c = evas_object_textblock_cursor_get(tb);
+ evas_object_geometry_get(tb, &x, NULL, NULL, NULL);
+ evas_textblock_cursor_line_geometry_get(c, &clx, NULL, &clw, NULL);
+ cx = canvasx - x;
+
+ if ((cx < clx) || (cx > (clx + clw)))
+ {
+ return EINA_FALSE;
+ }
+ else
+ {
+ return EINA_TRUE;
+ }
+}
+
+static void
+_cursor_down_pos_set(Evas_Object *obj)
+{
+ Evas_Coord ex, ey, cx, cy;
+ ELM_ENTRY_DATA_GET(obj, sd);
+
+ evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+ cx = sd->downx - ex;
+ cy = sd->downy - ey;
+ edje_object_part_text_cursor_coord_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_MAIN, cx, cy);
+}
+
+static void
+_select_word(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ ELM_ENTRY_DATA_GET(data, sd);
+
+ const Evas_Object *tb = NULL;
+ Evas_Textblock_Cursor *cur = NULL;
+ int pos = 0;
+
+ sd->sel_mode = EINA_TRUE;
+
+ _adjust_eol_cursor(data);
+
+ if (!_elm_config->desktop_entry)
+ edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text",
+ EINA_TRUE);
+ edje_object_signal_emit(sd->entry_edje, "elm,state,select,on", "elm");
+
+ tb = edje_object_part_object_get(sd->entry_edje, "elm.text");
+ cur = evas_object_textblock_cursor_new(tb);
+ pos = edje_object_part_text_cursor_pos_get(sd->entry_edje,
+ "elm.text", EDJE_CURSOR_MAIN);
+ sd->cursor_move_pos = edje_object_part_text_cursor_pos_get
+ (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
+ evas_textblock_cursor_pos_set(cur, pos);
+ evas_textblock_cursor_word_start(cur);
+ pos = evas_textblock_cursor_pos_get(cur);
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_MAIN, pos);
+ edje_object_part_text_select_begin(sd->entry_edje, "elm.text");
+ evas_textblock_cursor_word_end(cur);
+ evas_textblock_cursor_char_next(cur);
+ pos = evas_textblock_cursor_pos_get(cur);
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_MAIN, pos);
+ edje_object_part_text_select_extend(sd->entry_edje, "elm.text");
+ evas_textblock_cursor_free(cur);
+
+ if (edje_object_part_text_selection_get(sd->entry_edje, "elm.text"))
+ sd->have_selection = EINA_TRUE;
+ if (!sd->long_pressed || event_info)
+ _menu_call(data);
+ if (!_elm_config->desktop_entry)
+ edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text",
+ EINA_FALSE);
+}
+
+static void
+_keep_selection(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ ELM_ENTRY_DATA_GET(obj, sd);
+
+ sd->start_sel_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje,
+ "elm.text", EDJE_CURSOR_SELECTION_BEGIN);
+ sd->end_sel_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje,
+ "elm.text", EDJE_CURSOR_SELECTION_END);
+}
+
+static void
+_paste_translation(void *data, Evas_Object *obj, void *event_info)
+{
+ ELM_ENTRY_DATA_GET(obj, sd);
+
+ elm_entry_cursor_pos_set(obj, sd->start_sel_pos);
+ elm_entry_cursor_selection_begin(obj);
+ elm_entry_cursor_pos_set(obj, sd->end_sel_pos);
+ elm_entry_cursor_selection_end(obj);
+ if (data)
+ _elm_entry_entry_paste(obj, data);
+ if ((data) && (event_info))
+ _elm_entry_entry_paste(obj, " ");
+ if (event_info)
+ _elm_entry_entry_paste(obj, event_info);
+}
+
+static void
+_is_selected_all(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ if ((!data) || (!obj)) return;
+ ELM_ENTRY_DATA_GET(obj, sd);
+ int pos = 0;
+ Eina_Bool *ret = (Eina_Bool *)data;
+
+ pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN);
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_USER, pos);
+ if (edje_object_part_text_cursor_prev(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_USER))
+ {
+ *ret = EINA_FALSE;
+ return;
+ }
+ else
+ {
+ pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_END);
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_USER, pos);
+ if (edje_object_part_text_cursor_next(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_USER))
+ {
+ *ret = EINA_FALSE;
+ return;
+ }
+ }
+ *ret = EINA_TRUE;
+}
+
+EAPI void elm_entry_extension_module_data_get(Evas_Object *obj, Elm_Entry_Extension_data *ext_mod)
+{
+ ELM_ENTRY_DATA_GET(obj, sd);
+
+ ext_mod->cancel = _hover_cancel_cb;
+ ext_mod->copy = _copy_cb;
+ ext_mod->cut = _cut_cb;
+ ext_mod->paste = _paste_cb;
+ ext_mod->select = _select_word;
+ ext_mod->selectall = _select_all;
+ ext_mod->ent = sd->entry_edje;
+ ext_mod->items = sd->items;
+ ext_mod->editable = sd->editable;
+ ext_mod->have_selection = sd->have_selection;
+ ext_mod->password = sd->password;
+ ext_mod->selmode = sd->sel_mode;
+ ext_mod->context_menu = sd->context_menu;
+ ext_mod->cnp_mode = sd->cnp_mode;
+ ext_mod->_elm_config = _elm_config;
+ ext_mod->viewport_rect = _viewport_region_get(obj);
+ ext_mod->selection_rect = _selection_geometry_get(obj);
+ ext_mod->keep_selection = _keep_selection;
+ ext_mod->paste_translation = _paste_translation;
+ ext_mod->is_selected_all = _is_selected_all;
+ ext_mod->start_handler = sd->start_handler;
+ ext_mod->end_handler = sd->end_handler;
+ ext_mod->cursor_handler = sd->cursor_handler;
+ ext_mod->cursor_handler_shown = sd->cursor_handler_shown;
+ ext_mod->ent_scroll = sd->scroll;
+}
+/////////////////////////////////////////////////////////////////
+// TIZEN ONLY : END
+/////////////////////////////////////////////////////////////////
+
static Mod_Api *
_module_find(Evas_Object *obj EINA_UNUSED)
_elm_module_symbol_get(m, "obj_unhook");
((Mod_Api *)(m->api))->obj_longpress = // called on long press menu
_elm_module_symbol_get(m, "obj_longpress");
+ // TIZEN ONLY (20150205): Support CopyPasteUI
+ ((Mod_Api *)(m->api))->obj_hidemenu = // called on hide menu
+ _elm_module_symbol_get(m, "obj_hidemenu");
+ ((Mod_Api *)(m->api))->obj_mouseup = // called on mouseup
+ _elm_module_symbol_get(m, "obj_mouseup");
+ ((Mod_Api *)(m->api))->obj_update_popup_pos = //in update selection handler
+ _elm_module_symbol_get(m, "obj_update_popup_pos");
+ ((Mod_Api *)(m->api))->obj_popup_showing_get = // check cnp popup showing status
+ _elm_module_symbol_get(m, "obj_popup_showing_get");
+ //
+
ok: // ok - return api
return m->api;
}
if (sd->start_handler_shown)
{
- edje_object_signal_emit(sd->start_handler, "elm,handler,hide", "elm");
+ // TIZEN ONLY (20150901): Support tizen 2.4 CNPUI
+ /*edje_object_signal_emit(sd->start_handler, "elm,handler,hide", "elm");*/
+ evas_object_hide(sd->start_handler);
+ //
sd->start_handler_shown = EINA_FALSE;
}
if (sd->end_handler_shown)
{
- edje_object_signal_emit(sd->end_handler, "elm,handler,hide", "elm");
+ // TIZEN ONLY (20150901): Support tizen 2.4 CNPUI
+ /*edje_object_signal_emit(sd->end_handler, "elm,handler,hide", "elm");*/
+ evas_object_hide(sd->end_handler);
+ //
sd->end_handler_shown = EINA_FALSE;
}
}
return rect;
}
+// TIZEN ONLY (20150723): Show sel handler on top
+static Evas_Coord_Rectangle
+_layout_region_get(Evas_Object *obj)
+{
+ Evas_Coord_Rectangle r;
+ Evas_Object *child = NULL, *parent = NULL;
+
+ r.x = r.y = r.w = r.h = -1;
+ if (!obj || !elm_widget_type_get(obj)) return r;
+
+ child = obj;
+ parent = elm_widget_parent_get(obj);
+ while (parent)
+ {
+ const char *wt = elm_widget_type_get(parent);
+ if (wt && !strcmp(wt, "Elm_Conformant"))
+ {
+ evas_object_geometry_get(child, &r.x, &r.y, &r.w, &r.h);
+ return r;
+ }
+ child = parent;
+ parent = elm_widget_parent_get(parent);
+ }
+ return r;
+}
+//
+
static void
_update_selection_handler(Evas_Object *obj)
{
ELM_ENTRY_DATA_GET(obj, sd);
- Evas_Coord sx, sy, sh;
+ Evas_Coord sx, sy, sw, sh;
Evas_Coord ent_x, ent_y;
- Evas_Coord ex, ey, eh;
+ Evas_Coord ex, ey, ew, eh;
int start_pos, end_pos, last_pos;
- if (!sd->sel_handler_disabled)
- {
+ // TIZEN ONLY (20150603): CopyPasteUI Tizen 2.4
+ //if ((!sd->sel_handler_disabled))
+ if ((!sd->sel_handler_disabled) && ((!evas_object_visible_get(sd->mgf_bg)) ||
+ (sd->start_handler_down || sd->end_handler_down)))
+ {//
Eina_Rectangle *rect;
- Evas_Coord hx, hy;
+ Evas_Coord_Rectangle layrect;
+ Evas_Coord hx, hy, hh;
Eina_Bool hidden = EINA_FALSE;
if (!sd->start_handler)
_create_selection_handlers(obj, sd);
rect = _viewport_region_get(obj);
+ // TIZEN ONLY (20150723): Show sel handler on top
+ layrect = _layout_region_get(obj);
+ edje_object_parts_extends_calc(sd->start_handler, NULL, NULL, NULL, &hh);
+ //
start_pos = edje_object_part_text_cursor_pos_get
(sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_BEGIN);
end_pos = edje_object_part_text_cursor_pos_get
edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
EDJE_CURSOR_MAIN, start_pos);
edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
- &sx, &sy, NULL, &sh);
+ &sx, &sy, &sw, &sh);
edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
EDJE_CURSOR_MAIN, end_pos);
edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
- &ex, &ey, NULL, &eh);
+ &ex, &ey, &ew, &eh);
edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
EDJE_CURSOR_MAIN, last_pos);
if (start_pos < end_pos)
hy = ent_y + ey + eh;
evas_object_move(sd->start_handler, hx, hy);
}
+ // TIZEN ONLY (20150901): Show start sel handler on top by default
+ if (ent_y + sy - hh < layrect.y)
+ {
+ hy--;
+ edje_object_signal_emit(sd->start_handler, "elm,state,bottom", "elm");
+ }
+ else
+ {
+ edje_object_signal_emit(sd->start_handler, "elm,state,top", "elm");
+ hy = hy - sh;
+ evas_object_move(sd->start_handler, hx, hy);
+ }
+ edje_object_message_signal_process(sd->start_handler);
+ //
+
if (!eina_rectangle_xcoord_inside(rect, hx) ||
!eina_rectangle_ycoord_inside(rect, hy))
{
}
if (!sd->start_handler_shown && !hidden)
{
- edje_object_signal_emit(sd->start_handler,
- "elm,handler,show", "elm");
+ // TIZEN ONLY (20140204): Support tizen 2.4 CNPUI
+ /*edje_object_signal_emit(sd->start_handler,
+ "elm,handler,show", "elm");*/
+ evas_object_show(sd->start_handler);
+ //
sd->start_handler_shown = EINA_TRUE;
}
else if (sd->start_handler_shown && hidden)
{
- edje_object_signal_emit(sd->start_handler,
- "elm,handler,hide", "elm");
+ // TIZEN ONLY (20140204): Support tizen 2.4 CNPUI
+ /*edje_object_signal_emit(sd->start_handler,
+ "elm,handler,hide", "elm");*/
+ evas_object_hide(sd->start_handler);
+ //
sd->start_handler_shown = EINA_FALSE;
}
hy = ent_y + sy + sh;
evas_object_move(sd->end_handler, hx, hy);
}
+ // TIZEN ONLY (20150723): Show sel handler on top
+ if (hy + hh > layrect.y + layrect.h)
+ {
+ edje_object_signal_emit(sd->end_handler, "elm,state,top", "elm");
+ hy = hy - sh;
+ evas_object_move(sd->end_handler, hx, hy);
+ }
+ else
+ {
+ hy--;
+ edje_object_signal_emit(sd->end_handler, "elm,state,bottom", "elm");
+ }
+ edje_object_message_signal_process(sd->end_handler);
+ //
+
if (!eina_rectangle_xcoord_inside(rect, hx) ||
!eina_rectangle_ycoord_inside(rect, hy))
{
}
if (!sd->end_handler_shown && !hidden)
{
- edje_object_signal_emit(sd->end_handler,
- "elm,handler,show", "elm");
+ // TIZEN ONLY (20140204): Support tizen 2.4 CNPUI
+ /*edje_object_signal_emit(sd->end_handler,
+ "elm,handler,show", "elm");*/
+ evas_object_show(sd->end_handler);
+ //
sd->end_handler_shown = EINA_TRUE;
}
else if (sd->end_handler_shown && hidden)
{
- edje_object_signal_emit(sd->end_handler,
- "elm,handler,hide", "elm");
+ // TIZEN ONLY (20140204): Support tizen 2.4 CNPUI
+ /*edje_object_signal_emit(sd->end_handler,
+ "elm,handler,hide", "elm");*/
+ evas_object_hide(sd->end_handler);
+ //
sd->end_handler_shown = EINA_FALSE;
}
eina_rectangle_free(rect);
{
if (sd->start_handler_shown)
{
- edje_object_signal_emit(sd->start_handler,
- "elm,handler,hide", "elm");
+ // TIZEN ONLY (20150901): Support tizen 2.4 CNPUI
+ /*edje_object_signal_emit(sd->start_handler,
+ "elm,handler,hide", "elm");*/
+ evas_object_hide(sd->start_handler);
+ //
sd->start_handler_shown = EINA_FALSE;
}
if (sd->end_handler_shown)
{
- edje_object_signal_emit(sd->end_handler,
- "elm,handler,hide", "elm");
+ // TIZEN ONLY (20140204): Support tizen 2.4 CNPUI
+ /*edje_object_signal_emit(sd->end_handler,
+ "elm,handler,hide", "elm");*/
+ evas_object_hide(sd->end_handler);
+ //
sd->end_handler_shown = EINA_FALSE;
}
}
+ // TIZEN ONLY (20150201): Add cursor handler
+ if (sd->cursor_handler_shown)
+ {
+ evas_object_hide(sd->cursor_handler);
+ sd->cursor_handler_shown = EINA_FALSE;
+ }
+ //
+ // TIZEN ONLY (20150522): update cnp popup position
+ if ((sd->api) && (sd->api->obj_update_popup_pos) &&
+ (!sd->start_handler_down) && (!sd->end_handler_down) &&
+ (!sd->cursor_handler_down))
+ {
+ sd->api->obj_update_popup_pos(obj);
+ }
+ //
}
static const char *
EOLIAN static Eina_Bool
_elm_entry_elm_widget_disable(Eo *obj, Elm_Entry_Data *sd)
{
- elm_drop_target_del(obj, sd->drop_format,
+ /////////////////////////////////////////////////////////////////
+ // TIZEN ONLY (20150129) Add more control when drop happens.
+ /*elm_drop_target_del(obj, sd->drop_format,
NULL, NULL,
NULL, NULL,
NULL, NULL,
+ _drag_drop_cb, NULL);*/
+ elm_drop_target_del(obj, sd->drop_format,
+ _dnd_enter_cb, obj,
+ _dnd_leave_cb, obj,
+ _dnd_pos_cb, obj,
_drag_drop_cb, NULL);
+ /////////////////////////////////////////////////////////////////
if (elm_object_disabled_get(obj))
{
edje_object_signal_emit(sd->entry_edje, "elm,state,disabled", "elm");
}
sd->disabled = EINA_FALSE;
sd->drop_format = _get_drop_format(obj);
- elm_drop_target_add(obj, sd->drop_format,
+ /////////////////////////////////////////////////////////////////
+ // TIZEN ONLY (20150129) Add more control when drop happens.
+ /*elm_drop_target_add(obj, sd->drop_format,
NULL, NULL,
NULL, NULL,
NULL, NULL,
+ _drag_drop_cb, NULL);*/
+ elm_drop_target_add(obj, sd->drop_format,
+ _dnd_enter_cb, obj,
+ _dnd_leave_cb, obj,
+ _dnd_pos_cb, obj,
_drag_drop_cb, NULL);
+ /////////////////////////////////////////////////////////////////
}
return EINA_TRUE;
eo_do(obj, eo_event_callback_call(ELM_WIDGET_EVENT_UNFOCUSED, NULL));
if (_elm_config->atspi_mode)
elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
-
+ // TIZEN ONLY (20150201): Add cursor handler
+ if (sd->cursor_handler_shown)
+ {
+ evas_object_hide(sd->cursor_handler);
+ sd->cursor_handler_shown = EINA_FALSE;
+ }
+ //
if (_elm_config->selection_clear_enable)
{
if ((sd->have_selection) && (!sd->hoversel))
{
ELM_ENTRY_DATA_GET(data, sd);
- if (_elm_config->magnifier_enable)
+ // TIZEN ONLY: START ////////////////////////////////////////////
+ if (!elm_widget_focus_get(data))
{
- _magnifier_create(data);
- _magnifier_show(data);
- _magnifier_move(data, sd->downx, sd->downy);
+ sd->longpress_timer = NULL;
+ return ECORE_CALLBACK_CANCEL;
}
- else if (!_elm_config->desktop_entry)
- _menu_call(data);
+ // 20150229: Add drag feature.
+ Eina_Bool hit_selection = EINA_FALSE;
sd->long_pressed = EINA_TRUE;
+ sd->long_pressing = EINA_TRUE;
+ if (sd->cursor_handler_shown)
+ {
+ evas_object_hide(sd->cursor_handler);
+ sd->cursor_handler_shown = EINA_FALSE;
+ }
+ hit_selection = _hit_selection_check(data, sd->downx, sd->downy);
+
+ if (!hit_selection)
+ {
+ sd->drag_started = EINA_FALSE;
+ }
+ else if (!sd->password)
+ {
+ const char *sel =
+ edje_object_part_text_selection_get(sd->entry_edje, "elm.text");
+
+ if ((sel) && (sel[0]))
+ {
+ sd->drag_started = EINA_TRUE;
+ elm_drag_start(data, ELM_SEL_FORMAT_TEXT,
+ sel,
+ ELM_XDND_ACTION_COPY,
+ _entry_icon_create_cb, data,
+ NULL, /*Elm_Drag_Pos dragpos*/
+ NULL, /*void *dragdata*/
+ NULL, /*Elm_Drag_Accept acceptcb*/
+ NULL, /*void *acceptdata*/
+ NULL, /*Elm_Drag_Done dragdone*/
+ NULL); /*void *donecbdata*/
+ _hover_cancel_cb(data, NULL, NULL);
+ elm_widget_scroll_freeze_push(data);
+ }
+ }
+ if (!sd->drag_started) //TIZEN ONLY : END
+ {
+ if (_elm_config->magnifier_enable)
+ {
+ // TIZEN ONLY (20150205): CopyPasteUI 2.4
+ if ((sd->api) && (sd->api->obj_hidemenu))
+ sd->api->obj_hidemenu(data);
+ //
+
+ // TIZEN ONLY (20150603): CopyPasteUI 2.4
+ if (sd->has_text)
+ {
+ // TIZEN_ONLY (20150829): Keep selection over text only
+ if (_cursor_coordinate_check(data, sd->downx))
+ {
+ _cursor_down_pos_set(data);
+ _magnifier_create(data);
+ _magnifier_show(data);
+ //_magnifier_move(data, sd->downx, sd->downy);
+ Evas_Coord cx, cy, cw, ch;
+ Evas_Coord ex, ey;
+ evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+ edje_object_part_text_cursor_geometry_get(sd->entry_edje,
+ "elm.text", &cx, &cy, &cw, &ch);
+ _magnifier_move(data, ex + cx, ey + cy);
+ // do select word
+ _select_word(data, NULL, NULL);
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_MAIN, sd->cursor_move_pos);
+ //
+ }
+ //
+ }
+ //
+ }
+ //TIZEN_ONLY (20150806): Enable word selection when magnifier is disabled
+ else if (sd->has_text)
+ {
+ if ((sd->api) && (sd->api->obj_hidemenu))
+ sd->api->obj_hidemenu(data);
+ _cursor_down_pos_set(data);
+ if (_cursor_coordinate_check(data, sd->downx))
+ {
+ _select_word(data, NULL, NULL);
+ elm_widget_scroll_freeze_push(data);
+ }
+ if (!_elm_config->desktop_entry)
+ {
+ _menu_call(data);
+ }
+ }
+ //
+ else if (!_elm_config->desktop_entry)
+ _menu_call(data);
+ }
+
+ //sd->long_pressed = EINA_TRUE;
sd->longpress_timer = NULL;
eo_do(data, eo_event_callback_call
{
Evas_Event_Key_Down *ev = event_info;
+ // TIZEN ONLY (20150205): Support CopyPasteUI
+ ELM_ENTRY_DATA_GET(data, sd);
+ if ((sd->api) && (sd->api->obj_hidemenu) && (!sd->sel_mode))
+ sd->api->obj_hidemenu(data);
+ //
if (!strcmp(ev->key, "Menu"))
_menu_call(data);
}
if (ev->button == 1)
{
ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
- if ((sd->long_pressed) && (_elm_config->magnifier_enable))
+ // TIZEN ONLY (20150717): For selection clear on mouse up
+ sd->long_pressing = EINA_FALSE;
+ if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK) return;
+ if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) return;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+ if (!_elm_config->desktop_entry && sd->have_selection && !sd->long_pressed)
+ elm_entry_select_none(data);
+ //
+ //TIZEN_ONLY (20150806): Enable word selection when magnifier is disabled
+ //if ((sd->long_pressed) && (_elm_config->magnifier_enable))
+ // {
+ // _magnifier_hide(data);
+ if (sd->long_pressed)
{
- _magnifier_hide(data);
- _menu_call(data);
+ if (_elm_config->magnifier_enable)
+ _magnifier_hide(data);
+ //
+ // TIZEN ONLY (20150603): CopyPasteUI 2.4
+ Eina_Bool popup_showing = EINA_FALSE;
+ if (elm_widget_scroll_freeze_get(data))
+ elm_widget_scroll_freeze_pop(data);
+ if (sd->have_selection)
+ {
+ if (elm_widget_focus_get(data))
+ _update_selection_handler(data);
+ else
+ elm_entry_select_none(data);
+ }
+ if ((sd->api) && (sd->api->obj_popup_showing_get))
+ popup_showing = sd->api->obj_popup_showing_get(data);
+ if (!popup_showing)
+ {
+ _menu_call(data);
+ }
+ //
}
else
{
!edje_object_part_text_imf_context_get(sd->entry_edje, "elm.text"))
elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON);
}
+ // TIZEN ONY (20150603): CopyPaste 2.4
+ if (sd->editable && elm_widget_focus_get(data) &&
+ (!sd->have_selection) && (sd->has_text))
+ {
+ Evas_Coord dx, dy;
+
+ dx = sd->downx - ev->canvas.x;
+ dx *= dx;
+ dy = sd->downy - ev->canvas.y;
+ dy *= dy;
+ if ((dx + dy) <=
+ ((_elm_config->finger_size / 2) *
+ (_elm_config->finger_size / 2)))
+ {
+ _create_cursor_handler(data, sd);
+ _update_cursor_handler(data, sd);
+ evas_object_show(sd->cursor_handler);
+ sd->cursor_handler_shown = EINA_TRUE;
+ }
+ else if (sd->cursor_handler_shown)
+ {
+ evas_object_hide(sd->cursor_handler);
+ sd->cursor_handler_shown = EINA_FALSE;
+ }
+ }
+ //
+ }
+ // TIZEN ONLY (20150729): Freeze scrolling on draging
+ if (sd->drag_started)
+ {
+ elm_widget_scroll_freeze_pop(data);
+ sd->drag_started = EINA_FALSE;
}
+ //
}
else if ((ev->button == 3) && (!_elm_config->desktop_entry))
{
if (sd->disabled) return;
if (ev->buttons == 1)
{
- if ((sd->long_pressed) && (_elm_config->magnifier_enable))
+ // TIZEN ONLY: START ///////////////////////////////////////
+ // 20150129: Add drag feature.
+ /*if ((sd->long_pressed) && (_elm_config->magnifier_enable))*/
+ if ((sd->long_pressed) && (!sd->drag_started))
+ // TIZEN ONLY: END /////////////////////////////////////////
{
Evas_Coord x, y;
Eina_Bool rv;
evas_object_geometry_get(sd->entry_edje, &x, &y, NULL, NULL);
+ // TIZEN ONLY (20150716): for easy movement in single line
+ Evas_Coord cury;
+ const Evas_Object *tb = NULL;
+ Evas_Textblock_Cursor *tc;
+ Evas_Coord fy = 0, fh = 0, ly = 0, lh = 0;
+
+ tb = edje_object_part_object_get(sd->entry_edje, "elm.text");
+ tc = evas_object_textblock_cursor_new(tb);
+ evas_textblock_cursor_paragraph_first(tc);
+ evas_textblock_cursor_line_geometry_get(tc, NULL, &fy, NULL, &fh);
+ evas_textblock_cursor_paragraph_last(tc);
+ evas_textblock_cursor_line_geometry_get(tc, NULL, &ly, NULL, &lh);
+ evas_textblock_cursor_free(tc);
+ cury = ev->cur.canvas.y - y;
+ if (cury < fy + fh / 2) cury = fy + fh / 2;
+ if (cury > ly + lh) cury = ly + lh - 1;
rv = edje_object_part_text_cursor_coord_set
(sd->entry_edje, "elm.text", EDJE_CURSOR_USER,
- ev->cur.canvas.x - x, ev->cur.canvas.y - y);
+ ev->cur.canvas.x - x, cury);
+ /*rv = edje_object_part_text_cursor_coord_set
+ (sd->entry_edje, "elm.text", EDJE_CURSOR_USER,
+ ev->cur.canvas.x - x, ev->cur.canvas.y - y);*/
+ //
+
if (rv)
{
edje_object_part_text_cursor_copy
}
else
WRN("Warning: Cannot move cursor");
-
- _magnifier_move(data, ev->cur.canvas.x, ev->cur.canvas.y);
+ // TIZEN_ONLY (20150829): Keep selection over text only
+ if (_cursor_coordinate_check(data, ev->cur.canvas.x))
+ {
+ // TIZEN ONLY (20150603): Support CopyPasteUI
+ if ((sd->has_text) && (_elm_config->magnifier_enable))
+ {
+ //_magnifier_move(data, ev->cur.canvas.x, ev->cur.canvas.y);
+ Evas_Coord cx, cy, cw, ch;
+ edje_object_part_text_cursor_geometry_get(sd->entry_edje,
+ "elm.text", &cx, &cy, &cw, &ch);
+ _magnifier_move(data, x + cx, y + cy);
+ }
+ //do select word
+ int cur_pos = edje_object_part_text_cursor_pos_get
+ (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
+ if (cur_pos != sd->cursor_move_pos)
+ _select_word(data, NULL, NULL);
+ //
+ }
+ //
}
}
if (!sd->sel_mode)
ELM_ENTRY_DATA_GET(data, sd);
+ // TIZEN ONLY(20150815): feature: remove mgf, popup, handlers if entry changed
+ if (sd->cursor_handler_down || sd->start_handler_down ||
+ sd->end_handler_down || sd->long_pressed)
+ {
+ if (sd->cursor_handler_down)
+ sd->cursor_handler_down = EINA_FALSE;
+ else if (sd->start_handler_down)
+ sd->start_handler_down = EINA_FALSE;
+ else if (sd->end_handler_down)
+ sd->end_handler_down = EINA_FALSE;
+ else if (sd->long_pressed)
+ sd->long_pressed = EINA_FALSE;
+ if (_elm_config->magnifier_enable)
+ {
+ if (sd->has_text)
+ _magnifier_hide(data);
+ }
+ }
+ else if (sd->longpress_timer)
+ {
+ ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+ // TIZEN_ONLY(20150924): Renew longpress timer when entry is changed.
+ sd->longpress_timer = ecore_timer_add
+ (_elm_config->longpress_timeout, _long_press_cb, data);
+ //
+ }
+ //
evas_event_freeze(evas_object_evas_get(data));
sd->changed = EINA_TRUE;
/* Reset the size hints which are no more relevant. Keep the
else
_elm_entry_guide_update(data, EINA_FALSE);
}
+
+ // TIZEN ONLY (20150205): Support CopyPasteUI
+ if ((sd->api) && (sd->api->obj_hidemenu))
+ sd->api->obj_hidemenu(data);
+ //
+ // TIZEN ONLY (20150201): Add cursor handler
+ if (sd->cursor_handler_shown)
+ {
+ evas_object_hide(sd->cursor_handler);
+ sd->cursor_handler_shown = EINA_FALSE;
+ }
+ //
_validate(data);
/* callback - this could call callbacks that delete the
const char *source EINA_UNUSED)
{
elm_entry_select_none(data);
+
+ // TIZEN ONLY (20150205): Support CopyPasteUI
+ ELM_ENTRY_DATA_GET(data, sd);
+ if ((sd->api) && (sd->api->obj_hidemenu))
+ sd->api->obj_hidemenu(data);
+ //
}
static void
if (!sd->have_selection) return;
+ // TIZEN ONLY (20150205): Support CopyPasteUI
+ if (!sd->long_pressing)
+ {
+ if ((sd->api) && (sd->api->obj_hidemenu))
+ sd->api->obj_hidemenu(data);
+ }
+ //
sd->have_selection = EINA_FALSE;
eo_do(data, eo_event_callback_call
(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTION_CLEARED, NULL));
ELM_SAFE_FREE(sd->cut_sel, eina_stringshare_del);
}
- else
+ // TIZEN ONLY: START ///////////////////////////////////////
+ // 20150129: Add drag feature.
+ /*else*/
+ else if (!sd->drag_started)
+ // TIZEN ONLY: END /////////////////////////////////////////
{
elm_object_cnp_selection_clear(data, ELM_SEL_TYPE_PRIMARY);
}
(ELM_ENTRY_EVENT_CURSOR_CHANGED_MANUAL, NULL));
if (_elm_config->atspi_mode)
eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL));
+ // TIZEN ONLY (20150715): update cursor handler when cursor pos changes
+ ELM_ENTRY_DATA_GET(data, sd);
+ if (sd->cursor_handler_shown)
+ {
+ _update_cursor_handler(data, sd);
+ }
+ //
}
static void
const char *emission EINA_UNUSED,
const char *source EINA_UNUSED)
{
+ // TIZEN ONLY (20140205): Support CopyPaste UI
+ ELM_ENTRY_DATA_GET(data, sd);
+ if (sd->disabled) return; //???
+
+ if (!_elm_config->desktop_entry)
+ {
+ _cursor_down_pos_set(data);
+ _select_word(data, NULL, NULL);
+ }
+ //
eo_do(data, eo_event_callback_call
(EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED_DOUBLE, NULL));
}
Evas_Coord cx, cy, cw, ch;
int start_pos, end_pos, main_pos, pos;
+ // TIZEN ONLY (20150205): Support CopyPasteUI
+ if ((sd->api) && (sd->api->obj_hidemenu))
+ sd->api->obj_hidemenu(data);
+ if (!_elm_config->desktop_entry)
+ edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text",
+ EINA_TRUE);
+ //
sd->start_handler_down = EINA_TRUE;
start_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
EDJE_CURSOR_SELECTION_BEGIN);
ELM_ENTRY_DATA_GET(data, sd);
sd->start_handler_down = EINA_FALSE;
+
+ // TIZEN ONLY(20150815): feature: remove mgf, popup, handlers if entry changed
+ int start_pos, end_pos;
+ Eina_Bool hidden = EINA_FALSE;
+
+ start_pos = edje_object_part_text_cursor_pos_get
+ (sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_BEGIN);
+ end_pos = edje_object_part_text_cursor_pos_get
+ (sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_END);
+ if (start_pos < end_pos)
+ {
+ if (!sd->start_handler_shown)
+ hidden = EINA_TRUE;
+ }
+ else
+ {
+ if (!sd->end_handler_shown)
+ hidden = EINA_TRUE;
+ }
+
+ if (hidden)
+ {
+ if (!_elm_config->desktop_entry)
+ edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text",
+ EINA_FALSE);
+ return;
+ }
+ //
+ // TIZEN ONLY (20150720): Keep at least one character in selection
+ int pos1 = 0, pos2 = 0;
+ pos1 = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN);
+ pos2 = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_END);
+ if (pos1 > pos2)
+ {
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN, pos2);
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_END, pos1);
+ }
+ //
if (_elm_config->magnifier_enable)
_magnifier_hide(data);
- if ((!_elm_config->desktop_entry) && (sd->long_pressed))
+ // TIZEN ONLY (20150205): Support CopyPaste UI
+ /*if ((!_elm_config->desktop_entry) && (sd->long_pressed))
+ _menu_call(data);*/
+ if (!_elm_config->desktop_entry)
_menu_call(data);
+ if (!_elm_config->desktop_entry)
+ edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text",
+ EINA_FALSE);
+ //
}
static void
Evas_Coord cx, cy, ch;
int pos;
+ // TIZEN ONLY(20150815): feature: remove mgf, popup, handlers if entry changed
+ if (!sd->start_handler_shown)
+ {
+ ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+ sd->long_pressed = EINA_FALSE;
+ return;
+ }
+ //
+
evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
cx = ev->cur.canvas.x - sd->ox - ex;
cy = ev->cur.canvas.y - sd->oy - ey;
if (cx <= 0) cx = 1;
+ // TIZEN ONLY (20150715): for easy movement in single line
+ const Evas_Object *tb = NULL;
+ Evas_Textblock_Cursor *tc;
+ Evas_Coord fy = 0, fh = 0, ly = 0, lh = 0;
+
+ tb = edje_object_part_object_get(sd->entry_edje, "elm.text");
+ tc = evas_object_textblock_cursor_new(tb);
+ evas_textblock_cursor_paragraph_first(tc);
+ evas_textblock_cursor_line_geometry_get(tc, NULL, &fy, NULL, &fh);
+ evas_textblock_cursor_paragraph_last(tc);
+ evas_textblock_cursor_line_geometry_get(tc, NULL, &ly, NULL, &lh);
+ evas_textblock_cursor_free(tc);
+ if (cy < fy + fh / 2) cy = fy + fh / 2;
+ else if (cy > ly + lh) cy = ly + lh - 1;
+ //
+
edje_object_part_text_cursor_coord_set(sd->entry_edje, "elm.text",
sd->sel_handler_cursor, cx, cy);
pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
sd->sel_handler_cursor);
+ // TIZEN ONLY (20150720): Keep at least one character in selection
+ int pos1 = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_END);
+ if (pos == pos1)
+ {
+ pos++;
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN, pos);
+ pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN);
+ if (pos == pos1)
+ {
+ pos--;
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN, pos);
+ }
+ }
+ //
edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
EDJE_CURSOR_MAIN, pos);
edje_object_part_text_cursor_geometry_get(sd->entry_edje,
Evas_Coord cx, cy, cw, ch;
int pos, start_pos, end_pos, main_pos;
+ // TIZEN ONLY (20150205): Support CopyPasteUI
+ if ((sd->api) && (sd->api->obj_hidemenu))
+ sd->api->obj_hidemenu(data);
+ if (!_elm_config->desktop_entry)
+ edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text",
+ EINA_TRUE);
+ //
sd->end_handler_down = EINA_TRUE;
start_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
EDJE_CURSOR_SELECTION_BEGIN);
ELM_ENTRY_DATA_GET(data, sd);
sd->end_handler_down = EINA_FALSE;
+ // TIZEN ONLY(20150815): feature: remove mgf, popup, handlers if entry changed
+ int start_pos, end_pos;
+ Eina_Bool hidden = EINA_FALSE;
+
+ start_pos = edje_object_part_text_cursor_pos_get
+ (sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_BEGIN);
+ end_pos = edje_object_part_text_cursor_pos_get
+ (sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_END);
+ if (start_pos < end_pos)
+ {
+ if (!sd->end_handler_shown)
+ hidden = EINA_TRUE;
+ }
+ else
+ {
+ if (!sd->start_handler_shown)
+ hidden = EINA_TRUE;
+ }
+
+ if (hidden)
+ {
+ if (!_elm_config->desktop_entry)
+ edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text",
+ EINA_FALSE);
+ return;
+ }
+ //
+ // TIZEN ONLY (20150720): Keep at least one character in selection
+ int pos1 = 0, pos2 = 0;
+ pos1 = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN);
+ pos2 = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_END);
+ if (pos1 > pos2)
+ {
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN, pos2);
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_END, pos1);
+ }
+ //
if (_elm_config->magnifier_enable)
_magnifier_hide(data);
- if ((!_elm_config->desktop_entry) && (sd->long_pressed))
+ // TIZEN ONLY (20150205): Support CopyPaste UI
+ /*if ((!_elm_config->desktop_entry) && (sd->long_pressed))
+ _menu_call(data);*/
+ if (!_elm_config->desktop_entry)
_menu_call(data);
+ if (!_elm_config->desktop_entry)
+ edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text",
+ EINA_FALSE);
+ //
}
static void
Evas_Coord cx, cy, ch;
int pos;
+ // TIZEN ONLY(20150815): feature: remove mgf, popup, handlers if entry changed
+ if (!sd->end_handler_shown)
+ {
+ ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+ sd->long_pressed = EINA_FALSE;
+ return;
+ }
+ //
+
evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
cx = ev->cur.canvas.x - sd->ox - ex;
cy = ev->cur.canvas.y - sd->oy - ey;
if (cx <= 0) cx = 1;
+ // TIZEN ONLY (20150715): for easy movement in single line
+ const Evas_Object *tb = NULL;
+ Evas_Textblock_Cursor *tc;
+ Evas_Coord fy = 0, fh = 0, ly = 0, lh = 0;
+
+ tb = edje_object_part_object_get(sd->entry_edje, "elm.text");
+ tc = evas_object_textblock_cursor_new(tb);
+ evas_textblock_cursor_paragraph_first(tc);
+ evas_textblock_cursor_line_geometry_get(tc, NULL, &fy, NULL, &fh);
+ evas_textblock_cursor_paragraph_last(tc);
+ evas_textblock_cursor_line_geometry_get(tc, NULL, &ly, NULL, &lh);
+ evas_textblock_cursor_free(tc);
+ if (cy < fy + fh / 2) cy = fy + fh / 2;
+ if (cy > ly + lh) cy = ly + lh - 1;
+ //
+
edje_object_part_text_cursor_coord_set(sd->entry_edje, "elm.text",
sd->sel_handler_cursor, cx, cy);
pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
sd->sel_handler_cursor);
+ // TIZEN ONLY (20150720): Keep at least one character in selection
+ int pos1 = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN);
+ if (pos == pos1)
+ {
+ if (pos > 0)
+ pos--;
+ else
+ pos++;
+ edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+ EDJE_CURSOR_SELECTION_END, pos);
+ }
+ //
edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
EDJE_CURSOR_MAIN, pos);
edje_object_part_text_cursor_geometry_get(sd->entry_edje,
priv->editable = EINA_TRUE;
priv->drop_format = ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE;
- elm_drop_target_add(obj, priv->drop_format,
+ /////////////////////////////////////////////////////////////////
+ // TIZEN ONLY (20150129) Add more control when drop happens.
+ /*elm_drop_target_add(obj, sd->drop_format,
NULL, NULL,
NULL, NULL,
NULL, NULL,
+ _drag_drop_cb, NULL);*/
+ elm_drop_target_add(obj, priv->drop_format,
+ _dnd_enter_cb, obj,
+ _dnd_leave_cb, obj,
+ _dnd_pos_cb, obj,
_drag_drop_cb, NULL);
+ /////////////////////////////////////////////////////////////////
if (!elm_layout_theme_set(obj, "entry", "base", elm_widget_style_get(obj)))
CRI("Failed to set layout!");
if (_elm_config->desktop_entry)
priv->sel_handler_disabled = EINA_TRUE;
+
+ priv->cursor_handler_shown = EINA_FALSE; // TIZEN ONLY (20150201)
}
static void
handle = edje_object_add(evas_object_evas_get(obj));
sd->start_handler = handle;
_elm_theme_object_set(obj, handle, "entry", "handler/start", style);
+ // TIZEN ONLY(20150605): support tizen theme
+ edje_object_signal_emit(handle, "edje,focus,in", "edje");
+ edje_object_signal_emit(handle, "elm,state,bottom", "elm");
+ sd->start_handler_shown = EINA_TRUE;
+ //
evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_DOWN,
_start_handler_mouse_down_cb, obj);
evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_MOVE,
handle = edje_object_add(evas_object_evas_get(obj));
sd->end_handler = handle;
_elm_theme_object_set(obj, handle, "entry", "handler/end", style);
+ // TIZEN ONLY(20150605): support tizen theme
+ edje_object_signal_emit(handle, "edje,focus,in", "edje");
+ //edje_object_signal_emit(handle, "elm,state,top", "elm");
+ edje_object_signal_emit(handle, "elm,state,bottom", "elm");
+ sd->end_handler_shown = EINA_TRUE;
+ //
evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_DOWN,
_end_handler_mouse_down_cb, obj);
evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_MOVE,
evas_object_del(sd->end_handler);
}
+ // TIZEN ONLY (20150201): Add cursor handler
+ if (sd->cursor_handler)
+ {
+ evas_object_del(sd->cursor_handler);
+ }
+ //
+ // TIZEN ONLY (20150721): use job to get correct parent's gometry
+ if (sd->sel_handler_update_job)
+ ecore_job_del(sd->sel_handler_update_job);
+ if (sd->cursor_handler_update_job)
+ ecore_job_del(sd->cursor_handler_update_job);
+ //
+
eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
}
+// TIZEN ONLY (20150721): use job to get correct parent's gometry
+static void
+_sel_handler_update_job_cb(void *data)
+{
+ Evas_Object *obj = data;
+
+ ELM_ENTRY_DATA_GET(obj, sd);
+ sd->sel_handler_update_job = NULL;
+ _update_selection_handler(obj);
+}
+
+static void
+_cursor_handler_update_job_cb(void *data)
+{
+ Evas_Object *obj = data;
+
+ ELM_ENTRY_DATA_GET(obj, sd);
+ sd->cursor_handler_update_job = NULL;
+ _update_cursor_handler(obj, sd);
+}
+//
+
EOLIAN static void
_elm_entry_evas_object_smart_move(Eo *obj, Elm_Entry_Data *sd, Evas_Coord x, Evas_Coord y)
{
if (sd->hoversel) _hoversel_position(obj);
if (edje_object_part_text_selection_get(sd->entry_edje, "elm.text"))
- _update_selection_handler(obj);
+ {
+ _update_selection_handler(obj);
+ // TIZEN ONLY (20150721): use job to get correct parent's gometry
+ if (sd->sel_handler_update_job)
+ ecore_job_del(sd->sel_handler_update_job);
+ sd->sel_handler_update_job =
+ ecore_job_add(_sel_handler_update_job_cb, obj);
+ //
+ }
+ // TIZEN ONLY (20150306): Update cursor handler
+ if (sd->cursor_handler_shown)
+ {
+ _update_cursor_handler(obj, sd);
+ if (sd->cursor_handler_update_job)
+ ecore_job_del(sd->cursor_handler_update_job);
+ sd->cursor_handler_update_job =
+ ecore_job_add(_cursor_handler_update_job_cb, obj);
+ }
+ //
}
EOLIAN static void
evas_object_resize(sd->hit_rect, w, h);
if (sd->have_selection)
- _update_selection_handler(obj);
+ {
+ _update_selection_handler(obj);
+ // TIZEN ONLY (20150721): use job to get correct parent's gometry
+ if (sd->sel_handler_update_job)
+ ecore_job_del(sd->sel_handler_update_job);
+ sd->sel_handler_update_job =
+ ecore_job_add(_sel_handler_update_job_cb, obj);
+ //
+ }
}
EOLIAN static void
if (sd->password == password) return;
sd->password = password;
- elm_drop_target_del(obj, sd->drop_format,
+ /////////////////////////////////////////////////////////////////
+ // TIZEN ONLY (20150129) Add more control when drop happens.
+ /*elm_drop_target_del(obj, sd->drop_format,
NULL, NULL,
NULL, NULL,
NULL, NULL,
+ _drag_drop_cb, NULL);*/
+ elm_drop_target_del(obj, sd->drop_format,
+ _dnd_enter_cb, obj,
+ _dnd_leave_cb, obj,
+ _dnd_pos_cb, obj,
_drag_drop_cb, NULL);
+ /////////////////////////////////////////////////////////////////
if (password)
{
sd->single_line = EINA_TRUE;
else
{
sd->drop_format = _get_drop_format(obj);
- elm_drop_target_add(obj, sd->drop_format,
+ /////////////////////////////////////////////////////////////////
+ // TIZEN ONLY (20150129) Add more control when drop happens.
+ /*elm_drop_target_add(obj, sd->drop_format,
NULL, NULL,
NULL, NULL,
NULL, NULL,
+ _drag_drop_cb, NULL);*/
+ elm_drop_target_add(obj, sd->drop_format,
+ _dnd_enter_cb, obj,
+ _dnd_leave_cb, obj,
+ _dnd_pos_cb, obj,
_drag_drop_cb, NULL);
+ /////////////////////////////////////////////////////////////////
elm_entry_input_hint_set(obj, ((sd->input_hints | ELM_INPUT_HINT_AUTO_COMPLETE) & ~ELM_INPUT_HINT_SENSITIVE_DATA));
_entry_selection_callbacks_register(obj);
sd->editable = editable;
eo_do(obj, elm_obj_widget_theme_apply());
- elm_drop_target_del(obj, sd->drop_format,
+ /////////////////////////////////////////////////////////////////
+ // TIZEN ONLY (20150129) Add more control when drop happens.
+ /*elm_drop_target_del(obj, sd->drop_format,
NULL, NULL,
NULL, NULL,
NULL, NULL,
+ _drag_drop_cb, NULL);*/
+ elm_drop_target_del(obj, sd->drop_format,
+ _dnd_enter_cb, obj,
+ _dnd_leave_cb, obj,
+ _dnd_pos_cb, obj,
_drag_drop_cb, NULL);
+ /////////////////////////////////////////////////////////////////
if (editable)
{
sd->drop_format = _get_drop_format(obj);
- elm_drop_target_add(obj, sd->drop_format,
+ /////////////////////////////////////////////////////////////////
+ // TIZEN ONLY (20150129) Add more control when drop happens.
+ /*elm_drop_target_add(obj, sd->drop_format,
NULL, NULL,
NULL, NULL,
NULL, NULL,
+ _drag_drop_cb, NULL);*/
+ elm_drop_target_add(obj, sd->drop_format,
+ _dnd_enter_cb, obj,
+ _dnd_leave_cb, obj,
+ _dnd_pos_cb, obj,
_drag_drop_cb, NULL);
+ /////////////////////////////////////////////////////////////////
}
}
else if (cnp_mode == ELM_CNP_MODE_MARKUP)
format |= ELM_SEL_FORMAT_IMAGE;
- elm_drop_target_del(obj, sd->drop_format,
+ /////////////////////////////////////////////////////////////////
+ // TIZEN ONLY (20150129) Add more control when drop happens.
+ /*elm_drop_target_del(obj, sd->drop_format,
NULL, NULL,
NULL, NULL,
NULL, NULL,
+ _drag_drop_cb, NULL);*/
+ elm_drop_target_del(obj, sd->drop_format,
+ _dnd_enter_cb, obj,
+ _dnd_leave_cb, obj,
+ _dnd_pos_cb, obj,
_drag_drop_cb, NULL);
sd->drop_format = format;
- elm_drop_target_add(obj, sd->drop_format,
+ /*elm_drop_target_add(obj, sd->drop_format,
NULL, NULL,
NULL, NULL,
NULL, NULL,
+ _drag_drop_cb, NULL);*/
+ elm_drop_target_add(obj, format,
+ _dnd_enter_cb, obj,
+ _dnd_leave_cb, obj,
+ _dnd_pos_cb, obj,
_drag_drop_cb, NULL);
+ /////////////////////////////////////////////////////////////////
}
EOLIAN static Elm_Cnp_Mode
if (sd->have_selection)
_update_selection_handler(obj);
+ // TIZEN ONLY (20150625): Update cursor handler
+ if (sd->cursor_handler_shown)
+ {
+ if (!sd->cursor_handler_down)
+ {
+ evas_object_hide(sd->cursor_handler);
+ sd->cursor_handler_shown = EINA_FALSE;
+ }
+ else
+ {
+ _update_cursor_handler(obj, sd);
+ }
+ }
+ //
}
EOLIAN static void
--- /dev/null
+#include "cbhm_helper.h"
+#include <Elementary.h>
+#include "elm_priv.h"
+#include "elm_module_priv.h"
+
+#if HAVE_APPSVC
+#include <appsvc/appsvc.h>
+#endif
+
+
+#define S_TRANSLATE dgettext("elementary", "Translate")
+
+/*#define CP_ICON_ADD(icon, item) icon = edje_object_add(evas_object_evas_get(ext_mod->popup)); \
+ elm_widget_theme_object_set(ext_mod->popup, \
+ icon,"copypaste", item, "default")*/
+#define CP_ICON_ADD(icon, item) icon = NULL
+
+#define ACCESS_FOCUS_ENABLE() if (ext_mod->_elm_config->access_mode) \
+ { \
+ elm_object_focus_allow_set(((Elm_Widget_Item_Data *)added_item)->view, EINA_FALSE); \
+ ao = ((Elm_Widget_Item_Data *)added_item)->access_obj; \
+ elm_object_focus_allow_set(ao, EINA_FALSE); \
+ lao = eina_list_append(lao, ao); \
+ }
+
+#define GET_CTX_AVAI_DIR() elm_layout_sizing_eval(ext_mod->popup); \
+ dir = elm_ctxpopup_direction_get(ext_mod->popup)
+
+#define DEBUGON 1
+#ifdef DEBUGON
+#define LOG(fmt, args...) printf("[CNP]%s %d: " fmt "\n", __func__, __LINE__, ##args)
+#else
+#define LOG(x...) do { } while (0)
+#endif
+
+Elm_Entry_Extension_data *ext_mod;
+static int _mod_hook_count = 0;
+static Evas_Coord _previous_pressed_point_x = -1;
+static Evas_Coord _previous_pressed_point_y = -1;
+static int _copy_paste_move_threshold = 15;
+
+typedef struct _Elm_Entry_Context_Menu_Item Elm_Entry_Context_Menu_Item;
+
+struct _Elm_Entry_Context_Menu_Item
+{
+ Evas_Object *obj;
+ const char *label;
+ const char *icon_file;
+ const char *icon_group;
+ Elm_Icon_Type icon_type;
+ Evas_Smart_Cb func;
+ void *data;
+};
+
+static void _entry_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _entry_hide_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _entry_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _entry_scroll_cb(void *data, Evas_Object *scroller, void *event_info);
+static void _ctxpopup_hide(Evas_Object *popup);
+static void _ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info);
+void obj_longpress(Evas_Object *obj);
+
+#if HAVE_APPSVC
+static char *
+_remove_tags(const char *str)
+{
+ char *ret;
+ if (!str)
+ return NULL;
+
+ Eina_Strbuf *buf = eina_strbuf_new();
+ if (!buf)
+ return NULL;
+
+ if (!eina_strbuf_append(buf, str))
+ {
+ eina_strbuf_free(buf);
+ return NULL;
+ }
+
+ eina_strbuf_replace_all(buf, "<br>", " ");
+ eina_strbuf_replace_all(buf, "<br/>", " ");
+ eina_strbuf_replace_all(buf, "<ps>", " ");
+ eina_strbuf_replace_all(buf, "<ps/>", " ");
+
+ while (EINA_TRUE)
+ {
+ const char *temp = eina_strbuf_string_get(buf);
+
+ char *startTag = NULL;
+ char *endTag = NULL;
+
+ startTag = strstr(temp, "<");
+ if (startTag)
+ endTag = strstr(startTag, ">");
+ else
+ break;
+ if (!endTag || startTag > endTag)
+ break;
+
+ size_t sindex = startTag - temp;
+ size_t eindex = endTag - temp + 1;
+ if (!eina_strbuf_remove(buf, sindex, eindex))
+ break;
+ }
+ ret = eina_strbuf_string_steal(buf);
+ eina_strbuf_free(buf);
+ return ret;
+}
+#endif
+
+static void
+_parent_mouse_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ if ((!ext_mod) || (!ext_mod->popup))
+ return;
+ ext_mod->popup_clicked = EINA_TRUE;
+ evas_object_hide(ext_mod->popup);
+ ext_mod->mouse_up = EINA_FALSE;
+ ext_mod->entry_move = EINA_FALSE;
+}
+
+static void
+_parent_mouse_up_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ if ((!ext_mod) || (!ext_mod->popup))
+ return;
+ if ((ext_mod->popup_clicked) && (ext_mod->popup_showing))
+ {
+ ext_mod->popup_showing = EINA_FALSE;
+ evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_DEL, _entry_del_cb);
+ evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_HIDE, _entry_hide_cb);
+ evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_MOVE, _entry_move_cb);
+
+ evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_MOUSE_DOWN,
+ _entry_mouse_down_cb);
+ evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_MOUSE_MOVE,
+ _entry_mouse_move_cb);
+ evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_MOUSE_UP,
+ _entry_mouse_up_cb);
+ evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_DOWN,
+ _parent_mouse_down_cb);
+ evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_UP,
+ _parent_mouse_up_cb);
+ evas_object_smart_callback_del(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb);
+ if (ext_mod->ent_scroll)
+ {
+ evas_object_smart_callback_del(obj, "scroll", _entry_scroll_cb);
+ }
+ }
+}
+
+static void
+_entry_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ if (ext_mod)
+ {
+ evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_DOWN,
+ _parent_mouse_down_cb);
+ evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_UP,
+ _parent_mouse_up_cb);
+ if (ext_mod->popup)
+ {
+ _ctxpopup_hide(ext_mod->popup);
+ evas_object_del(ext_mod->popup);
+ ext_mod->popup = NULL;
+ }
+ }
+}
+
+static void
+_entry_hide_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ evas_object_hide(data);
+}
+
+static void
+_entry_mouse_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ if ((!ext_mod) || (!ext_mod->popup))
+ return;
+ ext_mod->mouse_up = EINA_FALSE;
+ ext_mod->mouse_move = EINA_FALSE;
+ ext_mod->mouse_down = EINA_TRUE;
+
+ Evas_Event_Mouse_Down *ev = event_info;
+
+ _previous_pressed_point_x = ev->canvas.x;
+ _previous_pressed_point_y = ev->canvas.y;
+}
+
+static Eina_Bool
+_ctx_show(void *data)
+{
+ ext_mod->show_timer = NULL;
+ if (!data) return ECORE_CALLBACK_CANCEL;
+ ext_mod->entry_move = EINA_FALSE;
+ if (ext_mod->popup_showing)
+ {
+ obj_longpress(data);
+ }
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_entry_mouse_move_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ if ((!ext_mod) || (!ext_mod->popup))
+ return;
+
+ if (!ext_mod->mouse_down)
+ return;
+
+ Evas_Event_Mouse_Move *ev = event_info;
+ if ((abs(_previous_pressed_point_x - ev->cur.canvas.x) >= _copy_paste_move_threshold)||(abs(_previous_pressed_point_y - ev->cur.canvas.y) >= _copy_paste_move_threshold))
+ {
+ ext_mod->popup_clicked = EINA_FALSE;
+ ext_mod->mouse_move = EINA_TRUE;
+ }
+ else
+ {
+ return;
+ }
+
+ evas_object_hide(ext_mod->popup);
+ evas_object_smart_callback_del(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb);
+ if (ext_mod->show_timer)
+ {
+ ecore_timer_del(ext_mod->show_timer);
+ ext_mod->show_timer = NULL;
+ }
+}
+
+static void
+_entry_scroll_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ if (!ext_mod)
+ return;
+ evas_object_hide(ext_mod->popup);
+ evas_object_smart_callback_del(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb);
+ if (ext_mod->show_timer) ecore_timer_del(ext_mod->show_timer);
+ ext_mod->show_timer = ecore_timer_add(0.1, _ctx_show, obj);
+}
+
+static void
+_entry_mouse_up_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ _previous_pressed_point_x = -1;
+ _previous_pressed_point_y = -1;
+
+ if (!ext_mod)
+ return;
+ if ((ext_mod->mouse_down && ext_mod->entry_move) || (ext_mod->mouse_down && ext_mod->mouse_move))
+ {
+ evas_object_smart_callback_del(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb);
+ if (ext_mod->show_timer)
+ {
+ ecore_timer_del(ext_mod->show_timer);
+ ext_mod->show_timer = NULL;
+ }
+
+ if (ext_mod->popup && !evas_object_visible_get(ext_mod->popup))
+ {
+ ext_mod->show_timer = ecore_timer_add(0.1, _ctx_show, obj);
+ }
+ }
+ ext_mod->mouse_up = EINA_TRUE;
+ ext_mod->mouse_move = EINA_FALSE;
+ ext_mod->mouse_down = EINA_FALSE;
+}
+
+static void
+_entry_move_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ if (!ext_mod)
+ return;
+ ext_mod->entry_move = EINA_TRUE;
+ ext_mod->popup_clicked = EINA_FALSE;
+ evas_object_hide(ext_mod->popup);
+ evas_object_smart_callback_del(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb);
+ if (ext_mod->show_timer) ecore_timer_del(ext_mod->show_timer);
+ ext_mod->show_timer = ecore_timer_add(0.1, _ctx_show, obj);
+}
+
+static void
+_ctxpopup_hide(Evas_Object *popup)
+{
+ if (!ext_mod->popup_showing) return;
+ ext_mod->popup_showing = EINA_FALSE;
+ evas_object_hide(popup);
+ evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_DEL, _entry_del_cb);
+ evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_HIDE, _entry_hide_cb);
+ evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_MOVE, _entry_move_cb);
+ //FIXME: check access API to disable/enable highlight
+ if (ext_mod->_elm_config->access_mode && ext_mod->caller)
+ //_elm_access_highlight_set(ext_mod->caller, EINA_TRUE);
+ _elm_access_highlight_set(ext_mod->caller);
+}
+
+static Eina_Bool
+_in_viewport_check()
+{
+ if (!ext_mod) return EINA_FALSE;
+
+ Eina_Rectangle vp;
+
+ /*update*/
+ if (ext_mod->caller)
+ {
+ if (ext_mod->viewport_rect)
+ eina_rectangle_free(ext_mod->viewport_rect);
+ elm_entry_extension_module_data_get(ext_mod->caller, ext_mod);
+ }
+ /* Entry returns x y coordinate to be 0 when intersection is not obtained
+ * but x y coordinate can be 0 */
+ if ((ext_mod->viewport_rect->x == 0) && (ext_mod->viewport_rect->y == 0) &&
+ (ext_mod->viewport_rect->w == 0) && (ext_mod->viewport_rect->h == 0))
+ {
+ ext_mod->viewport_rect->x = -1;
+ ext_mod->viewport_rect->y = -1;
+ ext_mod->viewport_rect->w = -1;
+ ext_mod->viewport_rect->h = -1;
+ }
+ vp.x = ext_mod->viewport_rect->x;
+ vp.y = ext_mod->viewport_rect->y;
+ vp.w = ext_mod->viewport_rect->w;
+ vp.h = ext_mod->viewport_rect->h;
+
+ if (ext_mod->have_selection)
+ {
+ if ((ext_mod->viewport_rect->x != -1) || (ext_mod->viewport_rect->y != -1) ||
+ (ext_mod->viewport_rect->w != -1) || (ext_mod->viewport_rect->h != -1))
+ {
+ Evas_Coord ex, ey;
+ Eina_Rectangle sel;
+
+ evas_object_geometry_get(ext_mod->ent, &ex, &ey, NULL, NULL);
+ sel.x = ext_mod->selection_rect.x;
+ sel.y = ext_mod->selection_rect.y;
+ sel.w = ext_mod->selection_rect.w;
+ sel.h = ext_mod->selection_rect.h;
+ LOG("sel geo: %d %d %d %d\n", sel.x, sel.y, sel.w, sel.h);
+ LOG("vpr geo: %d %d %d %d\n", vp.x, vp.y, vp.w, vp.h);
+ if (eina_rectangle_intersection(&sel, &vp))
+ {
+ return EINA_TRUE;
+ }
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+ }
+ else
+ {
+ if ((ext_mod->viewport_rect->x != -1) || (ext_mod->viewport_rect->y != -1) ||
+ (ext_mod->viewport_rect->w != -1) || (ext_mod->viewport_rect->h != -1))
+ {
+ Evas_Coord ex, ey;
+ Evas_Coord cx, cy, cw, ch;
+ Eina_Rectangle cur;
+
+ evas_object_geometry_get(ext_mod->ent, &ex, &ey, NULL, NULL);
+ edje_object_part_text_cursor_geometry_get(ext_mod->ent, "elm.text",
+ &cx, &cy, &cw, &ch);
+ cx = ex + cx;
+ cy = ey + cy;
+ cur.x = cx;
+ cur.y = cy;
+ cur.w = cw;
+ cur.h = ch;
+ if (eina_rectangle_intersection(&cur, &vp))
+ {
+ return EINA_TRUE;
+ }
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+ }
+ return EINA_FALSE;
+}
+
+static void
+_ctxpopup_position(Evas_Object *obj EINA_UNUSED)
+{
+ if(!ext_mod) return;
+
+ Evas_Coord ex, ey;
+ Evas_Coord sx, sy, sw, sh;
+ Evas_Coord x, y, w;
+ int gap = 35; //in GUI
+ Elm_Ctxpopup_Direction dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
+
+ evas_object_geometry_get(ext_mod->ent, &ex, &ey, NULL, NULL);
+ elm_ctxpopup_direction_priority_set(ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP,
+ ELM_CTXPOPUP_DIRECTION_DOWN, ELM_CTXPOPUP_DIRECTION_LEFT,
+ ELM_CTXPOPUP_DIRECTION_RIGHT);
+ if (!ext_mod->have_selection)
+ { //cannot get selection shape
+ LOG("Cannot get selection (have no sel)\n");
+ Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0;
+ Evas_Coord chx = 0, chy = 0, chw = 0, chh = 0;
+ Eina_Bool ch_visible = EINA_FALSE;
+ Eina_Bool need_update = EINA_FALSE;
+
+ edje_object_part_text_cursor_geometry_get(ext_mod->ent, "elm.text",
+ &cx, &cy, &cw, &ch);
+ x = ex + cx;
+ y = ey + cy;
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_DOWN)
+ {
+ elm_ctxpopup_direction_priority_set(ext_mod->popup,
+ ELM_CTXPOPUP_DIRECTION_DOWN,
+ ELM_CTXPOPUP_DIRECTION_UP,
+ ELM_CTXPOPUP_DIRECTION_LEFT,
+ ELM_CTXPOPUP_DIRECTION_RIGHT);
+ x = ex + cx;
+ y = ey + cy + ch;
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_UP)
+ need_update = EINA_TRUE;
+ }
+
+ //limit ctx in viewport
+ if (ext_mod->viewport_rect->x != -1 || ext_mod->viewport_rect->y != -1
+ || ext_mod->viewport_rect->w != -1 || ext_mod->viewport_rect->h != -1)
+ {
+ if (ext_mod->viewport_rect->x > x)
+ x = ext_mod->viewport_rect->x;
+ else if (x > ext_mod->viewport_rect->x + ext_mod->viewport_rect->w)
+ x = ext_mod->viewport_rect->x + ext_mod->viewport_rect->w;
+
+ if (ext_mod->viewport_rect->y > y)
+ y = ext_mod->viewport_rect->y;
+ else if (y > ext_mod->viewport_rect->y + ext_mod->viewport_rect->h)
+ y = ext_mod->viewport_rect->y + ext_mod->viewport_rect->h;
+ }
+
+ evas_object_move(ext_mod->popup, x, y);
+
+ ch_visible = ext_mod->cursor_handler_shown;
+ if (ext_mod->cursor_handler)
+ {
+ Evas_Coord xx, yy;
+ evas_object_geometry_get(ext_mod->cursor_handler, &chx, &chy, NULL, NULL);
+ edje_object_parts_extends_calc(ext_mod->cursor_handler, &xx, &yy, &chw, &chh);
+ chx += xx;
+ chy += yy;
+ LOG("Cursor handler: %d %d %d %d\n", chx, chy, chw, chh);
+ }
+
+ GET_CTX_AVAI_DIR();
+ //move to above or below cursor handler
+ if (ch_visible && strcmp(edje_object_part_text_get(ext_mod->ent, "elm.text"), ""))
+ {
+ if ((chy < ey + cy) && (dir == ELM_CTXPOPUP_DIRECTION_UP))
+ {
+ y = chy;
+ evas_object_move(ext_mod->popup, x, y);
+ LOG("Ctxpopup pos: %d %d\n", x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir != ELM_CTXPOPUP_DIRECTION_UP)
+ need_update = EINA_TRUE;
+ }
+ else if ((chy > ey + cy) && (dir == ELM_CTXPOPUP_DIRECTION_DOWN))
+ {
+ y = chy + chh;
+ evas_object_move(ext_mod->popup, x, y);
+ LOG("Ctxpopup pos: %d %d\n", x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir != ELM_CTXPOPUP_DIRECTION_DOWN)
+ need_update = EINA_TRUE;
+ }
+ }
+ if (((dir != ELM_CTXPOPUP_DIRECTION_UP) && (dir != ELM_CTXPOPUP_DIRECTION_DOWN)) || need_update)
+ {
+ y = ey + cy + ch / 2;
+ elm_ctxpopup_direction_priority_set(ext_mod->popup,
+ ELM_CTXPOPUP_DIRECTION_LEFT,
+ ELM_CTXPOPUP_DIRECTION_RIGHT,
+ ELM_CTXPOPUP_DIRECTION_UP,
+ ELM_CTXPOPUP_DIRECTION_DOWN);
+ evas_object_move(ext_mod->popup, x, y);
+ LOG("Ctxpopup pos: %d %d\n", x, y);
+ }
+ }
+ else //get selection shape
+ {
+ LOG("Have selection\n");
+ Evas_Coord shx = 0, shy = 0, shw = 0, shh = 0;
+ Evas_Coord ehx = 0, ehy = 0, ehw = 0, ehh = 0;
+ /* Currently, we cannot get size of ctxpopup, we must set hard value for threshold.
+ After fixing ctxpopup, we can get correctly threshold */
+ Evas_Coord threshold = 300;
+
+ sx = ext_mod->selection_rect.x;
+ sy = ext_mod->selection_rect.y;
+ sw = ext_mod->selection_rect.w;
+ sh = ext_mod->selection_rect.h;
+ LOG("sel geo: %d %d %d %d\n", sx, sy, sw, sh);
+ if (ext_mod->start_handler)
+ {
+ Evas_Coord xx, yy;
+ evas_object_geometry_get(ext_mod->start_handler, &shx, ­, NULL, NULL);
+ edje_object_parts_extends_calc(ext_mod->start_handler, &xx, &yy, &shw, &shh);
+ shx += xx;
+ shy += yy;
+ }
+ if (ext_mod->end_handler)
+ {
+ Evas_Coord xx, yy;
+ evas_object_geometry_get(ext_mod->end_handler, &ehx, &ehy, NULL, NULL);
+ edje_object_parts_extends_calc(ext_mod->end_handler, &xx, &yy, &ehw, &ehh);
+ ehx += xx;
+ ehy += yy;
+ }
+ LOG("start handler: %d %d %d %d, end handler: %d %d %d %d\n", shx, shy, shw, shh, ehx, ehy, ehw, ehh);
+ if (ext_mod->viewport_rect->x != -1 || ext_mod->viewport_rect->y != -1
+ || ext_mod->viewport_rect->w != -1 || ext_mod->viewport_rect->h != -1)
+ {
+ Evas_Coord vx, vy, vw, vh, x2, y2;
+ x2 = sx + sw;
+ if ((ehh > 0) && (ehy + ehh > sy + sh))
+ {
+ //y2 = ey + ehy + ehh;
+ y2 = ehy + gap;
+ }
+ else
+ y2 = sy + sh;
+ vx = ext_mod->viewport_rect->x;
+ vy = ext_mod->viewport_rect->y;
+ vw = ext_mod->viewport_rect->w;
+ vh = ext_mod->viewport_rect->h;
+
+ //limit ctx in viewport
+ x = sx;
+ if (sx < vx) x = vx;
+ if (sy < vy)
+ {
+ LOG("start of selection is behind viewport");
+ if (ehy + ehh < vy + vh) //end handler is showing
+ {
+ y = ehy + ehh;
+ if (x2 > vx + vw) x2 = vx + vw;
+ w = x2 - x;
+ elm_ctxpopup_direction_priority_set(ext_mod->popup,
+ ELM_CTXPOPUP_DIRECTION_DOWN,
+ ELM_CTXPOPUP_DIRECTION_UP,
+ ELM_CTXPOPUP_DIRECTION_LEFT,
+ ELM_CTXPOPUP_DIRECTION_RIGHT);
+ evas_object_move(ext_mod->popup, x + w/2, y);
+ LOG("move: %d %d", x + w/2, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_DOWN)
+ {
+ LOG("show down");
+ return;
+ }
+ else
+ {
+ elm_ctxpopup_direction_priority_set(ext_mod->popup,
+ ELM_CTXPOPUP_DIRECTION_UP,
+ ELM_CTXPOPUP_DIRECTION_DOWN,
+ ELM_CTXPOPUP_DIRECTION_LEFT,
+ ELM_CTXPOPUP_DIRECTION_RIGHT);
+ y = vy + (vh / 2);
+ LOG("show middle of sel: %d %d", x, y);
+ }
+ }
+ else
+ {
+ y = vy + (vh / 2);
+ LOG("show middle of sel: %d %d", x, y);
+ }
+ }
+ else
+ {
+ if ((sx >= vx) && (shy < sy)) //case: start handler is upside
+ {
+ y = shy;
+ w = x2 - x;
+ evas_object_move(ext_mod->popup, x + w/2, y);
+ GET_CTX_AVAI_DIR();
+ if (dir != ELM_CTXPOPUP_DIRECTION_UP)
+ {
+ y = sy - gap;
+ }
+ }
+ else if ((sx + sw <= vx + vw) && (ehy < sy))
+ {
+ y = ehy;
+ }
+ else
+ y = sy;
+ }
+ if (x2 > vx + vw) x2 = vx + vw;
+ if (y2 > vy + vh) y2 = vy + vh;
+ w = x2 - x;
+ evas_object_move(ext_mod->popup, x + w/2, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_UP)
+ return;
+ }
+ else //get selection & cannot get viewport
+ {
+ Evas_Coord ww = 0, wh = 0, x2, y2;
+ x2 = sx + sw;
+ if (ehy + ehh > sy + sh)
+ y2 = ehy + ehh; //end handler is downside
+ else
+ y2 = sy + sh;
+
+ //FIXME: check this
+#ifdef HAVE_ELEMENTARY_X
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &ww, &wh);
+#endif
+
+ x = sx;
+ if (sx < 0) x = 0;
+ if (sy < 0)
+ {
+ y = 0; //start of selection is negative
+ }
+ else
+ {
+ if (shy < sy) //start handler is upside
+ {
+ y = shy;
+ w = x2 - x;
+ evas_object_move(ext_mod->popup, x + w/2, y);
+ GET_CTX_AVAI_DIR();
+ if (dir != ELM_CTXPOPUP_DIRECTION_UP)
+ {
+ y = sy - gap;
+ }
+ }
+ else
+ {
+ y = sy;
+ }
+ }
+ if (x2 > ww) x2 = ww;
+ if (y2 > wh) y2 = wh;
+ w = x2 - x;
+ }
+ x = x + (w / 2);
+ evas_object_move(ext_mod->popup, x, y);
+
+ GET_CTX_AVAI_DIR();
+ if (dir != ELM_CTXPOPUP_DIRECTION_UP)
+ {
+ Eina_Rectangle vp;
+ Eina_Rectangle sel; //selection area which is not covered by start,end sel handlers
+ Evas_Coord cry;
+
+ elm_ctxpopup_direction_priority_set(ext_mod->popup, ELM_CTXPOPUP_DIRECTION_DOWN,
+ ELM_CTXPOPUP_DIRECTION_UP,
+ ELM_CTXPOPUP_DIRECTION_LEFT,
+ ELM_CTXPOPUP_DIRECTION_RIGHT);
+ vp.x = ext_mod->viewport_rect->x;
+ vp.y = ext_mod->viewport_rect->y;
+ vp.w = ext_mod->viewport_rect->w;
+ vp.h = ext_mod->viewport_rect->h;
+ sel.x = sx;
+ if (shy + shh < sy + sh)
+ sel.y = sy > shy + shh ? sy : shy + shh;
+ else
+ sel.y = sy;
+ sel.w = sw;
+ cry = sy + sh < ehy ? sy + sh : ehy;
+ sel.h = cry > sel.y ? cry - sel.y : sel.y - cry;
+ if ((eina_rectangle_intersection(&sel, &vp)) && (sel.h > threshold))
+ {
+ elm_ctxpopup_direction_priority_set(ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP,
+ ELM_CTXPOPUP_DIRECTION_DOWN,
+ ELM_CTXPOPUP_DIRECTION_LEFT,
+ ELM_CTXPOPUP_DIRECTION_RIGHT);
+ evas_object_move(ext_mod->popup, x, sel.y + sel.h/2);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_UP)
+ return;
+ }
+
+ y = sel.y + sel.h;
+ if ((y < ehy + ehh) && (ehy < vp.y + vp.h)) //end handler is downside
+ {
+ y = ehy + ehh;
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_DOWN)
+ return;
+ y = sy + sh + gap;
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_DOWN)
+ return;
+ }
+ y = ehy + ehh;
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_DOWN)
+ return;
+
+ // not enough space and small viewport (like landscape mode)
+ sel.x = sx;
+ sel.y = sy;
+ sel.w = sw;
+ sel.h = sh;
+ if (!eina_rectangle_intersection(&sel, &vp))
+ return;
+
+ if (shy < sel.y) //start handler is up side
+ {
+ y = shy;
+ while (y <= sel.y + ehh/2)
+ {
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_UP)
+ return;
+ y += shh/4;
+ }
+ }
+ else
+ {
+ if (ehy + ehh > sel.y + sel.h) //end handler is down side
+ {
+ y = ehy + ehh;
+ while (y > sel.y + sel.h - ehh/2)
+ {
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_DOWN)
+ return;
+ y -= ehh/4;
+ }
+ }
+ else
+ {
+ y = sel.y + sel.h;
+ while (y > sel.y + sel.h - ehh/2)
+ {
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_DOWN)
+ return;
+ y -= ehh/4;
+ }
+ }
+ }
+
+ elm_ctxpopup_direction_priority_set(ext_mod->popup,
+ ELM_CTXPOPUP_DIRECTION_LEFT,
+ ELM_CTXPOPUP_DIRECTION_RIGHT,
+ ELM_CTXPOPUP_DIRECTION_UP,
+ ELM_CTXPOPUP_DIRECTION_DOWN);
+ x = sel.x;
+ y = sel.y + sel.h/2;
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_LEFT)
+ return;
+
+ x = sel.x;
+ y = sel.y + sel.h;
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_LEFT)
+ return;
+
+ elm_ctxpopup_direction_priority_set(ext_mod->popup,
+ ELM_CTXPOPUP_DIRECTION_RIGHT,
+ ELM_CTXPOPUP_DIRECTION_LEFT,
+ ELM_CTXPOPUP_DIRECTION_UP,
+ ELM_CTXPOPUP_DIRECTION_DOWN);
+ x = sel.x + sel.w;
+ y = sel.y + sel.h/2;
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_RIGHT)
+ return;
+
+ x = sel.x + sel.w;
+ y = sel.y + sel.h;
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_RIGHT)
+ return;
+
+ x = sel.x;
+ y = sel.y + sel.h/2;
+ while (x < sel.x + sel.w/2)
+ {
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_LEFT)
+ return;
+ x += sel.w/4;
+ }
+
+ x = sel.x + sel.w;
+ y = sel.y + sel.h/2;
+ while (x > sel.x + sel.w/2)
+ {
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_RIGHT)
+ return;
+ x -= sel.w/4;
+ }
+
+ x = sel.x + sel.w;
+ y = sel.y + sel.h;
+ while (x > sel.x + sel.w/2)
+ {
+ evas_object_move(ext_mod->popup, x, y);
+ GET_CTX_AVAI_DIR();
+ if (dir == ELM_CTXPOPUP_DIRECTION_RIGHT)
+ return;
+ x -= sel.w/4;
+ }
+ }
+ }
+}
+
+static void
+_select_all(void *data, Evas_Object *obj, void *event_info)
+{
+ if((!ext_mod) || (!data)) return;
+
+ _ctxpopup_hide(obj);
+ ext_mod->selectall(data, obj, event_info);
+}
+
+static void
+_select(void *data, Evas_Object *obj, void *event_info)
+{
+ if((!ext_mod) || (!data)) return;
+
+ _ctxpopup_hide(obj);
+ ext_mod->select(data, obj, event_info);
+}
+
+static void
+_paste(void *data, Evas_Object *obj, void *event_info)
+{
+ if((!ext_mod) || (!data)) return;
+
+ ext_mod->paste(data, obj, event_info);
+ _ctxpopup_hide(obj);
+}
+
+static void
+_cut(void *data, Evas_Object *obj, void *event_info)
+{
+ if((!ext_mod) || (!data)) return;
+
+ ext_mod->cut(data, obj, event_info);
+ _ctxpopup_hide(obj);
+}
+
+static void
+_copy(void *data, Evas_Object *obj, void *event_info)
+{
+ if((!ext_mod) || (!data)) return;
+
+ if (edje_object_part_text_selection_get(ext_mod->ent, "elm.text"))
+ {
+ int pos = 0, pos1 = 0, pos2 = 0;
+ pos1 = edje_object_part_text_cursor_pos_get(ext_mod->ent, "elm.text",
+ EDJE_CURSOR_SELECTION_BEGIN);
+ pos2 = edje_object_part_text_cursor_pos_get(ext_mod->ent, "elm.text",
+ EDJE_CURSOR_SELECTION_END);
+ pos = pos1 > pos2 ? pos1 : pos2;
+ edje_object_part_text_cursor_pos_set(ext_mod->ent, "elm.text",
+ EDJE_CURSOR_MAIN, pos);
+ }
+ ext_mod->copy(data, obj, event_info);
+ _ctxpopup_hide(obj);
+ elm_entry_select_none(data);
+}
+
+static void
+_cancel(void *data, Evas_Object *obj, void *event_info)
+{
+ if((!ext_mod) || (!data)) return;
+
+ ext_mod->cancel(data, obj, event_info);
+ _ctxpopup_hide(obj);
+}
+
+#if HAVE_APPSVC
+static void
+_recvd_bundle(const char *key, const int type EINA_UNUSED, const bundle_keyval_t *kv, void *date EINA_UNUSED)
+{
+ char *val;
+ size_t size;
+
+ if (!ext_mod) return;
+
+ if (bundle_keyval_type_is_array((bundle_keyval_t *)kv) <= 0)
+ {
+ bundle_keyval_get_basic_val((bundle_keyval_t *)kv, (void **)&val, &size);
+ if (!strcmp(key, "source_text"))
+ {
+ ext_mod->source_text = strdup(val);
+ }
+ if (!strcmp(key, "target_text"))
+ {
+ ext_mod->target_text = strdup(val);
+ }
+ }
+}
+
+static void
+_translate_cb(bundle *b, int request_code EINA_UNUSED, appsvc_result_val rv, void *data EINA_UNUSED)
+{
+ if (!ext_mod) return;
+
+ if (ext_mod->source_text)
+ {
+ free(ext_mod->source_text);
+ ext_mod->source_text = NULL;
+ }
+ if (ext_mod->target_text)
+ {
+ free(ext_mod->target_text);
+ ext_mod->target_text = NULL;
+ }
+ if ((rv == APPSVC_RES_CANCEL) || (rv == APPSVC_RES_NOT_OK)) //CANCEL, NOT_OK, OK
+ {
+ return;
+ }
+ else
+ {
+ bundle_foreach(b, _recvd_bundle, NULL);
+ }
+ if ((ext_mod->source_text) || (ext_mod->target_text))
+ {
+ if (ext_mod->editable)
+ {
+ ext_mod->paste_translation(ext_mod->source_text,
+ ext_mod->caller, ext_mod->target_text);
+ }
+ }
+}
+
+static unsigned int
+_get_window_id()
+{
+ Evas_Object *top;
+ Ecore_X_Window xwin;
+
+ top = elm_widget_top_get(ext_mod->caller);
+ xwin = elm_win_xwindow_get(top);
+
+ return xwin;
+}
+
+static void
+_translate_menu(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ if (!ext_mod) return;
+
+ bundle *b = bundle_create();
+ if (!b)
+ {
+ return;
+ }
+ ext_mod->keep_selection(NULL, ext_mod->caller, NULL);
+
+ appsvc_set_operation(b, APPSVC_OPERATION_PICK);
+ appsvc_set_appid(b, "com.samsung.stranslator-shared");
+
+ if (ext_mod->selmode)
+ {
+ const char *selection = elm_entry_selection_get(ext_mod->caller);
+ if (selection)
+ {
+ unsigned int winid = _get_window_id();
+ char wis[20];
+ snprintf(wis, 20, "%u", winid);
+ appsvc_add_data(b, "winid", wis);
+ appsvc_add_data(b, "display", "yes");
+ appsvc_add_data(b, "text_type", "plain_text");
+ appsvc_add_data(b, "source_language", "recently_used"); //auto_detection, recently_used
+ appsvc_add_data(b, "target_language", "recently_used"); //recently_used, specify(en_US)
+ appsvc_add_data(b, "result_type", "selective"); //target_only, selective, both
+ if (ext_mod->editable)
+ appsvc_add_data(b, "mode", "edit_mode_translate"); //edit_mode, edit_mode_translate
+ else
+ appsvc_add_data(b, "mode", "view_mode_translate"); //view_mode, view_mode_translate
+
+ char *str = _remove_tags(selection);
+ if (str)
+ appsvc_add_data(b, "source_text", str);
+ else
+ appsvc_add_data(b, "source_text", selection);
+ }
+ }
+ appsvc_run_service(b, 0, _translate_cb, NULL);
+ bundle_free(b);
+ elm_entry_input_panel_hide(ext_mod->caller);
+ _ctxpopup_hide(obj);
+}
+#endif
+
+static void
+_clipboard_menu(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ if(!ext_mod) return;
+
+ // start for cbhm
+#ifdef HAVE_ELEMENTARY_X
+ Evas_Object *top;
+ Ecore_X_Window xwin;
+ top = elm_widget_top_get(ext_mod->caller);
+ xwin = elm_win_xwindow_get(top);
+ ecore_x_selection_secondary_set(xwin, NULL, 0);
+#endif
+ if (ext_mod->cnp_mode != ELM_CNP_MODE_MARKUP)
+ _cbhm_msg_send(data, "show0");
+ else
+ _cbhm_msg_send(data, "show1");
+ _ctxpopup_hide(obj);
+ // end for cbhm
+ elm_entry_select_none(data);
+}
+
+static void
+_item_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ Elm_Entry_Context_Menu_Item *it = data;
+ Evas_Object *obj2 = it->obj;
+
+ if (it->func) it->func(it->data, obj2, NULL);
+ _ctxpopup_hide(obj);
+}
+
+static void
+_ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ Elm_Ctxpopup_Direction dir;
+ if (!ext_mod) return;
+
+ dir = elm_ctxpopup_direction_get(obj);
+ //clear selection if ctxpopup is dismissed by clicking (not parent resizing)
+ if (dir != ELM_CTXPOPUP_DIRECTION_UNKNOWN)
+ {
+ if ((ext_mod->mouse_up) && (ext_mod->entry_move))
+ {
+ _ctxpopup_position(obj);
+ evas_object_show(ext_mod->popup);
+ }
+ else
+ {
+ elm_entry_select_none(data);
+ ext_mod->popup_showing = EINA_FALSE;
+ //FIXME: check access API to disable/enable highlight
+ if (ext_mod->_elm_config->access_mode)
+ //_elm_access_highlight_set(ext_mod->caller, EINA_FALSE);
+ _elm_access_highlight_set(ext_mod->caller);
+ }
+ }
+ else if (ext_mod->popup_showing)
+ {
+ if (_in_viewport_check())
+ {
+ if (ext_mod->show_timer) ecore_timer_del(ext_mod->show_timer);
+ ext_mod->show_timer = ecore_timer_add(0.1, _ctx_show, data);
+ }
+ }
+ ext_mod->mouse_up = EINA_FALSE;
+}
+
+// module api funcs needed
+EAPI int
+elm_modapi_init(void *m EINA_UNUSED)
+{
+ return 1; // succeed always
+}
+
+EAPI int
+elm_modapi_shutdown(void *m EINA_UNUSED)
+{
+ return 1; // succeed always
+}
+
+// module funcs for the specific module type
+EAPI void
+obj_hook(Evas_Object *obj)
+{
+ _mod_hook_count++;
+ //if(_mod_hook_count > 1) return;
+
+ if(!ext_mod)
+ {
+ ext_mod = ELM_NEW(Elm_Entry_Extension_data);
+ if (!ext_mod) return;
+ if (ext_mod->viewport_rect)
+ eina_rectangle_free(ext_mod->viewport_rect);
+ elm_entry_extension_module_data_get(obj, ext_mod);
+ ext_mod->mouse_up = EINA_FALSE;
+ ext_mod->mouse_down = EINA_FALSE;
+ ext_mod->entry_move = EINA_FALSE;
+ }
+ // Clipboard item: can be removed by application
+ elm_entry_context_menu_item_add(obj, "Clipboard", NULL,
+ ELM_ICON_STANDARD, NULL, NULL);
+
+#if HAVE_APPSVC
+ // Tranlate item: can be removed by application
+ elm_entry_context_menu_item_add(obj, "Translate", NULL,
+ ELM_ICON_STANDARD, NULL, NULL);
+#endif
+}
+
+EAPI void
+obj_unhook(Evas_Object *obj EINA_UNUSED)
+{
+ _mod_hook_count--;
+ if(_mod_hook_count > 0) return;
+
+ if(ext_mod)
+ {
+ evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_DOWN,
+ _parent_mouse_down_cb);
+ evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_UP,
+ _parent_mouse_up_cb);
+ if (ext_mod->show_timer)
+ {
+ ecore_timer_del(ext_mod->show_timer);
+ ext_mod->show_timer = NULL;
+ }
+ if (ext_mod->popup)
+ {
+ evas_object_del(ext_mod->popup);
+ ext_mod->popup = NULL;
+ }
+ if (ext_mod->source_text)
+ {
+ free(ext_mod->source_text);
+ ext_mod->source_text = NULL;
+ }
+ if (ext_mod->target_text)
+ {
+ free(ext_mod->target_text);
+ ext_mod->target_text = NULL;
+ }
+ if (ext_mod->viewport_rect)
+ eina_rectangle_free(ext_mod->viewport_rect);
+ free(ext_mod);
+ ext_mod = NULL;
+ }
+}
+
+EAPI void
+obj_longpress(Evas_Object *obj)
+{
+ if(!ext_mod) return;
+ LOG("IN\n\n");
+
+ Evas_Object *ctxparent;
+ Evas_Object *parent, *child;
+ const Eina_List *l;
+ const Elm_Entry_Context_Menu_Item *it;
+ const char *context_menu_orientation;
+ Evas_Object* icon;
+ Elm_Object_Item *added_item = NULL;
+ Eina_Bool has_clipboard = EINA_FALSE;
+#if HAVE_APPSVC
+ Eina_Bool has_translate = EINA_FALSE;
+#endif
+ Ecore_X_Atom first_cbhm_item_type = 0;
+ Eina_Bool has_focused = EINA_FALSE;
+
+ /*update*/
+ if (ext_mod->viewport_rect)
+ eina_rectangle_free(ext_mod->viewport_rect);
+ elm_entry_extension_module_data_get(obj, ext_mod);
+ has_focused = elm_widget_focus_get(obj);
+ if (ext_mod->context_menu && has_focused)
+ {
+ Eina_List *lao = NULL;
+ Evas_Object *ao = NULL;
+#ifdef HAVE_ELEMENTARY_X
+ int cbhm_count = 0;
+ if (elm_entry_cnp_mode_get(obj) != ELM_CNP_MODE_MARKUP)
+ cbhm_count = _cbhm_item_count_get(obj, ATOM_INDEX_CBHM_COUNT_TEXT);
+ else
+ cbhm_count = _cbhm_item_count_get(obj, ATOM_INDEX_CBHM_COUNT_ALL);
+#endif
+ if (ext_mod->popup)
+ {
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _entry_del_cb);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_HIDE, _entry_hide_cb);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_MOVE, _entry_move_cb);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_DOWN, _entry_mouse_down_cb);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE, _entry_mouse_move_cb);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_UP, _entry_mouse_up_cb);
+ evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_DOWN,
+ _parent_mouse_down_cb);
+ evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_UP,
+ _parent_mouse_up_cb);
+ evas_object_smart_callback_del(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb);
+ if (ext_mod->ent_scroll)
+ {
+ evas_object_smart_callback_del(obj, "scroll", _entry_scroll_cb);
+ }
+ evas_object_del(ext_mod->popup);
+ ext_mod->popup = NULL;
+ }
+ ctxparent = elm_widget_top_get(obj);
+ parent = elm_widget_parent_get(obj);
+ child = obj;
+ if (parent)
+ {
+ while(parent)
+ {
+ const char *type = elm_widget_type_get(parent);
+ if ((type) && (!strcmp(type, "Elm_Conformant")))
+ {
+ ctxparent = child;
+ break;
+ }
+ child = parent;
+ parent = elm_widget_parent_get(parent);
+ }
+ }
+ ext_mod->ctx_par = ctxparent;
+
+ if(ctxparent)
+ {
+ ext_mod->popup = elm_ctxpopup_add(ctxparent);
+ if (ext_mod->_elm_config->access_mode)
+ {
+ elm_object_tree_focus_allow_set(ext_mod->popup, EINA_TRUE);
+ elm_object_focus_allow_set(ext_mod->popup, EINA_FALSE);
+ }
+ else
+ {
+ elm_object_tree_focus_allow_set(ext_mod->popup, EINA_FALSE);
+ }
+ evas_object_smart_callback_add(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb, obj);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _entry_del_cb, ext_mod->popup);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _entry_hide_cb, ext_mod->popup);
+ }
+ else
+ {
+ ext_mod->caller = NULL;
+ LOG("Have no parent\n");
+ return;
+ }
+ elm_object_style_set(ext_mod->popup, "copypaste");
+
+ elm_ctxpopup_horizontal_set(ext_mod->popup, EINA_TRUE);
+ context_menu_orientation = edje_object_data_get
+ (ext_mod->ent, "context_menu_orientation");
+ if ((context_menu_orientation) &&
+ (!strcmp(context_menu_orientation, "vertical")))
+ elm_ctxpopup_horizontal_set(ext_mod->popup, EINA_FALSE);
+
+ EINA_LIST_FOREACH(ext_mod->items, l, it)
+ {
+ if (!strcmp(it->label, "Clipboard"))
+ has_clipboard = EINA_TRUE;
+#if HAVE_APPSVC
+ else if (!strcmp(it->label, "Translate"))
+ has_translate = EINA_TRUE;
+#endif
+ }
+
+ if (!ext_mod->selmode && !ext_mod->have_selection)
+ {
+ if (!elm_entry_is_empty(obj))
+ {
+ if (!ext_mod->password)
+ {
+#ifndef ELM_FEATURE_WEARABLE
+ CP_ICON_ADD(icon, "select");
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_SK_SELECT"), icon, _select, obj);
+ ACCESS_FOCUS_ENABLE();
+#endif
+ }
+
+ CP_ICON_ADD(icon, "select_all");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _select_all, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_SELECT_ALL"),
+ icon, _select_all, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+
+#ifdef HAVE_ELEMENTARY_X
+ if (cbhm_count)
+#else
+ if (1) // need way to detect if someone has a selection
+#endif
+ {
+ if (elm_entry_cnp_mode_get(obj) == ELM_CNP_MODE_PLAINTEXT)
+ {
+#ifdef HAVE_ELEMENTARY_X
+ _cbhm_item_get(obj, 0, &first_cbhm_item_type, NULL);
+ if (ext_mod->editable &&
+ !(first_cbhm_item_type == ecore_x_atom_get("text/uri")) &&
+ !(first_cbhm_item_type == ecore_x_atom_get("text/uri-list")))
+#endif
+ {
+ CP_ICON_ADD(icon, "paste");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _paste, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_PASTE"),
+ icon, _paste, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+ }
+ else
+ {
+ if (ext_mod->editable)
+ {
+ CP_ICON_ADD(icon, "paste");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _paste, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_PASTE"),
+ icon, _paste, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+ }
+ }
+ // start for cbhm
+#ifdef HAVE_ELEMENTARY_X
+ if ((ext_mod->editable) && (cbhm_count) && (has_clipboard))
+#else
+ if ((ext_mod->editable) && (has_clipboard))
+#endif
+ {
+ CP_ICON_ADD(icon, "clipboard");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _clipboard_menu, obj); // Clipboard
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_CLIPBOARD"),
+ icon, _clipboard_menu, obj); // Clipboard
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+ // end for cbhm
+#if HAVE_APPSVC
+ const char *entry_str;
+ entry_str = elm_entry_selection_get(obj);
+ if ((entry_str) && (has_translate))
+ {
+ CP_ICON_ADD(icon, "translate");
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, S_TRANSLATE,
+ icon, _translate_menu, obj);
+ ACCESS_FOCUS_ENABLE();
+ }
+#endif
+ }
+ else
+ {
+ if (ext_mod->have_selection)
+ {
+ Eina_Bool selected_all = EINA_TRUE;
+ ext_mod->is_selected_all(&selected_all, obj, NULL);
+ if (selected_all == EINA_FALSE)
+ {
+ CP_ICON_ADD(icon, "select_all");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _select_all, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_SELECT_ALL"),
+ icon, _select_all, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+
+ if (!ext_mod->password)
+ {
+ CP_ICON_ADD(icon, "copy");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _copy, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_COPY"),
+ icon, _copy, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ if (ext_mod->editable)
+ {
+ CP_ICON_ADD(icon, "cut");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _cut, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_CUT"),
+ icon, _cut, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+ }
+
+#ifdef HAVE_ELEMENTARY_X
+ if (ext_mod->editable && cbhm_count)
+#else
+ if (ext_mod->editable)
+#endif
+ {
+ if (elm_entry_cnp_mode_get(obj) == ELM_CNP_MODE_PLAINTEXT)
+ {
+#ifdef HAVE_ELEMENTARY_X
+ _cbhm_item_get(obj, 0, &first_cbhm_item_type, NULL);
+ if (!(first_cbhm_item_type == ecore_x_atom_get("text/uri")) &&
+ !(first_cbhm_item_type == ecore_x_atom_get("text/uri-list")))
+#endif
+ {
+ CP_ICON_ADD(icon, "paste");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _paste, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_PASTE"),
+ icon, _paste, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+ }
+ else
+ {
+ CP_ICON_ADD(icon, "paste");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _paste, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_PASTE"),
+ icon, _paste, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+ }
+ }
+ else
+ {
+ _cancel(obj,ext_mod->popup,NULL);
+ if (!elm_entry_is_empty(obj))
+ {
+ if (!ext_mod->password)
+ {
+#ifndef ELM_FEATURE_WEARABLE
+ CP_ICON_ADD(icon, "select");
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_SK_SELECT"),
+ icon, _select, obj);
+ ACCESS_FOCUS_ENABLE();
+#endif
+ }
+
+ CP_ICON_ADD(icon, "select_all");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _select_all, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_SELECT_ALL"),
+ icon, _select_all, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+#ifdef HAVE_ELEMENTARY_X
+ if (cbhm_count)
+#else
+ if (1) // need way to detect if someone has a selection
+#endif
+ {
+ if (ext_mod->editable)
+ {
+ if (elm_entry_cnp_mode_get(obj) == ELM_CNP_MODE_PLAINTEXT)
+ {
+#ifdef HAVE_ELEMENTARY_X
+ _cbhm_item_get(obj, 0, &first_cbhm_item_type, NULL);
+ if (!(first_cbhm_item_type == ecore_x_atom_get("text/uri")) &&
+ !(first_cbhm_item_type == ecore_x_atom_get("text/uri-list")))
+#endif
+ {
+ CP_ICON_ADD(icon, "paste");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _paste, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_PASTE"),
+ icon, _paste, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+ }
+ else
+ {
+ CP_ICON_ADD(icon, "paste");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _paste, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_PASTE"),
+ icon, _paste, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+ }
+ }
+ }
+ // start for cbhm
+#ifdef HAVE_ELEMENTARY_X
+ if ((ext_mod->editable) && (cbhm_count) && (has_clipboard))
+#else
+ if ((ext_mod->editable) && (has_clipboard))
+#endif
+ {
+ CP_ICON_ADD(icon, "clipboard");
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ icon, _clipboard_menu, obj);
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, dgettext("elementary", "IDS_COM_BODY_CLIPBOARD"),
+ icon, _clipboard_menu, obj);
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+ // end for cbhm
+#if HAVE_APPSVC
+ const char *entry_str;
+ entry_str = elm_entry_selection_get(obj);
+ if ((entry_str) && (has_translate))
+ {
+ CP_ICON_ADD(icon, "translate");
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, S_TRANSLATE,
+ icon, _translate_menu, obj);
+ ACCESS_FOCUS_ENABLE();
+ }
+#endif
+ }
+ EINA_LIST_FOREACH(ext_mod->items, l, it)
+ {
+ if (strcmp(it->label, "Clipboard") && strcmp(it->label, "Translate"))
+ {
+ Evas_Object *ic = NULL;
+ if (it->icon_file)
+ {
+ ic = elm_icon_add(obj);
+ elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
+ if (it->icon_type == ELM_ICON_FILE)
+ elm_image_file_set(ic, it->icon_file, it->icon_group);
+ else if (it->icon_type == ELM_ICON_STANDARD)
+ elm_icon_standard_set(ic, it->icon_file);
+ }
+#ifdef ELM_FEATURE_WEARABLE
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
+ ic, _item_clicked, it );
+#else
+ added_item = elm_ctxpopup_item_append(ext_mod->popup, it->label,
+ ic, _item_clicked, it );
+#endif
+ ACCESS_FOCUS_ENABLE();
+ }
+ }
+ if (ext_mod->popup && added_item)
+ {
+ Evas_Object *first_it_ao, *cur_it_ao, *prev_it_ao;
+ Evas_Object *popup_ao;
+ Elm_Widget_Smart_Data *wd;
+ Evas_Object *po;
+ int layer;
+ int count, itn;
+ Eina_List *lc;
+
+ ext_mod->caller = obj;
+ if (_in_viewport_check())
+ {
+ ext_mod->popup_showing = EINA_TRUE;
+ _ctxpopup_position(obj);
+ evas_object_show(ext_mod->popup);
+ ext_mod->popup_clicked = EINA_FALSE;
+ ext_mod->mouse_up = EINA_FALSE;
+ LOG("In viewport: will show popup\n");
+ }
+ else
+ LOG("NOT IN VIEWPORT, NO POPUP SHOWING\n\n");
+
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _entry_move_cb, ext_mod->popup);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
+ _entry_mouse_down_cb, ext_mod->popup);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
+ _entry_mouse_move_cb, ext_mod->popup);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
+ _entry_mouse_up_cb, ext_mod->popup);
+ evas_object_event_callback_add(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_DOWN,
+ _parent_mouse_down_cb, ext_mod->popup);
+ evas_object_event_callback_add(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_UP,
+ _parent_mouse_up_cb, ext_mod->popup);
+ if (ext_mod->ent_scroll)
+ {
+ evas_object_smart_callback_add(obj, "scroll", _entry_scroll_cb, ext_mod->popup);
+ }
+ layer = evas_object_layer_get(ext_mod->caller);
+ layer = layer >= EVAS_LAYER_MAX ? EVAS_LAYER_MAX : layer + 1;
+ evas_object_layer_set(ext_mod->popup, layer);
+
+ if (ext_mod->_elm_config->access_mode)
+ {
+ wd = evas_object_smart_data_get(ext_mod->popup);
+ po = (Evas_Object *)edje_object_part_object_get(wd->resize_obj,
+ "access.outline");
+ popup_ao = elm_access_object_get(po);
+ count = eina_list_count(lao);
+ first_it_ao = eina_list_data_get(lao);
+ elm_access_highlight_next_set(popup_ao,
+ ELM_HIGHLIGHT_DIR_NEXT,
+ first_it_ao);
+ elm_access_highlight_next_set(first_it_ao,
+ ELM_HIGHLIGHT_DIR_PREVIOUS,
+ popup_ao);
+ prev_it_ao = eina_list_data_get(lao);
+ itn = 1;
+ EINA_LIST_FOREACH(lao, lc, cur_it_ao)
+ {
+ if (itn == count)
+ {
+ elm_access_highlight_next_set(prev_it_ao,
+ ELM_HIGHLIGHT_DIR_NEXT,
+ cur_it_ao);
+ elm_access_highlight_next_set(cur_it_ao,
+ ELM_HIGHLIGHT_DIR_PREVIOUS,
+ prev_it_ao);
+ elm_access_highlight_next_set(cur_it_ao,
+ ELM_HIGHLIGHT_DIR_NEXT,
+ popup_ao);
+ elm_access_highlight_next_set(popup_ao,
+ ELM_HIGHLIGHT_DIR_PREVIOUS,
+ cur_it_ao);
+ }
+ else if (itn > 1)
+ {
+ elm_access_highlight_next_set(prev_it_ao,
+ ELM_HIGHLIGHT_DIR_NEXT,
+ cur_it_ao);
+ elm_access_highlight_next_set(cur_it_ao,
+ ELM_HIGHLIGHT_DIR_PREVIOUS,
+ prev_it_ao);
+ }
+ itn++;
+ prev_it_ao = cur_it_ao;
+ }
+ elm_access_highlight_set(popup_ao);
+ }
+ eina_list_free(lao);
+ }
+ else
+ ext_mod->caller = NULL;
+ }
+}
+
+EAPI void
+obj_mouseup(Evas_Object *obj)
+{
+ if (!obj || !ext_mod)
+ return;
+}
+
+
+EAPI void
+obj_hidemenu(Evas_Object *obj)
+{
+ if (!obj || !ext_mod || obj != ext_mod->caller)
+ return;
+
+ _ctxpopup_hide(ext_mod->popup);
+ // if (ext_mod->popup) evas_object_del(ext_mod->popup);
+}
+
+EAPI void
+obj_update_popup_pos(Evas_Object *obj)
+{
+ if (!obj || !ext_mod || !ext_mod->popup || !ext_mod->popup_showing ||
+ (obj != ext_mod->caller))
+ return;
+
+ elm_entry_extension_module_data_get(obj, ext_mod);
+ LOG("call _ctxpopup_position");
+ _ctxpopup_position(obj);
+}
+
+EAPI Eina_Bool
+obj_popup_showing_get(Evas_Object *obj)
+{
+ if ((!obj) || (!ext_mod) || (obj != ext_mod->caller))
+ return EINA_FALSE;
+ if (!ext_mod->popup)
+ return EINA_FALSE;
+ return evas_object_visible_get(ext_mod->popup);
+}