[gnumeric] Implement sheet resize.



commit 670efca3f2c4e105ecd48e6fe5dfa5c28ee94801
Author: Morten Welinder <terra gnome org>
Date:   Tue Apr 21 15:03:53 2009 -0400

    Implement sheet resize.
---
 ChangeLog      |    5 +++
 NEWS           |    1 +
 src/colrow.c   |   18 +++++++++
 src/colrow.h   |    2 +
 src/commands.c |    8 +++--
 src/sheet.c    |  105 +++++++++++++++++++++++++++++++++++++++++++++++---------
 src/sheet.h    |    2 +-
 7 files changed, 120 insertions(+), 21 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 09ac12b..96e96d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2009-04-21  Morten Welinder  <terra gnome org>
 
+	* src/sheet.c (sheet_destroy_contents): Use colrow_resize.
+	(gnm_sheet_resize): Initial implementation.
+
+	* src/colrow.c (colrow_resize): New function.
+
 	* src/sheet.c (gnm_sheet_resize): Stub.
 
 	* src/commands.c (cmd_resize_sheets): Undo framework for resizing
diff --git a/NEWS b/NEWS
index dee64e7..6bbf359 100644
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,7 @@ Morten:
 	* Clean up str.h usage.
 	* Load csv and txt files into sheets as big as needed.  [Part of
 	#168875]
+	* Implement sheet resize.
 
 Vivien Malerba:
 	* Move to libgda4.
diff --git a/src/colrow.c b/src/colrow.c
index 280ed52..4c5a4ad 100644
--- a/src/colrow.c
+++ b/src/colrow.c
@@ -1199,3 +1199,21 @@ colrow_reset_defaults (Sheet *sheet, gboolean is_cols, int maxima)
 	}
 	infos->max_used = maxima - 1;
 }
+
+void
+colrow_resize (ColRowCollection *infos, int size)
+{
+	int end_idx = COLROW_SEGMENT_INDEX (size);
+	int i = infos->info->len - 1;
+
+	while (i >= end_idx) {
+		ColRowSegment *segment = g_ptr_array_index (infos->info, i);
+		if (segment) {
+			g_free (segment);
+			g_ptr_array_index (infos->info, i) = NULL;
+		}
+		i--;
+	}
+
+	g_ptr_array_set_size (infos->info, end_idx);
+}
diff --git a/src/colrow.h b/src/colrow.h
index b193bb3..d64bedf 100644
--- a/src/colrow.h
+++ b/src/colrow.h
@@ -89,6 +89,8 @@ gboolean colrow_foreach	   (ColRowCollection const *infos,
 			    ColRowHandler callback,
 			    gpointer user_data);
 
