dialog-sheet-order.c 45.5 KB
Newer Older
Dom Lachowicz's avatar
Dom Lachowicz committed
1 2 3 4 5
/*
 * dialog-sheet-order.c: Dialog to change the order of sheets in the Gnumeric
 * spreadsheet
 *
 * Author:
6 7
 *	Jody Goldberg <jody@gnome.org>
 *	Andreas J. Guelzow <aguelzow@taliesin.ca>
8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * (C) Copyright 2000, 2001, 2002 Jody Goldberg <jody@gnome.org>
 *
 * 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
22
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
Dom Lachowicz's avatar
Dom Lachowicz committed
23
 */
24

25
#include <gnumeric-config.h>
26
#include <glib/gi18n-lib.h>
27 28
#include <gnumeric.h>
#include "dialogs.h"
29
#include "help.h"
30 31

#include <gui-util.h>
32
#include <wbc-gtk.h>
33 34
#include <workbook-view.h>
#include <workbook.h>
35 36 37 38

/* We shouldn't need workbook-priv.h but we need to know whether undo commands are pending */
#include <workbook-priv.h>

39
#include <sheet.h>
40
#include <style-color.h>
41
#include <commands.h>
Morten Welinder's avatar
Morten Welinder committed
42
#include <application.h>
43
#include <widgets/gnumeric-cell-renderer-text.h>
44
#include <widgets/gnumeric-cell-renderer-toggle.h>
45
#include <goffice/goffice.h>
46

Jody Goldberg's avatar
Jody Goldberg committed
47
#include <string.h>
Dom Lachowicz's avatar
Dom Lachowicz committed
48

49

50 51
#define SHEET_ORDER_KEY          "sheet-order-dialog"

Dom Lachowicz's avatar
Dom Lachowicz committed
52
typedef struct {
53
	WBCGtk  *wbcg;
54

55
	GtkBuilder *gui;
Dom Lachowicz's avatar
Dom Lachowicz committed
56
	GtkWidget *dialog;
57
	GtkTreeView *sheet_list;
58
	GtkListStore *model;
59 60
	GtkWidget *up_btn;
	GtkWidget *down_btn;
61
	GtkWidget *add_btn;
62
	GtkWidget *append_btn;
63 64
	GtkWidget *duplicate_btn;
	GtkWidget *delete_btn;
65 66 67 68
	GtkWidget *apply_names_btn;
	GtkWidget *sort_asc_btn;
	GtkWidget *sort_desc_btn;
	GtkWidget *undo_btn;
69
	GtkWidget *cancel_btn;
70
	GtkWidget *advanced_check;
71 72
	GtkWidget *ccombo_back;
	GtkWidget *ccombo_fore;
73
	GtkWidget *warning;
74

75
	GdkPixbuf *image_padlock;
Morten Welinder's avatar
Morten Welinder committed
76
	GdkPixbuf *image_padlock_no;
77

78 79
	GdkPixbuf *image_ltr;
	GdkPixbuf *image_rtl;
80

81 82
	GdkPixbuf *image_visible;

83
	gboolean initial_colors_set;
84

85
	GtkTreeViewColumn *dir_column;
86 87
	GtkTreeViewColumn *row_max_column;
	GtkTreeViewColumn *col_max_column;
88

89
	gulong sheet_order_changed_listener;
90 91 92
	gulong sheet_added_listener;
	gulong sheet_deleted_listener;

93 94
	gulong model_selection_changed_listener;
	gulong model_row_insertion_listener;
Dom Lachowicz's avatar
Dom Lachowicz committed
95 96
} SheetManager;

97
enum {
98 99
	SHEET_LOCKED,
	SHEET_LOCK_IMAGE,
100 101
	SHEET_VISIBLE,
	SHEET_VISIBLE_IMAGE,
102 103
	SHEET_ROW_MAX,
	SHEET_COL_MAX,
104
	SHEET_NAME,
105
	SHEET_NEW_NAME,
106
	SHEET_POINTER,
107 108
	BACKGROUND_COLOUR,
	FOREGROUND_COLOUR,
109 110
	SHEET_DIRECTION,
	SHEET_DIRECTION_IMAGE,
111
	NUM_COLUMNS
112 113
};

114
static char *verify_validity (SheetManager *state, gboolean *pchanged);
115
static void dialog_sheet_order_update_sheet_order (SheetManager *state);
116 117


118 119 120 121 122 123 124
static void
update_undo (SheetManager *state, WorkbookControl *wbc)
{

	gtk_widget_set_sensitive (state->undo_btn, TRUE);
}

125 126 127
static void
workbook_signals_block (SheetManager *state)
{
Morten Welinder's avatar
Morten Welinder committed
128
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
129 130 131 132 133 134 135 136 137 138 139 140 141
	Workbook *wb = wb_control_get_workbook (wbc);

	g_signal_handler_block (G_OBJECT (wb),
				state->sheet_order_changed_listener);
	g_signal_handler_block (G_OBJECT (wb),
				state->sheet_added_listener);
	g_signal_handler_block (G_OBJECT (wb),
				state->sheet_deleted_listener);
}

static void
workbook_signals_unblock (SheetManager *state)
{
Morten Welinder's avatar
Morten Welinder committed
142
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
143 144 145 146 147 148 149 150 151 152
	Workbook *wb = wb_control_get_workbook (wbc);

	g_signal_handler_unblock (G_OBJECT (wb),
				state->sheet_order_changed_listener);
	g_signal_handler_unblock (G_OBJECT (wb),
				state->sheet_added_listener);
	g_signal_handler_unblock (G_OBJECT (wb),
				state->sheet_deleted_listener);
}

153
static void
154
cb_name_edited (GtkCellRendererText *cell,
155 156 157 158
	gchar               *path_string,
	gchar               *new_text,
        SheetManager        *state)
{
159 160
	GtkTreeIter iter;
	GtkTreePath *path;
161 162
	gboolean changed = FALSE;
	char *error;
163

164 165
	if (cell != NULL) {
		path = gtk_tree_path_new_from_string (path_string);
Morten Welinder's avatar
Morten Welinder committed
166
		if (gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model),
167
					     &iter, path))
Morten Welinder's avatar
Morten Welinder committed
168
			gtk_list_store_set (state->model, &iter,
169 170 171 172
					    SHEET_NEW_NAME, new_text, -1);
		else
			g_warning ("Did not get a valid iterator");
		gtk_tree_path_free (path);
