[gnumeric] Rewrite cmd_area_set_text to use cmd_generic (and GO_Undos)



commit 008a2ee5f86a9f108a7b3157cbab5a8d3f52f3d7
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Mon Jun 28 08:52:43 2010 -0600

    Rewrite cmd_area_set_text to use cmd_generic (and GO_Undos)
    
    2010-06-28  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* src/commands.c (CMD_AREA_SET_TEXT): deleted
    	(cmd_area_set_text_*): deleted
    	(cmd_area_set_text): rewritten using GO_UNDO
    	* src/sheet.h (sheet_range_set_text_undo): new
    	(sheet_range_set_expr_undo): new
    	(sheet_apply_style_undo): new
    	* src/sheet.c (sheet_range_set_text_undo): new
    	(sheet_range_set_expr_undo): new
    	(sheet_apply_style_undo): new
    	(sheet_apply_style_cb): new
    	(sheet_range_set_expr_cb): new
    	(sheet_range_set_text_cb): new
    	* src/wbc-gtk-edit.c (wbcg_edit_finish): provide initialization to
    	  quieten gcc

 ChangeLog          |   17 ++++
 src/commands.c     |  224 +++++++++++++++++-----------------------------------
 src/sheet.c        |  110 +++++++++++++++++++++++++
 src/sheet.h        |    9 ++-
 src/wbc-gtk-edit.c |    2 +-
 5 files changed, 207 insertions(+), 155 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 91c57ec..70627e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2010-06-28  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* src/commands.c (CMD_AREA_SET_TEXT): deleted 
+	(cmd_area_set_text_*): deleted
+	(cmd_area_set_text): rewritten using GO_UNDO
+	* src/sheet.h (sheet_range_set_text_undo): new
+	(sheet_range_set_expr_undo): new
+	(sheet_apply_style_undo): new
+	* src/sheet.c (sheet_range_set_text_undo): new
+	(sheet_range_set_expr_undo): new
+	(sheet_apply_style_undo): new
+	(sheet_apply_style_cb): new
+	(sheet_range_set_expr_cb): new
+	(sheet_range_set_text_cb): new
+	* src/wbc-gtk-edit.c (wbcg_edit_finish): provide initialization to
+	  quieten gcc
+
 2010-06-27  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* src/commands.h (cmd_area_set_text): change arguments
