billiob pushed a commit to branch master.

http://git.enlightenment.org/apps/terminology.git/commit/?id=7e4276c0333c7bad262c6eef5fb60e265684cf9b

commit 7e4276c0333c7bad262c6eef5fb60e265684cf9b
Author: Boris Faure <bill...@gmail.com>
Date:   Sun Apr 5 12:13:04 2015 +0200

    right click on a selection shows popup to copy it
    
    Closes T2246
---
 src/bin/termio.c | 133 +++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 105 insertions(+), 28 deletions(-)

diff --git a/src/bin/termio.c b/src/bin/termio.c
index 527def6..4f03072 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -53,7 +53,6 @@ struct _Termio
       int x1, y1, x2, y2;
       int suspend;
       Eina_List *objs;
-      Evas_Object *ctxpopup;
       struct {
          Evas_Object *dndobj;
          Evas_Coord x, y;
@@ -62,6 +61,7 @@ struct _Termio
          unsigned char dndobjdel : 1;
       } down;
    } link;
+   Evas_Object *ctxpopup;
    int zoom_fontsize_start;
    int scroll;
    Evas_Object *self;
@@ -111,7 +111,9 @@ static void _smart_update_queue(Evas_Object *obj, Termio 
*sd);
 static void _smart_apply(Evas_Object *obj);
 static void _smart_size(Evas_Object *obj, int w, int h, Eina_Bool force);
 static void _smart_calculate(Evas_Object *obj);
-static void _take_selection_text(Evas_Object *obj, Elm_Sel_Type type, const 
char *text);
+static void _take_selection_text(Termio *sd, Elm_Sel_Type type, const char 
*text);
+static void _smart_xy_to_cursor(Termio *sd, Evas_Coord x, Evas_Coord y, int 
*cx, int *cy);
+static Eina_Bool _mouse_in_selection(Termio *sd, int cx, int cy);
 
 
 /* {{{ Helpers */
@@ -689,7 +691,7 @@ termio_config_set(Evas_Object *obj, Config *config)
 /* }}} */
 /* {{{ Links */
 