173
	}
Morten Welinder's avatar
Morten Welinder committed
174

175 176 177 178 179 180 181
	error = verify_validity (state, &changed);

	if (error != NULL) {
		gtk_widget_set_sensitive (state->apply_names_btn, FALSE);
		gtk_label_set_text (GTK_LABEL (state->warning), error);
	} else {
		gtk_widget_set_sensitive (state->apply_names_btn, changed);
Morten Welinder's avatar
Morten Welinder committed
182
		gtk_label_set_markup (GTK_LABEL (state->warning),
183 184
				      changed ? _("<b>Note:</b> A sheet name change is pending.") : "");
	}
185 186
}

187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209

typedef struct {
	char *key;
	int i;
} gtmff_sort_t;

static gint
gtmff_compare_func (gconstpointer a, gconstpointer b)
{
	gtmff_sort_t const *pa = a, *pb = b;

	return strcmp (pa->key, pb->key);
}


static gboolean
gtmff_asc (GtkTreeModel *model, GtkTreePath *path,
	   GtkTreeIter *iter, gpointer data)
{
	GSList **l = data;
	Sheet *this_sheet;
	char *name;
	gtmff_sort_t *ptr;
Morten Welinder's avatar
Morten Welinder committed
210

211 212

	ptr = g_new (gtmff_sort_t, 1);
Morten Welinder's avatar
Morten Welinder committed
213
	gtk_tree_model_get (model, iter,
214 215 216 217 218 219
			    SHEET_POINTER, &this_sheet,
			    SHEET_NAME, &name,
			    -1);
	ptr->i = this_sheet->index_in_wb;
	ptr->key = g_utf8_collate_key_for_filename (name, -1);

Morten Welinder's avatar
Morten Welinder committed
220
	*l = g_slist_insert_sorted (*l, ptr, (GCompareFunc) gtmff_compare_func);
221 222 223 224 225 226 227 228

	return FALSE;
}

static void
sort_asc_desc (SheetManager *state, gboolean asc)
{
	WorkbookSheetState *old_state;
Morten Welinder's avatar
Morten Welinder committed
229
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
	Workbook *wb = wb_control_get_workbook (wbc);
	GSList *l = NULL, *l_tmp;
	gint n = 0;

	gtk_tree_model_foreach (GTK_TREE_MODEL (state->model), gtmff_asc, &l);

	if (!asc)
		l = g_slist_reverse (l);

	workbook_signals_block (state);

	old_state = workbook_sheet_state_new (wb);

	for (l_tmp = l; l_tmp != NULL; l_tmp = l_tmp->next) {
		gtmff_sort_t *ptr = l_tmp->data;
		GtkTreeIter iter;
		Sheet *sheet;
Morten Welinder's avatar
Morten Welinder committed
247

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
		gtk_tree_model_iter_nth_child  (GTK_TREE_MODEL (state->model),
						&iter, NULL, ptr->i);
		g_free (ptr->key);
		g_free (ptr);
		l_tmp->data = NULL;

		gtk_tree_model_get (GTK_TREE_MODEL (state->model), &iter,
				    SHEET_POINTER, &sheet,
				    -1);
		workbook_sheet_move (sheet, n - sheet->index_in_wb);
		n++;
	}
	g_slist_free (l);

	/* Now we change the list store  */
	dialog_sheet_order_update_sheet_order (state);
Morten Welinder's avatar
Morten Welinder committed
264

265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
	cmd_reorganize_sheets (wbc, old_state, NULL);
	update_undo (state, wbc);

	workbook_signals_unblock (state);
}

static void
cb_asc (G_GNUC_UNUSED GtkWidget *w, SheetManager *state)
{
	sort_asc_desc (state, TRUE);
}

static void
cb_desc (G_GNUC_UNUSED GtkWidget *w, SheetManager *state)
{
	sort_asc_desc (state, FALSE);
}

283
static gboolean
284
color_equal (const GdkRGBA *color_a, const GnmColor *color_gb)
285 286 287
{
	if (color_gb == NULL)
		return color_a == NULL;
288
	/* FIXME: What about ->is_auto?  */
289
	return color_a && GO_COLOR_FROM_GDK_RGBA (*color_a) == color_gb->go_color;
290 291
}

292
static void
Jody Goldberg's avatar
Jody Goldberg committed
293
cb_color_changed_fore (G_GNUC_UNUSED GOComboColor *go_combo_color,
294
		       GOColor color, G_GNUC_UNUSED gboolean custom,
Morten Welinder's avatar
Morten Welinder committed
295 296
		       G_GNUC_UNUSED gboolean by_user,
		       G_GNUC_UNUSED gboolean is_default,
297
		       SheetManager *state)
298
{
299
	GList *selected_rows, *l;
300
	GtkTreeSelection  *selection = gtk_tree_view_get_selection (state->sheet_list);
301
	WorkbookSheetState *old_state;
Morten Welinder's avatar
Morten Welinder committed
302
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
303
	Workbook *wb = wb_control_get_workbook (wbc);
304 305
	GdkRGBA gdk_color;
	GdkRGBA *p_gdk_color;
306 307 308
	GnmColor *gnm_color;

	g_return_if_fail (selection != NULL);
Morten Welinder's avatar
Morten Welinder committed
309

310 311
	selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);

312
	p_gdk_color = (color == 0) ? NULL : go_color_to_gdk_rgba (color, &gdk_color);
313
	gnm_color = (color == 0) ? NULL : gnm_color_new_gdk (&gdk_color);
Morten Welinder's avatar
Morten Welinder committed
314

315
	old_state = workbook_sheet_state_new (wb);
316

317
	for (l = selected_rows; l != NULL; l = l->next) {
318
		Sheet *this_sheet;
319 320
		GtkTreeIter sel_iter;
		GtkTreePath *path = l->data;
Morten Welinder's avatar
Morten Welinder committed
321

322
		gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model), &sel_iter, path);
323 324 325 326
		gtk_tree_model_get (GTK_TREE_MODEL (state->model), &sel_iter,
				    SHEET_POINTER, &this_sheet,
				    -1);
		if (color_equal (p_gdk_color, this_sheet->tab_text_color))
327
			continue;
328

