[gnumeric] Preserve (one) text attribute when editing text labels



commit 41515f0e3b714cf4a11ee5f8185af502f44caf0d
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date:   Tue Apr 21 21:31:11 2009 -0600

    Preserve (one) text attribute when editing text labels
    
         2009-04-21  Andreas J. Guelzow <aguelzow pyrshep ca>
    
        	* src/commands.h (cmd_object_format): add argument
        	* src/commands.c (cmd_object_format): handle attributes
        	(cmd_object_format_redo): ditto
        	(cmd_object_format_finalize): ditto
        	* src/gnm-so-filled.c (cb_gnm_so_filled_changed): also set
        	  attributes
        	* src/gui-util.h (gnumeric_textbuffer_get_text): new
        	(gnm_load_pango_attributes_into_buffer): new
        	(gnm_get_pango_attributes_from_buffer): new
        	* src/gui-util.c (gnumeric_textbuffer_get_text): new
        	(gnm_load_pango_attributes_into_buffer): new
        	(gnm_get_pango_attributes_from_buffer): new
        	(gnumeric_textview_get_text): use gnumeric_textbuffer_get_text
        	(gnm_load_pango_attributes_into_buffer_filter): new
        	(gnm_store_text_tag_attr_in_pango): new
    
        2009-04-21  Andreas J. Guelzow <aguelzow pyrshep ca>
    
        	* dialog-so-styled.c (DialogSOStyled): include original attributes
        	(dialog_so_styled_free): free attributes
        	(cb_dialog_so_styled_response): adjust arguments of cmd_object_format
        	(cb_dialog_so_styled_text_widget_changed): handle attributes
        	(dialog_so_styled_text_widget): ditto
---
 ChangeLog                      |   18 ++++++
 src/commands.c                 |   19 ++++++-
 src/commands.h                 |    3 +-
 src/dialogs/ChangeLog          |    8 +++
 src/dialogs/dialog-so-styled.c |   25 ++++++--
 src/gnm-so-filled.c            |    5 +-
 src/gui-util.c                 |  122 +++++++++++++++++++++++++++++++++++++++-
 src/gui-util.h                 |    4 +
 8 files changed, 191 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 62d17f7..2b3474c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -22,6 +22,24 @@
 
 2009-04-21  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* src/commands.h (cmd_object_format): add argument
+	* src/commands.c (cmd_object_format): handle attributes
+	(cmd_object_format_redo): ditto
+	(cmd_object_format_finalize): ditto
+	* src/gnm-so-filled.c (cb_gnm_so_filled_changed): also set
+	  attributes
+	* src/gui-util.h (gnumeric_textbuffer_get_text): new
+	(gnm_load_pango_attributes_into_buffer): new
+	(gnm_get_pango_attributes_from_buffer): new
+	* src/gui-util.c (gnumeric_textbuffer_get_text): new
+	(gnm_load_pango_attributes_into_buffer): new
+	(gnm_get_pango_attributes_from_buffer): new
+	(gnumeric_textview_get_text): use gnumeric_textbuffer_get_text
+	(gnm_load_pango_attributes_into_buffer_filter): new
+	(gnm_store_text_tag_attr_in_pango): new
+
+2009-04-21  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* src/gnm-so-filled.c (gnm_so_filled_user_config): adjust for 
 	  changed arguments of dialog_so_styled
 	* src/gnm-so-line.c (gnm_so_line_user_config): ditto
diff --git a/src/commands.c b/src/commands.c
index 3c01575..f504d58 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -4627,6 +4627,7 @@ typedef struct {
 	GnmCommand cmd;
 	GObject	 *so, *style;
 	char *text;
+	PangoAttrList *attr;
 	gboolean  first_time;
 } CmdObjectFormat;
 
@@ -4652,6 +4653,14 @@ cmd_object_format_redo (GnmCommand *cmd, G_GNUC_UNUSED WorkbookControl *wbc)
 			g_free (me->text);
 			me->text = old_text;
 		}
+		if (me->attr != NULL) {
+			PangoAttrList *old_attr;
+			g_object_get (me->so, "markup",  &old_attr, NULL);
+			g_object_set (me->so, "markup",  me->attr, NULL);
+			pango_attr_list_unref (me->attr);
+			me->attr = old_attr;
+			pango_attr_list_ref (me->attr);
+		}
 	}
 	sheet_mark_dirty (me->cmd.sheet);
 	return FALSE;
@@ -4671,6 +4680,8 @@ cmd_object_format_finalize (GObject *cmd)
 	g_object_unref (me->so);
 	if (me->text)
 		g_free (me->text);
