]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtklabel.c
Merge branch 'bgo593793-filechooser-recent-folders-master'
[~andy/gtk] / gtk / gtklabel.c
index 3f837459115d0c7fd7accd7679ab899ccb727eac..0b7ee8833235b8391f193fb5aa8cd15b389fd246 100644 (file)
@@ -52,6 +52,7 @@
 #include "gtkprivate.h"
 #include "gtktypebuiltins.h"
 
+#include "a11y/gtklabelaccessible.h"
 
 /**
  * SECTION:gtklabel
@@ -464,6 +465,7 @@ static void gtk_label_select_region_index (GtkLabel *label,
                                            gint      anchor_index,
                                            gint      end_index);
 
+
 static gboolean gtk_label_mnemonic_activate (GtkWidget         *widget,
                                             gboolean           group_cycling);
 static void     gtk_label_setup_mnemonic    (GtkLabel          *label,
@@ -1093,6 +1095,8 @@ gtk_label_class_init (GtkLabelClass *class)
                                "activate-current-link", 0);
 
   g_type_class_add_private (class, sizeof (GtkLabelPrivate));
+
+  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_LABEL_ACCESSIBLE);
 }
 
 static void 
@@ -1201,24 +1205,10 @@ gtk_label_get_property (GObject     *object,
       g_value_set_object (value, (GObject*) priv->mnemonic_widget);
       break;
     case PROP_CURSOR_POSITION:
-      if (priv->select_info && priv->select_info->selectable)
-       {
-         gint offset = g_utf8_pointer_to_offset (priv->text,
-                                                 priv->text + priv->select_info->selection_end);
-         g_value_set_int (value, offset);
-       }
-      else
-       g_value_set_int (value, 0);
+      g_value_set_int (value, _gtk_label_get_cursor_position (label));
       break;
     case PROP_SELECTION_BOUND:
-      if (priv->select_info && priv->select_info->selectable)
-       {
-         gint offset = g_utf8_pointer_to_offset (priv->text,
-                                                 priv->text + priv->select_info->selection_anchor);
-         g_value_set_int (value, offset);
-       }
-      else
-       g_value_set_int (value, 0);
+      g_value_set_int (value, _gtk_label_get_selection_bound (label));
       break;
     case PROP_ELLIPSIZE:
       g_value_set_enum (value, priv->ellipsize);
@@ -1346,8 +1336,16 @@ attribute_from_text (GtkBuilder   *builder,
        attribute = pango_attr_stretch_new (g_value_get_enum (&val));
       break;
     case PANGO_ATTR_UNDERLINE:
-      if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
-       attribute = pango_attr_underline_new (g_value_get_boolean (&val));
+      if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_UNDERLINE, value, &val, NULL))
+       attribute = pango_attr_underline_new (g_value_get_enum (&val));
+      else
+        {
+          /* XXX: allow boolean for backwards compat, so ignore error */
+          /* Deprecate this somehow */
+          g_value_unset (&val);
+          if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
+            attribute = pango_attr_underline_new (g_value_get_boolean (&val));
+        }
       break;
     case PANGO_ATTR_STRIKETHROUGH:     
       if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
@@ -1531,11 +1529,12 @@ pango_start_element (GMarkupParseContext *context,
        }
 
       attr = attribute_from_text (data->builder, name, value, error);