329
		gtk_list_store_set (state->model, &sel_iter,
330
				    FOREGROUND_COLOUR, p_gdk_color,
331
				    -1);
332 333 334 335
		g_object_set (this_sheet,
			      "tab-foreground", gnm_color,
			      NULL);
	}
336 337 338 339 340

	style_color_unref (gnm_color);
	cmd_reorganize_sheets (wbc, old_state, NULL);
	update_undo (state, wbc);

341
	g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
342 343
}

344
static void
Jody Goldberg's avatar
Jody Goldberg committed
345
cb_color_changed_back (G_GNUC_UNUSED GOComboColor *go_combo_color,
346
		       GOColor color, G_GNUC_UNUSED gboolean custom,
Morten Welinder's avatar
Morten Welinder committed
347 348
		       G_GNUC_UNUSED gboolean by_user,
		       G_GNUC_UNUSED gboolean is_default,
349
		       SheetManager *state)
350
{
351
	GList *selected_rows, *l;
352
	GtkTreeSelection  *selection = gtk_tree_view_get_selection (state->sheet_list);
353
	WorkbookSheetState *old_state;
Morten Welinder's avatar
Morten Welinder committed
354
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
355
	Workbook *wb = wb_control_get_workbook (wbc);
356 357
	GdkRGBA gdk_color;
	GdkRGBA *p_gdk_color;
358 359 360
	GnmColor *gnm_color;

	g_return_if_fail (selection != NULL);
Morten Welinder's avatar
Morten Welinder committed
361

362 363
	selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);

364
	p_gdk_color = (color == 0) ? NULL : go_color_to_gdk_rgba (color, &gdk_color);
365
	gnm_color = (color == 0) ? NULL : gnm_color_new_gdk (&gdk_color);
Morten Welinder's avatar
Morten Welinder committed
366

367
	old_state = workbook_sheet_state_new (wb);
368

369
	for (l = selected_rows; l != NULL; l = l->next) {
370
		Sheet *this_sheet;
371 372
		GtkTreeIter sel_iter;
		GtkTreePath *path = l->data;
Morten Welinder's avatar
Morten Welinder committed
373

374
		gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model), &sel_iter, path);
375 376 377 378
		gtk_tree_model_get (GTK_TREE_MODEL (state->model), &sel_iter,
				    SHEET_POINTER, &this_sheet,
				    -1);
		if (color_equal (p_gdk_color, this_sheet->tab_color))
379
			continue;
380

381
		gtk_list_store_set (state->model, &sel_iter,
382
				    BACKGROUND_COLOUR, p_gdk_color,
383
				    -1);
384 385 386 387
		g_object_set (this_sheet,
			      "tab-background", gnm_color,
			      NULL);
	}
388 389 390 391 392

	style_color_unref (gnm_color);
	cmd_reorganize_sheets (wbc, old_state, NULL);
	update_undo (state, wbc);

393
	g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
}

static gboolean
cb_sheet_order_cnt_visible (GtkTreeModel *model,
			    GtkTreePath *path,
			    GtkTreeIter *iter,
			    gpointer data)
{
	gint *i = data;
	gboolean is_visible;

	gtk_tree_model_get (model, iter,
			    SHEET_VISIBLE, &is_visible,
			    -1);
	if (is_visible)
		(*i)++;

	return FALSE;
}

static gint
sheet_order_cnt_visible (SheetManager *state)
{
	gint data = 0;
	gtk_tree_model_foreach (GTK_TREE_MODEL (state->model),
				cb_sheet_order_cnt_visible,
				&data);
	return data;
422 423
}

424
/*
425 426
 * Refreshes the buttons on a row (un)selection and selects the chosen sheet
 * for this view.
Dom Lachowicz's avatar
Dom Lachowicz committed
427
 */
428
static void
Morten Welinder's avatar
Morten Welinder committed
429
cb_selection_changed (G_GNUC_UNUSED GtkTreeSelection *ignored,
430
		      SheetManager *state)
Dom Lachowicz's avatar
Dom Lachowicz committed
431
{
432
	GtkTreeIter  iter;
433
	Sheet *sheet;
434
	gboolean has_iter;
435
	GdkRGBA *fore, *back;
436
	GtkTreeSelection *selection = gtk_tree_view_get_selection (state->sheet_list);
437
	GList *selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
438
	gboolean multiple = gtk_tree_model_iter_n_children(GTK_TREE_MODEL (state->model), NULL) > 1;
439 440
	int cnt_sel = g_list_length (selected_rows);
	gboolean single_sel = (cnt_sel < 2);
441 442 443 444

	gtk_widget_set_sensitive (state->sort_asc_btn, multiple);
	gtk_widget_set_sensitive (state->sort_desc_btn, multiple);

445
	if (selected_rows == NULL) {
446 447
		gtk_widget_set_sensitive (state->up_btn, FALSE);
		gtk_widget_set_sensitive (state->down_btn, FALSE);
448
		gtk_widget_set_sensitive (state->delete_btn, FALSE);
449 450
		gtk_widget_set_sensitive (state->ccombo_back, FALSE);
		gtk_widget_set_sensitive (state->ccombo_fore, FALSE);
451
		gtk_widget_set_sensitive (state->add_btn, FALSE);
452
		gtk_widget_set_sensitive (state->duplicate_btn, FALSE);
453
		return;
454
	}
455

456 457
	gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model),
				 &iter, (GtkTreePath *) selected_rows->data);
Morten Welinder's avatar
Morten Welinder committed
458

459 460
	gtk_tree_model_get (GTK_TREE_MODEL (state->model), &iter,
			    SHEET_POINTER, &sheet,
461 462
			    BACKGROUND_COLOUR, &back,
			    FOREGROUND_COLOUR, &fore,
463
			    -1);
464
	if (!state->initial_colors_set) {
465 466
		go_combo_color_set_color_gdk (GO_COMBO_COLOR (state->ccombo_back), back);
		go_combo_color_set_color_gdk (GO_COMBO_COLOR (state->ccombo_fore), fore);
467 468
		state->initial_colors_set = TRUE;
	}
469
	if (back != NULL)
470
		gdk_rgba_free (back);
471
	if (fore != NULL)
472
		gdk_rgba_free (fore);
473

474 475
	gtk_widget_set_sensitive (state->ccombo_back, TRUE);
	gtk_widget_set_sensitive (state->ccombo_fore, TRUE);