+	if (me->attr)
+		pango_attr_list_unref (me->attr);
 	gnm_command_finalize (cmd);
 }
 
@@ -4678,7 +4689,8 @@ cmd_object_format_finalize (GObject *cmd)
  * instant apply. */
 gboolean
 cmd_object_format (WorkbookControl *wbc, SheetObject *so,
-		   gpointer orig_style, char *orig_text)
+		   gpointer orig_style, char *orig_text,
+		   PangoAttrList *orig_attr)
 {
 	CmdObjectFormat *me;
 
@@ -4690,6 +4702,11 @@ cmd_object_format (WorkbookControl *wbc, SheetObject *so,
 	me->so    = g_object_ref (G_OBJECT (so));
 	me->style = g_object_ref (G_OBJECT (orig_style));
 	me->text = orig_text ? g_strdup (orig_text) : NULL;
+	if (orig_attr != NULL) {
+		me->attr = orig_attr;
+		pango_attr_list_ref (me->attr);
+	} else
+		me->attr = NULL;
 	me->first_time = TRUE;
 
 	me->cmd.sheet = sheet_object_get_sheet (so);
diff --git a/src/commands.h b/src/commands.h
index a4605d4..a977784 100644
--- a/src/commands.h
+++ b/src/commands.h
@@ -145,7 +145,8 @@ gboolean cmd_objects_move	(WorkbookControl *wbc,
 				 GSList *objects, GSList *anchors,
 				 gboolean objects_created, char const *name);
 gboolean cmd_object_format	(WorkbookControl *wbc, SheetObject *so,
-				 gpointer orig_style, char *orig_text);
+				 gpointer orig_style, char *orig_text,
+				 PangoAttrList *orig_attr);
 
 gboolean cmd_reorganize_sheets  (WorkbookControl *wbc,
 				 WorkbookSheetState *old_state,
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index 3a602c1..2a99c83 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,5 +1,13 @@
 2009-04-21  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* dialog-so-styled.c (DialogSOStyled): include original attributes
+	(dialog_so_styled_free): free attributes
+	(cb_dialog_so_styled_response): adjust arguments of cmd_object_format
+	(cb_dialog_so_styled_text_widget_changed): handle attributes
+	(dialog_so_styled_text_widget): ditto
+
+2009-04-21  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* dialogs.h (dialog_so_styled): pass both the title and information
 	  on the extent of the properties dialog
 	* dialog-so-styled.c (dialog_so_styled): use the passsed title
diff --git a/src/dialogs/dialog-so-styled.c b/src/dialogs/dialog-so-styled.c
index 165990f..f7c4f8f 100644
--- a/src/dialogs/dialog-so-styled.c
+++ b/src/dialogs/dialog-so-styled.c
@@ -40,6 +40,7 @@ typedef struct {
 	WBCGtk	*wbcg;
 	GOStyle		*orig_style;
 	char    *orig_text;
+	PangoAttrList *orig_attributes;
 } DialogSOStyled;
 
 #define GNM_SO_STYLED_KEY "gnm-so-styled-key"
@@ -55,6 +56,10 @@ dialog_so_styled_free (DialogSOStyled *pref)
 		g_object_set (G_OBJECT (pref->so), "text", pref->orig_text, NULL);
 		g_free (pref->orig_text);
 	}
+	if (pref->orig_attributes != NULL) {
+		g_object_set (G_OBJECT (pref->so), "markup", pref->orig_attributes, NULL);
+		pango_attr_list_unref (pref->orig_attributes);
+	}
 	g_free (pref);
 }
 
@@ -67,11 +72,13 @@ cb_dialog_so_styled_response (GtkWidget *dialog,
 	if (response_id == GTK_RESPONSE_OK) {
 		cmd_object_format (WORKBOOK_CONTROL (pref->wbcg),
 				   SHEET_OBJECT (pref->so), pref->orig_style, 
-				   pref->orig_text);
+				   pref->orig_text, pref->orig_attributes);
 		g_object_unref (pref->orig_style);
 		pref->orig_style = NULL;
 		g_free (pref->orig_text);
 		pref->orig_text = NULL;
+		pango_attr_list_unref (pref->orig_attributes);
+		pref->orig_attributes = NULL;
 	}
 	gtk_object_destroy (GTK_OBJECT (dialog));
 }
