1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * dialog-sheet-order.c: Dialog to change the order of sheets in the Gnumeric
7 * Jody Goldberg <jody@gnome.org>
8 * Andreas J. Guelzow <aguelzow@taliesin.ca>
10 * (C) Copyright 2000, 2001, 2002 Jody Goldberg <jody@gnome.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses/>.
26 #include <gnumeric-config.h>
27 #include <glib/gi18n-lib.h>
34 #include <workbook-view.h>
37 /* We shouldn't need workbook-priv.h but we need to know whether undo commands are pending */
38 #include <workbook-priv.h>
41 #include <style-color.h>
43 #include <application.h>
44 #include <widgets/gnumeric-cell-renderer-text.h>
45 #include <widgets/gnumeric-cell-renderer-toggle.h>
46 #include <goffice/goffice.h>
52 #define SHEET_ORDER_KEY "sheet-order-dialog"
59 GtkTreeView
*sheet_list
;
64 GtkWidget
*append_btn
;
65 GtkWidget
*duplicate_btn
;
66 GtkWidget
*delete_btn
;
67 GtkWidget
*apply_names_btn
;
68 GtkWidget
*sort_asc_btn
;
69 GtkWidget
*sort_desc_btn
;
71 GtkWidget
*cancel_btn
;
72 GtkWidget
*advanced_check
;
73 GtkWidget
*ccombo_back
;
74 GtkWidget
*ccombo_fore
;
77 GdkPixbuf
*image_padlock
;
78 GdkPixbuf
*image_padlock_no
;
83 GdkPixbuf
*image_visible
;
85 gboolean initial_colors_set
;
87 GtkTreeViewColumn
*dir_column
;
88 GtkTreeViewColumn
*row_max_column
;
89 GtkTreeViewColumn
*col_max_column
;
91 gulong sheet_order_changed_listener
;
92 gulong sheet_added_listener
;
93 gulong sheet_deleted_listener
;
95 gulong model_selection_changed_listener
;
96 gulong model_row_insertion_listener
;
112 SHEET_DIRECTION_IMAGE
,
116 static char *verify_validity (SheetManager
*state
, gboolean
*pchanged
);
117 static void dialog_sheet_order_update_sheet_order (SheetManager
*state
);
121 update_undo (SheetManager
*state
, WorkbookControl
*wbc
)
124 gtk_widget_set_sensitive (state
->undo_btn
, TRUE
);
128 workbook_signals_block (SheetManager
*state
)
130 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
131 Workbook
*wb
= wb_control_get_workbook (wbc
);
133 g_signal_handler_block (G_OBJECT (wb
),
134 state
->sheet_order_changed_listener
);
135 g_signal_handler_block (G_OBJECT (wb
),
136 state
->sheet_added_listener
);
137 g_signal_handler_block (G_OBJECT (wb
),
138 state
->sheet_deleted_listener
);
142 workbook_signals_unblock (SheetManager
*state
)
144 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
145 Workbook
*wb
= wb_control_get_workbook (wbc
);
147 g_signal_handler_unblock (G_OBJECT (wb
),
148 state
->sheet_order_changed_listener
);
149 g_signal_handler_unblock (G_OBJECT (wb
),
150 state
->sheet_added_listener
);
151 g_signal_handler_unblock (G_OBJECT (wb
),
152 state
->sheet_deleted_listener
);
156 cb_name_edited (GtkCellRendererText
*cell
,
163 gboolean changed
= FALSE
;
167 path
= gtk_tree_path_new_from_string (path_string
);
168 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->model
),
170 gtk_list_store_set (state
->model
, &iter
,
171 SHEET_NEW_NAME
, new_text
, -1);
173 g_warning ("Did not get a valid iterator");
174 gtk_tree_path_free (path
);
177 error
= verify_validity (state
, &changed
);
180 gtk_widget_set_sensitive (state
->apply_names_btn
, FALSE
);
181 gtk_label_set_text (GTK_LABEL (state
->warning
), error
);
183 gtk_widget_set_sensitive (state
->apply_names_btn
, changed
);
184 gtk_label_set_markup (GTK_LABEL (state
->warning
),
185 changed
? _("<b>Note:</b> A sheet name change is pending.") : "");
196 gtmff_compare_func (gconstpointer a
, gconstpointer b
)
198 gtmff_sort_t
const *pa
= a
, *pb
= b
;
200 return strcmp (pa
->key
, pb
->key
);
205 gtmff_asc (GtkTreeModel
*model
, GtkTreePath
*path
,
206 GtkTreeIter
*iter
, gpointer data
)
214 ptr
= g_new (gtmff_sort_t
, 1);
215 gtk_tree_model_get (model
, iter
,
216 SHEET_POINTER
, &this_sheet
,
219 ptr
->i
= this_sheet
->index_in_wb
;
220 ptr
->key
= g_utf8_collate_key_for_filename (name
, -1);
222 *l
= g_slist_insert_sorted (*l
, ptr
, (GCompareFunc
) gtmff_compare_func
);
228 sort_asc_desc (SheetManager
*state
, gboolean asc
)
230 WorkbookSheetState
*old_state
;
231 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
232 Workbook
*wb
= wb_control_get_workbook (wbc
);
233 GSList
*l
= NULL
, *l_tmp
;
236 gtk_tree_model_foreach (GTK_TREE_MODEL (state
->model
), gtmff_asc
, &l
);
239 l
= g_slist_reverse (l
);
241 workbook_signals_block (state
);
243 old_state
= workbook_sheet_state_new (wb
);
245 for (l_tmp
= l
; l_tmp
!= NULL
; l_tmp
= l_tmp
->next
) {
246 gtmff_sort_t
*ptr
= l_tmp
->data
;
250 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (state
->model
),
251 &iter
, NULL
, ptr
->i
);
256 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &iter
,
257 SHEET_POINTER
, &sheet
,
259 workbook_sheet_move (sheet
, n
- sheet
->index_in_wb
);
264 /* Now we change the list store */
265 dialog_sheet_order_update_sheet_order (state
);
267 cmd_reorganize_sheets (wbc
, old_state
, NULL
);
268 update_undo (state
, wbc
);
270 workbook_signals_unblock (state
);
274 cb_asc (G_GNUC_UNUSED GtkWidget
*w
, SheetManager
*state
)
276 sort_asc_desc (state
, TRUE
);
280 cb_desc (G_GNUC_UNUSED GtkWidget
*w
, SheetManager
*state
)
282 sort_asc_desc (state
, FALSE
);
286 color_equal (const GdkRGBA
*color_a
, const GnmColor
*color_gb
)
288 if (color_gb
== NULL
)
289 return color_a
== NULL
;
290 /* FIXME: What about ->is_auto? */
291 return color_a
&& GO_COLOR_FROM_GDK_RGBA (*color_a
) == color_gb
->go_color
;
295 cb_color_changed_fore (G_GNUC_UNUSED GOComboColor
*go_combo_color
,
296 GOColor color
, G_GNUC_UNUSED gboolean custom
,
297 G_GNUC_UNUSED gboolean by_user
,
298 G_GNUC_UNUSED gboolean is_default
,
301 GList
*selected_rows
, *l
;
302 GtkTreeSelection
*selection
= gtk_tree_view_get_selection (state
->sheet_list
);
303 WorkbookSheetState
*old_state
;
304 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
305 Workbook
*wb
= wb_control_get_workbook (wbc
);
307 GdkRGBA
*p_gdk_color
;
310 g_return_if_fail (selection
!= NULL
);
312 selected_rows
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
314 p_gdk_color
= (color
== 0) ? NULL
: go_color_to_gdk_rgba (color
, &gdk_color
);
315 gnm_color
= (color
== 0) ? NULL
: gnm_color_new_gdk (&gdk_color
);
317 old_state
= workbook_sheet_state_new (wb
);
319 for (l
= selected_rows
; l
!= NULL
; l
= l
->next
) {
321 GtkTreeIter sel_iter
;
322 GtkTreePath
*path
= l
->data
;
324 gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->model
), &sel_iter
, path
);
325 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &sel_iter
,
326 SHEET_POINTER
, &this_sheet
,
328 if (color_equal (p_gdk_color
, this_sheet
->tab_text_color
))
331 gtk_list_store_set (state
->model
, &sel_iter
,
332 FOREGROUND_COLOUR
, p_gdk_color
,
334 g_object_set (this_sheet
,
335 "tab-foreground", gnm_color
,
339 style_color_unref (gnm_color
);
340 cmd_reorganize_sheets (wbc
, old_state
, NULL
);
341 update_undo (state
, wbc
);
343 g_list_free_full (selected_rows
, (GDestroyNotify
) gtk_tree_path_free
);
347 cb_color_changed_back (G_GNUC_UNUSED GOComboColor
*go_combo_color
,
348 GOColor color
, G_GNUC_UNUSED gboolean custom
,
349 G_GNUC_UNUSED gboolean by_user
,
350 G_GNUC_UNUSED gboolean is_default
,
353 GList
*selected_rows
, *l
;
354 GtkTreeSelection
*selection
= gtk_tree_view_get_selection (state
->sheet_list
);
355 WorkbookSheetState
*old_state
;
356 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
357 Workbook
*wb
= wb_control_get_workbook (wbc
);
359 GdkRGBA
*p_gdk_color
;
362 g_return_if_fail (selection
!= NULL
);
364 selected_rows
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
366 p_gdk_color
= (color
== 0) ? NULL
: go_color_to_gdk_rgba (color
, &gdk_color
);
367 gnm_color
= (color
== 0) ? NULL
: gnm_color_new_gdk (&gdk_color
);
369 old_state
= workbook_sheet_state_new (wb
);
371 for (l
= selected_rows
; l
!= NULL
; l
= l
->next
) {
373 GtkTreeIter sel_iter
;
374 GtkTreePath
*path
= l
->data
;
376 gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->model
), &sel_iter
, path
);
377 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &sel_iter
,
378 SHEET_POINTER
, &this_sheet
,
380 if (color_equal (p_gdk_color
, this_sheet
->tab_color
))
383 gtk_list_store_set (state
->model
, &sel_iter
,
384 BACKGROUND_COLOUR
, p_gdk_color
,
386 g_object_set (this_sheet
,
387 "tab-background", gnm_color
,
391 style_color_unref (gnm_color
);
392 cmd_reorganize_sheets (wbc
, old_state
, NULL
);
393 update_undo (state
, wbc
);
395 g_list_free_full (selected_rows
, (GDestroyNotify
) gtk_tree_path_free
);
399 cb_sheet_order_cnt_visible (GtkTreeModel
*model
,
407 gtk_tree_model_get (model
, iter
,
408 SHEET_VISIBLE
, &is_visible
,
417 sheet_order_cnt_visible (SheetManager
*state
)
420 gtk_tree_model_foreach (GTK_TREE_MODEL (state
->model
),
421 cb_sheet_order_cnt_visible
,
427 * Refreshes the buttons on a row (un)selection and selects the chosen sheet
431 cb_selection_changed (G_GNUC_UNUSED GtkTreeSelection
*ignored
,
437 GdkRGBA
*fore
, *back
;
438 GtkTreeSelection
*selection
= gtk_tree_view_get_selection (state
->sheet_list
);
439 GList
*selected_rows
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
440 gboolean multiple
= gtk_tree_model_iter_n_children(GTK_TREE_MODEL (state
->model
), NULL
) > 1;
441 int cnt_sel
= g_list_length (selected_rows
);
442 gboolean single_sel
= (cnt_sel
< 2);
444 gtk_widget_set_sensitive (state
->sort_asc_btn
, multiple
);
445 gtk_widget_set_sensitive (state
->sort_desc_btn
, multiple
);
447 if (selected_rows
== NULL
) {
448 gtk_widget_set_sensitive (state
->up_btn
, FALSE
);
449 gtk_widget_set_sensitive (state
->down_btn
, FALSE
);
450 gtk_widget_set_sensitive (state
->delete_btn
, FALSE
);
451 gtk_widget_set_sensitive (state
->ccombo_back
, FALSE
);
452 gtk_widget_set_sensitive (state
->ccombo_fore
, FALSE
);
453 gtk_widget_set_sensitive (state
->add_btn
, FALSE
);
454 gtk_widget_set_sensitive (state
->duplicate_btn
, FALSE
);
458 gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->model
),
459 &iter
, (GtkTreePath
*) selected_rows
->data
);
461 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &iter
,
462 SHEET_POINTER
, &sheet
,
463 BACKGROUND_COLOUR
, &back
,
464 FOREGROUND_COLOUR
, &fore
,
466 if (!state
->initial_colors_set
) {
467 go_combo_color_set_color_gdk (GO_COMBO_COLOR (state
->ccombo_back
), back
);
468 go_combo_color_set_color_gdk (GO_COMBO_COLOR (state
->ccombo_fore
), fore
);
469 state
->initial_colors_set
= TRUE
;
472 gdk_rgba_free (back
);
474 gdk_rgba_free (fore
);
476 gtk_widget_set_sensitive (state
->ccombo_back
, TRUE
);
477 gtk_widget_set_sensitive (state
->ccombo_fore
, TRUE
);
478 gtk_widget_set_sensitive (state
->delete_btn
, sheet_order_cnt_visible (state
) > cnt_sel
);
479 gtk_widget_set_sensitive (state
->add_btn
, single_sel
);
480 gtk_widget_set_sensitive (state
->duplicate_btn
, single_sel
);
482 has_iter
= gtk_tree_model_get_iter_first (GTK_TREE_MODEL (state
->model
), &iter
);
483 g_return_if_fail (has_iter
);
484 gtk_widget_set_sensitive (state
->up_btn
,
486 !gtk_tree_selection_iter_is_selected (selection
, &iter
));
487 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (state
->model
), &iter
, NULL
,
488 gtk_tree_model_iter_n_children
489 (GTK_TREE_MODEL (state
->model
), NULL
) - 1);
490 gtk_widget_set_sensitive (state
->down_btn
,
492 !gtk_tree_selection_iter_is_selected (selection
, &iter
));
495 wb_view_sheet_focus (
496 wb_control_view (GNM_WBC (state
->wbcg
)), sheet
);
498 g_list_free_full (selected_rows
, (GDestroyNotify
) gtk_tree_path_free
);
502 cb_toggled_lock (G_GNUC_UNUSED GtkCellRendererToggle
*cell
,
506 SheetManager
*state
= data
;
507 GtkTreeModel
*model
= GTK_TREE_MODEL (state
->model
);
509 GtkTreePath
*path
= gtk_tree_path_new_from_string (path_string
);
510 gboolean is_locked
= TRUE
;
511 Sheet
*this_sheet
= NULL
;
512 WorkbookSheetState
*old_state
= NULL
;
513 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
514 Workbook
*wb
= wb_control_get_workbook (wbc
);
516 if (gtk_tree_model_get_iter (model
, &iter
, path
)) {
517 gtk_tree_model_get (model
, &iter
,
518 SHEET_LOCKED
, &is_locked
,
519 SHEET_POINTER
, &this_sheet
,
524 (GTK_LIST_STORE (model
), &iter
, SHEET_LOCKED
,
525 FALSE
, SHEET_LOCK_IMAGE
,
526 state
->image_padlock_no
, -1);
529 (GTK_LIST_STORE (model
), &iter
, SHEET_LOCKED
,
530 TRUE
, SHEET_LOCK_IMAGE
,
531 state
->image_padlock
, -1);
534 g_warning ("Did not get a valid iterator");
535 gtk_tree_path_free (path
);
538 gtk_tree_path_free (path
);
540 old_state
= workbook_sheet_state_new (wb
);
541 g_object_set (this_sheet
,
542 "protected", !is_locked
,
544 cmd_reorganize_sheets (wbc
, old_state
, this_sheet
);
545 update_undo (state
, wbc
);
549 cb_toggled_direction (G_GNUC_UNUSED GtkCellRendererToggle
*cell
,
553 GtkTreeModel
*model
= GTK_TREE_MODEL (state
->model
);
554 GtkTreePath
*path
= gtk_tree_path_new_from_string (path_string
);
556 gboolean is_rtl
= TRUE
;
557 Sheet
*this_sheet
= NULL
;
558 WorkbookSheetState
*old_state
= NULL
;
559 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
560 Workbook
*wb
= wb_control_get_workbook (wbc
);
562 if (gtk_tree_model_get_iter (model
, &iter
, path
)) {
563 gtk_tree_model_get (model
, &iter
,
564 SHEET_DIRECTION
, &is_rtl
,
565 SHEET_POINTER
, &this_sheet
,
568 (GTK_LIST_STORE (model
), &iter
,
569 SHEET_DIRECTION
, !is_rtl
,
570 SHEET_DIRECTION_IMAGE
,
571 is_rtl
? state
->image_ltr
: state
->image_rtl
,
574 g_warning ("Did not get a valid iterator");
575 gtk_tree_path_free (path
);
579 gtk_tree_path_free (path
);
581 old_state
= workbook_sheet_state_new (wb
);
582 g_object_set (this_sheet
,
583 "text-is-rtl", !is_rtl
,
585 cmd_reorganize_sheets (wbc
, old_state
, this_sheet
);
586 update_undo (state
, wbc
);
589 static void populate_sheet_list (SheetManager
*state
);
592 cb_toggled_visible (G_GNUC_UNUSED GtkCellRendererToggle
*cell
,
596 SheetManager
*state
= data
;
597 GtkTreeModel
*model
= GTK_TREE_MODEL (state
->model
);
599 GtkTreePath
*path
= gtk_tree_path_new_from_string (path_string
);
602 WorkbookSheetState
*old_state
;
603 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
604 Workbook
*wb
= wb_control_get_workbook (wbc
);
607 if (!gtk_tree_model_get_iter (model
, &iter
, path
)) {
608 g_warning ("Did not get a valid iterator");
609 gtk_tree_path_free (path
);
613 gtk_tree_model_get (model
, &iter
,
614 SHEET_VISIBLE
, &is_visible
,
615 SHEET_POINTER
, &this_sheet
,
619 cnt
= sheet_order_cnt_visible (state
);
621 go_gtk_notice_dialog (GTK_WINDOW (state
->dialog
), GTK_MESSAGE_ERROR
,
622 _("At least one sheet must remain visible!"));
623 gtk_tree_path_free (path
);
626 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
627 SHEET_VISIBLE
, FALSE
,
628 SHEET_VISIBLE_IMAGE
, NULL
,
632 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
635 state
->image_visible
,
638 gtk_tree_path_free (path
);
640 old_state
= workbook_sheet_state_new (wb
);
641 g_object_set (this_sheet
,
643 !is_visible
? GNM_SHEET_VISIBILITY_VISIBLE
644 : GNM_SHEET_VISIBILITY_HIDDEN
,
647 cmd_reorganize_sheets (wbc
, old_state
, this_sheet
);
648 update_undo (state
, wbc
);
651 populate_sheet_list (state
);
655 sheet_selection_can_toggle(GtkTreeSelection
*selection
,
658 gboolean path_currently_selected
,
659 G_GNUC_UNUSED gpointer data
)
664 if (path_currently_selected
||
665 !gtk_tree_model_get_iter (model
, &iter
, path
))
668 gtk_tree_model_get (model
, &iter
,
669 SHEET_VISIBLE
, &is_visible
,
676 create_sheet_list (SheetManager
*state
)
678 GtkTreeViewColumn
*column
;
679 GtkTreeSelection
*selection
;
680 GtkWidget
*scrolled
= go_gtk_builder_get_widget (state
->gui
, "scrolled");
681 GtkCellRenderer
*renderer
;
683 state
->model
= gtk_list_store_new (NUM_COLUMNS
,
697 state
->sheet_list
= GTK_TREE_VIEW (gtk_tree_view_new_with_model
698 (GTK_TREE_MODEL (state
->model
)));
699 selection
= gtk_tree_view_get_selection (state
->sheet_list
);
700 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_MULTIPLE
);
702 renderer
= gnumeric_cell_renderer_toggle_new ();
703 g_signal_connect (G_OBJECT (renderer
),
705 G_CALLBACK (cb_toggled_lock
), state
);
706 column
= gtk_tree_view_column_new_with_attributes
707 /* xgettext : "Lock" is short for locked. Keep this short. */
710 "active", SHEET_LOCKED
,
711 "pixbuf", SHEET_LOCK_IMAGE
,
713 gtk_tree_view_append_column (state
->sheet_list
, column
);
715 renderer
= gnumeric_cell_renderer_toggle_new ();
716 g_signal_connect (G_OBJECT (renderer
),
718 G_CALLBACK (cb_toggled_visible
), state
);
719 column
= gtk_tree_view_column_new_with_attributes
720 /* xgettext : "Viz" is short for visibility. Keep this short. */
723 "active", SHEET_VISIBLE
,
724 "pixbuf", SHEET_VISIBLE_IMAGE
,
726 gtk_tree_view_append_column (state
->sheet_list
, column
);
728 renderer
= gnumeric_cell_renderer_toggle_new ();
729 g_signal_connect (G_OBJECT (renderer
), "toggled",
730 G_CALLBACK (cb_toggled_direction
), state
);
731 column
= gtk_tree_view_column_new_with_attributes
732 /* xgettext : "Dir" is short for direction. Keep this short. */
735 "active", SHEET_DIRECTION
,
736 "pixbuf", SHEET_DIRECTION_IMAGE
,
738 gtk_tree_view_column_set_visible (column
, FALSE
);
739 gtk_tree_view_append_column (state
->sheet_list
, column
);
740 state
->dir_column
= column
;
742 column
= gtk_tree_view_column_new_with_attributes
743 /*Translators: Table header for column with number of "Rows"*/
744 (C_("sheetlist", "Rows"),
745 gnumeric_cell_renderer_text_new (),
746 "text", SHEET_ROW_MAX
,
748 gtk_tree_view_column_set_visible (column
, FALSE
);
749 gtk_tree_view_append_column (state
->sheet_list
, column
);
750 state
->row_max_column
= column
;
752 column
= gtk_tree_view_column_new_with_attributes
753 /*Translators: Table header for column with number of "Cols"*/
754 (C_("sheetlist", "Cols"),
755 gnumeric_cell_renderer_text_new (),
756 "text", SHEET_COL_MAX
,
758 gtk_tree_view_column_set_visible (column
, FALSE
);
759 gtk_tree_view_append_column (state
->sheet_list
, column
);
760 state
->col_max_column
= column
;
762 column
= gtk_tree_view_column_new_with_attributes (_("Current Name"),
763 gnumeric_cell_renderer_text_new (),
765 "background-rgba",BACKGROUND_COLOUR
,
766 "foreground-rgba",FOREGROUND_COLOUR
,
768 gtk_tree_view_append_column (state
->sheet_list
, column
);
770 renderer
= gnumeric_cell_renderer_text_new ();
771 g_object_set (G_OBJECT (renderer
),
773 "editable-set", TRUE
,
775 column
= gtk_tree_view_column_new_with_attributes (_("New Name"),
777 "text", SHEET_NEW_NAME
,
778 "background-rgba",BACKGROUND_COLOUR
,
779 "foreground-rgba",FOREGROUND_COLOUR
,
781 gtk_tree_view_append_column (state
->sheet_list
, column
);
782 g_signal_connect (G_OBJECT (renderer
), "edited",
783 G_CALLBACK (cb_name_edited
), state
);
785 gtk_tree_view_set_reorderable (state
->sheet_list
, TRUE
);
787 /* Init the buttons & selection */
788 state
->model_selection_changed_listener
=
789 g_signal_connect (selection
,
791 G_CALLBACK (cb_selection_changed
), state
);
792 gtk_tree_selection_set_select_function (selection
,
793 sheet_selection_can_toggle
,
796 gtk_container_add (GTK_CONTAINER (scrolled
), GTK_WIDGET (state
->sheet_list
));
800 set_sheet_info_at_iter (SheetManager
*state
, GtkTreeIter
*iter
, Sheet
*sheet
)
802 GdkRGBA cback
, *color
= NULL
;
803 GdkRGBA cfore
, *text_color
= NULL
;
805 if (sheet
->tab_color
)
806 color
= go_color_to_gdk_rgba (sheet
->tab_color
->go_color
, &cback
);
807 if (sheet
->tab_text_color
)
808 text_color
= go_color_to_gdk_rgba (sheet
->tab_text_color
->go_color
, &cfore
);
810 gtk_list_store_set (state
->model
, iter
,
811 SHEET_LOCKED
, sheet
->is_protected
,
812 SHEET_LOCK_IMAGE
, (sheet
->is_protected
813 ? state
->image_padlock
814 : state
->image_padlock_no
),
815 SHEET_VISIBLE
, (sheet
->visibility
== GNM_SHEET_VISIBILITY_VISIBLE
),
816 SHEET_VISIBLE_IMAGE
, (sheet
->visibility
== GNM_SHEET_VISIBILITY_VISIBLE
817 ? state
->image_visible
819 SHEET_ROW_MAX
, gnm_sheet_get_max_rows (sheet
),
820 SHEET_COL_MAX
, gnm_sheet_get_max_cols (sheet
),
821 SHEET_NAME
, sheet
->name_unquoted
,
823 SHEET_POINTER
, sheet
,
824 BACKGROUND_COLOUR
, color
,
825 FOREGROUND_COLOUR
, text_color
,
826 SHEET_DIRECTION
, sheet
->text_is_rtl
,
827 SHEET_DIRECTION_IMAGE
, (sheet
->text_is_rtl
835 /* Add all of the sheets to the sheet_list */
837 populate_sheet_list (SheetManager
*state
)
839 GtkTreeSelection
*selection
;
841 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
842 Workbook
*wb
= wb_control_get_workbook (wbc
);
843 Sheet
*cur_sheet
= wb_control_cur_sheet (wbc
);
844 int i
, n
= workbook_sheet_count (wb
);
845 GtkTreePath
*sel_path
= NULL
;
847 selection
= gtk_tree_view_get_selection (state
->sheet_list
);
849 g_signal_handler_block (selection
, state
->model_selection_changed_listener
);
850 if (state
->model_row_insertion_listener
)
851 g_signal_handler_block (state
->model
, state
->model_row_insertion_listener
);
853 gtk_list_store_clear (state
->model
);
854 gtk_label_set_text (GTK_LABEL (state
->warning
), "");
856 for (i
= 0 ; i
< n
; i
++) {
857 Sheet
*sheet
= workbook_sheet_by_index (wb
, i
);
859 gtk_list_store_append (state
->model
, &iter
);
860 set_sheet_info_at_iter (state
, &iter
, sheet
);
862 if (sheet
== cur_sheet
)
863 sel_path
= gtk_tree_model_get_path (GTK_TREE_MODEL (state
->model
),
868 gtk_tree_selection_select_path (selection
, sel_path
);
869 gtk_tree_path_free (sel_path
);
872 if (state
->model_row_insertion_listener
)
873 g_signal_handler_unblock (state
->model
, state
->model_row_insertion_listener
);
874 g_signal_handler_unblock (selection
, state
->model_selection_changed_listener
);
876 /* Init the buttons & selection */
877 cb_selection_changed (NULL
, state
);
881 cb_item_move (SheetManager
*state
, gnm_iter_search_t iter_search
)
883 GtkTreeSelection
*selection
= gtk_tree_view_get_selection (state
->sheet_list
);
885 GList
*selected_rows
;
887 g_return_if_fail (selection
!= NULL
);
888 g_return_if_fail (gtk_tree_selection_count_selected_rows (selection
) == 1);
890 selected_rows
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
891 gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->model
),
892 &a
, (GtkTreePath
*) selected_rows
->data
);
893 g_list_free_full (selected_rows
, (GDestroyNotify
) gtk_tree_path_free
);
896 if (!iter_search (GTK_TREE_MODEL (state
->model
), &b
))
899 gtk_list_store_swap (state
->model
, &a
, &b
);
900 cb_selection_changed (NULL
, state
);
904 cb_up (G_GNUC_UNUSED GtkWidget
*w
, SheetManager
*state
)
906 cb_item_move (state
, gtk_tree_model_iter_previous
);
910 cb_down (G_GNUC_UNUSED GtkWidget
*w
, SheetManager
*state
)
912 cb_item_move (state
, gtk_tree_model_iter_next
);
916 cb_add_clicked (G_GNUC_UNUSED GtkWidget
*ignore
, SheetManager
*state
)
918 GtkTreeIter sel_iter
, iter
;
919 GtkTreeSelection
*selection
= gtk_tree_view_get_selection (state
->sheet_list
);
920 GList
*selected_rows
;
922 WorkbookSheetState
*old_state
;
923 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
924 Workbook
*wb
= wb_control_get_workbook (wbc
);
925 Sheet
*sheet
, *old_sheet
= NULL
;
927 g_return_if_fail (selection
!= NULL
);
928 g_return_if_fail (gtk_tree_selection_count_selected_rows (selection
) == 1);
930 selected_rows
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
931 gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->model
),
932 &sel_iter
, (GtkTreePath
*) selected_rows
->data
);
933 g_list_free_full (selected_rows
, (GDestroyNotify
) gtk_tree_path_free
);
935 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &sel_iter
,
936 SHEET_POINTER
, &old_sheet
,
938 index
= old_sheet
->index_in_wb
;
940 workbook_signals_block (state
);
942 old_state
= workbook_sheet_state_new (wb
);
943 workbook_sheet_add (wb
, index
,
944 gnm_sheet_get_max_cols (old_sheet
),
945 gnm_sheet_get_max_rows (old_sheet
));
946 cmd_reorganize_sheets (wbc
, old_state
, NULL
);
947 update_undo (state
, wbc
);
949 workbook_signals_unblock (state
);
951 g_signal_handler_block (state
->model
, state
->model_row_insertion_listener
);
952 sheet
= workbook_sheet_by_index (wb
, index
);
953 gtk_list_store_insert_before (state
->model
, &iter
, &sel_iter
);
954 g_signal_handler_unblock (state
->model
, state
->model_row_insertion_listener
);
956 set_sheet_info_at_iter (state
, &iter
, sheet
);
958 cb_selection_changed (NULL
, state
);
962 cb_append_clicked (G_GNUC_UNUSED GtkWidget
*ignore
, SheetManager
*state
)
964 WorkbookSheetState
*old_state
;
965 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
966 Workbook
*wb
= wb_control_get_workbook (wbc
);
968 Sheet
*sheet
, *old_sheet
;
970 workbook_signals_block (state
);
972 old_state
= workbook_sheet_state_new (wb
);
973 old_sheet
= workbook_sheet_by_index (wb
, 0);
974 workbook_sheet_add (wb
, -1,
975 gnm_sheet_get_max_cols (old_sheet
),
976 gnm_sheet_get_max_rows (old_sheet
));
977 cmd_reorganize_sheets (wbc
, old_state
, NULL
);
978 update_undo (state
, wbc
);
980 workbook_signals_unblock (state
);
982 sheet
= workbook_sheet_by_index (wb
, workbook_sheet_count (wb
) - 1);
984 g_signal_handler_block (state
->model
, state
->model_row_insertion_listener
);
985 gtk_list_store_append (state
->model
, &iter
);
986 g_signal_handler_unblock (state
->model
, state
->model_row_insertion_listener
);
988 set_sheet_info_at_iter (state
, &iter
, sheet
);
990 cb_selection_changed (NULL
, state
);
994 cb_duplicate_clicked (G_GNUC_UNUSED GtkWidget
*ignore
,
997 GtkTreeIter sel_iter
, iter
;
998 GtkTreeSelection
*selection
= gtk_tree_view_get_selection (state
->sheet_list
);
999 GList
*selected_rows
;
1000 WorkbookSheetState
*old_state
;
1002 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
1003 Workbook
*wb
= wb_control_get_workbook (wbc
);
1004 Sheet
*new_sheet
, *this_sheet
;
1006 g_return_if_fail (selection
!= NULL
);
1007 g_return_if_fail (gtk_tree_selection_count_selected_rows (selection
) == 1);
1009 selected_rows
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
1010 gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->model
),
1011 &sel_iter
, (GtkTreePath
*) selected_rows
->data
);
1012 g_list_free_full (selected_rows
, (GDestroyNotify
) gtk_tree_path_free
);
1014 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &sel_iter
,
1015 SHEET_POINTER
, &this_sheet
,
1018 workbook_signals_block (state
);
1020 old_state
= workbook_sheet_state_new (wb
);
1021 index
= this_sheet
->index_in_wb
;
1022 new_sheet
= sheet_dup (this_sheet
);
1023 workbook_sheet_attach_at_pos (wb
, new_sheet
, index
+ 1);
1024 g_signal_emit_by_name (G_OBJECT (wb
), "sheet_added", 0);
1025 cmd_reorganize_sheets (wbc
, old_state
, NULL
);
1026 update_undo (state
, wbc
);
1028 workbook_signals_unblock (state
);
1030 g_signal_handler_block (state
->model
, state
->model_row_insertion_listener
);
1031 gtk_list_store_insert_after (state
->model
, &iter
, &sel_iter
);
1032 g_signal_handler_unblock (state
->model
, state
->model_row_insertion_listener
);
1034 set_sheet_info_at_iter (state
, &iter
, new_sheet
);
1035 g_object_unref (new_sheet
);
1037 cb_selection_changed (NULL
, state
);
1041 cb_delete_clicked (G_GNUC_UNUSED GtkWidget
*ignore
,
1042 SheetManager
*state
)
1044 GtkTreeSelection
*selection
= gtk_tree_view_get_selection (state
->sheet_list
);
1045 GList
*selected_rows
, *l
;
1046 WorkbookSheetState
*old_state
;
1047 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
1048 Workbook
*wb
= wb_control_get_workbook (wbc
);
1050 g_return_if_fail (selection
!= NULL
);
1052 selected_rows
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
1054 for (l
= selected_rows
; l
!= NULL
; l
= l
->next
)
1055 l
->data
= gtk_tree_row_reference_new (GTK_TREE_MODEL (state
->model
),
1056 (GtkTreePath
*) l
->data
);
1057 workbook_signals_block (state
);
1058 old_state
= workbook_sheet_state_new (wb
);
1060 for (l
= selected_rows
; l
!= NULL
; l
= l
->next
) {
1061 GtkTreeRowReference
*ref
= l
->data
;
1062 if (gtk_tree_row_reference_valid (ref
)) {
1063 GtkTreePath
*path
= gtk_tree_row_reference_get_path (ref
);
1064 GtkTreeIter sel_iter
;
1067 gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->model
), &sel_iter
, path
);
1068 gtk_tree_path_free (path
);
1069 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &sel_iter
,
1070 SHEET_POINTER
, &sheet
,
1072 gtk_list_store_remove (state
->model
, &sel_iter
);
1073 workbook_sheet_delete (sheet
);
1077 cmd_reorganize_sheets (wbc
, old_state
, NULL
);
1078 update_undo (state
, wbc
);
1079 workbook_signals_unblock (state
);
1081 populate_sheet_list (state
);
1082 cb_name_edited (NULL
, NULL
, NULL
, state
);
1084 g_list_free_full (selected_rows
, (GDestroyNotify
) gtk_tree_row_reference_free
);
1088 cb_cancel_clicked (G_GNUC_UNUSED GtkWidget
*ignore
,
1089 SheetManager
*state
)
1091 gtk_widget_destroy (GTK_WIDGET (state
->dialog
));
1095 verify_validity (SheetManager
*state
, gboolean
*pchanged
)
1097 char *result
= NULL
;
1098 gboolean changed
= FALSE
;
1099 GHashTable
*names
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
1100 (GDestroyNotify
)g_free
, NULL
);
1101 GtkTreeIter this_iter
;
1104 while (result
== NULL
&&
1105 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (state
->model
),
1106 &this_iter
, NULL
, n
)) {
1108 char *old_name
, *new_name
, *new_name2
;
1110 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &this_iter
,
1111 SHEET_POINTER
, &this_sheet
,
1112 SHEET_NAME
, &old_name
,
1113 SHEET_NEW_NAME
, &new_name
,
1116 new_name2
= g_utf8_casefold (*new_name
!= 0 ? new_name
: old_name
, -1);
1117 if (g_hash_table_lookup (names
, new_name2
)) {
1118 result
= g_strdup_printf (_("You may not call more than one sheet \"%s\"."),
1119 *new_name
!= 0 ? new_name
: old_name
);
1122 g_hash_table_insert (names
, new_name2
, new_name2
);
1124 if (*new_name
&& strcmp (old_name
, new_name
))
1132 g_hash_table_destroy (names
);
1133 *pchanged
= changed
;
1139 cb_apply_names_clicked (G_GNUC_UNUSED GtkWidget
*ignore
, SheetManager
*state
)
1141 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
1142 Workbook
*wb
= wb_control_get_workbook (wbc
);
1143 WorkbookSheetState
*old_state
;
1144 GtkTreeIter this_iter
;
1147 /* Stop listening to changes in the sheet order. */
1148 workbook_signals_block (state
);
1150 old_state
= workbook_sheet_state_new (wb
);
1151 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (state
->model
),
1152 &this_iter
, NULL
, n
)) {
1156 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &this_iter
,
1157 SHEET_POINTER
, &this_sheet
,
1158 SHEET_NEW_NAME
, &new_name
,
1162 g_object_set (this_sheet
,
1165 gtk_list_store_set (state
->model
, &this_iter
,
1166 SHEET_NAME
, new_name
,
1175 cmd_reorganize_sheets (wbc
, old_state
, NULL
);
1176 gtk_label_set_text (GTK_LABEL (state
->warning
), "");
1177 update_undo (state
, wbc
);
1179 workbook_signals_unblock (state
);
1183 cb_sheet_order_destroy (SheetManager
*state
)
1185 Workbook
*wb
= wb_control_get_workbook (GNM_WBC (state
->wbcg
));
1187 /* Stop to listen to changes in the sheet order. */
1188 if (state
->sheet_order_changed_listener
)
1189 g_signal_handler_disconnect (G_OBJECT (wb
),
1190 state
->sheet_order_changed_listener
);
1191 if (state
->sheet_added_listener
)
1192 g_signal_handler_disconnect (G_OBJECT (wb
),
1193 state
->sheet_added_listener
);
1194 if (state
->sheet_deleted_listener
)
1195 g_signal_handler_disconnect (G_OBJECT (wb
),
1196 state
->sheet_deleted_listener
);
1198 if (state
->model
!= NULL
) {
1199 g_object_unref (state
->model
);
1200 state
->model
= NULL
;
1202 g_object_unref (state
->gui
);
1203 g_object_set_data (G_OBJECT (wb
), SHEET_ORDER_KEY
, NULL
);
1206 g_object_unref (state
->image_padlock
);
1207 state
->image_padlock
= NULL
;
1209 g_object_unref (state
->image_padlock_no
);
1210 state
->image_padlock_no
= NULL
;
1212 g_object_unref (state
->image_visible
);
1213 state
->image_visible
= NULL
;
1215 g_object_unref (state
->image_rtl
);
1216 state
->image_rtl
= NULL
;
1218 g_object_unref (state
->image_ltr
);
1219 state
->image_ltr
= NULL
;
1225 dialog_sheet_order_update_sheet_order (SheetManager
*state
)
1228 Workbook
*wb
= wb_control_get_workbook (GNM_WBC (state
->wbcg
));
1229 int i
, n_sheets
, n_children
;
1230 GtkTreeModel
*model
= GTK_TREE_MODEL (state
->model
);
1231 GtkTreeSelection
*sel
= gtk_tree_view_get_selection (state
->sheet_list
);
1233 n_sheets
= workbook_sheet_count (wb
);
1234 n_children
= gtk_tree_model_iter_n_children (model
, NULL
);
1236 if (n_sheets
!= n_children
) {
1237 /* This signal also occurs when sheets are added or deleted. We handle this */
1238 /* when those signals arrive. */
1242 for (i
= 0; i
< n_sheets
; i
++) {
1243 gchar
*name
, *new_name
;
1245 gboolean is_visible
;
1247 GdkRGBA
*back
, *fore
;
1248 Sheet
*sheet_wb
= workbook_sheet_by_index (wb
, i
);
1251 int j
, row_max
, col_max
;
1253 for (j
= i
; j
< n_children
; j
++) {
1254 if (!gtk_tree_model_iter_nth_child (model
, &iter
,
1257 gtk_tree_model_get (model
, &iter
, SHEET_POINTER
,
1259 if (sheet_model
== sheet_wb
)
1265 if (!gtk_tree_model_iter_nth_child (model
, &iter
, NULL
, j
))
1267 selected
= gtk_tree_selection_iter_is_selected (sel
, &iter
);
1268 gtk_tree_model_get (model
, &iter
,
1269 SHEET_LOCKED
, &is_locked
,
1270 SHEET_VISIBLE
, &is_visible
,
1271 SHEET_ROW_MAX
, &row_max
,
1272 SHEET_COL_MAX
, &col_max
,
1274 SHEET_NEW_NAME
, &new_name
,
1275 SHEET_POINTER
, &sheet_model
,
1276 BACKGROUND_COLOUR
, &back
,
1277 FOREGROUND_COLOUR
, &fore
,
1278 SHEET_DIRECTION
, &is_rtl
,
1280 gtk_list_store_remove (state
->model
, &iter
);
1281 g_signal_handler_block (state
->model
, state
->model_row_insertion_listener
);
1282 gtk_list_store_insert (state
->model
, &iter
, i
);
1283 g_signal_handler_unblock (state
->model
, state
->model_row_insertion_listener
);
1284 gtk_list_store_set (state
->model
, &iter
,
1285 SHEET_LOCKED
, is_locked
,
1286 SHEET_LOCK_IMAGE
, is_locked
?
1287 state
->image_padlock
: state
->image_padlock_no
,
1288 SHEET_VISIBLE
, is_visible
,
1289 SHEET_VISIBLE_IMAGE
, is_visible
?
1290 state
->image_visible
: NULL
,
1291 SHEET_ROW_MAX
, row_max
,
1292 SHEET_COL_MAX
, col_max
,
1294 SHEET_NEW_NAME
, new_name
,
1295 SHEET_POINTER
, sheet_model
,
1296 BACKGROUND_COLOUR
, back
,
1297 FOREGROUND_COLOUR
, fore
,
1298 SHEET_DIRECTION
, is_rtl
,
1299 SHEET_DIRECTION_IMAGE
,
1300 is_rtl
? state
->image_rtl
: state
->image_ltr
,
1303 gdk_rgba_free (back
);
1305 gdk_rgba_free (fore
);
1309 gtk_tree_selection_select_iter (sel
, &iter
);
1312 cb_selection_changed (NULL
, state
);
1316 cb_sheet_order_changed (Workbook
*wb
, SheetManager
*state
)
1318 dialog_sheet_order_update_sheet_order (state
);
1322 cb_sheet_deleted (Workbook
*wb
, SheetManager
*state
)
1324 populate_sheet_list (state
);
1328 cb_sheet_added (Workbook
*wb
, SheetManager
*state
)
1330 populate_sheet_list (state
);
1336 dialog_sheet_order_changed (SheetManager
*state
)
1338 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
1339 Workbook
*wb
= wb_control_get_workbook (wbc
);
1340 WorkbookSheetState
*old_state
;
1341 GtkTreeIter this_iter
;
1342 gint n
= 0, changes
= 0;
1344 workbook_signals_block (state
);
1346 old_state
= workbook_sheet_state_new (wb
);
1347 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (state
->model
),
1348 &this_iter
, NULL
, n
)) {
1350 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &this_iter
,
1351 SHEET_POINTER
, &this_sheet
,
1353 if (this_sheet
->index_in_wb
!= n
) {
1355 workbook_sheet_move (this_sheet
, n
- this_sheet
->index_in_wb
);
1361 cmd_reorganize_sheets (wbc
, old_state
, NULL
);
1362 update_undo (state
, wbc
);
1364 workbook_sheet_state_free (old_state
);
1366 workbook_signals_unblock (state
);
1370 cb_dialog_order_changed (G_GNUC_UNUSED GtkListStore
*model
,
1371 G_GNUC_UNUSED GtkTreePath
*path
,
1372 G_GNUC_UNUSED GtkTreeIter
*iter
,
1373 G_GNUC_UNUSED gpointer arg3
,
1374 SheetManager
*state
)
1376 dialog_sheet_order_changed (state
);
1380 dialog_sheet_order_changed_idle_handler (SheetManager
*state
)
1382 dialog_sheet_order_changed (state
);
1388 cb_dialog_order_changed_by_insertion (G_GNUC_UNUSED GtkListStore
*model
,
1389 G_GNUC_UNUSED GtkTreePath
*path
,
1390 G_GNUC_UNUSED GtkTreeIter
*iter
,
1391 SheetManager
*state
)
1393 g_idle_add_full (G_PRIORITY_HIGH_IDLE
,
1394 (GSourceFunc
)dialog_sheet_order_changed_idle_handler
,
1399 cb_undo_clicked (G_GNUC_UNUSED GtkWidget
*ignore
, SheetManager
*state
)
1401 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
1402 Workbook
*wb
= wb_control_get_workbook (wbc
);
1405 gtk_widget_set_sensitive (state
->undo_btn
, wb
->undo_commands
!= NULL
);
1407 populate_sheet_list (state
);
1411 cb_adv_check_toggled (G_GNUC_UNUSED GtkToggleButton
*ignored
,
1412 SheetManager
*state
)
1414 gboolean visible
= gtk_toggle_button_get_active
1415 (GTK_TOGGLE_BUTTON (state
->advanced_check
));
1417 gtk_tree_view_column_set_visible (state
->dir_column
, visible
);
1418 gtk_tree_view_column_set_visible (state
->col_max_column
, visible
);
1419 gtk_tree_view_column_set_visible (state
->row_max_column
, visible
);
1423 destroy_cb (GObject
*obj
)
1425 g_object_set_data (obj
, "state", NULL
);
1429 dialog_sheet_order (WBCGtk
*wbcg
)
1431 SheetManager
*state
;
1439 g_return_if_fail (wbcg
!= NULL
);
1441 widget
= GTK_WIDGET (wbcg_toplevel (wbcg
));
1443 gui
= gnm_gtk_builder_load ("sheet-order.ui", NULL
, GO_CMD_CONTEXT (wbcg
));
1447 wb
= wb_control_get_workbook (GNM_WBC (wbcg
));
1448 if (g_object_get_data (G_OBJECT (wb
), SHEET_ORDER_KEY
)) {
1449 GtkWidget
*dialog
= gtk_message_dialog_new
1450 (wbcg_toplevel (wbcg
),
1451 GTK_DIALOG_DESTROY_WITH_PARENT
,
1452 GTK_MESSAGE_WARNING
,
1454 _("Another view is already managing sheets"));
1455 go_gtk_dialog_run (GTK_DIALOG (dialog
), wbcg_toplevel (wbcg
));
1458 g_object_set_data (G_OBJECT (wb
), SHEET_ORDER_KEY
, (gpointer
) gui
);
1459 state
= g_new0 (SheetManager
, 1);
1462 state
->dialog
= go_gtk_builder_get_widget (gui
, "sheet-order-dialog");
1463 state
->warning
= go_gtk_builder_get_widget (gui
, "warning");
1464 state
->up_btn
= go_gtk_builder_get_widget (gui
, "up_button");
1465 state
->down_btn
= go_gtk_builder_get_widget (gui
, "down_button");
1466 state
->add_btn
= go_gtk_builder_get_widget (gui
, "add_button");
1467 state
->append_btn
= go_gtk_builder_get_widget (gui
, "append_button");
1468 state
->duplicate_btn
= go_gtk_builder_get_widget (gui
, "duplicate_button");
1469 state
->delete_btn
= go_gtk_builder_get_widget (gui
, "delete_button");
1471 state
->apply_names_btn
= go_gtk_builder_get_widget (gui
, "ok_button");
1472 state
->sort_asc_btn
= go_gtk_builder_get_widget (gui
, "sort-asc-button");
1473 state
->sort_desc_btn
= go_gtk_builder_get_widget (gui
, "sort-desc-button");
1474 state
->undo_btn
= go_gtk_builder_get_widget (gui
, "undo-button");
1475 state
->cancel_btn
= go_gtk_builder_get_widget (gui
, "cancel_button");
1476 state
->advanced_check
= go_gtk_builder_get_widget (gui
, "advanced-check");
1477 state
->initial_colors_set
= FALSE
;
1478 state
->image_padlock
= go_gtk_widget_render_icon_pixbuf (widget
, "gnumeric-protection-yes", GTK_ICON_SIZE_MENU
);
1479 state
->image_padlock_no
= go_gtk_widget_render_icon_pixbuf (widget
, "gnumeric-protection-no", GTK_ICON_SIZE_MENU
);
1480 state
->image_visible
= go_gtk_widget_render_icon_pixbuf (widget
, "gnumeric-visible", GTK_ICON_SIZE_MENU
);
1481 state
->image_ltr
= go_gtk_widget_render_icon_pixbuf (widget
, "format-text-direction-ltr", GTK_ICON_SIZE_MENU
);
1482 state
->image_rtl
= go_gtk_widget_render_icon_pixbuf (widget
, "format-text-direction-rtl", GTK_ICON_SIZE_MENU
);
1483 /* Listen for changes in the sheet order. */
1484 state
->sheet_order_changed_listener
= g_signal_connect (G_OBJECT (wb
),
1485 "sheet_order_changed", G_CALLBACK (cb_sheet_order_changed
),
1487 state
->sheet_added_listener
= g_signal_connect (G_OBJECT (wb
),
1488 "sheet_added", G_CALLBACK (cb_sheet_added
),
1490 state
->sheet_deleted_listener
= g_signal_connect (G_OBJECT (wb
),
1491 "sheet_deleted", G_CALLBACK (cb_sheet_deleted
),
1494 grid
= GTK_GRID (go_gtk_builder_get_widget (gui
,"main-grid"));
1495 cg
= go_color_group_fetch ("back_color_group",
1496 wb_control_view (GNM_WBC (wbcg
)));
1497 icon
= go_gtk_widget_render_icon_pixbuf (widget
, "gnumeric-bucket", GTK_ICON_SIZE_LARGE_TOOLBAR
);
1498 state
->ccombo_back
= go_combo_color_new (icon
, _("Default"), 0, cg
);
1499 g_object_unref (icon
);
1500 g_object_unref (cg
);
1501 go_combo_color_set_instant_apply (
1502 GO_COMBO_COLOR (state
->ccombo_back
), TRUE
);
1503 gtk_grid_attach (grid
, state
->ccombo_back
, 1, 4, 1, 1);
1504 gtk_widget_set_sensitive (state
->ccombo_back
, FALSE
);
1506 cg
= go_color_group_fetch ("fore_color_group",
1507 wb_control_view (GNM_WBC (wbcg
)));
1508 icon
= go_gtk_widget_render_icon_pixbuf (widget
, "font", GTK_ICON_SIZE_LARGE_TOOLBAR
);
1509 state
->ccombo_fore
= go_combo_color_new (icon
, _("Default"), 0, cg
);
1510 g_object_unref (icon
);
1511 g_object_unref (cg
);
1512 go_combo_color_set_instant_apply (
1513 GO_COMBO_COLOR (state
->ccombo_fore
), TRUE
);
1514 gtk_grid_attach (grid
, state
->ccombo_fore
, 2, 4, 1, 1);
1515 gtk_widget_set_sensitive (state
->ccombo_fore
, FALSE
);
1517 create_sheet_list (state
);
1518 populate_sheet_list (state
);
1520 #define CONNECT(o,s,c) g_signal_connect(G_OBJECT(o),s,G_CALLBACK(c),state)
1521 CONNECT (state
->up_btn
, "clicked", cb_up
);
1522 CONNECT (state
->down_btn
, "clicked", cb_down
);
1523 CONNECT (state
->sort_asc_btn
, "clicked", cb_asc
);
1524 CONNECT (state
->sort_desc_btn
, "clicked", cb_desc
);
1525 CONNECT (state
->add_btn
, "clicked", cb_add_clicked
);
1526 CONNECT (state
->append_btn
, "clicked", cb_append_clicked
);
1527 CONNECT (state
->duplicate_btn
, "clicked", cb_duplicate_clicked
);
1528 CONNECT (state
->delete_btn
, "clicked", cb_delete_clicked
);
1529 CONNECT (state
->apply_names_btn
, "clicked", cb_apply_names_clicked
);
1530 CONNECT (state
->cancel_btn
, "clicked", cb_cancel_clicked
);
1531 CONNECT (state
->undo_btn
, "clicked", cb_undo_clicked
);
1532 CONNECT (state
->advanced_check
, "toggled", cb_adv_check_toggled
);
1533 CONNECT (state
->ccombo_back
, "color_changed", cb_color_changed_back
);
1534 CONNECT (state
->ccombo_fore
, "color_changed", cb_color_changed_fore
);
1535 CONNECT (state
->model
, "rows-reordered", cb_dialog_order_changed
);
1536 state
->model_row_insertion_listener
=
1537 CONNECT (state
->model
, "row-inserted", cb_dialog_order_changed_by_insertion
);
1540 cb_adv_check_toggled (NULL
, state
);
1542 gnm_init_help_button (
1543 go_gtk_builder_get_widget (state
->gui
, "help_button"),
1544 GNUMERIC_HELP_LINK_SHEET_MANAGER
);
1546 gtk_widget_set_sensitive (state
->undo_btn
, wb
->undo_commands
!= NULL
);
1547 gtk_widget_set_sensitive (state
->apply_names_btn
, FALSE
);
1549 /* a candidate for merging into attach guru */
1550 wbc_gtk_attach_guru (state
->wbcg
, GTK_WIDGET (state
->dialog
));
1551 g_object_set_data_full (G_OBJECT (state
->dialog
),
1552 "state", state
, (GDestroyNotify
) cb_sheet_order_destroy
);
1553 g_signal_connect (G_OBJECT (state
->dialog
), "destroy", G_CALLBACK (destroy_cb
), NULL
);
1555 gnm_restore_window_geometry (GTK_WINDOW (state
->dialog
),
1558 go_gtk_nonmodal_dialog (wbcg_toplevel (state
->wbcg
),
1559 GTK_WINDOW (state
->dialog
));
1560 gtk_widget_show_all (GTK_WIDGET (state
->dialog
));