[gnumeric] Fixed selecting text in a cell



commit 56bd90ed469c7e12412832eac7bf3bd7968c9a05
Author: Jean Brefort <jean brefort normalesup org>
Date:   Sat Nov 28 18:40:40 2009 +0100

    Fixed selecting text in a cell

 ChangeLog       |    8 +++++
 NEWS            |    1 +
 src/item-edit.c |   81 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 80 insertions(+), 10 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6eec2ed..b4ac60b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2009-11-28  Jean Brefort  <jean brefort normalesup org>
 
+	* src/item-edit.c (item_edit_draw): fix selection bounds in case of
+	multibytes characters,
+	(item_edit_button_pressed), (item_edit_motion),
+	(item_edit_button_released), (item_edit_init),
+	(item_edit_class_init): implement dragging in ItemEdit. [#337521]
+
+2009-11-28  Jean Brefort  <jean brefort normalesup org>
+
 	* src/item-edit.c (item_edit_draw), (item_edit_button_pressed),
 	(item_edit_realize), (item_edit_unrealize): invert selected text, and allow
 	mouse selection past the last character. [#122176 and #388342]
diff --git a/NEWS b/NEWS
index a68a026..175189b 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ Jean:
 	* Fix multiple error message boxes in graph guru. [#152517]
 	* Invert selected text in a cell when editing. [#122176]
 	* Allow selection when the click occur after the last character. [#388342]
+	* Fixed selecting text in a cell. [#337521]
 
 Jody:
 	* turnkey win32 build on 32bit host.
diff --git a/src/item-edit.c b/src/item-edit.c
index 4f7e460..67b4fa2 100644
--- a/src/item-edit.c
+++ b/src/item-edit.c
@@ -55,6 +55,7 @@ struct _ItemEdit {
 	GnmCellPos pos;
 	gboolean   cursor_visible;
 	int        blink_timer;
+	int	   sel_start;
 
 	GnmFont   *gfont;
 	GnmStyle  *style;
@@ -137,6 +138,8 @@ item_edit_draw (GocItem const *item, cairo_t *cr)
 		int x, y, w, h;
 		GdkEventExpose *expose = (GdkEventExpose *) goc_canvas_get_cur_event (item->canvas);
 		GdkDrawable *drawable = GDK_DRAWABLE (expose->window);
+		start = g_utf8_offset_to_pointer (text, start) - text;
+		end = g_utf8_offset_to_pointer (text, end) - text;
 		pango_layout_index_to_pos (ie->layout, start, &pos);
 		x = PANGO_PIXELS (pos.x);
 		y = PANGO_PIXELS (pos.y);
@@ -203,9 +206,8 @@ item_edit_button_pressed (GocItem *item, int button, double x, double y)
 			target_index = strlen (text);
 			trailing = 0;
 		}
-		gtk_editable_set_position (GTK_EDITABLE (ie->entry),
-			g_utf8_pointer_to_offset (text, text + target_index)
-			+ trailing);
+		ie->sel_start = g_utf8_pointer_to_offset (text, text + target_index) + trailing; 
+		gtk_editable_set_position (GTK_EDITABLE (ie->entry), ie->sel_start);
 
 		return TRUE;
 	}
@@ -213,6 +215,62 @@ item_edit_button_pressed (GocItem *item, int button, double x, double y)
 	return FALSE;
 }
 
+static gboolean
+item_edit_motion (GocItem *item, double x, double y)
+{
+	ItemEdit *ie = ITEM_EDIT (item);
+	if (ie->sel_start >=0) {
+		GtkEditable *ed = GTK_EDITABLE (ie->entry);
+		int target_index, trailing;
+		int top, left;
+		char const *text = pango_layout_get_text (ie->layout);
+
+		get_top_left (ie, &top, &left);
+		y -= top;
+		x -= left;
+
+		if (pango_layout_xy_to_index (ie->layout,
+					      x * PANGO_SCALE, y * PANGO_SCALE,
+					      &target_index, &trailing)) {
+			int preedit = GNM_PANE (item->canvas)->preedit_length;
+			gint cur_index = gtk_editable_get_position (ed);
+			cur_index = g_utf8_offset_to_pointer (text, cur_index) - text;
+
+			if (target_index >= cur_index && preedit > 0) {
+				if (target_index < (cur_index + preedit)) {
+					target_index = cur_index;
+					trailing = 0;
+				} else
+					target_index -= preedit;
+			}
+		} else {
+			/* the click occured after text end (#388342) */
+			target_index = strlen (text);
+			trailing = 0;
+		}
+		target_index = g_utf8_pointer_to_offset (text, text + target_index) + trailing;
+		if (target_index > ie->sel_start)
+			gtk_editable_select_region (GTK_EDITABLE (ie->entry), ie->sel_start, target_index);
+		else
+			gtk_editable_select_region (GTK_EDITABLE (ie->entry), target_index, ie->sel_start);
+		goc_item_invalidate (item);
+
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static gboolean
+item_edit_button_released (GocItem *item, int button, G_GNUC_UNUSED double x, G_GNUC_UNUSED double y)
+{
+	ItemEdit *ie = ITEM_EDIT (item);
+	if (ie->sel_start >= 0) {
+		ie->sel_start = -1;
+		return TRUE;
+	}
+	return FALSE;
+}
+
 static void
 item_edit_update_bounds (GocItem *item)
 {
@@ -491,6 +549,7 @@ item_edit_init (ItemEdit *ie)
 	ie->gfont = NULL;
 	ie->style      = NULL;
 	ie->cursor_visible = TRUE;
+	ie->sel_start = -1;
 }
 
 static void
@@ -535,13 +594,15 @@ item_edit_class_init (GObjectClass *gobject_class)
 			 GSF_PARAM_STATIC | G_PARAM_WRITABLE));
 
 	/* GocItem method overrides */
-	item_class->realize        = item_edit_realize;
-	item_class->unrealize      = item_edit_unrealize;
-	item_class->draw           = item_edit_draw;
-	item_class->distance       = item_edit_distance;
-	item_class->update_bounds  = item_edit_update_bounds;
-	item_class->button_pressed = item_edit_button_pressed;
-	item_class->enter_notify   = item_edit_enter_notify;
+	item_class->realize         = item_edit_realize;
+	item_class->unrealize       = item_edit_unrealize;
+	item_class->draw            = item_edit_draw;
+	item_class->distance        = item_edit_distance;
+	item_class->update_bounds   = item_edit_update_bounds;
+	item_class->button_pressed  = item_edit_button_pressed;
+	item_class->enter_notify    = item_edit_enter_notify;
+	item_class->motion          = item_edit_motion;
+	item_class->button_released = item_edit_button_released;
 }
 
 GSF_CLASS (ItemEdit, item_edit,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]