-      attr->start_index = start_val;
-      attr->end_index   = end_val;
 
       if (attr)
        {
+          attr->start_index = start_val;
+          attr->end_index   = end_val;
+
          if (!data->attrs)
            data->attrs = pango_attr_list_new ();
 
@@ -2256,7 +2255,7 @@ gtk_label_set_label (GtkLabel    *label,
  * Return value: the text of the label widget. This string is
  *   owned by the widget and must not be modified or freed.
  **/
-G_CONST_RETURN gchar *
+const gchar *
 gtk_label_get_label (GtkLabel *label)
 {
   g_return_val_if_fail (GTK_IS_LABEL (label), NULL);
@@ -2721,7 +2720,7 @@ gtk_label_set_markup_with_mnemonic (GtkLabel    *label,
  * Return value: the text in the label widget. This is the internal
  *   string used by the label, and must not be modified.
  **/
-G_CONST_RETURN gchar *
+const gchar *
 gtk_label_get_text (GtkLabel *label)
 {
   g_return_val_if_fail (GTK_IS_LABEL (label), NULL);
@@ -2821,7 +2820,7 @@ void
 gtk_label_set_pattern (GtkLabel           *label,
                       const gchar *pattern)
 {
-  GtkLabelPrivate *priv = label->priv;
+  GtkLabelPrivate *priv;
 
   g_return_if_fail (GTK_IS_LABEL (label));
 
@@ -3191,19 +3190,16 @@ static PangoFontMetrics *
 get_font_metrics (PangoContext *context, GtkWidget *widget)
 {
   GtkStyleContext *style_context;
-  PangoFontDescription *font;
+  const PangoFontDescription *font;
   PangoFontMetrics *retval;
 
   style_context = gtk_widget_get_style_context (widget);
-  gtk_style_context_get (style_context, 0, "font", &font, NULL);
+  font = gtk_style_context_get_font (style_context, GTK_STATE_FLAG_NORMAL);
 
   retval = pango_context_get_metrics (context,
                                       font,
                                       pango_context_get_language (context));
 
-  if (font != NULL)
-    pango_font_description_free (font);
-
   return retval;
 }
 
@@ -3568,6 +3564,11 @@ gtk_label_get_preferred_layout_size (GtkLabel *label,
       layout = gtk_label_get_measuring_layout (label, layout, 0, -1);
 
       pango_layout_get_extents (layout, NULL, required);
+
+      /* can happen when Pango decides to ellipsize text */
+      if (required->width > natural->width)
+        required->width = natural->width;
+
       required->x = required->y = 0;
       required->height = natural->height;
     }
@@ -3935,12 +3936,7 @@ get_layout_location (GtkLabel  *label,
 
   gtk_widget_get_allocation (widget, &allocation);
 
-  x = floor (allocation.x + xpad + xalign * (allocation.width - req_width));
-
-  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
-    x = MAX (x, allocation.x + xpad);
-  else
-    x = MIN (x, allocation.x + allocation.width - xpad);
+  x = floor (allocation.x + xpad + xalign * (allocation.width - req_width) - logical.x);
 
 
   /* bgo#315462 - For single-line labels, *do* align the requisition with
@@ -3957,9 +3953,9 @@ get_layout_location (GtkLabel  *label,
    *   middle".  You want to read the first line, at least, to get some context.
    */
   if (pango_layout_get_line_count (priv->layout) == 1)
-    y = floor (allocation.y + ypad + (allocation.height - req_height) * yalign);
+    y = floor (allocation.y + ypad + (allocation.height - req_height) * yalign) - logical.y;
   else
-    y = floor (allocation.y + ypad + MAX ((allocation.height - req_height) * yalign, 0));
+    y = floor (allocation.y + ypad + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y;
 
   if (xp)
     *xp = x;
@@ -4135,7 +4131,7 @@ gtk_label_draw (GtkWidget *widget,
 
   if (priv->text && (*priv->text != '\0'))
     {
-      GdkRGBA *bg_color, *fg_color;
+      GdkRGBA bg_color, fg_color;
 
       get_layout_location (label, &x, &y);
 
@@ -4183,23 +4179,18 @@ gtk_label_draw (GtkWidget *widget,
           if (gtk_widget_has_focus (widget))
             state |= GTK_STATE_FLAG_FOCUSED;
 
-          gtk_style_context_get (context, state,
-                                 "background-color", &bg_color,
-                                 "color", &fg_color,
-                                 NULL);
+          gtk_style_context_get_color (context, state, &fg_color);
+          gtk_style_context_get_background_color (context, state, &bg_color);
 
-          gdk_cairo_set_source_rgba (cr, bg_color);
+          gdk_cairo_set_source_rgba (cr, &bg_color);
           cairo_paint (cr);
 
-          gdk_cairo_set_source_rgba (cr, fg_color);
+          gdk_cairo_set_source_rgba (cr, &fg_color);
           cairo_move_to (cr, x, y);
           _gtk_pango_fill_layout (cr, priv->layout);
 
           cairo_restore (cr);
           cairo_region_destroy (clip);
-
-          gdk_rgba_free (bg_color);
-          gdk_rgba_free (fg_color);
         }
       else if (info)
         {
@@ -4221,7 +4212,7 @@ gtk_label_draw (GtkWidget *widget,
 
           if (active_link)
             {
-              GdkRGBA *bg_color;
+              GdkRGBA bg_color;
 
               range[0] = active_link->start;
               range[1] = active_link->end;
@@ -4247,11 +4238,9 @@ gtk_label_draw (GtkWidget *widget,
               else
                 state = GTK_STATE_FLAG_PRELIGHT;
 
-              gtk_style_context_get (context, state,
-                                     "background-color", &bg_color,
-                                     NULL);
+              gtk_style_context_get_background_color (context, state, &bg_color);
 
-              gdk_cairo_set_source_rgba (cr, bg_color);
+              gdk_cairo_set_source_rgba (cr, &bg_color);
               cairo_paint (cr);
 
               gdk_cairo_set_source_color (cr, text_color);
@@ -4260,7 +4249,6 @@ gtk_label_draw (GtkWidget *widget,
 
               gdk_color_free (link_color);
               gdk_color_free (visited_link_color);
-              gdk_rgba_free (bg_color);
 
               cairo_restore (cr);
             }
@@ -4765,24 +4753,24 @@ gtk_label_button_press (GtkWidget      *widget,
   if (event->button == 1)
     {
       if (!gtk_widget_has_focus (widget))
-       {
-         priv->in_click = TRUE;
-         gtk_widget_grab_focus (widget);
-         priv->in_click = FALSE;
-       }
+        {
+          priv->in_click = TRUE;
+          gtk_widget_grab_focus (widget);
+          priv->in_click = FALSE;
+        }
 
       if (event->type == GDK_3BUTTON_PRESS)
-       {
-         gtk_label_select_region_index (label, 0, strlen (priv->text));
-         return TRUE;
-       }
+        {
+          gtk_label_select_region_index (label, 0, strlen (priv->text));
+          return TRUE;
+        }
 
       if (event->type == GDK_2BUTTON_PRESS)
-       {
+        {
           info->select_words = TRUE;
-         gtk_label_select_word (label);
-         return TRUE;
-       }
+          gtk_label_select_word (label);
+          return TRUE;
+        }
 
       get_layout_index (label, event->x, event->y, &index);
 
@@ -4790,38 +4778,49 @@ gtk_label_button_press (GtkWidget      *widget,
       max = MAX (info->selection_anchor, info->selection_end);
 
       if ((info->selection_anchor != info->selection_end) &&
-         (event->state & GDK_SHIFT_MASK))
-       {
-         /* extend (same as motion) */
-         min = MIN (min, index);
-         max = MAX (max, index);
+          (event->state & GDK_SHIFT_MASK))
+        {
+          if (index > min && index < max)
+            {
+              /* truncate selection, but keep it as big as possible */
+              if (index - min > max - index)
+                max = index;
+              else
+                min = index;
+            }
+          else
+            {
+              /* extend (same as motion) */
+              min = MIN (min, index);
+              max = MAX (max, index);
+            }
 
-         /* ensure the anchor is opposite index */
-         if (index == min)
-           {
-             gint tmp = min;
-             min = max;
-             max = tmp;
-           }
+          /* ensure the anchor is opposite index */
+          if (index == min)
+            {
+              gint tmp = min;
+              min = max;
+              max = tmp;
+            }
 
-         gtk_label_select_region_index (label, min, max);
-       }
+          gtk_label_select_region_index (label, min, max);
+        }
       else
-       {
-         if (event->type == GDK_3BUTTON_PRESS)
-           gtk_label_select_region_index (label, 0, strlen (priv->text));
-         else if (event->type == GDK_2BUTTON_PRESS)
-           gtk_label_select_word (label);
-         else if (min < max && min <= index && index <= max)
-           {
-             info->in_drag = TRUE;
-             info->drag_start_x = event->x;
-             info->drag_start_y = event->y;
-           }
-         else
-           /* start a replacement */
-           gtk_label_select_region_index (label, index, index);
-       }
+        {
+          if (event->type == GDK_3BUTTON_PRESS)
+            gtk_label_select_region_index (label, 0, strlen (priv->text));
+          else if (event->type == GDK_2BUTTON_PRESS)
+            gtk_label_select_word (label);
+          else if (min < max && min <= index && index <= max)
+            {
+              info->in_drag = TRUE;
+              info->drag_start_x = event->x;
+              info->drag_start_y = event->y;
+            }
+          else
+            /* start a replacement */
+            gtk_label_select_region_index (label, index, index);
+        }
 
       return TRUE;
     }
@@ -5429,14 +5428,24 @@ gtk_label_select_region_index (GtkLabel *label,
       GtkClipboard *clipboard;
 
       if (priv->select_info->selection_anchor == anchor_index &&
-         priv->select_info->selection_end == end_index)
-       return;
+          priv->select_info->selection_end == end_index)
+        return;
+
+      g_object_freeze_notify (G_OBJECT (label));
+
+      if (priv->select_info->selection_anchor != anchor_index)
+        g_object_notify (G_OBJECT (label), "selection-bound");
+      if (priv->select_info->selection_end != end_index)
+        g_object_notify (G_OBJECT (label), "cursor-position");
 
       priv->select_info->selection_anchor = anchor_index;
       priv->select_info->selection_end = end_index;
 
-      clipboard = gtk_widget_get_clipboard (GTK_WIDGET (label),
-                                           GDK_SELECTION_PRIMARY);
+      if (gtk_widget_has_screen (GTK_WIDGET (label)))
+        clipboard = gtk_widget_get_clipboard (GTK_WIDGET (label),
+                                              GDK_SELECTION_PRIMARY);
+      else
+        clipboard = NULL;
 
       if (anchor_index != end_index)
         {
@@ -5448,26 +5457,25 @@ gtk_label_select_region_index (GtkLabel *label,
           gtk_target_list_add_text_targets (list, 0);
           targets = gtk_target_table_new_from_list (list, &n_targets);
 
-          gtk_clipboard_set_with_owner (clipboard,
-                                        targets, n_targets,
-                                        get_text_callback,
-                                        clear_text_callback,
-                                        G_OBJECT (label));
+          if (clipboard)
+            gtk_clipboard_set_with_owner (clipboard,
+                                          targets, n_targets,
+                                          get_text_callback,
+                                          clear_text_callback,
+                                          G_OBJECT (label));
 
           gtk_target_table_free (targets, n_targets);
           gtk_target_list_unref (list);
         }
       else
         {
-          if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (label))
+          if (clipboard &&
+              gtk_clipboard_get_owner (clipboard) == G_OBJECT (label))
             gtk_clipboard_clear (clipboard);
         }
 
       gtk_widget_queue_draw (GTK_WIDGET (label));
 
-      g_object_freeze_notify (G_OBJECT (label));
-      g_object_notify (G_OBJECT (label), "cursor-position");
-      g_object_notify (G_OBJECT (label), "selection-bound");
       g_object_thaw_notify (G_OBJECT (label));
     }
 }
@@ -5649,8 +5657,12 @@ gtk_label_set_use_markup (GtkLabel *label,
 {
   g_return_if_fail (GTK_IS_LABEL (label));
 
+  g_object_freeze_notify (G_OBJECT (label));
+
   gtk_label_set_use_markup_internal (label, setting);
   gtk_label_recalculate (label);
+
+  g_object_thaw_notify (G_OBJECT (label));
 }
 
 /**
@@ -5685,8 +5697,12 @@ gtk_label_set_use_underline (GtkLabel *label,
 {
   g_return_if_fail (GTK_IS_LABEL (label));
 
+  g_object_freeze_notify (G_OBJECT (label));
+
   gtk_label_set_use_underline_internal (label, setting);
   gtk_label_recalculate (label);
+
+  g_object_thaw_notify (G_OBJECT (label));
 }
 
 /**
@@ -5966,9 +5982,9 @@ gtk_label_move_backward_word (GtkLabel *label,
 
 static void
 gtk_label_move_cursor (GtkLabel       *label,
-                      GtkMovementStep step,
-                      gint            count,
-                      gboolean        extend_selection)
+                       GtkMovementStep step,
+                       gint            count,
+                       gboolean        extend_selection)
 {
   GtkLabelPrivate *priv = label->priv;
   gint old_pos;
@@ -5986,53 +6002,53 @@ gtk_label_move_cursor (GtkLabel       *label,
        * start/or end of the selection as appropriate
        */
       switch (step)
-       {
-       case GTK_MOVEMENT_VISUAL_POSITIONS:
-         {
-           gint end_x, end_y;
-           gint anchor_x, anchor_y;
-           gboolean end_is_left;
-
-           get_better_cursor (label, priv->select_info->selection_end, &end_x, &end_y);
-           get_better_cursor (label, priv->select_info->selection_anchor, &anchor_x, &anchor_y);
-
-           end_is_left = (end_y < anchor_y) || (end_y == anchor_y && end_x < anchor_x);
-           
-           if (count < 0)
-             new_pos = end_is_left ? priv->select_info->selection_end : priv->select_info->selection_anchor;
-           else
-             new_pos = !end_is_left ? priv->select_info->selection_end : priv->select_info->selection_anchor;
-           break;
-         }
-       case GTK_MOVEMENT_LOGICAL_POSITIONS:
-       case GTK_MOVEMENT_WORDS:
-         if (count < 0)
-           new_pos = MIN (priv->select_info->selection_end, priv->select_info->selection_anchor);
-         else
-           new_pos = MAX (priv->select_info->selection_end, priv->select_info->selection_anchor);
-         break;
-       case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
-       case GTK_MOVEMENT_PARAGRAPH_ENDS:
-       case GTK_MOVEMENT_BUFFER_ENDS:
-         /* FIXME: Can do better here */
-         new_pos = count < 0 ? 0 : strlen (priv->text);
-         break;
-       case GTK_MOVEMENT_DISPLAY_LINES:
-       case GTK_MOVEMENT_PARAGRAPHS:
-       case GTK_MOVEMENT_PAGES:
-       case GTK_MOVEMENT_HORIZONTAL_PAGES:
-         break;
-       }
+        {
+        case GTK_MOVEMENT_VISUAL_POSITIONS:
+          {
+            gint end_x, end_y;
+            gint anchor_x, anchor_y;
+            gboolean end_is_left;
+
+            get_better_cursor (label, priv->select_info->selection_end, &end_x, &end_y);
+            get_better_cursor (label, priv->select_info->selection_anchor, &anchor_x, &anchor_y);
+
+            end_is_left = (end_y < anchor_y) || (end_y == anchor_y && end_x < anchor_x);
+
+            if (count < 0)
+              new_pos = end_is_left ? priv->select_info->selection_end : priv->select_info->selection_anchor;
+            else
+              new_pos = !end_is_left ? priv->select_info->selection_end : priv->select_info->selection_anchor;
+            break;
+          }
+        case GTK_MOVEMENT_LOGICAL_POSITIONS:
+        case GTK_MOVEMENT_WORDS:
+          if (count < 0)
+            new_pos = MIN (priv->select_info->selection_end, priv->select_info->selection_anchor);
+          else
+            new_pos = MAX (priv->select_info->selection_end, priv->select_info->selection_anchor);
+          break;
+        case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
+        case GTK_MOVEMENT_PARAGRAPH_ENDS:
+        case GTK_MOVEMENT_BUFFER_ENDS:
+          /* FIXME: Can do better here */
+          new_pos = count < 0 ? 0 : strlen (priv->text);
+          break;
+        case GTK_MOVEMENT_DISPLAY_LINES:
+        case GTK_MOVEMENT_PARAGRAPHS:
+        case GTK_MOVEMENT_PAGES:
+        case GTK_MOVEMENT_HORIZONTAL_PAGES:
+          break;
+        }
     }
   else
     {
       switch (step)
-       {
-       case GTK_MOVEMENT_LOGICAL_POSITIONS:
-         new_pos = gtk_label_move_logically (label, new_pos, count);
-         break;
-       case GTK_MOVEMENT_VISUAL_POSITIONS:
-         new_pos = gtk_label_move_visually (label, new_pos, count);
+        {
+        case GTK_MOVEMENT_LOGICAL_POSITIONS:
+          new_pos = gtk_label_move_logically (label, new_pos, count);
+          break;
+        case GTK_MOVEMENT_VISUAL_POSITIONS:
+          new_pos = gtk_label_move_visually (label, new_pos, count);
           if (new_pos == old_pos)
             {
               if (!extend_selection)
@@ -6054,41 +6070,41 @@ gtk_label_move_cursor (GtkLabel       *label,
                   gtk_widget_error_bell (GTK_WIDGET (label));
                 }
             }
-         break;
-       case GTK_MOVEMENT_WORDS:
-         while (count > 0)
-           {
-             new_pos = gtk_label_move_forward_word (label, new_pos);
-             count--;
-           }
-         while (count < 0)
-           {
-             new_pos = gtk_label_move_backward_word (label, new_pos);
-             count++;
-           }
+          break;
+        case GTK_MOVEMENT_WORDS:
+          while (count > 0)
+            {
+              new_pos = gtk_label_move_forward_word (label, new_pos);
+              count--;
+            }
+          while (count < 0)
+            {
+              new_pos = gtk_label_move_backward_word (label, new_pos);
+              count++;
+            }
           if (new_pos == old_pos)
             gtk_widget_error_bell (GTK_WIDGET (label));
-         break;
-       case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
-       case GTK_MOVEMENT_PARAGRAPH_ENDS:
-       case GTK_MOVEMENT_BUFFER_ENDS:
-         /* FIXME: Can do better here */
-         new_pos = count < 0 ? 0 : strlen (priv->text);
+          break;
+        case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
+        case GTK_MOVEMENT_PARAGRAPH_ENDS:
+        case GTK_MOVEMENT_BUFFER_ENDS:
+          /* FIXME: Can do better here */
+          new_pos = count < 0 ? 0 : strlen (priv->text);
           if (new_pos == old_pos)
             gtk_widget_error_bell (GTK_WIDGET (label));
-         break;
-       case GTK_MOVEMENT_DISPLAY_LINES:
-       case GTK_MOVEMENT_PARAGRAPHS:
-       case GTK_MOVEMENT_PAGES:
-       case GTK_MOVEMENT_HORIZONTAL_PAGES:
-         break;
-       }
+          break;
+        case GTK_MOVEMENT_DISPLAY_LINES:
+        case GTK_MOVEMENT_PARAGRAPHS:
+        case GTK_MOVEMENT_PAGES:
+        case GTK_MOVEMENT_HORIZONTAL_PAGES:
+          break;
+        }
     }
 
   if (extend_selection)
     gtk_label_select_region_index (label,
-                                  priv->select_info->selection_anchor,
-                                  new_pos);
+                                   priv->select_info->selection_anchor,
+                                   new_pos);
   else
     gtk_label_select_region_index (label, new_pos, new_pos);
 }
@@ -6522,7 +6538,7 @@ gtk_label_get_current_link (GtkLabel *label)
  *
  * Since: 2.18
  */
-G_CONST_RETURN gchar *
+const gchar *
 gtk_label_get_current_uri (GtkLabel *label)
 {
   GtkLabelLink *link;
@@ -6638,3 +6654,27 @@ gtk_label_query_tooltip (GtkWidget  *widget,
                                                                    keyboard_tip,
                                                                    tooltip);
 }
+
+gint
+_gtk_label_get_cursor_position (GtkLabel *label)
+{
+  GtkLabelPrivate *priv = label->priv;
+
+  if (priv->select_info && priv->select_info->selectable)
+    return g_utf8_pointer_to_offset (priv->text,
+                                     priv->text + priv->select_info->selection_end);
+
+  return 0;
+}
+
+gint
+_gtk_label_get_selection_bound (GtkLabel *label)
+{
+  GtkLabelPrivate *priv = label->priv;
+
+  if (priv->select_info && priv->select_info->selectable)
+    return g_utf8_pointer_to_offset (priv->text,
+                                     priv->text + priv->select_info->selection_anchor);
+
+  return 0;
+}