diff --git a/src/commands.c b/src/commands.c
index 2c2bf4f..5930878 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -947,141 +947,6 @@ cmd_set_text (WorkbookControl *wbc,
 
 /******************************************************************/
 
-#define CMD_AREA_SET_TEXT_TYPE        (cmd_area_set_text_get_type ())
-#define CMD_AREA_SET_TEXT(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), CMD_AREA_SET_TEXT_TYPE, CmdAreaSetText))
-
-typedef struct {
-	GnmCommand cmd;
-
-	GnmParsePos   pp;
-	char	  *text;
-	GSList	*old_contents;
-	GSList	*selection;
-} CmdAreaSetText;
-
-static void
-cmd_area_set_text_repeat (GnmCommand const *cmd, WorkbookControl *wbc)
-{
-	CmdAreaSetText const *orig = (CmdAreaSetText const *) cmd;
-	SheetView *sv = wb_control_cur_sheet_view (wbc);
-	cmd_area_set_text (wbc, sv, orig->text, NULL);
-}
-MAKE_GNM_COMMAND (CmdAreaSetText, cmd_area_set_text, cmd_area_set_text_repeat)
-
-static gboolean
-cmd_area_set_text_undo (GnmCommand *cmd, WorkbookControl *wbc)
-{
-	CmdAreaSetText *me = CMD_AREA_SET_TEXT (cmd);
-	GSList *ranges;
-
-	g_return_val_if_fail (me != NULL, TRUE);
-	g_return_val_if_fail (me->selection != NULL, TRUE);
-	g_return_val_if_fail (me->old_contents != NULL, TRUE);
-
-	for (ranges = me->selection; ranges != NULL ; ranges = ranges->next) {
-		GnmRange const *r = ranges->data;
-		GnmCellRegion * c;
-		GnmPasteTarget pt;
-
-		g_return_val_if_fail (me->old_contents != NULL, TRUE);
-
-		c = me->old_contents->data;
-		clipboard_paste_region (c,
-			paste_target_init (&pt, me->cmd.sheet, r, PASTE_CONTENTS | PASTE_FORMATS),
-			GO_CMD_CONTEXT (wbc));
-		cellregion_unref (c);
-		me->old_contents = g_slist_remove (me->old_contents, c);
-	}
-	g_return_val_if_fail (me->old_contents == NULL, TRUE);
-
-	return FALSE;
-}
-
-static gboolean
-cmd_area_set_text_redo (GnmCommand *cmd, WorkbookControl *wbc)
-{
-	CmdAreaSetText *me = CMD_AREA_SET_TEXT (cmd);
-	GnmExprTop const *texpr = NULL;
-	GSList *l;
-	GnmStyle *new_style = NULL;
-	char const *expr_txt;
-
-	g_return_val_if_fail (me != NULL, TRUE);
-
-	expr_txt = gnm_expr_char_start_p (me->text);
-	if (expr_txt != NULL)
-		texpr = gnm_expr_parse_str
-			(expr_txt, &me->pp, GNM_EXPR_PARSE_DEFAULT,
-			 sheet_get_conventions (me->cmd.sheet), NULL);
-
-	if (texpr != NULL) {
-		GnmEvalPos ep;
-		GOFormat *sf = auto_style_format_suggest (texpr,
-			eval_pos_init_pos (&ep, me->cmd.sheet, &me->pp.eval));
-		gnm_expr_top_unref (texpr);
-		texpr = NULL;
-		if (sf != NULL) {
-			new_style = gnm_style_new ();
-			gnm_style_set_format (new_style, sf);
-			go_format_unref (sf);
-		}
-	}
-
-	/* Everything is ok. Store previous contents and perform the operation */
-	for (l = me->selection ; l != NULL ; l = l->next) {
-		GnmRange const *r = l->data;
-		me->old_contents = g_slist_prepend (me->old_contents,
-			clipboard_copy_range (me->cmd.sheet, r));
-
-		/* Queue depends of region as a block beforehand */
-		sheet_region_queue_recalc (me->cmd.sheet, r);
-
-		/* If there is an expression then this was an array */
-		if (texpr != NULL) {
-			gnm_cell_set_array_formula (me->cmd.sheet,
-						r->start.col, r->start.row,
-						r->end.col, r->end.row,
-						texpr);
-			sheet_region_queue_recalc (me->cmd.sheet, r);
-		} else {
-			sheet_range_set_text (&me->pp, r, me->text);
-			if (new_style) {
-				gnm_style_ref (new_style);
-				sheet_apply_style (me->cmd.sheet, r, new_style);
-			}
-		}
-
-		/* mark contents as dirty */
-		sheet_flag_status_update_range (me->cmd.sheet, r);
-		sheet_queue_respan (me->cmd.sheet, r->start.row, r->end.row);
-	}
-	me->old_contents = g_slist_reverse (me->old_contents);
-	sheet_redraw_all (me->cmd.sheet, FALSE);
-
-	if (new_style)
-		gnm_style_unref (new_style);
-
-	return FALSE;
-}
-
-static void
-cmd_area_set_text_finalize (GObject *cmd)
-{
-	CmdAreaSetText *me = CMD_AREA_SET_TEXT (cmd);
-
-	g_free (me->text);
-
-	if (me->old_contents != NULL) {
-		GSList *l;
-		for (l = me->old_contents ; l != NULL ; l = g_slist_remove (l, l->data))
-			cellregion_unref (l->data);
-		me->old_contents = NULL;
-	}
-	range_fragment_free (me->selection);
-	me->selection = NULL;
-
-	gnm_command_finalize (cmd);
-}
 
 /*
  * cmd_area_set_text
@@ -1097,29 +962,82 @@ gboolean
 cmd_area_set_text (WorkbookControl *wbc, SheetView *sv,
 		   char const *new_text, PangoAttrList *markup)
 {
-#warning add markup
-	CmdAreaSetText *me;
-	GString *text;
-
-	me = g_object_new (CMD_AREA_SET_TEXT_TYPE, NULL);
-
-	me->text        = g_strdup (new_text);
-	me->selection   = selection_get_ranges (sv, FALSE /* No intersection */);
-	me->old_contents = NULL;
+	GSList	*selection = selection_get_ranges (sv, FALSE), *l;
+	GnmParsePos pp;
+	char const *expr_txt;
+	GnmExprTop const  *texpr = NULL;
+	GOUndo *undo = NULL;
+	GOUndo *redo = NULL;
+	gboolean result;
+	char *text = NULL;
+	Sheet *sheet = sv_sheet (sv);
+	
+	g_return_val_if_fail (selection != NULL , TRUE);
+	
+	parse_pos_init_editpos (&pp, sv);
+	expr_txt = gnm_expr_char_start_p (new_text);
+	if (expr_txt != NULL)
+		texpr = gnm_expr_parse_str
+			(expr_txt, &pp, GNM_EXPR_PARSE_DEFAULT,
+			 sheet_get_conventions (pp.sheet), NULL);
 