@@ -79,14 +86,14 @@ cb_dialog_so_styled_response (GtkWidget *dialog,
 static void
 cb_dialog_so_styled_text_widget_changed (GtkTextBuffer *buffer, DialogSOStyled *state)
 {
-	GtkTextIter start, end;
-	gchar *text;
+	gchar *text = gnumeric_textbuffer_get_text (buffer);
+	PangoAttrList *attr = gnm_get_pango_attributes_from_buffer (buffer);
 
-	gtk_text_buffer_get_start_iter (buffer, &start);
-	gtk_text_buffer_get_end_iter (buffer, &end);
-	text = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
 	g_object_set (state->so, "text", text, NULL);
 	g_free (text);
+	
+	g_object_set (state->so, "markup", attr, NULL);
+	pango_attr_list_unref (attr);
 }
 
 static GtkWidget *
@@ -95,6 +102,7 @@ dialog_so_styled_text_widget (DialogSOStyled *state)
 	GtkWidget *tv = gtk_text_view_new ();
 	GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
 	char *strval;
+	PangoAttrList  *markup;
 
 	gtk_container_set_border_width (GTK_CONTAINER (tv), 5);
 	gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR);
@@ -104,6 +112,11 @@ dialog_so_styled_text_widget (DialogSOStyled *state)
 	gtk_text_buffer_set_text (buffer, strval, -1);
 	g_free (strval);
 
+	g_object_get (state->so, "markup", &markup, NULL);
+	state->orig_attributes = markup;
+	pango_attr_list_ref (state->orig_attributes);
+	gnm_load_pango_attributes_into_buffer (markup, buffer);
+
 	g_signal_connect (G_OBJECT (buffer), "changed",
 			  G_CALLBACK (cb_dialog_so_styled_text_widget_changed), state);
 
diff --git a/src/gnm-so-filled.c b/src/gnm-so-filled.c
index 5d703d5..d325f56 100644
--- a/src/gnm-so-filled.c
+++ b/src/gnm-so-filled.c
@@ -220,8 +220,9 @@ cb_gnm_so_filled_changed (GnmSOFilled const *sof,
 				"attributes",	sof->markup,
 				NULL);
 		foo_canvas_item_set (FOO_CANVAS_ITEM (group->item_list->next->data),
-			"text", sof->text,
-			NULL);
+				     "text", sof->text,
+				     "attributes",	sof->markup,
+				     NULL);
 	} else if (group->item_list->next != NULL)
 		g_object_unref (group->item_list->next->data);
 }
diff --git a/src/gui-util.c b/src/gui-util.c
index 2d4dba7..4dab183 100644
--- a/src/gui-util.c
+++ b/src/gui-util.c
@@ -28,6 +28,7 @@
 #include <goffice/app/error-info.h>
 #include <goffice/gtk/go-combo-color.h>
 #include <goffice/gtk/goffice-gtk.h>
+#include <goffice/utils/go-glib-extras.h>
 #include <glade/glade.h>
 #include <gtk/gtk.h>
 #include <atk/atkrelation.h>
@@ -634,16 +635,23 @@ gnumeric_init_help_button (GtkWidget *w, char const *link)
 }
 
 char *
-gnumeric_textview_get_text (GtkTextView *text_view)
+gnumeric_textbuffer_get_text (GtkTextBuffer *buf)
 {
 	GtkTextIter    start, end;
-	GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
 
 	g_return_val_if_fail (buf != NULL, NULL);
 
 	gtk_text_buffer_get_start_iter (buf, &start);
 	gtk_text_buffer_get_end_iter (buf, &end);
-	return gtk_text_buffer_get_text (buf, &start, &end, FALSE);
+	/* We are using slice rather than text so that the tags still match */
+	return gtk_text_buffer_get_slice (buf, &start, &end, FALSE);
+}
+
+char *
+gnumeric_textview_get_text (GtkTextView *text_view)
+{
+	return gnumeric_textbuffer_get_text 
+		(gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)));
 }
 
 void
@@ -654,6 +662,114 @@ gnumeric_textview_set_text (GtkTextView *text_view, char const *txt)
 		txt, -1);
 }
 