476 477 478
	gtk_widget_set_sensitive (state->delete_btn, sheet_order_cnt_visible (state) > cnt_sel);
	gtk_widget_set_sensitive (state->add_btn, single_sel);
	gtk_widget_set_sensitive (state->duplicate_btn, single_sel);
479

Jon Kåre Hellan's avatar
Jon Kåre Hellan committed
480
	has_iter = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (state->model), &iter);
481
	g_return_if_fail (has_iter);
482
	gtk_widget_set_sensitive (state->up_btn,
Morten Welinder's avatar
Morten Welinder committed
483
				  single_sel &&
484
				  !gtk_tree_selection_iter_is_selected (selection, &iter));
485
	gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (state->model), &iter, NULL,
Morten Welinder's avatar
Morten Welinder committed
486
				       gtk_tree_model_iter_n_children
487
				       (GTK_TREE_MODEL (state->model), NULL) - 1);
488
	gtk_widget_set_sensitive (state->down_btn,
Morten Welinder's avatar
Morten Welinder committed
489
				  single_sel &&
490
				  !gtk_tree_selection_iter_is_selected (selection, &iter));
491

492 493
	if (sheet != NULL)
		wb_view_sheet_focus (
Morten Welinder's avatar
Morten Welinder committed
494
			wb_control_view (GNM_WBC (state->wbcg)), sheet);
495

496
	g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
497 498
}

499
static void
Morten Welinder's avatar
Morten Welinder committed
500
cb_toggled_lock (G_GNUC_UNUSED GtkCellRendererToggle *cell,
501 502 503 504 505 506 507
		 gchar                 *path_string,
		 gpointer               data)
{
	SheetManager *state = data;
	GtkTreeModel *model = GTK_TREE_MODEL (state->model);
	GtkTreeIter iter;
	GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
508 509 510
	gboolean is_locked = TRUE;
	Sheet *this_sheet = NULL;
	WorkbookSheetState *old_state = NULL;
Morten Welinder's avatar
Morten Welinder committed
511
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
512
	Workbook *wb = wb_control_get_workbook (wbc);
513

514
	if (gtk_tree_model_get_iter (model, &iter, path)) {
Morten Welinder's avatar
Morten Welinder committed
515 516
		gtk_tree_model_get (model, &iter,
				    SHEET_LOCKED, &is_locked,
517 518
				    SHEET_POINTER, &this_sheet,
				    -1);
519

520
		if (is_locked) {
Morten Welinder's avatar
Morten Welinder committed
521
			gtk_list_store_set
522
				(GTK_LIST_STORE (model), &iter, SHEET_LOCKED,
Morten Welinder's avatar
Morten Welinder committed
523
				 FALSE, SHEET_LOCK_IMAGE,
524 525
				 state->image_padlock_no, -1);
		} else {
Morten Welinder's avatar
Morten Welinder committed
526
			gtk_list_store_set
527
				(GTK_LIST_STORE (model), &iter, SHEET_LOCKED,
Morten Welinder's avatar
Morten Welinder committed
528
				 TRUE, SHEET_LOCK_IMAGE,
529 530
				 state->image_padlock, -1);
		}
531
	} else {
532
		g_warning ("Did not get a valid iterator");
533 534
		gtk_tree_path_free (path);
		return;
535 536
	}
	gtk_tree_path_free (path);
537 538 539 540 541 542

	old_state = workbook_sheet_state_new (wb);
	g_object_set (this_sheet,
		      "protected", !is_locked,
		      NULL);
	cmd_reorganize_sheets (wbc, old_state, this_sheet);
543
	update_undo (state, wbc);
544 545
}

546 547 548 549 550 551 552 553
static void
cb_toggled_direction (G_GNUC_UNUSED GtkCellRendererToggle *cell,
		      gchar		*path_string,
		      SheetManager	*state)
{
	GtkTreeModel *model = GTK_TREE_MODEL (state->model);
	GtkTreePath  *path  = gtk_tree_path_new_from_string (path_string);
	GtkTreeIter iter;
554 555 556
	gboolean is_rtl = TRUE;
	Sheet *this_sheet = NULL;
	WorkbookSheetState *old_state = NULL;
Morten Welinder's avatar
Morten Welinder committed
557
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
558
	Workbook *wb = wb_control_get_workbook (wbc);
559

560
	if (gtk_tree_model_get_iter (model, &iter, path)) {
Morten Welinder's avatar
Morten Welinder committed
561 562
		gtk_tree_model_get (model, &iter,
				    SHEET_DIRECTION, &is_rtl,
563 564
				    SHEET_POINTER, &this_sheet,
				    -1);
Morten Welinder's avatar
Morten Welinder committed
565
		gtk_list_store_set
566
			(GTK_LIST_STORE (model), &iter,
567
			 SHEET_DIRECTION,	!is_rtl,
Morten Welinder's avatar
Morten Welinder committed
568
			 SHEET_DIRECTION_IMAGE,
569
			 is_rtl ? state->image_ltr : state->image_rtl,
570 571 572
			 -1);
	} else {
		g_warning ("Did not get a valid iterator");
573 574
		gtk_tree_path_free (path);
		return;
575 576
	}

577
	gtk_tree_path_free (path);
578 579 580 581 582 583

	old_state = workbook_sheet_state_new (wb);
	g_object_set (this_sheet,
		      "text-is-rtl", !is_rtl,
		      NULL);
	cmd_reorganize_sheets (wbc, old_state, this_sheet);
584
	update_undo (state, wbc);
585 586
}

587 588
static void populate_sheet_list (SheetManager *state);

