undo.c 8.53 KB
Newer Older
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
1 2 3 4 5
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * undo.c:
 *
 * Authors:
6
 * Andreas J. Guelzow  <aguelzow@pyrshep.ca>
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * (C) Copyright 2010 by Andreas J. Guelzow  <aguelzow@pyrshep.ca>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
22 23
 */

24 25
#include <gnumeric-config.h>

Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
26
#include "undo.h"
27 28 29 30 31 32 33
#include "sheet.h"
#include "sheet-view.h"
#include "sheet-control-gui.h"
#include "wbc-gtk.h"
#include "wbc-gtk-impl.h"
#include "colrow.h"

Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
34
#include <gsf/gsf-impl-utils.h>
35
#include <glib/gi18n-lib.h>
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
36 37 38 39 40 41 42 43

/* ------------------------------------------------------------------------- */

static GObjectClass *gnm_undo_colrow_restore_state_group_parent_class;

static void
gnm_undo_colrow_restore_state_group_finalize (GObject *o)
{
Jean Bréfort's avatar
Jean Bréfort committed
44
	GnmUndoColrowRestoreStateGroup *ua = (GnmUndoColrowRestoreStateGroup *)o;
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
45 46 47 48 49

	colrow_state_group_destroy (ua->saved_state);
	ua->saved_state = NULL;
	colrow_index_list_destroy (ua->selection);
	ua->selection = NULL;
50 51

	G_OBJECT_CLASS (gnm_undo_colrow_restore_state_group_parent_class)->finalize (o);
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
52 53 54
}

static void
55
gnm_undo_colrow_restore_state_group_undo (GOUndo *u, G_GNUC_UNUSED gpointer data)
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
56
{
Jean Bréfort's avatar
Jean Bréfort committed
57
	GnmUndoColrowRestoreStateGroup *ua = (GnmUndoColrowRestoreStateGroup *)u;
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

	colrow_restore_state_group (ua->sheet, ua->is_cols, ua->selection, ua->saved_state);
}

static void
gnm_undo_colrow_restore_state_group_class_init (GObjectClass *gobject_class)
{
	GOUndoClass *uclass = (GOUndoClass *)gobject_class;

	gnm_undo_colrow_restore_state_group_parent_class = g_type_class_peek_parent (gobject_class);

	gobject_class->finalize = gnm_undo_colrow_restore_state_group_finalize;
	uclass->undo = gnm_undo_colrow_restore_state_group_undo;
}


Jean Bréfort's avatar
Jean Bréfort committed
74
GSF_CLASS (GnmUndoColrowRestoreStateGroup, gnm_undo_colrow_restore_state_group,
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
75 76 77 78 79 80 81 82 83 84 85 86 87
	   gnm_undo_colrow_restore_state_group_class_init, NULL, GO_TYPE_UNDO)

/**
 * gnm_undo_colrow_restore_state_group_new:
 *
 * Returns: a new undo object.
 **/

GOUndo *
gnm_undo_colrow_restore_state_group_new (Sheet *sheet, gboolean is_cols,
					ColRowIndexList *selection,
					ColRowStateGroup *saved_state)
{
Jean Bréfort's avatar
Jean Bréfort committed
88
	GnmUndoColrowRestoreStateGroup *ua = g_object_new (GNM_TYPE_UNDO_COLROW_RESTORE_STATE_GROUP, NULL);
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

	ua->sheet = sheet;
	ua->is_cols = is_cols;
	ua->selection = selection;
	ua->saved_state = saved_state;

	return (GOUndo *)ua;
}

/* ------------------------------------------------------------------------- */

static GObjectClass *gnm_undo_colrow_set_sizes_parent_class;

static void
gnm_undo_colrow_set_sizes_finalize (GObject *o)
{
Jean Bréfort's avatar
Jean Bréfort committed
105
	GnmUndoColrowSetSizes *ua = (GnmUndoColrowSetSizes *)o;
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
106 107 108

	colrow_index_list_destroy (ua->selection);
	ua->selection = NULL;
109 110

	G_OBJECT_CLASS (gnm_undo_colrow_set_sizes_parent_class)->finalize (o);
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
111 112 113
}