+static gboolean
+gnm_load_pango_attributes_into_buffer_filter (PangoAttribute *attribute, 
+					  G_GNUC_UNUSED gpointer data)
+{
+	return (PANGO_ATTR_FOREGROUND == attribute->klass->type);
+}
+
+void 
+gnm_load_pango_attributes_into_buffer (PangoAttrList  *markup, GtkTextBuffer *buffer) 
+{
+	PangoAttrIterator * iter;
+	PangoAttrList  *copied_markup;
+	PangoAttrList  *our_markup;
+
+	if (markup == NULL)
+		return; 
+	copied_markup = pango_attr_list_copy (markup);
+	our_markup = pango_attr_list_filter (copied_markup, 
+					     gnm_load_pango_attributes_into_buffer_filter, 
+					     NULL);
+	pango_attr_list_unref (copied_markup);
+	if (our_markup == NULL)
+		return; 
+
+	iter = pango_attr_list_get_iterator (our_markup);
+
+	do {
+		GSList *attr = pango_attr_iterator_get_attrs (iter);
+		if (attr != NULL) {
+			char *string;
+			GSList *ptr;
+			gint start, end;
+			GtkTextIter start_iter, end_iter;
+			GtkTextTag *tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
+			for (ptr = attr; ptr != NULL; ptr = ptr->next) {
+				PangoAttribute *attribute = ptr->data;
+				switch (attribute->klass->type) {
+				case PANGO_ATTR_FOREGROUND:
+					string = pango_color_to_string 
+						(&((PangoAttrColor *)attribute)->color);
+					g_object_set (G_OBJECT (tag), 
+						      "foreground", string,
+						      "foreground-set", TRUE,
+						      NULL);
+					g_free (string);
+					break;
+				default:
+					break;
+				}
+			}
+			pango_attr_iterator_range (iter, &start, &end);
+			gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
+			gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
+			gtk_text_buffer_apply_tag (buffer, tag, &start_iter, &end_iter);
+			go_slist_free_custom (attr, (GFreeFunc)pango_attribute_destroy);
+		}
+	} while (pango_attr_iterator_next (iter));
+	pango_attr_iterator_destroy (iter);
+	pango_attr_list_unref (our_markup);
+}
+
+static void
+gnm_store_text_tag_attr_in_pango (PangoAttrList *list, GtkTextTag *tag, GtkTextIter *start, gchar const *text)
+{
+	GtkTextIter end = *start;
+	gint x, y;
+	gboolean is_set;
+	PangoAttribute * attr;
+
+	gtk_text_iter_forward_to_tag_toggle (&end, tag);
+	x = g_utf8_offset_to_pointer (text, gtk_text_iter_get_offset (start)) - text;
+	y = g_utf8_offset_to_pointer (text, gtk_text_iter_get_offset (&end)) - text;
+
+	g_object_get (G_OBJECT (tag), "foreground-set", &is_set, NULL);
+	if (is_set) {
+		GdkColor* color;
+		g_object_get (G_OBJECT (tag), "foreground-gdk", &color, NULL);
+		attr =  pango_attr_foreground_new (color->red, color->green, color->blue);
+		attr->start_index = x;
+		attr->end_index = y;
+		pango_attr_list_change (list, attr);
+		gdk_color_free (color);
+	}
+}
+
+PangoAttrList *
+gnm_get_pango_attributes_from_buffer (GtkTextBuffer *buffer)
+{
+	PangoAttrList *list = pango_attr_list_new ();
+	GtkTextIter start;
+	gchar *text = gnumeric_textbuffer_get_text (buffer);
+
+	gtk_text_buffer_get_start_iter (buffer, &start); 
+	
+	while (!gtk_text_iter_is_end (&start)) {
+		if (gtk_text_iter_begins_tag (&start, NULL)) {
+			GSList *ptr, *l = gtk_text_iter_get_toggled_tags (&start, TRUE);
+			for (ptr = l; ptr; ptr = ptr->next)
+				gnm_store_text_tag_attr_in_pango (list, ptr->data, &start, text);
+		}
+		gtk_text_iter_forward_to_tag_toggle (&start, NULL);
+	}
+
+	g_free (text);
+
+	return list;
+}
+
 void
 focus_on_entry (GtkEntry *entry)
 {
diff --git a/src/gui-util.h b/src/gui-util.h
index 21bd531..df68d94 100644
--- a/src/gui-util.h
+++ b/src/gui-util.h
@@ -70,8 +70,12 @@ GnmColor *go_combo_color_get_style_color (GtkWidget *color_combo);
 
 void gnumeric_init_help_button	(GtkWidget *w, char const *link);
 
+char *gnumeric_textbuffer_get_text (GtkTextBuffer *buf);
 char *gnumeric_textview_get_text (GtkTextView *text_view);
 void  gnumeric_textview_set_text (GtkTextView *text_view, char const *txt);
+void  gnm_load_pango_attributes_into_buffer (PangoAttrList  *markup, 
+					     GtkTextBuffer *buffer);
+PangoAttrList *gnm_get_pango_attributes_from_buffer (GtkTextBuffer *buffer);
 
 void focus_on_entry (GtkEntry *entry);
 



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