+void colrow_resize (ColRowCollection *infos, int size);
+
 ColRowIndexList *colrow_index_list_destroy   (ColRowIndexList *list);
 GString         *colrow_index_list_to_string (ColRowIndexList *list,
 					      gboolean is_cols,
diff --git a/src/commands.c b/src/commands.c
index 8213610..3c01575 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -4838,8 +4838,9 @@ static gboolean
 cmd_resize_sheets_undo (GnmCommand *cmd, WorkbookControl *wbc)
 {
 	CmdResizeSheets *me = CMD_RESIZE_SHEETS (cmd);
+	GOCmdContext *cc = GO_CMD_CONTEXT (wbc);
 
-	go_undo_undo (me->undo);
+	go_undo_undo_with_data (me->undo, cc);
 	g_object_unref (me->undo);
 	me->undo = NULL;
 
@@ -4850,11 +4851,12 @@ static gboolean
 cmd_resize_sheets_redo (GnmCommand *cmd, WorkbookControl *wbc)
 {
 	CmdResizeSheets *me = CMD_RESIZE_SHEETS (cmd);
+	GOCmdContext *cc = GO_CMD_CONTEXT (wbc);
 	GSList *l;
 
 	for (l = me->sheets; l; l = l->next) {
 		Sheet *sheet = l->data;
-		GOUndo *u = gnm_sheet_resize (sheet, me->cols, me->rows);
+		GOUndo *u = gnm_sheet_resize (sheet, me->cols, me->rows, cc);
 		me->undo = go_undo_combine (me->undo, u);
 	}
 
@@ -4888,7 +4890,7 @@ cmd_resize_sheets (WorkbookControl *wbc,
 	me->rows = rows;
 	me->cmd.sheet = sheets ? sheets->data : NULL;
 	me->cmd.size = 1;
-	me->cmd.cmd_descriptor = _("Resizing sheet");
+	me->cmd.cmd_descriptor = g_strdup (_("Resizing sheet"));
 
 	if (sheets &&
 	    gnm_sheet_valid_size (cols, rows))
diff --git a/src/sheet.c b/src/sheet.c
index f5d34fd..4e10624 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -1085,17 +1085,96 @@ gnm_sheet_suggest_size (int *cols, int *rows)
 	*rows = r;
 }
 
+static void gnm_sheet_resize_main (Sheet *sheet, int cols, int rows,
+				   GOCmdContext *cc, GOUndo **pundo);
+
+struct cb_sheet_resize {
+	int cols, rows;
+};
+
+static void
+cb_sheet_resize (Sheet *sheet, const struct cb_sheet_resize *data, GOCmdContext *cc)
+{
+	gnm_sheet_resize_main (sheet, data->cols, data->rows, cc, NULL);
+}
+
+static void
+gnm_sheet_resize_main (Sheet *sheet, int cols, int rows,
+		       GOCmdContext *cc, GOUndo **pundo)
+{
+	int old_cols, old_rows;
+
+	if (pundo) *pundo = NULL;
+
+	old_cols = gnm_sheet_get_max_cols (sheet);
+	old_rows = gnm_sheet_get_max_rows (sheet);
+	if (old_cols == cols && old_rows == rows)
+		return;
+
+	/* ---------------------------------------- */
+
+	if (cols < old_cols) {
+		GOUndo *u = NULL;
+		gboolean err;
+
+		err = sheet_delete_cols (sheet, cols, old_cols - cols,
+					 pundo ? &u : NULL, cc);
+		/* FIXME: handle err */
+		if (pundo)
+			*pundo = go_undo_combine (*pundo, u);
+	}
+	colrow_resize (&sheet->cols, cols);
+
+	if (rows < old_rows) {
+		GOUndo *u = NULL;
+		gboolean err;
+
+		err = sheet_delete_rows (sheet, rows, old_rows - rows,
+					 pundo ? &u : NULL, cc);
+		/* FIXME: handle err */
+		if (pundo)
+			*pundo = go_undo_combine (*pundo, u);
+	}
+	colrow_resize (&sheet->rows, rows);
+
+	/* ---------------------------------------- */
+	/* Actually change the properties.  */
+
+	sheet->max_cols = cols;
+	sheet->max_rows = rows;
+	if (old_cols != cols)
+		g_object_notify (G_OBJECT (sheet), "columns");
+	if (old_rows != rows)
+		g_object_notify (G_OBJECT (sheet), "rows");
+
+	if (pundo) {
+		struct cb_sheet_resize *data =
+			g_new (struct cb_sheet_resize, 1);
+		GOUndo *u;
+
+		data->cols = cols;
+		data->rows = rows;
+		u = go_undo_binary_new (sheet, data,
+					(GOUndoBinaryFunc)cb_sheet_resize,
+					NULL, g_free);
+		*pundo = go_undo_combine (*pundo, u);
+	}
+
+	sheet_redraw_all (sheet, TRUE);
+}
+
 GOUndo *
-gnm_sheet_resize (Sheet *sheet, int cols, int rows)
+gnm_sheet_resize (Sheet *sheet, int cols, int rows, GOCmdContext *cc)
 {
+	GOUndo *undo = NULL;
+
 	g_return_val_if_fail (IS_SHEET (sheet), NULL);
+	g_return_val_if_fail (gnm_sheet_valid_size (cols, rows), NULL);
 
-	if (gnm_sheet_get_max_cols (sheet) == cols &&
-	    gnm_sheet_get_max_rows (sheet) == rows)
-		return NULL;
+	g_warning ("Changing sheet size is experimental.");
+	gnm_sheet_resize_main (sheet, cols, rows, cc, &undo);
 
-	g_warning ("Changing sheet size is not implemented yet.");
-	return NULL;
+	return undo;
 }
 
 
@@ -3672,7 +3751,6 @@ sheet_destroy_contents (Sheet *sheet)
 	int const max_row = sheet->rows.max_used;
 	GSList *filters;
 	int i;
-	gpointer tmp;
 
 	/* By the time we reach here dependencies should have been shut down */
 	g_return_if_fail (sheet->deps == NULL);
@@ -3724,18 +3802,11 @@ sheet_destroy_contents (Sheet *sheet)
 		sheet_row_destroy (sheet, i, FALSE);
 
 	/* Free segments too */
-	for (i = COLROW_SEGMENT_INDEX (max_col); i >= 0 ; --i)
-		if ((tmp = g_ptr_array_index (sheet->cols.info, i)) != NULL) {
-			g_free (tmp);
-			g_ptr_array_index (sheet->cols.info, i) = NULL;
-		}
+	colrow_resize (&sheet->cols, 0);
 	g_ptr_array_free (sheet->cols.info, TRUE);
 	sheet->cols.info = NULL;
-	for (i = COLROW_SEGMENT_INDEX (max_row); i >= 0 ; --i)
-		if ((tmp = g_ptr_array_index (sheet->rows.info, i)) != NULL) {
-			g_free (tmp);
-			g_ptr_array_index (sheet->rows.info, i) = NULL;
-		}
+
+	colrow_resize (&sheet->rows, 0);
 	g_ptr_array_free (sheet->rows.info, TRUE);
 	sheet->rows.info = NULL;
 }
diff --git a/src/sheet.h b/src/sheet.h
index 4ea2098..00bff47 100644
--- a/src/sheet.h
+++ b/src/sheet.h
@@ -128,7 +128,7 @@ void      sheet_destroy_contents (Sheet *sheet);
 gboolean  gnm_sheet_valid_size   (int cols, int rows);
 void      gnm_sheet_suggest_size (int *cols, int *rows);
 
-GOUndo   *gnm_sheet_resize       (Sheet *sheet, int cols, int rows);
+GOUndo   *gnm_sheet_resize       (Sheet *sheet, int cols, int rows, GOCmdContext *cc);
 
 int gnm_sheet_get_max_rows (Sheet const *sheet);
 int gnm_sheet_get_max_cols (Sheet const *sheet);



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