static void
114
gnm_undo_colrow_set_sizes_undo (GOUndo *u, G_GNUC_UNUSED gpointer data)
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
115
{
Jean Bréfort's avatar
Jean Bréfort committed
116
	GnmUndoColrowSetSizes *ua = (GnmUndoColrowSetSizes *)u;
117
	ColRowStateGroup *group;
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
118

Morten Welinder's avatar
Morten Welinder committed
119
	group = colrow_set_sizes (ua->sheet, ua->is_cols, ua->selection, ua->new_size,
120 121
				  ua->from, ua->to);
	colrow_state_group_destroy (group);
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
122 123 124 125 126 127 128 129 130 131 132 133 134 135
}

static void
gnm_undo_colrow_set_sizes_class_init (GObjectClass *gobject_class)
{
	GOUndoClass *uclass = (GOUndoClass *)gobject_class;

	gnm_undo_colrow_set_sizes_parent_class = g_type_class_peek_parent (gobject_class);

	gobject_class->finalize = gnm_undo_colrow_set_sizes_finalize;
	uclass->undo = gnm_undo_colrow_set_sizes_undo;
}


Jean Bréfort's avatar
Jean Bréfort committed
136
GSF_CLASS (GnmUndoColrowSetSizes, gnm_undo_colrow_set_sizes,
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
137 138 139 140 141
	   gnm_undo_colrow_set_sizes_class_init, NULL, GO_TYPE_UNDO)

/**
 * gnm_undo_colrow_set_sizes_new:
 *
142
 * If r is non-null and new_size < 0, selection is ignored.
143
 *
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
144 145 146 147 148 149
 * Returns: a new undo object.
 **/

GOUndo *
gnm_undo_colrow_set_sizes_new (Sheet *sheet, gboolean is_cols,
			       ColRowIndexList *selection,
150
			       int new_size, GnmRange const *r)
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
151
{
Jean Bréfort's avatar
Jean Bréfort committed
152
	GnmUndoColrowSetSizes *ua;
153 154 155 156

	g_return_val_if_fail (selection != NULL || (r != NULL && new_size == -1), NULL);

	ua = g_object_new (GNM_TYPE_UNDO_COLROW_SET_SIZES, NULL);
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
157 158 159 160

	ua->sheet = sheet;
	ua->is_cols = is_cols;
	ua->new_size = new_size;
Morten Welinder's avatar
Morten Welinder committed
161

162
	if (r == NULL || new_size >= 0) {
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
		ua->selection = selection;
		ua->from = 0;
		ua->to = -1;
	} else {
		int first, last;

		if (is_cols) {
			first = r->start.col;
			last = r->end.col;
			ua->from =  r->start.row;
			ua->to = r->end.row;
		} else {
			first = r->start.row;
			last = r->end.row;
			ua->from =  r->start.col;
			ua->to = r->end.col;
		}
		ua->selection = colrow_get_index_list (first, last, NULL);
	}
Andreas J. Guelzow 's avatar
Andreas J. Guelzow committed
182 183 184 185 186

	return (GOUndo *)ua;
}

/* ------------------------------------------------------------------------- */
187 188 189 190 191 192

static GObjectClass *gnm_undo_filter_set_condition_parent_class;

static void
gnm_undo_filter_set_condition_finalize (GObject *o)
{
Jean Bréfort's avatar
Jean Bréfort committed
193
	GnmUndoFilterSetCondition *ua = (GnmUndoFilterSetCondition *)o;
194 195 196

	gnm_filter_condition_free (ua->cond);
	ua->cond = NULL;
197 198

	G_OBJECT_CLASS (gnm_undo_filter_set_condition_parent_class)->finalize (o);
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
}

static gboolean
cb_filter_set_condition_undo (GnmColRowIter const *iter, gint *count)
{
	if (iter->cri->visible)
		(*count)++;
	return FALSE;
}

static void
cb_filter_set_condition_undo_set_pb (SheetControl *control, char *text)
{
	SheetControlGUI *scg = (SheetControlGUI *) control;
	WBCGtk *wbcg = scg_wbcg (scg);
	if (wbcg != NULL)
Morten Welinder's avatar
Morten Welinder committed
215
		gtk_progress_bar_set_text
216 217 218 219
			(GTK_PROGRESS_BAR (wbcg->progress_bar), text);
}