-	parse_pos_init_editpos (&me->pp, sv);
+	if (texpr != NULL) {
+		char *name;
+		GOFormat *sf;
+		GnmEvalPos ep;
+		GnmStyle *new_style = NULL;
 
-	text = gnm_cmd_trunc_descriptor (g_string_new (new_text), NULL);
+		name = undo_range_list_name (sheet, selection);
+		text = g_strdup_printf (_("Inserting expression in %s"), name);
+		g_free (name);
 
-	me->cmd.sheet = me->pp.sheet;
-	me->cmd.size = 1;
-	me->cmd.cmd_descriptor =
-		g_strdup_printf (_("Typing \"%s\""),
-				 text->str);
+		sf = auto_style_format_suggest 
+			(texpr, eval_pos_init_editpos (&ep, sv));
+		if (sf != NULL) {
+			new_style = gnm_style_new ();
+			gnm_style_set_format (new_style, sf);
+			go_format_unref (sf);
+		}
 
-	g_string_free (text, TRUE);
+		for (l = selection; l != NULL; l = l->next) {
+			GnmSheetRange *sr;
+			undo = go_undo_combine 
+				(undo, clipboard_copy_range_undo (sheet, l->data));
+			sr = gnm_sheet_range_new (sheet, l->data);
+			redo = go_undo_combine 
+				(redo, sheet_range_set_expr_undo (sr, texpr));
+			if (new_style) {
+				sr = gnm_sheet_range_new (sheet, l->data);
+				redo = go_undo_combine 
+					(redo, sheet_apply_style_undo (sr, new_style));
+			}
+		}
+		if (new_style)
+			gnm_style_unref (new_style);
+		gnm_expr_top_unref (texpr);
+	} else {
+#warning add markup
+		GString *text_str;
+
+		text_str = gnm_cmd_trunc_descriptor (g_string_new (new_text), NULL);
+		text = g_strdup_printf (_("Typing \"%s\""), text_str->str);
+		g_string_free (text_str, TRUE);
+
+		for (l = selection; l != NULL; l = l->next) {
+			GnmSheetRange *sr;
+			undo = go_undo_combine 
+				(undo, clipboard_copy_range_undo (sheet, l->data));
+			sr = gnm_sheet_range_new (sheet, l->data);
+			redo = go_undo_combine 
+				(redo, sheet_range_set_text_undo (sr, new_text));
+		
+		}
+	}
 