589 590 591 592 593 594 595 596 597
static void
cb_toggled_visible (G_GNUC_UNUSED GtkCellRendererToggle *cell,
		 gchar                 *path_string,
		 gpointer               data)
{
	SheetManager *state = data;
	GtkTreeModel *model = GTK_TREE_MODEL (state->model);
	GtkTreeIter iter;
	GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
598 599 600
	gboolean is_visible;
	Sheet *this_sheet;
	WorkbookSheetState *old_state;
Morten Welinder's avatar
Morten Welinder committed
601
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
602
	Workbook *wb = wb_control_get_workbook (wbc);
603
	int cnt;
604

605 606 607 608 609
	if (!gtk_tree_model_get_iter (model, &iter, path)) {
		g_warning ("Did not get a valid iterator");
		gtk_tree_path_free (path);
		return;
	}
610

Morten Welinder's avatar
Morten Welinder committed
611 612
	gtk_tree_model_get (model, &iter,
			    SHEET_VISIBLE, &is_visible,
613 614
			    SHEET_POINTER, &this_sheet,
			    -1);
Morten Welinder's avatar
Morten Welinder committed
615

616
	if (is_visible) {
617 618
		cnt = sheet_order_cnt_visible (state);
		if (cnt <= 1) {
619 620 621 622
			go_gtk_notice_dialog (GTK_WINDOW (state->dialog), GTK_MESSAGE_ERROR,
					      _("At least one sheet must remain visible!"));
			gtk_tree_path_free (path);
			return;
623 624 625 626
		}
		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
				    SHEET_VISIBLE, FALSE,
				    SHEET_VISIBLE_IMAGE, NULL,
627
				    -1);
Morten Welinder's avatar
Morten Welinder committed
628

629
	} else {
630 631
		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
				    SHEET_VISIBLE, TRUE,
Morten Welinder's avatar
Morten Welinder committed
632
				    SHEET_VISIBLE_IMAGE,
633 634
				    state->image_visible,
				    -1);
635 636
	}
	gtk_tree_path_free (path);
Morten Welinder's avatar
Morten Welinder committed
637

638 639
	old_state = workbook_sheet_state_new (wb);
	g_object_set (this_sheet,
Morten Welinder's avatar
Morten Welinder committed
640 641
		      "visibility",
		      !is_visible ? GNM_SHEET_VISIBILITY_VISIBLE
642 643 644 645
		      : GNM_SHEET_VISIBILITY_HIDDEN,
		      NULL);

	cmd_reorganize_sheets (wbc, old_state, this_sheet);
646
	update_undo (state, wbc);
647 648

	if (is_visible)
Morten Welinder's avatar
Morten Welinder committed
649
		populate_sheet_list (state);
650 651 652 653 654 655 656 657 658 659 660 661
}

static gboolean
sheet_selection_can_toggle(GtkTreeSelection *selection,
			   GtkTreeModel *model,
			   GtkTreePath *path,
			   gboolean path_currently_selected,
			   G_GNUC_UNUSED gpointer data)
{
	GtkTreeIter iter;
	gboolean is_visible;

Morten Welinder's avatar
Morten Welinder committed
662
	if (path_currently_selected ||
663 664 665 666 667 668 669 670
	    !gtk_tree_model_get_iter (model, &iter, path))
		return TRUE;

	gtk_tree_model_get (model, &iter,
			    SHEET_VISIBLE, &is_visible,
			    -1);

	return is_visible;
671 672
}

Dom Lachowicz's avatar
Dom Lachowicz committed
673
static void
674
create_sheet_list (SheetManager *state)
Dom Lachowicz's avatar
Dom Lachowicz committed
675
{
676
	GtkTreeViewColumn *column;
677
	GtkTreeSelection  *selection;
Morten Welinder's avatar
Morten Welinder committed
678
	GtkWidget *scrolled = go_gtk_builder_get_widget (state->gui, "scrolled");
679
	GtkCellRenderer *renderer;
680

681
	state->model = gtk_list_store_new (NUM_COLUMNS,
682 683
					   G_TYPE_BOOLEAN,
					   GDK_TYPE_PIXBUF,
684
					   G_TYPE_BOOLEAN,
685
					   GDK_TYPE_PIXBUF,
686 687
					   G_TYPE_INT,
					   G_TYPE_INT,
Morten Welinder's avatar
Morten Welinder committed
688 689 690
					   G_TYPE_STRING,
					   G_TYPE_STRING,
					   G_TYPE_POINTER,
691 692
					   GDK_TYPE_RGBA,
					   GDK_TYPE_RGBA,
693
					   G_TYPE_BOOLEAN,
694
					   GDK_TYPE_PIXBUF);
Morten Welinder's avatar
Morten Welinder committed
695
	state->sheet_list = GTK_TREE_VIEW (gtk_tree_view_new_with_model
696
					   (GTK_TREE_MODEL (state->model)));
697
	selection = gtk_tree_view_get_selection (state->sheet_list);
698
	gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
699

700 701 702 703
	renderer = gnumeric_cell_renderer_toggle_new ();
	g_signal_connect (G_OBJECT (renderer),
		"toggled",
		G_CALLBACK (cb_toggled_lock), state);
704 705 706 707 708 709 710
	column = gtk_tree_view_column_new_with_attributes
		/* xgettext : "Lock" is short for locked.  Keep this short.  */
		(_("Lock"),
		 renderer,
		 "active", SHEET_LOCKED,
		 "pixbuf", SHEET_LOCK_IMAGE,
		 NULL);
711
	gtk_tree_view_append_column (state->sheet_list, column);
712

713 714 715 716
	renderer = gnumeric_cell_renderer_toggle_new ();
	g_signal_connect (G_OBJECT (renderer),
		"toggled",
		G_CALLBACK (cb_toggled_visible), state);
717 718 719 720 721 722 723
	column = gtk_tree_view_column_new_with_attributes
		/* xgettext : "Viz" is short for visibility.  Keep this short.  */
		(_("Viz"),
		 renderer,
		 "active", SHEET_VISIBLE,
		 "pixbuf", SHEET_VISIBLE_IMAGE,
		 NULL);
724 725
	gtk_tree_view_append_column (state->sheet_list, column);

726 727 728
	renderer = gnumeric_cell_renderer_toggle_new ();
	g_signal_connect (G_OBJECT (renderer), "toggled",
		G_CALLBACK (cb_toggled_direction), state);
729 730 731 732 733 734 735
	column = gtk_tree_view_column_new_with_attributes
		/* xgettext : "Dir" is short for direction.  Keep this short.  */
		(_("Dir"),
		 renderer,
		 "active", SHEET_DIRECTION,
		 "pixbuf", SHEET_DIRECTION_IMAGE,
		 NULL);
736
	gtk_tree_view_column_set_visible (column, FALSE);
737
	gtk_tree_view_append_column (state->sheet_list, column);
738
	state->dir_column = column;
739

740
	column = gtk_tree_view_column_new_with_attributes
741 742
		/*Translators: Table header for column with number of "Rows"*/
		(C_("sheetlist", "Rows"),
743 744 745 746 747 748 749 750
		 gnumeric_cell_renderer_text_new (),
		 "text", SHEET_ROW_MAX,
		 NULL);
	gtk_tree_view_column_set_visible (column, FALSE);
	gtk_tree_view_append_column (state->sheet_list, column);
	state->row_max_column = column;

	column = gtk_tree_view_column_new_with_attributes
751 752
		/*Translators: Table header for column with number of "Cols"*/
		(C_("sheetlist", "Cols"),
753 754 755 756 757 758 759
		 gnumeric_cell_renderer_text_new (),
		 "text", SHEET_COL_MAX,
		 NULL);
	gtk_tree_view_column_set_visible (column, FALSE);
	gtk_tree_view_append_column (state->sheet_list, column);
	state->col_max_column = column;

760
	column = gtk_tree_view_column_new_with_attributes (_("Current Name"),
761
					      gnumeric_cell_renderer_text_new (),
Morten Welinder's avatar
Morten Welinder committed
762
					      "text", SHEET_NAME,
763 764
					      "background-rgba",BACKGROUND_COLOUR,
					      "foreground-rgba",FOREGROUND_COLOUR,
765
					      NULL);
766 767
	gtk_tree_view_append_column (state->sheet_list, column);

768
	renderer = gnumeric_cell_renderer_text_new ();
769 770 771 772
	g_object_set (G_OBJECT (renderer),
		      "editable", TRUE,
		      "editable-set", TRUE,
		      NULL);
773
	column = gtk_tree_view_column_new_with_attributes (_("New Name"),
774
					      renderer,
Morten Welinder's avatar
Morten Welinder committed
775
					      "text", SHEET_NEW_NAME,
776 777
					      "background-rgba",BACKGROUND_COLOUR,
					      "foreground-rgba",FOREGROUND_COLOUR,
778
					      NULL);
779 780
	gtk_tree_view_append_column (state->sheet_list, column);
	g_signal_connect (G_OBJECT (renderer), "edited",
781
			  G_CALLBACK (cb_name_edited), state);
782

783
	gtk_tree_view_set_reorderable (state->sheet_list, TRUE);
784 785

	/* Init the buttons & selection */
Morten Welinder's avatar
Morten Welinder committed
786
	state->model_selection_changed_listener =
787 788 789
		g_signal_connect (selection,
				  "changed",
				  G_CALLBACK (cb_selection_changed), state);
790 791 792
	gtk_tree_selection_set_select_function (selection,
						sheet_selection_can_toggle,
						NULL, NULL);
793 794 795 796 797 798 799

	gtk_container_add (GTK_CONTAINER (scrolled), GTK_WIDGET (state->sheet_list));
}