static void
220
gnm_undo_filter_set_condition_undo (GOUndo *u, G_GNUC_UNUSED gpointer data)
221
{
Jean Bréfort's avatar
Jean Bréfort committed
222
	GnmUndoFilterSetCondition *ua = (GnmUndoFilterSetCondition *)u;
223 224 225 226
	gint count = 0;
	char const *format;
	char *text;

Morten Welinder's avatar
Morten Welinder committed
227
	gnm_filter_set_condition (ua->filter, ua->i,
228 229 230
				  gnm_filter_condition_dup (ua->cond), TRUE);
	sheet_update (ua->filter->sheet);

Morten Welinder's avatar
Morten Welinder committed
231
	sheet_colrow_foreach (ua->filter->sheet, FALSE,
232 233 234 235
			ua->filter->r.start.row + 1,
			ua->filter->r.end.row,
			(ColRowHandler) cb_filter_set_condition_undo,
			&count);
236 237 238 239
	if (ua->filter->r.end.row - ua->filter->r.start.row > 10) {
		/* xgettext: The first %d gives the number of rows that match. */
		/* The second %d gives the total number of rows. Assume that the */
		/* total number of rows is always large (>10). */
240 241 242
		/* Note that the english "matches" or "match" is the verb of this sentence! */
		/* There is no explicit noun associated with the second %d in english, the */
		/* meaning is really "%d rows of all %d rows match" */
243 244 245 246 247 248 249 250 251 252 253 254
		/* This is input to ngettext. */
		format = ngettext ("%d row of %d matches",
				   "%d rows of %d match",
				   count);
		text = g_strdup_printf (format, count,
					ua->filter->r.end.row -
					ua->filter->r.start.row);
	} else {
		/* xgettext: The %d gives the number of rows that match. */
		/* This is input to ngettext. */
		format = ngettext ("%d row matches",
				   "%d rows match",
Jean Bréfort's avatar
Jean Bréfort committed
255
				   count);
256 257
		text = g_strdup_printf (format, count);
	}
258 259

	SHEET_FOREACH_CONTROL (ua->filter->sheet, view, control, cb_filter_set_condition_undo_set_pb (control, text););
Morten Welinder's avatar
Morten Welinder committed
260

261 262 263 264 265 266 267 268
	g_free (text);
}

static void
gnm_undo_filter_set_condition_class_init (GObjectClass *gobject_class)
{
	GOUndoClass *uclass = (GOUndoClass *)gobject_class;

Morten Welinder's avatar
Morten Welinder committed
269
	gnm_undo_filter_set_condition_parent_class = g_type_class_peek_parent
270 271 272 273 274 275 276
		(gobject_class);

	gobject_class->finalize = gnm_undo_filter_set_condition_finalize;
	uclass->undo = gnm_undo_filter_set_condition_undo;
}


Jean Bréfort's avatar
Jean Bréfort committed
277
GSF_CLASS (GnmUndoFilterSetCondition, gnm_undo_filter_set_condition,
278 279 280 281 282 283 284 285 286 287 288
	   gnm_undo_filter_set_condition_class_init, NULL, GO_TYPE_UNDO)

/**
 * gnm_undo_filter_set_condition_new:
 *
 * if (retrieve_from_filter), cond is ignored
 *
 * Returns: a new undo object.
 **/

GOUndo *
Morten Welinder's avatar
Morten Welinder committed
289 290
gnm_undo_filter_set_condition_new (GnmFilter *filter, unsigned i,
				   GnmFilterCondition *cond,
291 292
				   gboolean retrieve_from_filter)
{
Jean Bréfort's avatar
Jean Bréfort committed
293
	GnmUndoFilterSetCondition *ua;
294 295 296 297 298 299 300 301 302 303

	g_return_val_if_fail (filter != NULL, NULL);
	g_return_val_if_fail (i < filter->fields->len , NULL);

	ua = g_object_new (GNM_TYPE_UNDO_FILTER_SET_CONDITION, NULL);

	ua->filter = filter;
	ua->i = i;

	if (retrieve_from_filter)
Morten Welinder's avatar
Morten Welinder committed
304
		ua->cond = gnm_filter_condition_dup
305 306 307 308 309 310 311
			(gnm_filter_get_condition (filter, i));
	else
		ua->cond = cond;

	return (GOUndo *)ua;
}
/* ------------------------------------------------------------------------- */