-	return gnm_command_push_undo (wbc, G_OBJECT (me));
+	result = cmd_generic (wbc, text, undo, redo);
+	g_free (text);
+	range_fragment_free (selection);
+	return result;	
 }
 
 /*
diff --git a/src/sheet.c b/src/sheet.c
index c6c458c..f851ed9 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -1530,6 +1530,28 @@ sheet_apply_style (Sheet       *sheet,
 	sheet_range_calc_spans (sheet, range, spanflags);
 }
 
+static void
+sheet_apply_style_cb (GnmSheetRange *sr,
+		      GnmStyle      *style)
+{
+	gnm_style_ref (style);
+	sheet_apply_style (sr->sheet, &sr->range, style);
+}
+
+GOUndo *     
+sheet_apply_style_undo (GnmSheetRange *sr, 
+			GnmStyle      *style)
+{
+	gnm_style_ref (style);
+	return go_undo_binary_new 
+		(sr, (gpointer)style, 
+		 (GOUndoBinaryFunc) sheet_apply_style_cb, 
+		 (GFreeFunc) gnm_sheet_range_free, 
+		 (GFreeFunc) gnm_style_unref);	
+}
+
+
+
 void
 sheet_apply_border (Sheet       *sheet,
 		    GnmRange const *range,
@@ -2429,6 +2451,66 @@ cb_clear_non_corner (GnmCellIter const *iter, GnmRange const *merged)
 }
 
 /**
+ * sheet_range_set_expr_cb :
+ *
+ *
+ * Does NOT check for array division.
+ **/
+static void
+sheet_range_set_expr_cb (GnmSheetRange const *sr, GnmExprTop const *texpr)
+{
+	closure_set_cell_value	closure;
+	GSList *merged, *ptr;
+
+	g_return_if_fail (sr != NULL);
+	g_return_if_fail (texpr != NULL);
+
+	closure.texpr = texpr;
+
+	range_init_full_sheet (&closure.expr_bound, sr->sheet);
+	gnm_expr_top_get_boundingbox (closure.texpr,
+				      sr->sheet,
+				      &closure.expr_bound);
+
+	sheet_region_queue_recalc (sr->sheet, &sr->range);
+	/* Store the parsed result creating any cells necessary */
+	sheet_foreach_cell_in_range 
+		(sr->sheet, CELL_ITER_ALL,
+		 sr->range.start.col, sr->range.start.row, 
+		 sr->range.end.col, sr->range.end.row,
+		 (CellIterFunc)&cb_set_cell_content, &closure);
+	
+	merged = gnm_sheet_merge_get_overlap (sr->sheet, &sr->range);
+	for (ptr = merged ; ptr != NULL ; ptr = ptr->next) {
+		GnmRange const *tmp = ptr->data;
+		sheet_foreach_cell_in_range 
+			(sr->sheet, CELL_ITER_ALL,
+			 tmp->start.col, tmp->start.row, 
+			 tmp->end.col, tmp->end.row,
+			 (CellIterFunc)&cb_clear_non_corner, 
+			 (gpointer)tmp);
+	}
+	g_slist_free (merged);
+
+	sheet_region_queue_recalc (sr->sheet, &sr->range);
+	sheet_flag_status_update_range (sr->sheet, &sr->range);
+	sheet_queue_respan (sr->sheet, sr->range.start.row, 
+			    sr->range.end.row);
+}
+
+GOUndo *
+sheet_range_set_expr_undo (GnmSheetRange *sr, GnmExprTop const  *texpr)
+{
+	gnm_expr_top_ref (texpr);
+	return go_undo_binary_new 
+		(sr, (gpointer)texpr, 
+		 (GOUndoBinaryFunc) sheet_range_set_expr_cb, 
+		 (GFreeFunc) gnm_sheet_range_free, 
+		 (GFreeFunc) gnm_expr_top_unref);
+}
+
+
+/**
  * sheet_range_set_text :
  *
  * @pos : The position from which to parse an expression.
@@ -2484,6 +2566,34 @@ sheet_range_set_text (GnmParsePos const *pos, GnmRange const *r, char const *str
 	sheet_flag_status_update_range (pos->sheet, r);
 }
 
+static void
+sheet_range_set_text_cb (GnmSheetRange const *sr, gchar const *text)
+{
+	GnmParsePos pos;
+
+	pos.eval = sr->range.start;
+	pos.sheet = sr->sheet;
+	pos.wb = sr->sheet->workbook;
+
+	sheet_range_set_text (&pos, &sr->range, text);
+	sheet_region_queue_recalc (sr->sheet, &sr->range);
+	sheet_flag_status_update_range (sr->sheet, &sr->range);
+	sheet_queue_respan (sr->sheet, sr->range.start.row, 
+			    sr->range.end.row);
+}
+
+GOUndo *     
+sheet_range_set_text_undo (GnmSheetRange *sr, 
+			   char const *text)
+{
+	return go_undo_binary_new 
+		(sr, g_strdup (text), 
+		 (GOUndoBinaryFunc) sheet_range_set_text_cb, 
+		 (GFreeFunc) gnm_sheet_range_free, 
+		 (GFreeFunc) g_free);
+}
+
+
 /**
  * sheet_cell_get_value:
  * @sheet: Sheet
diff --git a/src/sheet.h b/src/sheet.h
index 3446756..7350b90 100644
--- a/src/sheet.h
+++ b/src/sheet.h
@@ -319,8 +319,15 @@ void	     sheet_cell_set_value   (GnmCell *cell, GnmValue *v);
 void	     sheet_cell_set_text    (GnmCell *cell, char const *str,
 				     PangoAttrList *markup);
 GnmValue const *sheet_cell_get_value(Sheet *sheet, int col, int row);
-void	     sheet_range_set_text   (GnmParsePos const *pos, GnmRange const *r, char const *str);
+void	     sheet_range_set_text   (GnmParsePos const *pos, 
+				     GnmRange const *r, char const *str);
+GOUndo *     sheet_range_set_text_undo (GnmSheetRange *sr, 
+					char const *text);
+GOUndo *     sheet_range_set_expr_undo (GnmSheetRange *sr, 
+					GnmExprTop const  *texpr);
 void	     sheet_apply_style	    (Sheet  *sheet, GnmRange const *range, GnmStyle *mstyle);
+GOUndo *     sheet_apply_style_undo (GnmSheetRange *sr, 
+				     GnmStyle      *style);
 void	     sheet_apply_border	    (Sheet  *sheet, GnmRange const *range, GnmBorder **borders);
 void	     sheet_queue_respan     (Sheet const *sheet, int start_row, int end_row);
 void	     sheet_range_calc_spans (Sheet *sheet, GnmRange const *r, GnmSpanCalcFlags flags);
diff --git a/src/wbc-gtk-edit.c b/src/wbc-gtk-edit.c
index 7843ae3..d6365d0 100644
--- a/src/wbc-gtk-edit.c
+++ b/src/wbc-gtk-edit.c
@@ -133,7 +133,7 @@ wbcg_edit_finish (WBCGtk *wbcg, WBCEditResult result,
 
 	/* Save the results before changing focus */
 	if (result != WBC_EDIT_REJECT) {
-		ValidationStatus valid;
+		ValidationStatus valid = VALIDATION_STATUS_VALID;
 		char *free_txt = NULL;
 		char const *txt;
 		GnmStyle const *mstyle;



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