static void
set_sheet_info_at_iter (SheetManager *state, GtkTreeIter *iter, Sheet *sheet)
{
800 801
	GdkRGBA cback, *color = NULL;
	GdkRGBA cfore, *text_color = NULL;
802 803

	if (sheet->tab_color)
804
		color = go_color_to_gdk_rgba (sheet->tab_color->go_color, &cback);
805
	if (sheet->tab_text_color)
806
		text_color = go_color_to_gdk_rgba (sheet->tab_text_color->go_color, &cfore);
807 808 809 810 811 812 813 814 815 816

	gtk_list_store_set (state->model, iter,
			    SHEET_LOCKED, sheet->is_protected,
			    SHEET_LOCK_IMAGE, (sheet->is_protected
					       ? state->image_padlock
					       : state->image_padlock_no),
			    SHEET_VISIBLE, (sheet->visibility == GNM_SHEET_VISIBILITY_VISIBLE),
			    SHEET_VISIBLE_IMAGE, (sheet->visibility == GNM_SHEET_VISIBILITY_VISIBLE
						  ? state->image_visible
						  : NULL),
817 818
			    SHEET_ROW_MAX, gnm_sheet_get_max_rows (sheet),
			    SHEET_COL_MAX, gnm_sheet_get_max_cols (sheet),
819 820 821 822 823 824 825 826 827 828
			    SHEET_NAME, sheet->name_unquoted,
			    SHEET_NEW_NAME, "",
			    SHEET_POINTER, sheet,
			    BACKGROUND_COLOUR, color,
			    FOREGROUND_COLOUR, text_color,
			    SHEET_DIRECTION, sheet->text_is_rtl,
			    SHEET_DIRECTION_IMAGE, (sheet->text_is_rtl
						    ? state->image_rtl
						    : state->image_ltr),
			    -1);
Morten Welinder's avatar
Morten Welinder committed
829

830 831 832 833 834 835 836 837 838

}

/* Add all of the sheets to the sheet_list */
static void
populate_sheet_list (SheetManager *state)
{
	GtkTreeSelection  *selection;
	GtkTreeIter iter;
Morten Welinder's avatar
Morten Welinder committed
839
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
840 841 842 843 844 845 846 847 848 849 850 851
	Workbook *wb = wb_control_get_workbook (wbc);
	Sheet *cur_sheet = wb_control_cur_sheet (wbc);
	int i, n = workbook_sheet_count (wb);
	GtkTreePath *sel_path = NULL;

	selection = gtk_tree_view_get_selection (state->sheet_list);

	g_signal_handler_block (selection, state->model_selection_changed_listener);
	if (state->model_row_insertion_listener)
		g_signal_handler_block (state->model, state->model_row_insertion_listener);

	gtk_list_store_clear (state->model);
852
	gtk_label_set_text (GTK_LABEL (state->warning), "");
853 854 855 856 857 858 859 860 861 862 863

	for (i = 0 ; i < n ; i++) {
		Sheet *sheet = workbook_sheet_by_index (wb, i);

		gtk_list_store_append (state->model, &iter);
		set_sheet_info_at_iter (state, &iter, sheet);

		if (sheet == cur_sheet)
			sel_path = gtk_tree_model_get_path (GTK_TREE_MODEL (state->model),
							    &iter);
	}
864

865 866 867 868 869
	if (sel_path) {
		gtk_tree_selection_select_path (selection, sel_path);
		gtk_tree_path_free (sel_path);
	}

870 871
	if (state->model_row_insertion_listener)
		g_signal_handler_unblock (state->model, state->model_row_insertion_listener);
Morten Welinder's avatar
Morten Welinder committed
872
	g_signal_handler_unblock (selection, state->model_selection_changed_listener);
873 874 875

	/* Init the buttons & selection */
	cb_selection_changed (NULL, state);
Dom Lachowicz's avatar
Dom Lachowicz committed
876 877 878
}