-static inline Eina_Bool
+static Eina_Bool
 _should_inline(const Evas_Object *obj)
 {
    const Config *config = termio_config_get(obj);
@@ -878,7 +880,7 @@ _cb_ctxp_del(void *data, Evas *e EINA_UNUSED, Evas_Object 
*obj EINA_UNUSED,
 {
    Termio *sd = data;
    EINA_SAFETY_ON_NULL_RETURN(sd);
-   sd->link.ctxpopup = NULL;
+   sd->ctxpopup = NULL;
    elm_object_focus_set(sd->self, EINA_TRUE);
 }
 
@@ -912,7 +914,7 @@ _cb_ctxp_link_copy(void *data, Evas_Object *obj, void 
*event EINA_UNUSED)
    Termio *sd = evas_object_smart_data_get(term);
    EINA_SAFETY_ON_NULL_RETURN(sd);
    EINA_SAFETY_ON_NULL_RETURN(sd->link.string);
-   _take_selection_text(term, ELM_SEL_TYPE_CLIPBOARD, sd->link.string);
+   _take_selection_text(sd, ELM_SEL_TYPE_CLIPBOARD, sd->link.string);
    evas_object_del(obj);
 }
 
@@ -931,8 +933,19 @@ _cb_link_down(void *data, Evas *e EINA_UNUSED, Evas_Object 
*obj EINA_UNUSED, voi
      }
    else if (ev->button == 3)
      {
-        Evas_Object *ctxp = elm_ctxpopup_add(sd->win);
-        sd->link.ctxpopup = ctxp;
+        Evas_Object *ctxp;
+
+        if (sd->pty->selection.is_active)
+          {
+             int cx = 0, cy = 0;
+
+             _smart_xy_to_cursor(sd, ev->canvas.x, ev->canvas.y, &cx, &cy);
+             if (_mouse_in_selection(sd, cx, cy))
+               return;
+          }
+
+        ctxp = elm_ctxpopup_add(sd->win);
+        sd->ctxpopup = ctxp;
 
         if (sd->config->helper.inline_please)
           {
@@ -1936,6 +1949,42 @@ end:
 /* }}} */
 /* {{{ Selection */
 
+static Eina_Bool
+_mouse_in_selection(Termio *sd, int cx, int cy)
+{
+   int start_x = 0, start_y = 0, end_x = 0, end_y = 0;
+
+   if (!sd->pty->selection.is_active)
+     return EINA_FALSE;
+
+   start_x = sd->pty->selection.start.x;
+   start_y = sd->pty->selection.start.y;
+   end_x = sd->pty->selection.end.x;
+   end_y = sd->pty->selection.end.y;
+
+   if (!sd->pty->selection.is_top_to_bottom)
+     {
+        INT_SWAP(start_y, end_y);
+        INT_SWAP(start_x, end_x);
+     }
+   if (sd->pty->selection.is_box)
+     {
+        if ((start_y <= cy) && (cy <= end_y) &&
+            (start_x <= cx) && (cx <= end_x) )
+          return EINA_TRUE;
+     }
+   else
+     {
+        if ((cy < start_y) || (cy > end_y))
+          return EINA_FALSE;
+        if (((cy == start_y) && (cx < start_x)) ||
+            ((cy == end_y) && (cx > end_x)))
+          return EINA_FALSE;
+        return EINA_TRUE;
+     }
+     return EINA_FALSE;
+}
+
 struct termio_sb {
    char *buf;
    size_t len;
@@ -1965,7 +2014,7 @@ _sb_add(struct termio_sb *sb, const char *s, size_t len)
 }
 
 /* unlike eina_strbuf_rtrim, only trims \t, \f, ' ' */
-void
+static void
 _sb_spaces_rtrim(struct termio_sb *sb)
 {
    if (!sb->buf)
@@ -2222,10 +2271,8 @@ _lost_selection(void *data, Elm_Sel_Type selection)
 }
 
 static void
-_take_selection_text(Evas_Object *obj, Elm_Sel_Type type, const char *text)
+_take_selection_text(Termio *sd, Elm_Sel_Type type, const char *text)
 {
-   Termio *sd = evas_object_smart_data_get(obj);
-
    EINA_SAFETY_ON_NULL_RETURN(sd);
 
    text = eina_stringshare_add(text);
@@ -2239,7 +2286,7 @@ _take_selection_text(Evas_Object *obj, Elm_Sel_Type type, 
const char *text)
                          text,
                          eina_stringshare_strlen(text));
    elm_cnp_selection_loss_callback_set(sd->win, type,
-                                       _lost_selection, obj);
+                                       _lost_selection, sd->self);
    sd->have_sel = EINA_TRUE;
    if (sd->sel_str) eina_stringshare_del(sd->sel_str);
    sd->sel_str = text;
@@ -2305,7 +2352,7 @@ termio_take_selection(Evas_Object *obj, Elm_Sel_Type type)
    if (s)
      {
         if ((sd->win) && (len > 0))
-          _take_selection_text(obj, type, s);
+          _take_selection_text(sd, type, s);
         free(s);
      }
 }
@@ -3341,7 +3388,7 @@ _smart_cb_focus_out(void *data, Evas *e EINA_UNUSED, 
Evas_Object *obj,
    Termio *sd = evas_object_smart_data_get(data);
    EINA_SAFETY_ON_NULL_RETURN(sd);
 
-   if (sd->link.ctxpopup) return; /* ctxp triggers focus out we should ignore 
*/
+   if (sd->ctxpopup) return; /* ctxp triggers focus out we should ignore */
 
    edje_object_signal_emit(sd->cursor.obj, "focus,out", "terminology");
    if (!sd->win) return;
@@ -3404,14 +3451,13 @@ _smart_mouseover_apply(Evas_Object *obj)
 }
 
 static void
-_smart_xy_to_cursor(Evas_Object *obj, Evas_Coord x, Evas_Coord y,
+_smart_xy_to_cursor(Termio *sd, Evas_Coord x, Evas_Coord y,
                     int *cx, int *cy)
 {
-   Termio *sd = evas_object_smart_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(sd);
    Evas_Coord ox, oy;
+   EINA_SAFETY_ON_NULL_RETURN(sd);
 
-   evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
+   evas_object_geometry_get(sd->self, &ox, &oy, NULL, NULL);
    *cx = (x - ox) / sd->font.chw;
    *cy = (y - oy) / sd->font.chh;
    if (*cx < 0) *cx = 0;
@@ -3863,6 +3909,38 @@ _handle_mouse_down_single_click(Termio *sd,
 }
 
 static void
+_cb_ctxp_sel_copy(void *data, Evas_Object *obj, void *event EINA_UNUSED)
+{
+   termio_take_selection(data, ELM_SEL_TYPE_CLIPBOARD);
+   evas_object_del(obj);
+}
+
+static void
+_handle_right_click(Evas_Object *obj, Evas_Event_Mouse_Down *ev, Termio *sd,
+                    int cx, int cy)
+{
+   elm_object_focus_set(obj, EINA_TRUE);
+   if (_mouse_in_selection(sd, cx, cy))
+     {
+        Evas_Object *ctxp;
+        ctxp = elm_ctxpopup_add(sd->win);
+        sd->ctxpopup = ctxp;
+
+        elm_ctxpopup_item_append(ctxp, _("Copy"), NULL, _cb_ctxp_sel_copy,
+                                 sd->self);
+        evas_object_move(ctxp, ev->canvas.x, ev->canvas.y);
+        evas_object_show(ctxp);
+        evas_object_smart_callback_add(ctxp, "dismissed",
+                                       _cb_ctxp_dismissed, sd);
+        evas_object_event_callback_add(ctxp, EVAS_CALLBACK_DEL,
+                                       _cb_ctxp_del, sd);
+        return;
+     }
+   if (!sd->link.string)
+     evas_object_smart_callback_call(obj, "options", NULL);
+}
+
+static void
 _smart_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj 
EINA_UNUSED, void *event)
 {
    Evas_Event_Mouse_Down *ev = event;
@@ -3875,10 +3953,11 @@ _smart_cb_mouse_down(void *data, Evas *e EINA_UNUSED, 
Evas_Object *obj EINA_UNUS
    shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
    ctrl = evas_key_modifier_is_set(ev->modifiers, "Control");
    alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
-   _smart_xy_to_cursor(data, ev->canvas.x, ev->canvas.y, &cx, &cy);
+   _smart_xy_to_cursor(sd, ev->canvas.x, ev->canvas.y, &cx, &cy);
+
    if ((ev->button == 3) && ctrl)
      {
-        evas_object_smart_callback_call(data, "options", NULL);
+        _handle_right_click(data, ev, sd, cx, cy);
         return;
      }
    if (!shift && !ctrl)
@@ -3928,9 +4007,7 @@ _smart_cb_mouse_down(void *data, Evas *e EINA_UNUSED, 
Evas_Object *obj EINA_UNUS
      }
    else if (ev->button == 3)
      {
-        elm_object_focus_set(data, EINA_TRUE);
-        if (!sd->link.string)
-          evas_object_smart_callback_call(data, "options", NULL);
+        _handle_right_click(data, ev, sd, cx, cy);
      }
 }
 
@@ -3947,7 +4024,7 @@ _smart_cb_mouse_up(void *data, Evas *e EINA_UNUSED, 
Evas_Object *obj EINA_UNUSED
    shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
    ctrl = evas_key_modifier_is_set(ev->modifiers, "Control");
 
-   _smart_xy_to_cursor(data, ev->canvas.x, ev->canvas.y, &cx, &cy);
+   _smart_xy_to_cursor(sd, ev->canvas.x, ev->canvas.y, &cx, &cy);
    if (!shift && !ctrl && !sd->pty->selection.makesel)
       if (_rep_mouse_up(sd, ev, cx, cy))
         {
@@ -4162,7 +4239,7 @@ _smart_cb_mouse_in(void *data, Evas *e EINA_UNUSED,
    Termio *sd = evas_object_smart_data_get(data);
 
    EINA_SAFETY_ON_NULL_RETURN(sd);
-   _smart_xy_to_cursor(data, ev->canvas.x, ev->canvas.y, &cx, &cy);
+   _smart_xy_to_cursor(sd, ev->canvas.x, ev->canvas.y, &cx, &cy);
    sd->mouse.cx = cx;
    sd->mouse.cy = cy;
    termio_mouseover_suspend_pushpop(data, -1);
@@ -4177,7 +4254,7 @@ _smart_cb_mouse_out(void *data, Evas *e EINA_UNUSED, 
Evas_Object *obj,
 
    EINA_SAFETY_ON_NULL_RETURN(sd);
 
-   if (sd->link.ctxpopup) return; /* ctxp triggers mouse out we should ignore 
*/
+   if (sd->ctxpopup) return; /* ctxp triggers mouse out we should ignore */
 
    termio_mouseover_suspend_pushpop(data, 1);
    ty_dbus_link_hide();
@@ -4191,7 +4268,7 @@ _smart_cb_mouse_out(void *data, Evas *e EINA_UNUSED, 
Evas_Object *obj,
      {
         int cx = 0, cy = 0;
 
-        _smart_xy_to_cursor(data, ev->canvas.x, ev->canvas.y, &cx, &cy);
+        _smart_xy_to_cursor(sd, ev->canvas.x, ev->canvas.y, &cx, &cy);
         sd->mouse.cx = cx;
         sd->mouse.cy = cy;
      }
@@ -4245,7 +4322,7 @@ _smart_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, 
Evas_Object *obj EINA_UNU
      {
        int cx = 0, cy = 0;
 
-       _smart_xy_to_cursor(data, ev->canvas.x, ev->canvas.y, &cx, &cy);
+       _smart_xy_to_cursor(sd, ev->canvas.x, ev->canvas.y, &cx, &cy);
 
        switch (sd->pty->mouse_ext)
          {

-- 


Reply via email to