tizen 2.3 release
[framework/uifw/elementary.git] / src / modules / ctxpopup_copypasteUI / copypaste.c
1 #include <Elementary.h>
2 #include "elm_module_priv.h"
3 #include "elm_priv.h"
4
5 #if HAVE_APPSVC
6 #include <appsvc/appsvc.h>
7 #endif
8
9 #include "cbhm_helper.h"
10
11 #define MULTI_(id) dgettext("sys_string", #id)
12 #define S_SELECT MULTI_(IDS_COM_SK_SELECT)
13 #define S_SELECT_ALL MULTI_(IDS_COM_BODY_SELECT_ALL)
14 #define S_COPY MULTI_(IDS_COM_BODY_COPY)
15 #define S_CUT MULTI_(IDS_COM_BODY_CUT)
16 #define S_PASTE MULTI_(IDS_COM_BODY_PASTE)
17 #define S_CLIPBOARD MULTI_(IDS_COM_BODY_CLIPBOARD)
18 #define S_COPIED MULTI_(IDS_COM_POP_COPIED_TO_CLIPBOARD)
19 #define S_TRANSLATE dgettext("elementary", "Translate")
20
21 #define CP_ICON_THEME_SET(ITEM) elm_widget_theme_object_set(ext_mod->popup, \
22                                                            icon,"copypaste", ITEM, "default")
23
24 Elm_Entry_Extension_data *ext_mod;
25 static int _mod_hook_count = 0;
26
27 typedef struct _Elm_Entry_Context_Menu_Item Elm_Entry_Context_Menu_Item;
28
29 struct _Elm_Entry_Context_Menu_Item
30 {
31    Evas_Object *obj;
32    const char *label;
33    const char *icon_file;
34    const char *icon_group;
35    Elm_Icon_Type icon_type;
36    Evas_Smart_Cb func;
37    void *data;
38 };
39
40 static void _entry_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
41 static void _entry_hide_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
42 static void _entry_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
43 static void _entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
44 static void _entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
45 static void _ctxpopup_hide(Evas_Object *popup);
46 static void _ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info);
47 void obj_longpress(Evas_Object *obj);
48
49 #if HAVE_APPSVC
50 static char *
51 _remove_tags(const char *str)
52 {
53    char *ret;
54    if (!str)
55      return NULL;
56
57    Eina_Strbuf *buf = eina_strbuf_new();
58    if (!buf)
59      return NULL;
60
61    if (!eina_strbuf_append(buf, str))
62      {
63         eina_strbuf_free(buf);
64         return NULL;
65      }
66
67    eina_strbuf_replace_all(buf, "<br>", " ");
68    eina_strbuf_replace_all(buf, "<br/>", " ");
69    eina_strbuf_replace_all(buf, "<ps>", " ");
70    eina_strbuf_replace_all(buf, "<ps/>", " ");
71
72    while (EINA_TRUE)
73      {
74         const char *temp = eina_strbuf_string_get(buf);
75
76         char *startTag = NULL;
77         char *endTag = NULL;
78
79         startTag = strstr(temp, "<");
80         if (startTag)
81           endTag = strstr(startTag, ">");
82         else
83           break;
84         if (!endTag || startTag > endTag)
85           break;
86
87         size_t sindex = startTag - temp;
88         size_t eindex = endTag - temp + 1;
89         if (!eina_strbuf_remove(buf, sindex, eindex))
90           break;
91      }
92    ret = eina_strbuf_string_steal(buf);
93    eina_strbuf_free(buf);
94    return ret;
95 }
96 #endif
97
98 static void
99 _parent_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
100 {
101    if ((!ext_mod) || (!ext_mod->popup))
102      return;
103    ext_mod->popup_clicked = EINA_TRUE;
104    evas_object_hide(ext_mod->popup);
105    ext_mod->mouse_up = EINA_FALSE;
106    ext_mod->entry_move = EINA_FALSE;
107 }
108
109 static void
110 _parent_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
111 {
112    if ((!ext_mod) || (!ext_mod->popup))
113      return;
114    if ((ext_mod->popup_clicked) && (ext_mod->popup_showing))
115      {
116         ext_mod->popup_showing = EINA_FALSE;
117         evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_DEL, _entry_del_cb);
118         evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_HIDE, _entry_hide_cb);
119         evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_MOVE, _entry_move_cb);
120
121         evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_MOUSE_DOWN,
122                                        _entry_mouse_down_cb);
123         evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_MOUSE_UP,
124                                        _entry_mouse_up_cb);
125         evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_DOWN,
126                                        _parent_mouse_down_cb);
127         evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_UP,
128                                        _parent_mouse_up_cb);
129         evas_object_smart_callback_del(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb);
130      }
131 }
132
133 static void
134 _entry_del_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
135 {
136    if (ext_mod)
137      {
138         evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_DOWN,
139                                        _parent_mouse_down_cb);
140         evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_UP,
141                                        _parent_mouse_up_cb);
142         if (ext_mod->popup)
143           {
144              _ctxpopup_hide(ext_mod->popup);
145              evas_object_del(ext_mod->popup);
146              ext_mod->popup = NULL;
147           }
148      }
149 }
150
151 static void
152 _entry_hide_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
153 {
154    evas_object_hide(data);
155 }
156
157 static void
158 _entry_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
159 {
160    if ((!ext_mod) || (!ext_mod->popup))
161      return;
162    ext_mod->mouse_up = EINA_FALSE;
163    ext_mod->mouse_down = EINA_TRUE;
164 }
165
166 static Eina_Bool
167 _ctx_show(void *data)
168 {
169    ext_mod->show_timer = NULL;
170    if (!data) return ECORE_CALLBACK_CANCEL;
171    ext_mod->entry_move = EINA_FALSE;
172    if (ext_mod->popup_showing)
173      {
174         obj_longpress(data);
175      }
176    return ECORE_CALLBACK_CANCEL;
177 }
178
179 static void
180 _entry_mouse_up_cb(void *data  __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
181 {
182    if (!ext_mod)
183      return;
184    if (ext_mod->mouse_down && ext_mod->entry_move)
185      {
186         evas_object_smart_callback_del(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb);
187         if (ext_mod->show_timer) ecore_timer_del(ext_mod->show_timer);
188         ext_mod->show_timer = ecore_timer_add(0.1, _ctx_show, obj);
189      }
190    ext_mod->mouse_up = EINA_TRUE;
191    ext_mod->mouse_down = EINA_FALSE;
192 }
193
194 static void
195 _entry_move_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
196 {
197    if (!ext_mod)
198      return;
199    ext_mod->entry_move = EINA_TRUE;
200    ext_mod->popup_clicked = EINA_FALSE;
201    evas_object_hide(ext_mod->popup);
202    evas_object_smart_callback_del(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb);
203    if (ext_mod->show_timer) ecore_timer_del(ext_mod->show_timer);
204    ext_mod->show_timer = ecore_timer_add(0.1, _ctx_show, obj);
205 }
206
207 static void
208 _ctxpopup_hide(Evas_Object *popup)
209 {
210    if (!ext_mod->popup_showing) return;
211    ext_mod->popup_showing = EINA_FALSE;
212    evas_object_hide(popup);
213    evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_DEL, _entry_del_cb);
214    evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_HIDE, _entry_hide_cb);
215    evas_object_event_callback_del(ext_mod->caller, EVAS_CALLBACK_MOVE, _entry_move_cb);
216    if (_elm_config->access_mode && ext_mod->caller)
217      _elm_access_highlight_set(ext_mod->caller, EINA_TRUE);
218 }
219
220 static Eina_Bool
221 _in_viewport_check()
222 {
223    if (!ext_mod) return EINA_FALSE;
224
225    Evas_Coord sx, sy, sw, sh;
226    Eina_Rectangle vp;
227
228    /*update*/
229    if (ext_mod->caller)
230      elm_entry_extension_module_data_get(ext_mod->caller, ext_mod);
231
232    vp.x = ext_mod->viewport_rect.x;
233    vp.y = ext_mod->viewport_rect.y;
234    vp.w = ext_mod->viewport_rect.w;
235    vp.h = ext_mod->viewport_rect.h;
236
237    if (edje_object_part_text_selection_geometry_get(ext_mod->ent, "elm.text", &sx, &sy, &sw, &sh))
238      {
239         if ((ext_mod->viewport_rect.x != -1) || (ext_mod->viewport_rect.y != -1) ||
240             (ext_mod->viewport_rect.w != -1) || (ext_mod->viewport_rect.h != -1))
241           {
242              Eina_Rectangle sel;
243
244              sel.x = sx;
245              sel.y = sy;
246              sel.w = sw;
247              sel.h = sh;
248              if (eina_rectangle_intersection(&sel, &vp))
249                {
250                   return EINA_TRUE;
251                }
252              return EINA_FALSE;
253           }
254         return EINA_TRUE;
255      }
256    else
257      {
258         if ((ext_mod->viewport_rect.x != -1) || (ext_mod->viewport_rect.y != -1) ||
259             (ext_mod->viewport_rect.w != -1) || (ext_mod->viewport_rect.h != -1))
260           {
261              Evas_Coord ex, ey;
262              Evas_Coord cx, cy, cw, ch;
263              Eina_Rectangle cur;
264
265              evas_object_geometry_get(ext_mod->ent, &ex, &ey, NULL, NULL);
266              edje_object_part_text_cursor_geometry_get(ext_mod->ent, "elm.text",
267                                                        &cx, &cy, &cw, &ch);
268              cx = ex + cx;
269              cy = ey + cy;
270              cur.x = cx;
271              cur.y = cy;
272              cur.w = cw;
273              cur.h = ch;
274              if (eina_rectangle_intersection(&cur, &vp))
275                {
276                   return EINA_TRUE;
277                }
278              return EINA_FALSE;
279           }
280         return EINA_TRUE;
281      }
282    return EINA_FALSE;
283 }
284
285 static void
286 _ctxpopup_position(Evas_Object *obj __UNUSED__)
287 {
288    if(!ext_mod) return;
289
290    Evas_Coord ex, ey;
291    Evas_Coord sx, sy, sw, sh;
292    Evas_Coord x, y, w, h;
293    int gap = 13; //in GUI
294    Eina_Bool avai;
295
296    evas_object_geometry_get(ext_mod->ent, &ex, &ey, NULL, NULL);
297    elm_ctxpopup_direction_priority_set(ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP,
298                                        ELM_CTXPOPUP_DIRECTION_DOWN, ELM_CTXPOPUP_DIRECTION_LEFT,
299                                        ELM_CTXPOPUP_DIRECTION_RIGHT);
300    if (!edje_object_part_text_selection_geometry_get(ext_mod->ent, "elm.text", &sx, &sy, &sw, &sh))
301      { //cannot get selection shape
302         Evas_Coord cx, cy, cw, ch;
303         Evas_Coord chx, chy, chw, chh;
304         Eina_Bool ch_visible = EINA_FALSE;
305         Eina_Bool need_update = EINA_FALSE;
306         Eina_Bool up_avai, down_avai;
307
308         edje_object_part_text_cursor_geometry_get(ext_mod->ent, "elm.text",
309                                                   &cx, &cy, &cw, &ch);
310         x = ex + cx;
311         y = ey + cy;
312         evas_object_move(ext_mod->popup, x, y);
313         avai = elm_ctxpopup_direction_available_get
314            (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_DOWN);
315         if (avai == EINA_TRUE)
316           {
317              elm_ctxpopup_direction_priority_set(ext_mod->popup,
318                                                  ELM_CTXPOPUP_DIRECTION_DOWN,
319                                                  ELM_CTXPOPUP_DIRECTION_UP,
320                                                  ELM_CTXPOPUP_DIRECTION_LEFT,
321                                                  ELM_CTXPOPUP_DIRECTION_RIGHT);
322              x = ex + cx;
323              y = ey + cy + ch;
324              evas_object_move(ext_mod->popup, x, y);
325              avai = elm_ctxpopup_direction_available_get
326                 (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP);
327              if (avai == EINA_TRUE)
328                need_update = EINA_TRUE;
329           }
330
331         //limit ctx in viewport
332         if (ext_mod->viewport_rect.x != -1 || ext_mod->viewport_rect.y != -1
333             || ext_mod->viewport_rect.w != -1 || ext_mod->viewport_rect.h != -1)
334           {
335              if (ext_mod->viewport_rect.x > x)
336                x = ext_mod->viewport_rect.x;
337              else if (x > ext_mod->viewport_rect.x + ext_mod->viewport_rect.w)
338                x = ext_mod->viewport_rect.x + ext_mod->viewport_rect.w;
339
340              if (ext_mod->viewport_rect.y > y)
341                y = ext_mod->viewport_rect.y;
342              else if (y > ext_mod->viewport_rect.y + ext_mod->viewport_rect.h)
343                y = ext_mod->viewport_rect.y + ext_mod->viewport_rect.h;
344           }
345
346         evas_object_move(ext_mod->popup, x, y);
347
348         ch_visible = edje_object_part_text_cursor_handler_geometry_get
349                         (ext_mod->ent, "elm.text", &chx, &chy, &chw, &chh);
350         up_avai = elm_ctxpopup_direction_available_get
351            (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP);
352         down_avai = elm_ctxpopup_direction_available_get
353            (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_DOWN);
354         //move to above or below cursor handler
355         if (ch_visible)
356           {
357              if ((chy < cy) && (up_avai == EINA_TRUE))
358                {
359                   y = ey + chy;
360                   evas_object_move(ext_mod->popup, x, y);
361                   up_avai = elm_ctxpopup_direction_available_get
362                      (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP);
363                   if (up_avai == EINA_FALSE)
364                     need_update = EINA_TRUE;
365                }
366              else if ((chy > cy) && (down_avai == EINA_TRUE))
367                {
368                   y = ey + chy + chh;
369                   evas_object_move(ext_mod->popup, x, y);
370                   down_avai = elm_ctxpopup_direction_available_get
371                      (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_DOWN);
372                   if (down_avai == EINA_FALSE)
373                     need_update = EINA_TRUE;
374                }
375           }
376         if (((up_avai == EINA_FALSE) && (down_avai == EINA_FALSE)) || need_update)
377           {
378              y = ey + cy + ch / 2;
379              elm_ctxpopup_direction_priority_set(ext_mod->popup,
380                                                  ELM_CTXPOPUP_DIRECTION_LEFT,
381                                                  ELM_CTXPOPUP_DIRECTION_RIGHT,
382                                                  ELM_CTXPOPUP_DIRECTION_UP,
383                                                  ELM_CTXPOPUP_DIRECTION_DOWN);
384              evas_object_move(ext_mod->popup, x, y);
385           }
386      }
387    else //get selection shape
388      {
389         Evas_Coord shx, shy, shw, shh;
390         Evas_Coord ehx, ehy, ehw, ehh;
391         /* Currently, we cannot get size of ctxpopup, we must set hard value for threshold.
392            After fixing ctxpopup, we can get correctly threshold */
393         Evas_Coord threshold = 300;
394
395         edje_object_part_text_selection_handler_geometry_get(ext_mod->ent, "elm.text",
396                                                              EDJE_SELECTION_HANDLER_START,
397                                                              &shx, &shy, &shw, &shh);
398         edje_object_part_text_selection_handler_geometry_get(ext_mod->ent, "elm.text",
399                                                              EDJE_SELECTION_HANDLER_END,
400                                                              &ehx, &ehy, &ehw, &ehh);
401         if (ext_mod->viewport_rect.x != -1 || ext_mod->viewport_rect.y != -1
402             || ext_mod->viewport_rect.w != -1 || ext_mod->viewport_rect.h != -1)
403           {
404              Evas_Coord vx, vy, vw, vh, x2, y2;
405              x2 = sx + sw;
406              if ((ehh > 0) && (ey + ehy + ehh > sy + sh))
407                {
408                   //y2 = ey + ehy + ehh;
409                   y2 = ey + ehy + gap;
410                }
411              else
412                y2 = sy + sh;
413              vx = ext_mod->viewport_rect.x;
414              vy = ext_mod->viewport_rect.y;
415              vw = ext_mod->viewport_rect.w;
416              vh = ext_mod->viewport_rect.h;
417
418              //limit ctx in viewport
419              x = sx;
420              if (sx < vx) x = vx;
421              if (sy < vy)
422                {
423                   y = vy; //case: start of selection is behind the viewport
424                }
425              else
426                {
427                   if ((sx >= vx) && (ey + shy < sy)) //case: start handler is upside
428                     {
429                        y = ey + shy;
430                        w = x2 - x;
431                        evas_object_move(ext_mod->popup, x + w/2, y);
432                        avai = elm_ctxpopup_direction_available_get
433                           (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP);
434                        if (avai == EINA_FALSE)
435                          {
436                             y = sy - gap;
437                          }
438                     }
439                   else if ((sx + sw <= vx + vw) && (ey + ehy < sy))
440                     {
441                        y = ey + ehy;
442                     }
443                   else
444                     y = sy;
445                }
446              if (x2 > vx + vw) x2 = vx + vw;
447              if (y2 > vy + vh) y2 = vy + vh;
448              w = x2 - x;
449              h = y2 - y;
450              evas_object_move(ext_mod->popup, x + w/2, y);
451              avai = elm_ctxpopup_direction_available_get
452                 (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP);
453              if (avai == EINA_TRUE)
454                return;
455           }
456         else //get selection & cannot get viewport
457           {
458              Evas_Coord ww, wh, x2, y2;
459              x2 = sx + sw;
460              if (ey + ehy + ehh > sy + sh)
461                y2 = ey + ehy + ehh; //end handler is downside
462              else
463                y2 = sy + sh;
464
465              ecore_x_window_size_get(ecore_x_window_root_first_get(), &ww, &wh);
466
467              x = sx;
468              if (sx < 0) x = 0;
469              if (sy < 0)
470                {
471                   y = 0; //start of selection is negative
472                }
473              else
474                {
475                   if (ey + shy < sy) //start handler is upside
476                     {
477                        y = ey + shy;
478                        w = x2 - x;
479                        evas_object_move(ext_mod->popup, x + w/2, y);
480                        avai = elm_ctxpopup_direction_available_get
481                           (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP);
482                        if (avai == EINA_FALSE)
483                          {
484                             y = sy - gap;
485                          }
486                     }
487                   else
488                     y = sy;
489                }
490              if (x2 > ww) x2 = ww;
491              if (y2 > wh) y2 = wh;
492              w = x2 - x;
493              h = y2 - y;
494           }
495         x = x + (w / 2);
496         evas_object_move(ext_mod->popup, x, y);
497
498         avai = elm_ctxpopup_direction_available_get
499            (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP);
500         if (avai == EINA_FALSE)
501           {
502              Eina_Rectangle vp;
503              Eina_Rectangle sel; //selection area which is not covered by start,end sel handlers
504              Evas_Coord cry;
505
506              elm_ctxpopup_direction_priority_set(ext_mod->popup, ELM_CTXPOPUP_DIRECTION_DOWN,
507                                                  ELM_CTXPOPUP_DIRECTION_UP,
508                                                  ELM_CTXPOPUP_DIRECTION_LEFT,
509                                                  ELM_CTXPOPUP_DIRECTION_RIGHT);
510              vp.x = ext_mod->viewport_rect.x;
511              vp.y = ext_mod->viewport_rect.y;
512              vp.w = ext_mod->viewport_rect.w;
513              vp.h = ext_mod->viewport_rect.h;
514              sel.x = sx;
515              if (ey + shy + shh < sy + sh)
516                sel.y = sy > ey + shy + shh ? sy : ey + shy + shh;
517              else
518                sel.y = sy;
519              sel.w = sw;
520              cry = sy + sh < ey + ehy ? sy + sh : ey + ehy;
521              sel.h = cry > sel.y ? cry - sel.y : sel.y - cry;
522              if ((eina_rectangle_intersection(&sel, &vp)) && (sel.h > threshold))
523                {
524                   elm_ctxpopup_direction_priority_set(ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP,
525                                                       ELM_CTXPOPUP_DIRECTION_DOWN,
526                                                       ELM_CTXPOPUP_DIRECTION_LEFT,
527                                                       ELM_CTXPOPUP_DIRECTION_RIGHT);
528                   evas_object_move(ext_mod->popup, x, sel.y + sel.h/2);
529                   avai = elm_ctxpopup_direction_available_get
530                      (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP);
531                   if (avai == EINA_TRUE)
532                     return;
533                }
534
535              y = sel.y + sel.h;
536              if ((y < ey + ehy + ehh) && (ey + ehy < vp.y + vp.h)) //end handler is downside
537                {
538                   y = ey + ehy + ehh;
539                   evas_object_move(ext_mod->popup, x, y);
540                   avai = elm_ctxpopup_direction_available_get
541                      (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_DOWN);
542                   if (avai == EINA_TRUE)
543                     return;
544                   y = sy + sh + gap;
545                   evas_object_move(ext_mod->popup, x, y);
546                   avai = elm_ctxpopup_direction_available_get
547                      (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_DOWN);
548                   if (avai == EINA_TRUE)
549                     return;
550                }
551              y = ey + ehy + ehh;
552              evas_object_move(ext_mod->popup, x, y);
553              avai = elm_ctxpopup_direction_available_get
554                 (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_DOWN);
555              if (avai == EINA_TRUE)
556                return;
557
558              // not enough space and small viewport (like landscape mode)
559              sel.x = sx;
560              sel.y = sy;
561              sel.w = sw;
562              sel.h = sh;
563              if (!eina_rectangle_intersection(&sel, &vp))
564                return;
565
566              if (ey + shy < sel.y) //start handler is up side
567                {
568                   y = ey + shy;
569                   while (y <= sel.y + ehh/2)
570                     {
571                        evas_object_move(ext_mod->popup, x, y);
572                        avai = elm_ctxpopup_direction_available_get
573                           (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_UP);
574                        if (avai == EINA_TRUE)
575                          return;
576                        y += shh/4;
577                     }
578                }
579              else
580                {
581                   if (ey + ehy + ehh > sel.y + sel.h) //end handler is down side
582                     {
583                        y = ey + ehy + ehh;
584                        while (y > sel.y + sel.h - ehh/2)
585                          {
586                             evas_object_move(ext_mod->popup, x, y);
587                             avai = elm_ctxpopup_direction_available_get
588                                (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_DOWN);
589                             if (avai == EINA_TRUE)
590                               return;
591                             y -= ehh/4;
592                          }
593                     }
594                   else
595                     {
596                        y = sel.y + sel.h;
597                        while (y > sel.y + sel.h - ehh/2)
598                          {
599                             evas_object_move(ext_mod->popup, x, y);
600                             avai = elm_ctxpopup_direction_available_get
601                                (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_DOWN);
602                             if (avai == EINA_TRUE)
603                               return;
604                             y -= ehh/4;
605                          }
606                     }
607                }
608
609              elm_ctxpopup_direction_priority_set(ext_mod->popup,
610                                                  ELM_CTXPOPUP_DIRECTION_LEFT,
611                                                  ELM_CTXPOPUP_DIRECTION_RIGHT,
612                                                  ELM_CTXPOPUP_DIRECTION_UP,
613                                                  ELM_CTXPOPUP_DIRECTION_DOWN);
614              x = sel.x;
615              y = sel.y + sel.h/2;
616              evas_object_move(ext_mod->popup, x, y);
617              avai = elm_ctxpopup_direction_available_get
618                 (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_LEFT);
619              if (avai == EINA_TRUE)
620                return;
621
622              x = sel.x;
623              y = sel.y + sel.h;
624              evas_object_move(ext_mod->popup, x, y);
625              avai = elm_ctxpopup_direction_available_get
626                 (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_LEFT);
627              if (avai == EINA_TRUE)
628                return;
629
630              elm_ctxpopup_direction_priority_set(ext_mod->popup,
631                                                  ELM_CTXPOPUP_DIRECTION_RIGHT,
632                                                  ELM_CTXPOPUP_DIRECTION_LEFT,
633                                                  ELM_CTXPOPUP_DIRECTION_UP,
634                                                  ELM_CTXPOPUP_DIRECTION_DOWN);
635              x = sel.x + sel.w;
636              y = sel.y + sel.h/2;
637              evas_object_move(ext_mod->popup, x, y);
638              avai = elm_ctxpopup_direction_available_get
639                 (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_RIGHT);
640              if (avai == EINA_TRUE)
641                return;
642
643              x = sel.x + sel.w;
644              y = sel.y + sel.h;
645              evas_object_move(ext_mod->popup, x, y);
646              avai = elm_ctxpopup_direction_available_get
647                 (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_RIGHT);
648              if (avai == EINA_TRUE)
649                return;
650
651              x = sel.x;
652              y = sel.y + sel.h/2;
653              while (x < sel.x + sel.w/2)
654                {
655                   evas_object_move(ext_mod->popup, x, y);
656                   avai = elm_ctxpopup_direction_available_get
657                      (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_LEFT);
658                   if (avai == EINA_TRUE)
659                     return;
660                   x += sel.w/4;
661                }
662
663              x = sel.x + sel.w;
664              y = sel.y + sel.h/2;
665              while (x > sel.x + sel.w/2)
666                {
667                   evas_object_move(ext_mod->popup, x, y);
668                   avai = elm_ctxpopup_direction_available_get
669                      (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_RIGHT);
670                   if (avai == EINA_TRUE)
671                     return;
672                   x -= sel.w/4;
673                }
674
675              x = sel.x + sel.w;
676              y = sel.y + sel.h;
677              while (x > sel.x + sel.w/2)
678                {
679                   evas_object_move(ext_mod->popup, x, y);
680                   avai = elm_ctxpopup_direction_available_get
681                      (ext_mod->popup, ELM_CTXPOPUP_DIRECTION_RIGHT);
682                   if (avai == EINA_TRUE)
683                     return;
684                   x -= sel.w/4;
685                }
686           }
687      }
688 }
689
690 static void
691 _select_all(void *data, Evas_Object *obj, void *event_info)
692 {
693    if((!ext_mod) || (!data)) return;
694
695    _ctxpopup_hide(obj);
696    ext_mod->selectall(data, obj, event_info);
697 }
698
699 static void
700 _select(void *data, Evas_Object *obj, void *event_info)
701 {
702    if((!ext_mod) || (!data)) return;
703
704    ext_mod->select(data, obj, event_info);
705    _ctxpopup_hide(obj);
706 }
707
708 static void
709 _paste(void *data, Evas_Object *obj, void *event_info)
710 {
711    if((!ext_mod) || (!data)) return;
712
713    ext_mod->paste(data, obj, event_info);
714    _ctxpopup_hide(obj);
715 }
716
717 static void
718 _cut(void *data, Evas_Object *obj, void *event_info)
719 {
720    if((!ext_mod) || (!data)) return;
721
722    ext_mod->cut(data, obj, event_info);
723    _ctxpopup_hide(obj);
724 }
725
726 static void
727 _copy(void *data, Evas_Object *obj, void *event_info)
728 {
729    if((!ext_mod) || (!data)) return;
730
731    ext_mod->copy(data, obj, event_info);
732    _ctxpopup_hide(obj);
733    elm_entry_select_none(data);
734 }
735
736 static void
737 _cancel(void *data, Evas_Object *obj, void *event_info)
738 {
739    if((!ext_mod) || (!data)) return;
740
741    ext_mod->cancel(data, obj, event_info);
742    _ctxpopup_hide(obj);
743 }
744
745 #if HAVE_APPSVC
746 static void
747 _recvd_bundle(const char *key, const int type __UNUSED__, const bundle_keyval_t *kv, void *date __UNUSED__)
748 {
749    char *val;
750    size_t size;
751
752    if (!ext_mod) return;
753
754    if (bundle_keyval_type_is_array((bundle_keyval_t *)kv) <= 0)
755      {
756         bundle_keyval_get_basic_val((bundle_keyval_t *)kv, (void **)&val, &size);
757         if (!strcmp(key, "source_text"))
758           {
759              ext_mod->source_text = strdup(val);
760           }
761         if (!strcmp(key, "target_text"))
762           {
763              ext_mod->target_text = strdup(val);
764           }
765      }
766 }
767
768 static void
769 _translate_cb(bundle *b, int request_code __UNUSED__, appsvc_result_val rv, void *data __UNUSED__)
770 {
771    if (!ext_mod) return;
772
773    if (ext_mod->source_text)
774      {
775         free(ext_mod->source_text);
776         ext_mod->source_text = NULL;
777      }
778    if (ext_mod->target_text)
779      {
780         free(ext_mod->target_text);
781         ext_mod->target_text = NULL;
782      }
783    if ((rv == APPSVC_RES_CANCEL) || (rv == APPSVC_RES_NOT_OK)) //CANCEL, NOT_OK, OK
784      {
785         return;
786      }
787    else
788      {
789         bundle_foreach(b, _recvd_bundle, NULL);
790      }
791    if ((ext_mod->source_text) || (ext_mod->target_text))
792      {
793         if (ext_mod->editable)
794           {
795              ext_mod->paste_translation(ext_mod->source_text,
796                                         ext_mod->caller, ext_mod->target_text);
797           }
798      }
799 }
800
801 static unsigned int
802 _get_window_id()
803 {
804    Evas_Object *top;
805    Ecore_X_Window xwin;
806
807    top = elm_widget_top_get(ext_mod->caller);
808    xwin = elm_win_xwindow_get(top);
809
810    return xwin;
811 }
812
813 static void
814 _translate_menu(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
815 {
816    if (!ext_mod) return;
817
818    bundle *b = bundle_create();
819    if (!b)
820      {
821         return;
822      }
823    ext_mod->keep_selection(NULL, ext_mod->caller, NULL);
824
825    appsvc_set_operation(b, APPSVC_OPERATION_PICK);
826    appsvc_set_appid(b, "com.samsung.stranslator-shared");
827
828    if (ext_mod->selmode)
829      {
830         const char *selection = elm_entry_selection_get(ext_mod->caller);
831         if (selection)
832           {
833              unsigned int winid = _get_window_id();
834              char wis[20];
835              snprintf(wis, 20, "%u", winid);
836              appsvc_add_data(b, "winid", wis);
837              appsvc_add_data(b, "display", "yes");
838              appsvc_add_data(b, "text_type", "plain_text");
839              appsvc_add_data(b, "source_language", "recently_used"); //auto_detection, recently_used
840              appsvc_add_data(b, "target_language", "recently_used"); //recently_used, specify(en_US)
841              appsvc_add_data(b, "result_type", "selective"); //target_only, selective, both
842              if (ext_mod->editable)
843                appsvc_add_data(b, "mode", "edit_mode_translate"); //edit_mode, edit_mode_translate
844              else
845                appsvc_add_data(b, "mode", "view_mode_translate"); //view_mode, view_mode_translate
846
847              char *str = _remove_tags(selection);
848              if (str)
849                appsvc_add_data(b, "source_text", str);
850              else
851                appsvc_add_data(b, "source_text", selection);
852           }
853      }
854    appsvc_run_service(b, 0, _translate_cb, NULL);
855    bundle_free(b);
856    elm_entry_input_panel_hide(ext_mod->caller);
857    _ctxpopup_hide(obj);
858 }
859 #endif
860
861 static void
862 _clipboard_menu(void *data, Evas_Object *obj, void *event_info __UNUSED__)
863 {
864    if(!ext_mod) return;
865
866    // start for cbhm
867 #ifdef HAVE_ELEMENTARY_X
868    ecore_x_selection_secondary_set(elm_win_xwindow_get(obj), NULL, 0);
869 #endif
870    if (ext_mod->cnp_mode != ELM_CNP_MODE_MARKUP)
871      _cbhm_msg_send(data, "show0");
872    else
873      _cbhm_msg_send(data, "show1");
874    _ctxpopup_hide(obj);
875    // end for cbhm
876 }
877
878 static void
879 _item_clicked(void *data, Evas_Object *obj, void *event_info __UNUSED__)
880 {
881    Elm_Entry_Context_Menu_Item *it = data;
882    Evas_Object *obj2 = it->obj;
883
884    if (it->func) it->func(it->data, obj2, NULL);
885    _ctxpopup_hide(obj);
886 }
887
888 static void
889 _ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
890 {
891    Elm_Ctxpopup_Direction dir;
892    if (!ext_mod) return;
893
894    dir = elm_ctxpopup_direction_get(obj);
895    //clear selection if ctxpopup is dismissed by clicking (not parent resizing)
896    if (dir != ELM_CTXPOPUP_DIRECTION_UNKNOWN)
897      {
898         if ((ext_mod->mouse_up) && (ext_mod->entry_move))
899           {
900              _ctxpopup_position(obj);
901              evas_object_show(ext_mod->popup);
902           }
903         else
904           {
905              elm_entry_select_none(data);
906              ext_mod->popup_showing = EINA_FALSE;
907              if (_elm_config->access_mode)
908                _elm_access_highlight_set(ext_mod->caller, EINA_FALSE);
909           }
910      }
911    else if (ext_mod->popup_showing)
912      {
913         if (_in_viewport_check())
914           {
915              if (ext_mod->show_timer) ecore_timer_del(ext_mod->show_timer);
916              ext_mod->show_timer = ecore_timer_add(0.1, _ctx_show, data);
917           }
918      }
919    ext_mod->mouse_up = EINA_FALSE;
920 }
921
922 // module api funcs needed
923 EAPI int
924 elm_modapi_init(void *m __UNUSED__)
925 {
926    return 1; // succeed always
927 }
928
929 EAPI int
930 elm_modapi_shutdown(void *m __UNUSED__)
931 {
932    return 1; // succeed always
933 }
934
935 // module funcs for the specific module type
936 EAPI void
937 obj_hook(Evas_Object *obj)
938 {
939    _mod_hook_count++;
940    //if(_mod_hook_count > 1) return;
941
942    if(!ext_mod)
943      {
944         ext_mod = ELM_NEW(Elm_Entry_Extension_data);
945         if (!ext_mod) return;
946         elm_entry_extension_module_data_get(obj, ext_mod);
947         ext_mod->mouse_up = EINA_FALSE;
948         ext_mod->mouse_down = EINA_FALSE;
949         ext_mod->entry_move = EINA_FALSE;
950      }
951    // Clipboard item: can be removed by application
952    elm_entry_context_menu_item_add(obj, "Clipboard", NULL,
953                                    ELM_ICON_STANDARD, NULL, NULL);
954
955 #if HAVE_APPSVC
956    // Tranlate item: can be removed by application
957    elm_entry_context_menu_item_add(obj, "Translate", NULL,
958                                    ELM_ICON_STANDARD, NULL, NULL);
959 #endif
960 }
961
962 EAPI void
963 obj_unhook(Evas_Object *obj __UNUSED__)
964 {
965    _mod_hook_count--;
966    if(_mod_hook_count > 0) return;
967
968    if(ext_mod)
969      {
970         evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_DOWN,
971                                        _parent_mouse_down_cb);
972         evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_UP,
973                                        _parent_mouse_up_cb);
974         if (ext_mod->show_timer)
975           {
976              ecore_timer_del(ext_mod->show_timer);
977              ext_mod->show_timer = NULL;
978           }
979         if (ext_mod->popup)
980           {
981              evas_object_del(ext_mod->popup);
982              ext_mod->popup = NULL;
983           }
984         if (ext_mod->source_text)
985           {
986              free(ext_mod->source_text);
987              ext_mod->source_text = NULL;
988           }
989         if (ext_mod->target_text)
990           {
991              free(ext_mod->target_text);
992              ext_mod->target_text = NULL;
993           }
994         free(ext_mod);
995         ext_mod = NULL;
996      }
997 }
998
999 EAPI void
1000 obj_longpress(Evas_Object *obj)
1001 {
1002    if(!ext_mod) return;
1003
1004    Evas_Object *ctxparent;
1005    Evas_Object *parent, *child;
1006    const Eina_List *l;
1007    const Elm_Entry_Context_Menu_Item *it;
1008    const char *context_menu_orientation;
1009    Evas_Object* icon;
1010    Elm_Object_Item *added_item = NULL;
1011    Eina_Bool has_clipboard = EINA_FALSE;
1012    Eina_Bool has_translate = EINA_FALSE;
1013    Eina_Bool has_focused = EINA_FALSE;
1014    Ecore_X_Atom first_cbhm_item_type = 0;
1015
1016    /*update*/
1017    elm_entry_extension_module_data_get(obj, ext_mod);
1018    has_focused = elm_widget_focus_get(obj);
1019    if (ext_mod->context_menu && has_focused)
1020      {
1021         Eina_List *lao = NULL;
1022         Evas_Object *ao = NULL;
1023 #ifdef HAVE_ELEMENTARY_X
1024         int cbhm_count = 0;
1025         if (elm_entry_cnp_mode_get(obj) != ELM_CNP_MODE_MARKUP)
1026           cbhm_count = _cbhm_item_count_get(obj, ATOM_INDEX_CBHM_COUNT_TEXT);
1027         else
1028           cbhm_count = _cbhm_item_count_get(obj, ATOM_INDEX_CBHM_COUNT_ALL);
1029 #endif
1030         if (ext_mod->popup)
1031           {
1032              evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _entry_del_cb);
1033              evas_object_event_callback_del(obj, EVAS_CALLBACK_HIDE, _entry_hide_cb);
1034              evas_object_event_callback_del(obj, EVAS_CALLBACK_MOVE, _entry_move_cb);
1035              evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_DOWN, _entry_mouse_down_cb);
1036              evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_UP, _entry_mouse_up_cb);
1037              evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_DOWN,
1038                                             _parent_mouse_down_cb);
1039              evas_object_event_callback_del(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_UP,
1040                                             _parent_mouse_up_cb);
1041              evas_object_smart_callback_del(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb);
1042              evas_object_del(ext_mod->popup);
1043              ext_mod->popup = NULL;
1044           }
1045         ctxparent = elm_widget_top_get(obj);
1046         parent = elm_widget_parent_get(obj);
1047         child = obj;
1048         if (parent)
1049           {
1050              while(parent)
1051                {
1052                   if (!strcmp(elm_widget_type_get(parent), "elm_conformant"))
1053                     {
1054                        ctxparent = child;
1055                        break;
1056                     }
1057                   child = parent;
1058                   parent = elm_widget_parent_get(parent);
1059                }
1060           }
1061         ext_mod->ctx_par = ctxparent;
1062
1063         if(ctxparent)
1064           {
1065              ext_mod->popup = elm_ctxpopup_add(ctxparent);
1066              if (_elm_config->access_mode)
1067                {
1068                   elm_object_tree_focus_allow_set(ext_mod->popup, EINA_TRUE);
1069                   elm_object_focus_allow_set(ext_mod->popup, EINA_FALSE);
1070                }
1071              else
1072                {
1073                   elm_object_tree_focus_allow_set(ext_mod->popup, EINA_FALSE);
1074                }
1075              evas_object_smart_callback_add(ext_mod->popup, "dismissed", _ctxpopup_dismissed_cb, obj);
1076              evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _entry_del_cb, ext_mod->popup);
1077              evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _entry_hide_cb, ext_mod->popup);
1078           }
1079         else
1080           {
1081              ext_mod->caller = NULL;
1082              return;
1083           }
1084         elm_object_style_set(ext_mod->popup, "copypaste");
1085
1086         elm_ctxpopup_horizontal_set(ext_mod->popup, EINA_TRUE);
1087         context_menu_orientation = edje_object_data_get
1088            (ext_mod->ent, "context_menu_orientation");
1089         if ((context_menu_orientation) &&
1090             (!strcmp(context_menu_orientation, "vertical")))
1091           elm_ctxpopup_horizontal_set(ext_mod->popup, EINA_FALSE);
1092
1093         EINA_LIST_FOREACH(ext_mod->items, l, it)
1094           {
1095              if (!strcmp(it->label, "Clipboard"))
1096                has_clipboard = EINA_TRUE;
1097              else if (!strcmp(it->label, "Translate"))
1098                has_translate = EINA_TRUE;
1099           }
1100         if (!ext_mod->selmode)
1101           {
1102              if (!ext_mod->password)
1103                {
1104                   if (!elm_entry_is_empty(obj))
1105                     {
1106 #ifndef ELM_FEATURE_WEARABLE
1107                        icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1108                        CP_ICON_THEME_SET("select");
1109                        added_item = elm_ctxpopup_item_append(ext_mod->popup, S_SELECT, icon, _select, obj);
1110                        if (_elm_config->access_mode)
1111                          {
1112                             elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1113                             ao = ((Elm_Widget_Item *)added_item)->access_obj;
1114                             elm_object_focus_allow_set(ao, EINA_FALSE);
1115                             lao = eina_list_append(lao, ao);
1116                          }
1117 #endif
1118
1119                        icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1120                        CP_ICON_THEME_SET("select_all");
1121 #ifdef ELM_FEATURE_WEARABLE
1122                        added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1123                                                               icon, _select_all, obj);
1124 #else
1125                        added_item = elm_ctxpopup_item_append(ext_mod->popup, S_SELECT_ALL,
1126                                                               icon, _select_all, obj);
1127 #endif
1128                        if (_elm_config->access_mode)
1129                          {
1130                             elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1131                             ao = ((Elm_Widget_Item *)added_item)->access_obj;
1132                             elm_object_focus_allow_set(ao, EINA_FALSE);
1133                             lao = eina_list_append(lao, ao);
1134                          }
1135                     }
1136                }
1137
1138 #ifdef HAVE_ELEMENTARY_X
1139              if (cbhm_count)
1140 #else
1141              if (1) // need way to detect if someone has a selection
1142 #endif
1143                {
1144                   if (elm_entry_cnp_mode_get(obj) == ELM_CNP_MODE_PLAINTEXT)
1145                     {
1146                        _cbhm_item_get(obj, 0, &first_cbhm_item_type, NULL);
1147                        if (ext_mod->editable &&
1148                            !(first_cbhm_item_type == ecore_x_atom_get("text/uri")) &&
1149                            !(first_cbhm_item_type == ecore_x_atom_get("text/uri-list")))
1150                          {
1151                             icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1152                             CP_ICON_THEME_SET("paste");
1153 #ifdef ELM_FEATURE_WEARABLE
1154                             added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1155                                                                   icon, _paste, obj);
1156 #else
1157                             added_item = elm_ctxpopup_item_append(ext_mod->popup, S_PASTE,
1158                                                                   icon, _paste, obj);
1159 #endif
1160                             if (_elm_config->access_mode)
1161                               {
1162                                  elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1163                                  ao = ((Elm_Widget_Item *)added_item)->access_obj;
1164                                  elm_object_focus_allow_set(ao, EINA_FALSE);
1165                                  lao = eina_list_append(lao, ao);
1166                               }
1167                          }
1168                     }
1169                   else
1170                     {
1171                        if (ext_mod->editable)
1172                          {
1173                             icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1174                             CP_ICON_THEME_SET("paste");
1175 #ifdef ELM_FEATURE_WEARABLE
1176                             added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1177                                                                   icon, _paste, obj);
1178 #else
1179                             added_item = elm_ctxpopup_item_append(ext_mod->popup, S_PASTE,
1180                                                                   icon, _paste, obj);
1181 #endif
1182                             if (_elm_config->access_mode)
1183                               {
1184                                  elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1185                                  ao = ((Elm_Widget_Item *)added_item)->access_obj;
1186                                  elm_object_focus_allow_set(ao, EINA_FALSE);
1187                                  lao = eina_list_append(lao, ao);
1188                               }
1189                          }
1190                     }
1191                }
1192              //elm_ctxpopup_item_append(wd->ctxpopup, NULL, "Selectall",_select_all, obj );
1193              // start for cbhm
1194 #ifdef HAVE_ELEMENTARY_X
1195              if ((!ext_mod->password) && (ext_mod->editable) && (cbhm_count) && (has_clipboard))
1196 #else
1197              if ((!ext_mod->password) && (ext_mod->editable) && (has_clipboard))
1198 #endif
1199                {
1200                   icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1201                   CP_ICON_THEME_SET("clipboard");
1202 #ifdef ELM_FEATURE_WEARABLE
1203                   added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1204                                                         icon, _clipboard_menu, obj);  // Clipboard
1205 #else
1206                   added_item = elm_ctxpopup_item_append(ext_mod->popup, S_CLIPBOARD,
1207                                                         icon, _clipboard_menu, obj);    // Clipboard
1208 #endif
1209                   if (_elm_config->access_mode)
1210                     {
1211                        elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1212                        ao = ((Elm_Widget_Item *)added_item)->access_obj;
1213                        elm_object_focus_allow_set(ao, EINA_FALSE);
1214                        lao = eina_list_append(lao, ao);
1215                     }
1216                   //elm_ctxpopup_item_append(ext_mod->popup, "More", NULL, _clipboard_menu, obj );
1217                }
1218              // end for cbhm
1219 #if HAVE_APPSVC
1220              const char *entry_str;
1221              entry_str = elm_entry_selection_get(obj);
1222              if ((entry_str) && (has_translate))
1223                {
1224                   icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1225                   CP_ICON_THEME_SET("translate");
1226                   added_item = elm_ctxpopup_item_append(ext_mod->popup, S_TRANSLATE,
1227                                                         icon, _translate_menu, obj);
1228                   if (_elm_config->access_mode)
1229                     {
1230                        elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1231                        ao = ((Elm_Widget_Item *)added_item)->access_obj;
1232                        elm_object_focus_allow_set(ao, EINA_FALSE);
1233                        lao = eina_list_append(lao, ao);
1234                     }
1235                }
1236 #endif
1237           }
1238         else
1239           {
1240              if (!ext_mod->password)
1241                {
1242                   if (ext_mod->have_selection)
1243                     {
1244                        Eina_Bool selected_all = EINA_TRUE;
1245                        ext_mod->is_selected_all(&selected_all, obj, NULL);
1246                        if (selected_all == EINA_FALSE)
1247                          {
1248                             icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1249                             CP_ICON_THEME_SET("select_all");
1250 #ifdef ELM_FEATURE_WEARABLE
1251                             added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1252                                                                   icon, _select_all, obj);
1253 #else
1254                             added_item = elm_ctxpopup_item_append(ext_mod->popup, S_SELECT_ALL,
1255                                                                   icon, _select_all, obj);
1256 #endif
1257                             if (_elm_config->access_mode)
1258                               {
1259                                  elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1260                                  ao = ((Elm_Widget_Item *)added_item)->access_obj;
1261                                  elm_object_focus_allow_set(ao, EINA_FALSE);
1262                                  lao = eina_list_append(lao, ao);
1263                               }
1264                          }
1265
1266                        icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1267                        CP_ICON_THEME_SET("copy");
1268 #ifdef ELM_FEATURE_WEARABLE
1269                        added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1270                                                              icon, _copy, obj);
1271 #else
1272                        added_item = elm_ctxpopup_item_append(ext_mod->popup, S_COPY,
1273                                                              icon, _copy, obj);
1274 #endif
1275                        if (_elm_config->access_mode)
1276                          {
1277                             elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1278                             ao = ((Elm_Widget_Item *)added_item)->access_obj;
1279                             elm_object_focus_allow_set(ao, EINA_FALSE);
1280                             lao = eina_list_append(lao, ao);
1281                          }
1282                        if (ext_mod->editable)
1283                          {
1284                             icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1285                             CP_ICON_THEME_SET("cut");
1286 #ifdef ELM_FEATURE_WEARABLE
1287                             added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1288                                                                   icon, _cut, obj);
1289 #else
1290                             added_item = elm_ctxpopup_item_append(ext_mod->popup, S_CUT,
1291                                                                   icon, _cut, obj);
1292 #endif
1293                             if (_elm_config->access_mode)
1294                               {
1295                                  elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1296                                  ao = ((Elm_Widget_Item *)added_item)->access_obj;
1297                                  elm_object_focus_allow_set(ao, EINA_FALSE);
1298                                  lao = eina_list_append(lao, ao);
1299                               }
1300                          }
1301 #ifdef HAVE_ELEMENTARY_X
1302                        if (ext_mod->editable && cbhm_count)
1303 #else
1304                        if (ext_mod->editable)
1305 #endif
1306                          {
1307                             if (elm_entry_cnp_mode_get(obj) == ELM_CNP_MODE_PLAINTEXT)
1308                               {
1309                                  _cbhm_item_get(obj, 0, &first_cbhm_item_type, NULL);
1310                                  if (!(first_cbhm_item_type == ecore_x_atom_get("text/uri")) &&
1311                                      !(first_cbhm_item_type == ecore_x_atom_get("text/uri-list")))
1312                                    {
1313                                       icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1314                                       CP_ICON_THEME_SET("paste");
1315 #ifdef ELM_FEATURE_WEARABLE
1316                                       added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1317                                                                             icon, _paste, obj);
1318 #else
1319                                       added_item = elm_ctxpopup_item_append(ext_mod->popup, S_PASTE,
1320                                                                             icon, _paste, obj);
1321 #endif
1322                                       if (_elm_config->access_mode)
1323                                         {
1324                                            elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1325                                            ao = ((Elm_Widget_Item *)added_item)->access_obj;
1326                                            elm_object_focus_allow_set(ao, EINA_FALSE);
1327                                            lao = eina_list_append(lao, ao);
1328                                         }
1329                                    }
1330                               }
1331                             else
1332                               {
1333                                  icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1334                                  CP_ICON_THEME_SET("paste");
1335 #ifdef ELM_FEATURE_WEARABLE
1336                                  added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1337                                                                        icon, _paste, obj);
1338 #else
1339                                  added_item = elm_ctxpopup_item_append(ext_mod->popup, S_PASTE,
1340                                                                        icon, _paste, obj);
1341 #endif
1342                                  if (_elm_config->access_mode)
1343                                    {
1344                                       elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1345                                       ao = ((Elm_Widget_Item *)added_item)->access_obj;
1346                                       elm_object_focus_allow_set(ao, EINA_FALSE);
1347                                       lao = eina_list_append(lao, ao);
1348                                    }
1349                               }
1350                          }
1351                     }
1352                   else
1353                     {
1354                        _cancel(obj,ext_mod->popup,NULL);
1355                        if (!elm_entry_is_empty(obj))
1356                          {
1357 #ifndef ELM_FEATURE_WEARABLE
1358                             icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1359                             CP_ICON_THEME_SET("select");
1360                             added_item = elm_ctxpopup_item_append(ext_mod->popup, S_SELECT,
1361                                                                   icon, _select, obj);
1362                             if (_elm_config->access_mode)
1363                               {
1364                                  elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1365                                  ao = ((Elm_Widget_Item *)added_item)->access_obj;
1366                                  elm_object_focus_allow_set(ao, EINA_FALSE);
1367                                  lao = eina_list_append(lao, ao);
1368                               }
1369 #endif
1370                             icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1371                             CP_ICON_THEME_SET("select_all");
1372 #ifdef ELM_FEATURE_WEARABLE
1373                             added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1374                                                                   icon, _select_all, obj);
1375 #else
1376                             added_item = elm_ctxpopup_item_append(ext_mod->popup, S_SELECT_ALL,
1377                                                                   icon, _select_all, obj);
1378 #endif
1379                             if (_elm_config->access_mode)
1380                               {
1381                                  elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1382                                  ao = ((Elm_Widget_Item *)added_item)->access_obj;
1383                                  elm_object_focus_allow_set(ao, EINA_FALSE);
1384                                  lao = eina_list_append(lao, ao);
1385                               }
1386                          }
1387 #ifdef HAVE_ELEMENTARY_X
1388                        if (cbhm_count)
1389 #else
1390                        if (1) // need way to detect if someone has a selection
1391 #endif
1392                          {
1393                             if (ext_mod->editable)
1394                               {
1395                                  icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1396                                  CP_ICON_THEME_SET("paste");
1397 #ifdef ELM_FEATURE_WEARABLE
1398                                  added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1399                                                                        icon, _paste, obj);
1400 #else
1401                                  added_item = elm_ctxpopup_item_append(ext_mod->popup, S_PASTE,
1402                                                                        icon, _paste, obj);
1403 #endif
1404                                  if (_elm_config->access_mode)
1405                                    {
1406                                       elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1407                                       ao = ((Elm_Widget_Item *)added_item)->access_obj;
1408                                       elm_object_focus_allow_set(ao, EINA_FALSE);
1409                                       lao = eina_list_append(lao, ao);
1410                                    }
1411                               }
1412                          }
1413                     }
1414                   // start for cbhm
1415 #ifdef HAVE_ELEMENTARY_X
1416                   if ((ext_mod->editable) && (cbhm_count) && (has_clipboard))
1417 #else
1418                   if ((ext_mod->editable) && (has_clipboard))
1419 #endif
1420                     {
1421                        icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1422                        CP_ICON_THEME_SET("clipboard");
1423 #ifdef ELM_FEATURE_WEARABLE
1424                        added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1425                                                              icon, _clipboard_menu, obj);
1426 #else
1427                        added_item = elm_ctxpopup_item_append(ext_mod->popup, S_CLIPBOARD,
1428                                                              icon, _clipboard_menu, obj);
1429 #endif
1430                        if (_elm_config->access_mode)
1431                          {
1432                             elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1433                             ao = ((Elm_Widget_Item *)added_item)->access_obj;
1434                             elm_object_focus_allow_set(ao, EINA_FALSE);
1435                             lao = eina_list_append(lao, ao);
1436                          }
1437                        //elm_ctxpopup_item_append(ext_mod->popup, "More", NULL, _clipboard_menu, obj );
1438                     }
1439                   // end for cbhm
1440 #if HAVE_APPSVC
1441                   const char *entry_str;
1442                   entry_str = elm_entry_selection_get(obj);
1443                   if ((entry_str) && (has_translate))
1444                     {
1445                        icon = edje_object_add(evas_object_evas_get(ext_mod->popup));
1446                        CP_ICON_THEME_SET("translate");
1447                        added_item = elm_ctxpopup_item_append(ext_mod->popup, S_TRANSLATE,
1448                                                              icon, _translate_menu, obj);
1449                        if (_elm_config->access_mode)
1450                          {
1451                             elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1452                             ao = ((Elm_Widget_Item *)added_item)->access_obj;
1453                             elm_object_focus_allow_set(ao, EINA_FALSE);
1454                             lao = eina_list_append(lao, ao);
1455                          }
1456                     }
1457 #endif
1458               }
1459           }
1460         EINA_LIST_FOREACH(ext_mod->items, l, it)
1461           {
1462              if (strcmp(it->label, "Clipboard") && strcmp(it->label, "Translate"))
1463                {
1464                   Evas_Object *ic = NULL;
1465                   if (it->icon_file)
1466                     {
1467                        ic = elm_icon_add(obj);
1468                        elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
1469                        if (it->icon_type == ELM_ICON_FILE)
1470                          elm_image_file_set(ic, it->icon_file, it->icon_group);
1471                        else if (it->icon_type == ELM_ICON_STANDARD)
1472                          elm_icon_standard_set(ic, it->icon_file);
1473                     }
1474 #ifdef ELM_FEATURE_WEARABLE
1475                   added_item = elm_ctxpopup_item_append(ext_mod->popup, NULL,
1476                                                         ic, _item_clicked, it );
1477 #else
1478                   added_item = elm_ctxpopup_item_append(ext_mod->popup, it->label,
1479                                                         ic, _item_clicked, it );
1480 #endif
1481                   if (_elm_config->access_mode)
1482                     {
1483                        elm_object_focus_allow_set(VIEW(added_item), EINA_FALSE);
1484                        ao = ((Elm_Widget_Item *)added_item)->access_obj;
1485                        elm_object_focus_allow_set(ao, EINA_FALSE);
1486                        lao = eina_list_append(lao, ao);
1487                     }
1488                }
1489           }
1490         if (ext_mod->popup && added_item)
1491           {
1492              Evas_Object *first_it_ao, *cur_it_ao, *prev_it_ao;
1493              Evas_Object *popup_ao;
1494              Elm_Widget_Smart_Data *wd;
1495              Evas_Object *po;
1496              int layer;
1497              int count, itn;
1498              Eina_List *lc;
1499
1500              ext_mod->caller = obj;
1501              if (_in_viewport_check())
1502                {
1503                   ext_mod->popup_showing = EINA_TRUE;
1504                   _ctxpopup_position(obj);
1505                   evas_object_show(ext_mod->popup);
1506                   ext_mod->popup_clicked = EINA_FALSE;
1507                   ext_mod->mouse_up = EINA_FALSE;
1508                }
1509
1510              evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _entry_move_cb, ext_mod->popup);
1511              evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
1512                                             _entry_mouse_down_cb, ext_mod->popup);
1513              evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
1514                                             _entry_mouse_up_cb, ext_mod->popup);
1515              evas_object_event_callback_add(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_DOWN,
1516                                             _parent_mouse_down_cb, ext_mod->popup);
1517              evas_object_event_callback_add(ext_mod->ctx_par, EVAS_CALLBACK_MOUSE_UP,
1518                                             _parent_mouse_up_cb, ext_mod->popup);
1519              layer = evas_object_layer_get(ext_mod->caller);
1520              layer = layer >= EVAS_LAYER_MAX ? EVAS_LAYER_MAX : layer + 1;
1521              evas_object_layer_set(ext_mod->popup, layer);
1522
1523              if (_elm_config->access_mode)
1524                {
1525                   wd = evas_object_smart_data_get(ext_mod->popup);
1526                   po = (Evas_Object *)edje_object_part_object_get(wd->resize_obj,
1527                                                                   "access.outline");
1528                   popup_ao = elm_access_object_get(po);
1529                   count = eina_list_count(lao);
1530                   first_it_ao = eina_list_data_get(lao);
1531                   elm_access_highlight_next_set(popup_ao,
1532                                                 ELM_HIGHLIGHT_DIR_NEXT,
1533                                                 first_it_ao);
1534                   elm_access_highlight_next_set(first_it_ao,
1535                                                 ELM_HIGHLIGHT_DIR_PREVIOUS,
1536                                                 popup_ao);
1537                   prev_it_ao = eina_list_data_get(lao);
1538                   itn = 1;
1539                   EINA_LIST_FOREACH(lao, lc, cur_it_ao)
1540                     {
1541                        if (itn == count)
1542                          {
1543                             elm_access_highlight_next_set(prev_it_ao,
1544                                                           ELM_HIGHLIGHT_DIR_NEXT,
1545                                                           cur_it_ao);
1546                             elm_access_highlight_next_set(cur_it_ao,
1547                                                           ELM_HIGHLIGHT_DIR_PREVIOUS,
1548                                                           prev_it_ao);
1549                             elm_access_highlight_next_set(cur_it_ao,
1550                                                           ELM_HIGHLIGHT_DIR_NEXT,
1551                                                           popup_ao);
1552                             elm_access_highlight_next_set(popup_ao,
1553                                                           ELM_HIGHLIGHT_DIR_PREVIOUS,
1554                                                           cur_it_ao);
1555                          }
1556                        else if (itn > 1)
1557                          {
1558                             elm_access_highlight_next_set(prev_it_ao,
1559                                                           ELM_HIGHLIGHT_DIR_NEXT,
1560                                                           cur_it_ao);
1561                             elm_access_highlight_next_set(cur_it_ao,
1562                                                           ELM_HIGHLIGHT_DIR_PREVIOUS,
1563                                                           prev_it_ao);
1564                          }
1565                        itn++;
1566                        prev_it_ao = cur_it_ao;
1567                     }
1568                   elm_access_highlight_set(popup_ao);
1569                }
1570              eina_list_free(lao);
1571           }
1572         else
1573           ext_mod->caller = NULL;
1574      }
1575 }
1576
1577 EAPI void
1578 obj_mouseup(Evas_Object *obj)
1579 {
1580    if (!obj || !ext_mod)
1581      return;
1582 }
1583
1584
1585 EAPI void
1586 obj_hidemenu(Evas_Object *obj)
1587 {
1588    if (!obj || !ext_mod || obj != ext_mod->caller)
1589      return;
1590
1591    _ctxpopup_hide(ext_mod->popup);
1592    // if (ext_mod->popup) evas_object_del(ext_mod->popup);
1593 }