static void
879
cb_item_move (SheetManager *state, gnm_iter_search_t iter_search)
Dom Lachowicz's avatar
Dom Lachowicz committed
880
{
881 882
	GtkTreeSelection  *selection = gtk_tree_view_get_selection (state->sheet_list);
	GtkTreeIter  a, b;
883
	GList *selected_rows;
Morten Welinder's avatar
Morten Welinder committed
884

885
	g_return_if_fail (selection != NULL);
886
	g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
Morten Welinder's avatar
Morten Welinder committed
887

888 889 890
	selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
	gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model),
				 &a, (GtkTreePath *) selected_rows->data);
891
	g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
892

893
	b = a;
894
	if (!iter_search (GTK_TREE_MODEL (state->model), &b))
895 896
		return;

897
	gtk_list_store_swap (state->model, &a, &b);
898
	cb_selection_changed (NULL, state);
Dom Lachowicz's avatar
Dom Lachowicz committed
899 900
}

901
static void
Morten Welinder's avatar
Morten Welinder committed
902
cb_up (G_GNUC_UNUSED GtkWidget *w, SheetManager *state)
903
{
Morten Welinder's avatar
Morten Welinder committed
904
	cb_item_move (state, gtk_tree_model_iter_previous);
905 906 907
}

static void
Morten Welinder's avatar
Morten Welinder committed
908
cb_down (G_GNUC_UNUSED GtkWidget *w, SheetManager *state)
909
{
Morten Welinder's avatar
Morten Welinder committed
910
	cb_item_move (state, gtk_tree_model_iter_next);
911
}
Dom Lachowicz's avatar
Dom Lachowicz committed
912

913
static void
Morten Welinder's avatar
Morten Welinder committed
914
cb_add_clicked (G_GNUC_UNUSED GtkWidget *ignore, SheetManager *state)
915
{
916
	GtkTreeIter sel_iter, iter;
917
	GtkTreeSelection  *selection = gtk_tree_view_get_selection (state->sheet_list);
918
	GList *selected_rows;
919 920
	int index = -1;
	WorkbookSheetState *old_state;
Morten Welinder's avatar
Morten Welinder committed
921
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
922
	Workbook *wb = wb_control_get_workbook (wbc);
923
	Sheet *sheet, *old_sheet = NULL;
924

925 926
	g_return_if_fail (selection != NULL);
	g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
Morten Welinder's avatar
Morten Welinder committed
927

928 929 930
	selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
	gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model),
				 &sel_iter, (GtkTreePath *) selected_rows->data);
931
	g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
Morten Welinder's avatar
Morten Welinder committed
932

933 934 935 936
	gtk_tree_model_get (GTK_TREE_MODEL (state->model), &sel_iter,
			    SHEET_POINTER, &old_sheet,
			    -1);
	index = old_sheet->index_in_wb;
937

938
	workbook_signals_block (state);
939 940

	old_state = workbook_sheet_state_new (wb);
941 942 943
	workbook_sheet_add (wb, index,
			    gnm_sheet_get_max_cols (old_sheet),
			    gnm_sheet_get_max_rows (old_sheet));
944
	cmd_reorganize_sheets (wbc, old_state, NULL);
945
	update_undo (state, wbc);
946

947
	workbook_signals_unblock (state);
948 949

	g_signal_handler_block (state->model, state->model_row_insertion_listener);
950 951
	sheet = workbook_sheet_by_index (wb, index);
	gtk_list_store_insert_before (state->model, &iter, &sel_iter);
952 953 954
	g_signal_handler_unblock (state->model, state->model_row_insertion_listener);

	set_sheet_info_at_iter (state, &iter, sheet);
Morten Welinder's avatar
Morten Welinder committed
955

956
	cb_selection_changed (NULL, state);
957 958 959 960 961 962
}

static void
cb_append_clicked (G_GNUC_UNUSED GtkWidget *ignore, SheetManager *state)
{
	WorkbookSheetState *old_state;
Morten Welinder's avatar
Morten Welinder committed
963
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
964 965
	Workbook *wb = wb_control_get_workbook (wbc);
	GtkTreeIter iter;
966
	Sheet *sheet, *old_sheet;
967

968
	workbook_signals_block (state);
969 970

	old_state = workbook_sheet_state_new (wb);
971 972 973 974
	old_sheet = workbook_sheet_by_index (wb, 0);
	workbook_sheet_add (wb, -1,
			    gnm_sheet_get_max_cols (old_sheet),
			    gnm_sheet_get_max_rows (old_sheet));
975
	cmd_reorganize_sheets (wbc, old_state, NULL);
976
	update_undo (state, wbc);
977

978
	workbook_signals_unblock (state);
979 980

	sheet = workbook_sheet_by_index (wb, workbook_sheet_count (wb) - 1);
Morten Welinder's avatar
Morten Welinder committed
981

982 983 984
	g_signal_handler_block (state->model, state->model_row_insertion_listener);
	gtk_list_store_append (state->model, &iter);
	g_signal_handler_unblock (state->model, state->model_row_insertion_listener);
Morten Welinder's avatar
Morten Welinder committed
985

986
	set_sheet_info_at_iter (state, &iter, sheet);
987 988

	cb_selection_changed (NULL, state);
989 990 991
}

static void
Morten Welinder's avatar
Morten Welinder committed
992
cb_duplicate_clicked (G_GNUC_UNUSED GtkWidget *ignore,
993
		      SheetManager *state)
994
{
995 996
	GtkTreeIter sel_iter, iter;
	GtkTreeSelection  *selection = gtk_tree_view_get_selection (state->sheet_list);
997
	GList *selected_rows;
998 999
	WorkbookSheetState *old_state;
	int index;
Morten Welinder's avatar
Morten Welinder committed
1000
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
1001 1002 1003
	Workbook *wb = wb_control_get_workbook (wbc);
	Sheet *new_sheet, *this_sheet;

1004 1005
	g_return_if_fail (selection != NULL);
	g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
Morten Welinder's avatar
Morten Welinder committed
1006

1007 1008 1009
	selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
	gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model),
				 &sel_iter, (GtkTreePath *) selected_rows->data);
1010
	g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
Morten Welinder's avatar
Morten Welinder committed
1011 1012

	gtk_tree_model_get (GTK_TREE_MODEL (state->model), &sel_iter,
1013 1014 1015
			    SHEET_POINTER, &this_sheet,
			    -1);

1016 1017
	workbook_signals_block (state);

1018 1019 1020 1021 1022 1023
	old_state = workbook_sheet_state_new (wb);
	index = this_sheet->index_in_wb;
	new_sheet = sheet_dup (this_sheet);
	workbook_sheet_attach_at_pos (wb, new_sheet, index + 1);
	g_signal_emit_by_name (G_OBJECT (wb), "sheet_added", 0);
	cmd_reorganize_sheets (wbc, old_state, NULL);
1024
	update_undo (state, wbc);
1025 1026

	workbook_signals_unblock (state);
1027 1028 1029 1030 1031 1032

	g_signal_handler_block (state->model, state->model_row_insertion_listener);
	gtk_list_store_insert_after (state->model, &iter, &sel_iter);
	g_signal_handler_unblock (state->model, state->model_row_insertion_listener);

	set_sheet_info_at_iter (state, &iter, new_sheet);
Morten Welinder's avatar
Morten Welinder committed
1033
	g_object_unref (new_sheet);
1034 1035

	cb_selection_changed (NULL, state);
1036 1037 1038
}

static void
Morten Welinder's avatar
Morten Welinder committed
1039
cb_delete_clicked (G_GNUC_UNUSED GtkWidget *ignore,
1040
		   SheetManager *state)
1041
{
1042
	GtkTreeSelection  *selection = gtk_tree_view_get_selection (state->sheet_list);
1043
	GList *selected_rows, *l;
1044
	WorkbookSheetState *old_state;
Morten Welinder's avatar
Morten Welinder committed
1045
	WorkbookControl *wbc = GNM_WBC (state->wbcg);
1046
	Workbook *wb = wb_control_get_workbook (wbc);
1047

1048
	g_return_if_fail (selection != NULL);
Morten Welinder's avatar
Morten Welinder committed
1049

1050
	selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
Morten Welinder's avatar
Morten Welinder committed
1051 1052 1053

	for (l = selected_rows; l != NULL; l = l->next)
		l->data = gtk_tree_row_reference_new (GTK_TREE_MODEL (state->model),
1054 1055 1056
						      (GtkTreePath *) l->data);
	workbook_signals_block (state);
	old_state = workbook_sheet_state_new (wb);
1057

1058 1059 1060 1061 1062 1063
	for (l = selected_rows; l != NULL; l = l->next) {
		GtkTreeRowReference *ref = l->data;
		if (gtk_tree_row_reference_valid (ref)) {
			GtkTreePath *path = gtk_tree_row_reference_get_path (ref);
			GtkTreeIter sel_iter;
			Sheet *sheet;
Morten Welinder's avatar
Morten Welinder committed
1064

1065 1066 1067 1068 1069 1070 1071 1072 1073
			gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model), &sel_iter, path);
			gtk_tree_path_free (path);
			gtk_tree_model_get (GTK_TREE_MODEL (state->model), &sel_iter,
					    SHEET_POINTER, &sheet,
					    -1);
			gtk_list_store_remove (state->model, &sel_iter);
			workbook_sheet_delete (sheet);
		}
	}
Morten Welinder's avatar
Morten Welinder committed
1074

1075 1076 1077
	cmd_reorganize_sheets (wbc, old_state, NULL);
	update_undo (state, wbc);
	workbook_signals_unblock (state);
1078

1079 1080
	populate_sheet_list (state);
	cb_name_edited (NULL, NULL, NULL, state);
Morten Welinder's avatar
Morten Welinder committed
1081

1082
	g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_row_reference_free);
1083 1084
}

Dom Lachowicz's avatar
Dom Lachowicz committed
1085
static void
Morten Welinder's avatar
Morten Welinder committed
1086
cb_cancel_clicked (G_GNUC_UNUSED GtkWidget *ignore,
1087
		   SheetManager *state)
Dom Lachowicz's avatar
Dom Lachowicz committed
1088
{
1089 1090 1091
	    gtk_widget_destroy (GTK_WIDGET (state->dialog));
}

1092 1093
static char *
verify_validity (SheetManager *state, gboolean *pchanged)
1094
{
1095 1096 1097 1098
	char *result = NULL;
	gboolean changed = FALSE;
	GHashTable *names = g_hash_table_new_full (g_str_hash, g_str_equal,
						   (GDestroyNotify)g_free, NULL);
1099
	GtkTreeIter this_iter;
1100
	gint n = 0;
1101

1102 1103
	while (result == NULL &&
	       gtk_tree_model_iter_nth_child  (GTK_TREE_MODEL (state->model),
1104
					       &this_iter, NULL, n)) {
1105
		Sheet *this_sheet;
1106
		char *old_name, *new_name, *new_name2;
1107

Morten Welinder's avatar
Morten Welinder committed
1108 1109
		gtk_tree_model_get (GTK_TREE_MODEL (state->model), &this_iter,
				    SHEET_POINTER, &this_sheet,
1110 1111 1112
				    SHEET_NAME, &old_name,
				    SHEET_NEW_NAME, &new_name,
				    -1);
1113

1114 1115
		new_name2 = g_utf8_casefold (*new_name != 0 ? new_name : old_name, -1);
		if (g_hash_table_lookup (names, new_name2)) {
1116 1117
			result = g_strdup_printf (_("You may not call more than one sheet \"%s\"."),
						  *new_name != 0 ? new_name : old_name);
1118 1119 1120
			g_free (new_name2);
		} else
			g_hash_table_insert (names, new_name2, new_name2);
Morten Welinder's avatar
Morten Welinder committed
1121

1122
		if (*new_name && strcmp (old_name, new_name))
1123
				changed = TRUE;
Morten Welinder's avatar
Morten Welinder committed
1124

1125 1126
		g_free (old_name);
		g_free (new_name);
1127 1128 1129
		n++;
	}

1130 1131 1132 1133
	g_hash_table_destroy (names);
	*pchanged = changed;
	return result;
}
1134

Morten Welinder's avatar
Morten Welinder committed
1135

1136
static void
1137
cb_apply_names_clicked (G_GNUC_UNUSED GtkWidget *ignore, SheetManager *state)