1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * dialog-preferences.c: Dialog to edit application wide preferences and default values
6 * Andreas J. Guelzow <aguelzow@taliesin.ca>
8 * (C) Copyright 2000-2002 Jody Goldberg <jody@gnome.org>
9 * (C) Copyright 2003-2004 Andreas J. Guelzow <aguelzow@taliesin.ca>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * 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/>.
25 #include <gnumeric-config.h>
27 #include "application.h"
33 #include <gnm-format.h>
35 #include "workbook-control.h"
37 #include "number-match.h"
38 #include "widgets/gnumeric-cell-renderer-text.h"
40 #include "gnumeric-conf.h"
44 #include <glib/gi18n-lib.h>
47 #define PREF_DIALOG_KEY "pref-dialog"
59 GtkNotebook
*notebook
;
62 gulong app_wb_removed_sig
;
65 typedef void (* double_conf_setter_t
) (double value
);
66 typedef void (* gint_conf_setter_t
) (gint value
);
67 typedef void (* gboolean_conf_setter_t
) (gboolean value
);
68 typedef void (* enum_conf_setter_t
) (int value
);
69 typedef void (* wordlist_conf_setter_t
) (GSList
*value
);
71 typedef gboolean (* gboolean_conf_getter_t
) (void);
72 typedef GSList
* (* wordlist_conf_getter_t
) (void);
73 typedef int (* enum_conf_getter_t
) (void);
74 typedef gint (* gint_conf_getter_t
) (void);
75 typedef double (* double_conf_getter_t
) (void);
78 dialog_pref_add_item (PrefState
*state
, char const *page_name
,
79 char const *icon_name
,
80 int page
, char const* parent_path
)
82 GtkTreeIter iter
, parent
;
83 GdkPixbuf
* icon
= NULL
;
85 if (icon_name
!= NULL
)
86 icon
= gtk_widget_render_icon_pixbuf (state
->dialog
, icon_name
,
88 if ((parent_path
!= NULL
) && gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (state
->store
),
89 &parent
, parent_path
))
90 gtk_tree_store_append (state
->store
, &iter
, &parent
);
92 gtk_tree_store_append (state
->store
, &iter
, NULL
);
94 gtk_tree_store_set (state
->store
, &iter
,
96 ITEM_NAME
, _(page_name
),
100 g_object_unref (icon
);
104 set_tip (GOConfNode
*node
, GtkWidget
*w
)
106 const char *desc
= gnm_conf_get_long_desc (node
);
108 gtk_widget_set_tooltip_text (w
, desc
);
112 cb_pref_notification_destroy (gpointer handle
)
114 go_conf_remove_monitor (GPOINTER_TO_UINT (handle
));
118 connect_notification (GOConfNode
*node
, GOConfMonitorFunc func
,
119 gpointer data
, GtkWidget
*container
)
121 guint handle
= go_conf_add_monitor (node
, NULL
, func
, data
);
122 g_signal_connect_swapped (G_OBJECT (container
), "destroy",
123 G_CALLBACK (cb_pref_notification_destroy
),
124 GUINT_TO_POINTER (handle
));
127 /*************************************************************************/
130 pref_create_label (GOConfNode
*node
, GtkWidget
*grid
,
131 gint row
, gchar
const *default_label
, GtkWidget
*w
)
135 if (NULL
== default_label
) {
136 const char *desc
= gnm_conf_get_short_desc (node
);
137 label
= gtk_label_new (desc
);
139 label
= gtk_label_new_with_mnemonic (default_label
);
141 gtk_label_set_justify (GTK_LABEL (label
), GTK_JUSTIFY_LEFT
);
142 gtk_misc_set_alignment (GTK_MISC (label
), 0, 0.5);
143 gtk_widget_set_hexpand (label
, TRUE
);
144 gtk_grid_attach (GTK_GRID (grid
), label
, 0, row
, 1, 1);
146 gtk_label_set_mnemonic_widget (GTK_LABEL (label
), w
);
147 go_atk_setup_label (label
, w
);
150 /*************************************************************************/
153 bool_pref_widget_to_conf (GtkToggleButton
*button
,
154 gboolean_conf_setter_t setter
)
156 gboolean_conf_getter_t getter
157 = g_object_get_data (G_OBJECT (button
), "getter");
158 gboolean val_in_button
= gtk_toggle_button_get_active (button
);
159 gboolean val_in_conf
= getter ();
160 if ((!val_in_button
) != (!val_in_conf
))
161 setter (val_in_button
);
165 bool_pref_conf_to_widget (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
166 GtkToggleButton
*button
)
168 gboolean val_in_button
= gtk_toggle_button_get_active (button
);
170 /* We can't use the getter here since the main preferences */
171 /* may be notified after us */
172 gboolean val_in_conf
= go_conf_get_bool (node
, NULL
);
174 if ((!val_in_button
) != (!val_in_conf
))
175 gtk_toggle_button_set_active (button
, val_in_conf
);
179 bool_pref_create_widget (GOConfNode
*node
, GtkWidget
*grid
,
180 gint row
, gboolean_conf_setter_t setter
,
181 gboolean_conf_getter_t getter
,
182 char const *default_label
)
184 const char *desc
= gnm_conf_get_short_desc (node
);
185 GtkWidget
*item
= gtk_check_button_new_with_label (
186 (desc
!= NULL
) ? desc
: default_label
);
188 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item
), getter ());
190 g_object_set_data (G_OBJECT (item
), "getter", getter
);
191 g_signal_connect (G_OBJECT (item
), "toggled",
192 G_CALLBACK (bool_pref_widget_to_conf
),
194 gtk_grid_attach (GTK_GRID (grid
), item
, 0, row
, 2, 1);
196 connect_notification (node
, (GOConfMonitorFunc
)bool_pref_conf_to_widget
,
198 set_tip (node
, item
);
201 /*************************************************************************/
204 cb_enum_changed (GtkComboBox
*combo
, enum_conf_setter_t setter
)
207 if (gtk_combo_box_get_active_iter (combo
, &iter
)) {
208 GtkTreeModel
*model
= gtk_combo_box_get_model (combo
);
209 GEnumValue
*enum_val
;
210 gtk_tree_model_get (model
, &iter
, 1, &enum_val
, -1);
211 (*setter
) (enum_val
->value
);
221 cb_find_enum (GtkTreeModel
*model
, GtkTreePath
*path
, GtkTreeIter
*iter
,
222 FindEnumClosure
*cls
)
224 gboolean res
= FALSE
;
227 g_return_val_if_fail (model
!= NULL
, FALSE
);
228 g_return_val_if_fail (cls
->val
!= NULL
, FALSE
);
230 gtk_tree_model_get (model
, iter
, 0, &combo_val
, -1);
232 if (0 == strcmp (cls
->val
, combo_val
)) {
234 gtk_combo_box_set_active_iter (cls
->combo
, iter
);
242 enum_pref_conf_to_widget (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
246 GtkTreeModel
*model
= gtk_combo_box_get_model (combo
);
249 /* We can't use the getter here since the main preferences */
250 /* may be notified after us */
251 cls
.val
= go_conf_get_enum_as_str (node
, NULL
);
252 if (NULL
!= cls
.val
) { /* in case go_conf fails */
253 gtk_tree_model_foreach (model
,
254 (GtkTreeModelForeachFunc
)cb_find_enum
,
261 enum_pref_create_widget (GOConfNode
*node
, GtkWidget
*grid
,
262 gint row
, GType enum_type
,
263 enum_conf_setter_t setter
,
264 enum_conf_getter_t getter
,
265 gchar
const *default_label
,
266 char const *(*label_getter
)(int))
270 GtkCellRenderer
*renderer
;
271 GEnumClass
*enum_class
= G_ENUM_CLASS (g_type_class_ref (enum_type
));
272 GtkWidget
*combo
= gtk_combo_box_new ();
273 GtkListStore
*model
= gtk_list_store_new (2,
274 G_TYPE_STRING
, G_TYPE_POINTER
);
275 gint current
= getter ();
276 gint current_index
= -1;
278 for (i
= 0; i
< enum_class
->n_values
; i
++) {
279 gtk_list_store_append (model
, &iter
);
280 gtk_list_store_set (model
, &iter
,
281 0, label_getter ((int) enum_class
->values
[i
].value
),
282 1, enum_class
->values
+ i
,
284 if (enum_class
->values
[i
].value
== current
)
288 g_type_class_unref (enum_class
);
290 gtk_combo_box_set_model (GTK_COMBO_BOX (combo
), GTK_TREE_MODEL (model
));
291 g_object_unref (model
);
292 renderer
= gtk_cell_renderer_text_new ();
293 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo
), renderer
, TRUE
);
294 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo
), renderer
, "text", 0, NULL
);
296 gtk_combo_box_set_active (GTK_COMBO_BOX (combo
), current_index
);
298 gtk_grid_attach (GTK_GRID (grid
), combo
, 1, row
, 1, 1);
300 g_signal_connect (G_OBJECT (combo
), "changed",
301 G_CALLBACK (cb_enum_changed
), (gpointer
) setter
);
302 connect_notification (node
, (GOConfMonitorFunc
)enum_pref_conf_to_widget
,
305 pref_create_label (node
, grid
, row
, default_label
, combo
);
306 set_tip (node
, combo
);
309 /*************************************************************************/
312 int_pref_widget_to_conf (GtkSpinButton
*button
, gint_conf_setter_t setter
)
314 gint_conf_getter_t getter
315 = g_object_get_data (G_OBJECT (button
), "getter");
316 gint val_in_button
= gtk_spin_button_get_value_as_int (button
);
317 gint val_in_conf
= getter ();
319 if (val_in_conf
!= val_in_button
)
320 setter (val_in_button
);
324 int_pref_conf_to_widget (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
325 GtkSpinButton
*button
)
327 gint val_in_button
= gtk_spin_button_get_value_as_int (button
);
329 /* We can't use the getter here since the main preferences */
330 /* may be notified after us */
331 gint val_in_conf
= go_conf_get_int (node
, NULL
);
333 if (val_in_conf
!= val_in_button
)
334 gtk_spin_button_set_value (button
, (gdouble
) val_in_conf
);
338 int_pref_create_widget (GOConfNode
*node
, GtkWidget
*grid
,
339 gint row
, gint val
, gint from
, gint to
, gint step
,
340 gint_conf_setter_t setter
, gint_conf_getter_t getter
,
341 char const *default_label
)
343 GtkAdjustment
*adj
= GTK_ADJUSTMENT
344 (gtk_adjustment_new (val
, from
, to
, step
, step
, 0));
345 GtkWidget
*w
= gtk_spin_button_new (adj
, 1, 0);
347 gtk_spin_button_set_value (GTK_SPIN_BUTTON (w
), (gdouble
) getter ());
349 g_object_set_data (G_OBJECT (w
), "node", node
);
350 gtk_widget_set_hexpand (w
, TRUE
);
351 gtk_grid_attach (GTK_GRID (grid
), w
, 1, row
, 1, 1);
353 g_object_set_data (G_OBJECT (w
), "getter", getter
);
354 g_signal_connect (G_OBJECT (w
), "value-changed",
355 G_CALLBACK (int_pref_widget_to_conf
),
357 connect_notification (node
, (GOConfMonitorFunc
)int_pref_conf_to_widget
,
360 pref_create_label (node
, grid
, row
, default_label
, w
);
368 return i
> 0 && (i
& (i
- 1)) == 0;
372 cb_power_of_2 (GtkAdjustment
*adj
)
374 int val
= (int)gtk_adjustment_get_value (adj
);
376 if (powerof_2 (val
- 1))
377 gtk_adjustment_set_value (adj
, (val
- 1) * 2);
378 else if (powerof_2 (val
+ 1))
379 gtk_adjustment_set_value (adj
, (val
+ 1) / 2);
383 power_of_2_handlers (GtkWidget
*w
)
385 GtkSpinButton
*spin
= GTK_SPIN_BUTTON (w
);
386 GtkAdjustment
*adj
= gtk_spin_button_get_adjustment (spin
);
387 g_signal_connect (G_OBJECT (adj
), "value_changed",
388 G_CALLBACK (cb_power_of_2
), NULL
);
391 /*************************************************************************/
394 double_pref_widget_to_conf (GtkSpinButton
*button
, double_conf_setter_t setter
)
396 double_conf_getter_t getter
397 = g_object_get_data (G_OBJECT (button
), "getter");
398 double val_in_button
= gtk_spin_button_get_value (button
);
399 double val_in_conf
= getter();
401 if (fabs (val_in_conf
- val_in_button
) > 1e-10) /* dead simple */
402 setter (val_in_button
);
406 double_pref_conf_to_widget (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
407 GtkSpinButton
*button
)
409 double val_in_button
= gtk_spin_button_get_value (button
);
411 /* We can't use the getter here since the main preferences */
412 /* may be notified after us */
413 double val_in_conf
= go_conf_get_double (node
, NULL
);
415 if (fabs (val_in_conf
- val_in_button
) > 1e-10) /* dead simple */
416 gtk_spin_button_set_value (button
, val_in_conf
);
419 double_pref_create_widget (GOConfNode
*node
, GtkWidget
*grid
,
420 gint row
, gnm_float val
, gnm_float from
, gnm_float to
,
421 gnm_float step
, gint digits
,
422 double_conf_setter_t setter
,
423 double_conf_getter_t getter
,
424 char const *default_label
)
426 GtkWidget
*w
= gtk_spin_button_new (GTK_ADJUSTMENT (
427 gtk_adjustment_new (val
, from
, to
, step
, step
, 0)),
429 gtk_spin_button_set_value (GTK_SPIN_BUTTON (w
), getter ());
430 g_object_set_data (G_OBJECT (w
), "node", node
);
431 gtk_widget_set_hexpand (w
, TRUE
);
432 gtk_grid_attach (GTK_GRID (grid
), w
, 1, row
, 1, 1);
434 g_object_set_data (G_OBJECT (w
), "getter", getter
);
435 g_signal_connect (G_OBJECT (w
), "value-changed",
436 G_CALLBACK (double_pref_widget_to_conf
), (gpointer
) setter
);
437 connect_notification (node
,
438 (GOConfMonitorFunc
)double_pref_conf_to_widget
,
441 pref_create_label (node
, grid
, row
, default_label
, w
);
446 /*************************************************************************/
451 wordlist_pref_conf_to_widget (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
454 /* We can't use the getter here since the main preferences */
455 /* may be notified after us */
456 GSList
*l
, *list
= go_conf_get_str_list (node
, NULL
);
459 gtk_list_store_clear (store
);
461 for (l
= list
; l
!= NULL
; l
= l
->next
) {
462 gtk_list_store_append (store
, &iter
);
463 gtk_list_store_set (store
, &iter
,
472 wordlist_pref_remove (GtkButton
*button
, wordlist_conf_setter_t setter
) {
473 GtkTreeView
*tree
= g_object_get_data (G_OBJECT (button
), "treeview");
474 GtkTreeSelection
*select
= gtk_tree_view_get_selection (tree
);
478 if (gtk_tree_selection_get_selected (select
, &model
, &iter
)) {
480 wordlist_conf_getter_t getter
= g_object_get_data (G_OBJECT (button
), "getter");
481 GSList
*l
, *list
= getter ();
483 list
= go_string_slist_copy (list
);
485 gtk_tree_model_get (model
, &iter
,
488 l
= g_slist_find_custom (list
, text
, (GCompareFunc
)strcmp
);
491 list
= g_slist_delete_link (list
, l
);
494 g_slist_free_full (list
, g_free
);
500 wordlist_pref_add (GtkButton
*button
, wordlist_conf_setter_t setter
)
502 GtkEntry
*entry
= g_object_get_data (G_OBJECT (button
), "entry");
503 const gchar
*text
= gtk_entry_get_text (entry
);
506 wordlist_conf_getter_t getter
= g_object_get_data (G_OBJECT (button
), "getter");
507 GSList
*l
, *list
= getter ();
508 l
= g_slist_find_custom (list
, text
, (GCompareFunc
)strcmp
);
510 list
= go_string_slist_copy (list
);
511 list
= g_slist_append (list
, g_strdup (text
));
513 g_slist_free_full (list
, g_free
);
519 wordlist_pref_update_remove_button (GtkTreeSelection
*selection
, GtkButton
*button
)
521 gtk_widget_set_sensitive (GTK_WIDGET (button
),
522 gtk_tree_selection_get_selected (selection
, NULL
, NULL
));
526 wordlist_pref_create_widget (GOConfNode
*node
, GtkWidget
*grid
,
527 gint row
, wordlist_conf_setter_t setter
,
528 wordlist_conf_getter_t getter
,
529 char const *default_label
)
531 GtkWidget
*w
= gtk_grid_new ();
532 GtkWidget
*sw
= gtk_scrolled_window_new (NULL
, NULL
);
533 GtkWidget
*tv
= gtk_tree_view_new ();
534 GtkWidget
*entry
= gtk_entry_new ();
535 GtkWidget
*add_button
= gtk_button_new_from_stock (GTK_STOCK_ADD
);
536 GtkWidget
*remove_button
= gtk_button_new_from_stock (GTK_STOCK_REMOVE
);
537 GtkListStore
*model
= gtk_list_store_new (1, G_TYPE_STRING
);
538 GtkTreeSelection
*selection
;
540 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw
),
541 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
542 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw
),
543 GTK_SHADOW_ETCHED_IN
);
544 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tv
), FALSE
);
545 gtk_container_add (GTK_CONTAINER (sw
), tv
);
547 g_object_set (w
, "column-spacing", 12, "row-spacing", 6,
548 "hexpand", TRUE
, "vexpand", TRUE
, NULL
);
549 gtk_grid_attach (GTK_GRID (grid
), w
, 0, row
, 2, 1);
550 g_object_set (sw
, "hexpand", TRUE
, "vexpand", TRUE
, NULL
);
551 gtk_grid_attach (GTK_GRID (w
), sw
, 0, 1, 1, 3);
552 gtk_widget_set_hexpand (entry
, TRUE
);
553 gtk_grid_attach (GTK_GRID (w
), entry
, 0, 4, 1, 1);
554 gtk_widget_set_valign (remove_button
, GTK_ALIGN_END
);
555 gtk_grid_attach (GTK_GRID (w
), remove_button
, 1, 3, 1, 1);
556 gtk_grid_attach (GTK_GRID (w
), add_button
, 1, 4, 1, 1);
558 gtk_tree_view_set_model (GTK_TREE_VIEW (tv
),
559 GTK_TREE_MODEL (model
));
560 g_object_unref (model
);
561 gtk_tree_view_append_column (GTK_TREE_VIEW (tv
),
562 gtk_tree_view_column_new_with_attributes
564 gtk_cell_renderer_text_new (),
567 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tv
));
568 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
569 wordlist_pref_conf_to_widget (node
, "", model
);
571 g_object_set_data (G_OBJECT (remove_button
), "treeview", tv
);
572 g_object_set_data (G_OBJECT (add_button
), "entry", entry
);
573 g_object_set_data (G_OBJECT (remove_button
), "getter", getter
);
574 g_object_set_data (G_OBJECT (add_button
), "getter", getter
);
575 g_signal_connect (G_OBJECT (remove_button
), "clicked",
576 G_CALLBACK (wordlist_pref_remove
), setter
);
577 g_signal_connect (G_OBJECT (add_button
), "clicked",
578 G_CALLBACK (wordlist_pref_add
), setter
);
579 g_signal_connect (G_OBJECT (selection
), "changed",
580 G_CALLBACK (wordlist_pref_update_remove_button
), remove_button
);
581 wordlist_pref_update_remove_button (selection
,
582 GTK_BUTTON (remove_button
));
584 connect_notification (node
, (GOConfMonitorFunc
)wordlist_pref_conf_to_widget
,
587 pref_create_label (node
, w
, 0, default_label
, tv
);
592 /*******************************************************************************************/
593 /* Default Font Selector */
594 /*******************************************************************************************/
597 do_set_font (GOFontSel
*fs
,
598 const char *name
, double size
,
599 gboolean is_bold
, gboolean is_italic
)
601 PangoFontDescription
*desc
;
603 desc
= pango_font_description_new ();
604 pango_font_description_set_family (desc
, name
);
605 pango_font_description_set_size (desc
, PANGO_SCALE
* size
);
606 pango_font_description_set_weight
608 is_bold
? PANGO_WEIGHT_BOLD
: PANGO_WEIGHT_NORMAL
);
609 pango_font_description_set_style
611 is_italic
? PANGO_STYLE_ITALIC
: PANGO_STYLE_NORMAL
);
613 go_font_sel_set_font_desc (fs
, desc
);
614 pango_font_description_free (desc
);
619 cb_pref_font_set_fonts (G_GNUC_UNUSED GOConfNode
*node
,
620 G_GNUC_UNUSED
char const *key
,
623 GOFontSel
*fs
= GO_FONT_SEL (page
);
626 gnm_conf_get_core_defaultfont_name (),
627 gnm_conf_get_core_defaultfont_size (),
628 gnm_conf_get_core_defaultfont_bold (),
629 gnm_conf_get_core_defaultfont_italic ());
633 cb_pref_font_has_changed (GOFontSel
*fs
, G_GNUC_UNUSED PangoAttrList
*attrs
,
636 PangoFontDescription
*desc
= go_font_sel_get_font_desc (fs
);
637 PangoFontMask fields
= pango_font_description_get_set_fields (desc
);
639 if (fields
& PANGO_FONT_MASK_FAMILY
)
640 gnm_conf_set_core_defaultfont_name
641 (pango_font_description_get_family (desc
));
642 if (fields
& PANGO_FONT_MASK_SIZE
)
643 gnm_conf_set_core_defaultfont_size
644 (pango_font_description_get_size (desc
) / (double)PANGO_SCALE
);
645 if (fields
& PANGO_FONT_MASK_WEIGHT
)
646 gnm_conf_set_core_defaultfont_bold
647 (pango_font_description_get_weight (desc
) >= PANGO_WEIGHT_BOLD
);
648 if (fields
& PANGO_FONT_MASK_STYLE
)
649 gnm_conf_set_core_defaultfont_italic
650 (pango_font_description_get_style (desc
) != PANGO_STYLE_NORMAL
);
652 pango_font_description_free (desc
);
658 pref_font_initializer (PrefState
*state
,
659 G_GNUC_UNUSED gpointer data
,
660 G_GNUC_UNUSED GtkNotebook
*notebook
,
661 G_GNUC_UNUSED gint page_num
)
663 GtkWidget
*page
= g_object_new (GO_TYPE_FONT_SEL
,
667 cb_pref_font_set_fonts (NULL
, NULL
, page
);
669 connect_notification (gnm_conf_get_core_defaultfont_dir_node (),
670 (GOConfMonitorFunc
) cb_pref_font_set_fonts
,
672 g_signal_connect (G_OBJECT (page
),
674 G_CALLBACK (cb_pref_font_has_changed
), state
);
676 gtk_widget_show_all (page
);
681 /*******************************************************************************************/
682 /* Default Header/Footer Font Selector */
683 /*******************************************************************************************/
686 cb_pref_font_hf_set_fonts (G_GNUC_UNUSED GOConfNode
*node
,
687 G_GNUC_UNUSED
char const *key
,
690 GOFontSel
*fs
= GO_FONT_SEL (page
);
692 gnm_conf_get_printsetup_hf_font_name (),
693 gnm_conf_get_printsetup_hf_font_size (),
694 gnm_conf_get_printsetup_hf_font_bold (),
695 gnm_conf_get_printsetup_hf_font_italic ());
699 cb_pref_font_hf_has_changed (GOFontSel
*fs
, G_GNUC_UNUSED PangoAttrList
*attrs
,
702 PangoFontDescription
*desc
= go_font_sel_get_font_desc (fs
);
703 PangoFontMask fields
= pango_font_description_get_set_fields (desc
);
705 if (fields
& PANGO_FONT_MASK_FAMILY
)
706 gnm_conf_set_printsetup_hf_font_name
707 (pango_font_description_get_family (desc
));
708 if (fields
& PANGO_FONT_MASK_SIZE
)
709 gnm_conf_set_printsetup_hf_font_size
710 (pango_font_description_get_size (desc
) / (double)PANGO_SCALE
);
711 if (fields
& PANGO_FONT_MASK_WEIGHT
)
712 gnm_conf_set_printsetup_hf_font_bold
713 (pango_font_description_get_weight (desc
) >= PANGO_WEIGHT_BOLD
);
714 if (fields
& PANGO_FONT_MASK_STYLE
)
715 gnm_conf_set_printsetup_hf_font_italic
716 (pango_font_description_get_style (desc
) != PANGO_STYLE_NORMAL
);
718 pango_font_description_free (desc
);
724 pref_font_hf_initializer (PrefState
*state
,
725 G_GNUC_UNUSED gpointer data
,
726 G_GNUC_UNUSED GtkNotebook
*notebook
,
727 G_GNUC_UNUSED gint page_num
)
729 GtkWidget
*page
= g_object_new (GO_TYPE_FONT_SEL
,
733 cb_pref_font_hf_set_fonts (NULL
, NULL
, page
);
734 connect_notification (gnm_conf_get_printsetup_dir_node (),
735 (GOConfMonitorFunc
) cb_pref_font_hf_set_fonts
,
737 g_signal_connect (G_OBJECT (page
),
739 G_CALLBACK (cb_pref_font_hf_has_changed
), state
);
741 gtk_widget_show_all (page
);
746 /*******************************************************************************************/
747 /* Undo Preferences Page */
748 /*******************************************************************************************/
751 pref_undo_page_initializer (PrefState
*state
,
752 G_GNUC_UNUSED gpointer data
,
753 G_GNUC_UNUSED GtkNotebook
*notebook
,
754 G_GNUC_UNUSED gint page_num
)
756 GtkWidget
*page
= gtk_grid_new ();
759 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
760 "vexpand", TRUE
, NULL
);
761 int_pref_create_widget (gnm_conf_get_undo_max_descriptor_width_node (),
762 page
, row
++, 5, 5, 200, 1,
763 gnm_conf_set_undo_max_descriptor_width
,
764 gnm_conf_get_undo_max_descriptor_width
,
765 _("Length of Undo Descriptors"));
766 int_pref_create_widget (gnm_conf_get_undo_size_node (),
767 page
, row
++, 1000, 0, 30000, 100,
768 gnm_conf_set_undo_size
,
769 gnm_conf_get_undo_size
,
770 _("Maximal Undo Size"));
771 int_pref_create_widget (gnm_conf_get_undo_maxnum_node (),
772 page
, row
++, 20, 1, 200, 1,
773 gnm_conf_set_undo_maxnum
,
774 gnm_conf_get_undo_maxnum
,
775 _("Number of Undo Items"));
776 bool_pref_create_widget (gnm_conf_get_undo_show_sheet_name_node (),
778 gnm_conf_set_undo_show_sheet_name
,
779 gnm_conf_get_undo_show_sheet_name
,
780 _("Show Sheet Name in Undo List"));
782 gtk_widget_show_all (page
);
786 /*******************************************************************************************/
787 /* Sort Preferences Page */
788 /*******************************************************************************************/
791 pref_sort_page_initializer (PrefState
*state
,
792 G_GNUC_UNUSED gpointer data
,
793 G_GNUC_UNUSED GtkNotebook
*notebook
,
794 G_GNUC_UNUSED gint page_num
)
796 GtkWidget
*page
= gtk_grid_new ();
799 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
800 "vexpand", TRUE
, NULL
);
801 int_pref_create_widget (gnm_conf_get_core_sort_dialog_max_initial_clauses_node (),
802 page
, row
++, 10, 0, 50, 1,
803 gnm_conf_set_core_sort_dialog_max_initial_clauses
,
804 gnm_conf_get_core_sort_dialog_max_initial_clauses
,
805 _("Number of Automatic Clauses"));
806 bool_pref_create_widget (gnm_conf_get_core_sort_default_retain_formats_node (),
808 gnm_conf_set_core_sort_default_retain_formats
,
809 gnm_conf_get_core_sort_default_retain_formats
,
810 _("Sorting Preserves Formats"));
811 bool_pref_create_widget (gnm_conf_get_core_sort_default_by_case_node (),
813 gnm_conf_set_core_sort_default_by_case
,
814 gnm_conf_get_core_sort_default_by_case
,
815 _("Sorting is Case-Sensitive"));
816 bool_pref_create_widget (gnm_conf_get_core_sort_default_ascending_node (),
818 gnm_conf_set_core_sort_default_ascending
,
819 gnm_conf_get_core_sort_default_ascending
,
820 _("Sort Ascending"));
822 gtk_widget_show_all (page
);
826 /*******************************************************************************************/
827 /* Window Preferences Page */
828 /*******************************************************************************************/
831 pref_window_page_initializer (PrefState
*state
,
832 G_GNUC_UNUSED gpointer data
,
833 G_GNUC_UNUSED GtkNotebook
*notebook
,
834 G_GNUC_UNUSED gint page_num
)
836 GtkWidget
*page
= gtk_grid_new ();
840 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
841 "vexpand", TRUE
, NULL
);
842 double_pref_create_widget (gnm_conf_get_core_gui_window_y_node (),
843 page
, row
++, 0.75, 0.25, 1, 0.05, 2,
844 gnm_conf_set_core_gui_window_y
,
845 gnm_conf_get_core_gui_window_y
,
846 _("Default Vertical Window Size"));
847 double_pref_create_widget (gnm_conf_get_core_gui_window_x_node (),
848 page
, row
++, 0.75, 0.25, 1, 0.05, 2,
849 gnm_conf_set_core_gui_window_x
,
850 gnm_conf_get_core_gui_window_x
,
851 _("Default Horizontal Window Size"));
852 double_pref_create_widget (gnm_conf_get_core_gui_window_zoom_node (),
853 page
, row
++, 1.00, 0.10, 5.00, 0.05, 2,
854 gnm_conf_set_core_gui_window_zoom
,
855 gnm_conf_get_core_gui_window_zoom
,
856 _("Default Zoom Factor"));
857 int_pref_create_widget (gnm_conf_get_core_workbook_n_sheet_node (),
858 page
, row
++, 1, 1, 64, 1,
859 gnm_conf_set_core_workbook_n_sheet
,
860 gnm_conf_get_core_workbook_n_sheet
,
861 _("Default Number of Sheets"));
863 w
= int_pref_create_widget (gnm_conf_get_core_workbook_n_rows_node (),
865 GNM_DEFAULT_ROWS
, GNM_MIN_ROWS
, GNM_MAX_ROWS
, 1,
866 gnm_conf_set_core_workbook_n_rows
,
867 gnm_conf_get_core_workbook_n_rows
,
868 _("Default Number of Rows in a Sheet"));
869 power_of_2_handlers (w
);
871 w
= int_pref_create_widget (gnm_conf_get_core_workbook_n_cols_node (),
873 GNM_DEFAULT_COLS
, GNM_MIN_COLS
, GNM_MAX_COLS
, 1,
874 gnm_conf_set_core_workbook_n_cols
,
875 gnm_conf_get_core_workbook_n_cols
,
876 _("Default Number of Columns in a Sheet"));
877 power_of_2_handlers (w
);
879 bool_pref_create_widget (gnm_conf_get_core_gui_cells_function_markers_node (),
881 gnm_conf_set_core_gui_cells_function_markers
,
882 gnm_conf_get_core_gui_cells_function_markers
,
883 _("By default, mark cells with spreadsheet functions"));
884 bool_pref_create_widget (gnm_conf_get_core_gui_cells_extension_markers_node (),
886 gnm_conf_set_core_gui_cells_extension_markers
,
887 gnm_conf_get_core_gui_cells_extension_markers
,
888 _("By default, mark cells with truncated content"));
890 gtk_widget_show_all (page
);
894 /*******************************************************************************************/
895 /* File/XML Preferences Page */
896 /*******************************************************************************************/
899 gnm_conf_set_core_file_save_extension_check_disabled_wrap (gboolean val
)
904 list
= g_slist_prepend (NULL
, (char *)"Gnumeric_stf:stf_assistant");
905 gnm_conf_set_core_file_save_extension_check_disabled (list
);
909 gnm_conf_get_core_file_save_extension_check_disabled_wrap (void)
911 GSList
*list
= gnm_conf_get_core_file_save_extension_check_disabled ();
912 return (NULL
!= g_slist_find_custom (list
, "Gnumeric_stf:stf_assistant", go_str_compare
));
916 custom_pref_conf_to_widget_ecd (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
917 GtkToggleButton
*button
)
919 gboolean val_in_button
= gtk_toggle_button_get_active (button
);
921 /* We can't use the getter here since the main preferences */
922 /* may be notified after us */
923 GSList
*list
= go_conf_get_str_list (node
, NULL
);
925 = (NULL
!= g_slist_find_custom (list
, "Gnumeric_stf:stf_assistant", go_str_compare
));
927 if ((!val_in_button
) != (!val_in_conf
))
928 gtk_toggle_button_set_active (button
, val_in_conf
);
931 custom_pref_create_widget_ecd (GOConfNode
*node
, GtkWidget
*grid
,
932 gint row
, gboolean_conf_setter_t setter
,
933 gboolean_conf_getter_t getter
,
934 char const *default_label
)
936 GtkWidget
*item
= gtk_check_button_new_with_label (default_label
);
938 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item
), getter ());
940 g_object_set_data (G_OBJECT (item
), "getter", getter
);
941 g_signal_connect (G_OBJECT (item
), "toggled",
942 G_CALLBACK (bool_pref_widget_to_conf
),
944 gtk_grid_attach (GTK_GRID (grid
), item
, 0, row
, 2, 1);
946 connect_notification (node
, (GOConfMonitorFunc
)custom_pref_conf_to_widget_ecd
,
954 pref_file_page_initializer (PrefState
*state
,
955 G_GNUC_UNUSED gpointer data
,
956 G_GNUC_UNUSED GtkNotebook
*notebook
,
957 G_GNUC_UNUSED gint page_num
)
959 GtkWidget
*page
= gtk_grid_new ();
962 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
963 "vexpand", TRUE
, NULL
);
964 int_pref_create_widget (gnm_conf_get_core_xml_compression_level_node (),
965 page
, row
++, 9, 0, 9, 1,
966 gnm_conf_set_core_xml_compression_level
,
967 gnm_conf_get_core_xml_compression_level
,
968 _("Default Compression Level For "
970 int_pref_create_widget (gnm_conf_get_core_workbook_autosave_time_node (),
971 page
, row
++, 0, 0, 365*24*60*60, 60,
972 gnm_conf_set_core_workbook_autosave_time
,
973 gnm_conf_get_core_workbook_autosave_time
,
974 _("Default autosave frequency in seconds"));
975 bool_pref_create_widget (gnm_conf_get_core_file_save_def_overwrite_node (),
977 gnm_conf_set_core_file_save_def_overwrite
,
978 gnm_conf_get_core_file_save_def_overwrite
,
979 _("Default To Overwriting Files"));
980 bool_pref_create_widget (gnm_conf_get_core_file_save_single_sheet_node (),
982 gnm_conf_set_core_file_save_single_sheet
,
983 gnm_conf_get_core_file_save_single_sheet
,
984 _("Warn When Exporting Into Single "
986 bool_pref_create_widget (gnm_conf_get_plugin_latex_use_utf8_node (),
988 gnm_conf_set_plugin_latex_use_utf8
,
989 gnm_conf_get_plugin_latex_use_utf8
,
990 _("Use UTF-8 in LaTeX Export"));
991 custom_pref_create_widget_ecd ( gnm_conf_get_core_file_save_extension_check_disabled_node (),
993 gnm_conf_set_core_file_save_extension_check_disabled_wrap
,
994 gnm_conf_get_core_file_save_extension_check_disabled_wrap
,
995 _("Disable Extension Check for Configurable Text Exporter"));
997 gtk_widget_show_all (page
);
1001 /*******************************************************************************************/
1002 /* Screen Preferences Page */
1003 /*******************************************************************************************/
1006 pref_screen_page_initializer (PrefState
*state
,
1007 G_GNUC_UNUSED gpointer data
,
1008 G_GNUC_UNUSED GtkNotebook
*notebook
,
1009 G_GNUC_UNUSED gint page_num
)
1011 GtkWidget
*page
= gtk_grid_new ();
1014 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
1015 "vexpand", TRUE
, NULL
);
1016 double_pref_create_widget (gnm_conf_get_core_gui_screen_horizontaldpi_node (),
1017 page
, row
++, 96, 50, 250, 1, 1,
1018 gnm_conf_set_core_gui_screen_horizontaldpi
,
1019 gnm_conf_get_core_gui_screen_horizontaldpi
,
1020 _("Horizontal DPI"));
1021 double_pref_create_widget (gnm_conf_get_core_gui_screen_verticaldpi_node (),
1022 page
, row
++, 96, 50, 250, 1, 1,
1023 gnm_conf_set_core_gui_screen_verticaldpi
,
1024 gnm_conf_get_core_gui_screen_verticaldpi
,
1027 gtk_widget_show_all (page
);
1031 /*******************************************************************************************/
1032 /* Tool Preferences Page */
1033 /*******************************************************************************************/
1036 pref_tool_page_initializer (PrefState
*state
,
1037 G_GNUC_UNUSED gpointer data
,
1038 G_GNUC_UNUSED GtkNotebook
*notebook
,
1039 G_GNUC_UNUSED gint page_num
)
1041 GtkWidget
*page
= gtk_grid_new ();
1044 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
1045 "vexpand", TRUE
, NULL
);
1046 enum_pref_create_widget (gnm_conf_get_core_gui_editing_enter_moves_dir_node (),
1049 (enum_conf_setter_t
)gnm_conf_set_core_gui_editing_enter_moves_dir
,
1050 (enum_conf_getter_t
)gnm_conf_get_core_gui_editing_enter_moves_dir
,
1051 _("Enter _Moves Selection"), (char const *(*) (int)) go_direction_get_name
);
1052 bool_pref_create_widget (gnm_conf_get_core_gui_editing_transitionkeys_node (),
1054 gnm_conf_set_core_gui_editing_transitionkeys
,
1055 gnm_conf_get_core_gui_editing_transitionkeys
,
1056 _("Transition Keys"));
1057 bool_pref_create_widget (gnm_conf_get_core_gui_editing_autocomplete_node (),
1059 gnm_conf_set_core_gui_editing_autocomplete
,
1060 gnm_conf_get_core_gui_editing_autocomplete
,
1062 int_pref_create_widget (gnm_conf_get_core_gui_editing_autocomplete_min_chars_node (),
1063 page
, row
++, 3, 1, 10, 1,
1064 gnm_conf_set_core_gui_editing_autocomplete_min_chars
,
1065 gnm_conf_get_core_gui_editing_autocomplete_min_chars
,
1066 _("Minimum Number of Characters for Autocompletion"));
1067 bool_pref_create_widget (gnm_conf_get_core_gui_editing_function_name_tooltips_node (),
1069 gnm_conf_set_core_gui_editing_function_name_tooltips
,
1070 gnm_conf_get_core_gui_editing_function_name_tooltips
,
1071 _("Show Function Name Tooltips"));
1072 bool_pref_create_widget (gnm_conf_get_core_gui_editing_function_argument_tooltips_node (),
1074 gnm_conf_set_core_gui_editing_function_argument_tooltips
,
1075 gnm_conf_get_core_gui_editing_function_argument_tooltips
,
1076 _("Show Function Argument Tooltips"));
1077 bool_pref_create_widget (gnm_conf_get_dialogs_rs_unfocused_node (),
1079 gnm_conf_set_dialogs_rs_unfocused
,
1080 gnm_conf_get_dialogs_rs_unfocused
,
1081 _("Allow Unfocused Range Selections"));
1082 int_pref_create_widget (gnm_conf_get_functionselector_num_of_recent_node (),
1083 page
, row
++, 10, 0, 40, 1,
1084 gnm_conf_set_functionselector_num_of_recent
,
1085 gnm_conf_get_functionselector_num_of_recent
,
1086 _("Maximum Length of Recently "
1087 "Used Functions List"));
1089 gtk_widget_show_all (page
);
1093 /*******************************************************************************************/
1094 /* Copy/Paste Preferences Page */
1095 /*******************************************************************************************/
1100 pref_copypaste_page_initializer (PrefState
*state
,
1101 G_GNUC_UNUSED gpointer data
,
1102 G_GNUC_UNUSED GtkNotebook
*notebook
,
1103 G_GNUC_UNUSED gint page_num
)
1105 GtkWidget
*page
= gtk_grid_new ();
1108 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
1109 "vexpand", TRUE
, NULL
);
1110 bool_pref_create_widget (gnm_conf_get_cut_and_paste_prefer_clipboard_node (),
1112 gnm_conf_set_cut_and_paste_prefer_clipboard
,
1113 gnm_conf_get_cut_and_paste_prefer_clipboard
,
1114 /* xgettext : see https://en.wikipedia.org/wiki/X_Window_selection#Clipboard */
1115 _("Prefer CLIPBOARD Over PRIMARY Selection"));
1117 gtk_widget_show_all (page
);
1123 /*******************************************************************************************/
1124 /* AutoCorrect Preferences Page (General) */
1125 /*******************************************************************************************/
1128 pref_autocorrect_general_page_initializer (PrefState
*state
,
1129 G_GNUC_UNUSED gpointer data
,
1130 G_GNUC_UNUSED GtkNotebook
*notebook
,
1131 G_GNUC_UNUSED gint page_num
)
1133 GtkWidget
*page
= gtk_grid_new ();
1136 bool_pref_create_widget (gnm_conf_get_autocorrect_names_of_days_node (),
1138 gnm_conf_set_autocorrect_names_of_days
,
1139 gnm_conf_get_autocorrect_names_of_days
,
1140 _("Capitalize _names of days"));
1142 gtk_widget_show_all (page
);
1146 /*******************************************************************************************/
1147 /* AutoCorrect Preferences Page (InitialCaps) */
1148 /*******************************************************************************************/
1151 pref_autocorrect_initialcaps_page_initializer (PrefState
*state
,
1152 G_GNUC_UNUSED gpointer data
,
1153 G_GNUC_UNUSED GtkNotebook
*notebook
,
1154 G_GNUC_UNUSED gint page_num
)
1156 GtkWidget
*page
= gtk_grid_new ();
1159 bool_pref_create_widget (gnm_conf_get_autocorrect_init_caps_node (),
1161 gnm_conf_set_autocorrect_init_caps
,
1162 gnm_conf_get_autocorrect_init_caps
,
1163 _("Correct _TWo INitial CApitals"));
1164 wordlist_pref_create_widget (gnm_conf_get_autocorrect_init_caps_list_node (), page
,
1165 row
++, gnm_conf_set_autocorrect_init_caps_list
,
1166 gnm_conf_get_autocorrect_init_caps_list
,
1167 _("Do _not correct:"));
1169 gtk_widget_show_all (page
);
1173 /*******************************************************************************************/
1174 /* AutoCorrect Preferences Page (FirstLetter) */
1175 /*******************************************************************************************/
1178 pref_autocorrect_firstletter_page_initializer (PrefState
*state
,
1179 G_GNUC_UNUSED gpointer data
,
1180 G_GNUC_UNUSED GtkNotebook
*notebook
,
1181 G_GNUC_UNUSED gint page_num
)
1183 GtkWidget
*page
= gtk_grid_new ();
1186 bool_pref_create_widget (gnm_conf_get_autocorrect_first_letter_node (),
1188 gnm_conf_set_autocorrect_first_letter
,
1189 gnm_conf_get_autocorrect_first_letter
,
1190 _("Capitalize _first letter of sentence"));
1191 wordlist_pref_create_widget (gnm_conf_get_autocorrect_first_letter_list_node (), page
,
1192 row
++, gnm_conf_set_autocorrect_first_letter_list
,
1193 gnm_conf_get_autocorrect_first_letter_list
,
1194 _("Do _not capitalize after:"));
1196 gtk_widget_show_all (page
);
1202 /*******************************************************************************************/
1203 /* General Preference Dialog Routines */
1204 /*******************************************************************************************/
1207 char const *page_name
;
1208 char const *icon_name
;
1209 char const *parent_path
;
1210 GtkWidget
* (*page_initializer
) (PrefState
*state
, gpointer data
,
1211 GtkNotebook
*notebook
, gint page_num
);
1214 /* Note that the page names are used in calls to dialog_preferences and as default in dialog_pref_select_page! */
1215 static page_info_t
const page_info
[] = {
1216 {N_("Auto Correct"), GTK_STOCK_DIALOG_ERROR
, NULL
, &pref_autocorrect_general_page_initializer
},
1217 {N_("Font"), GTK_STOCK_ITALIC
, NULL
, &pref_font_initializer
},
1218 {N_("Files"), GTK_STOCK_FLOPPY
, NULL
, &pref_file_page_initializer
},
1219 {N_("Tools"), GTK_STOCK_EXECUTE
, NULL
, &pref_tool_page_initializer
},
1220 {N_("Undo"), GTK_STOCK_UNDO
, NULL
, &pref_undo_page_initializer
},
1221 {N_("Windows"), "gnumeric-object-combo", NULL
, &pref_window_page_initializer
},
1222 {N_("Header/Footer"), GTK_STOCK_ITALIC
, "1", &pref_font_hf_initializer
},
1224 {N_("Copy and Paste"),GTK_STOCK_PASTE
, "3", &pref_copypaste_page_initializer
},
1226 {N_("Sorting"), GTK_STOCK_SORT_ASCENDING
, "3", &pref_sort_page_initializer
},
1227 {N_("Screen"), GTK_STOCK_PREFERENCES
, "5", &pref_screen_page_initializer
},
1228 {N_("INitial CApitals"), NULL
, "0", &pref_autocorrect_initialcaps_page_initializer
},
1229 {N_("First Letter"), NULL
, "0", &pref_autocorrect_firstletter_page_initializer
},
1230 {NULL
, NULL
, NULL
, NULL
},
1239 dialog_pref_select_page_search (GtkTreeModel
*model
,
1245 gtk_tree_model_get (model
, iter
, ITEM_NAME
, &page
, -1);
1246 if (0 == strcmp (page
, pst
->page
)) {
1248 pst
->path
= gtk_tree_path_copy (path
);
1257 dialog_pref_select_page (PrefState
*state
, gchar
const *page
)
1259 page_search_t pst
= {NULL
, NULL
};
1265 gtk_tree_model_foreach (GTK_TREE_MODEL (state
->store
),
1266 (GtkTreeModelForeachFunc
) dialog_pref_select_page_search
,
1269 if (pst
.path
== NULL
)
1270 pst
.path
= gtk_tree_path_new_first ();
1272 if (pst
.path
!= NULL
) {
1273 gtk_tree_view_set_cursor (state
->view
, pst
.path
, NULL
, FALSE
);
1274 gtk_tree_view_expand_row (state
->view
, pst
.path
, TRUE
);
1275 gtk_tree_path_free (pst
.path
);
1280 cb_dialog_pref_selection_changed (GtkTreeSelection
*selection
,
1286 if (gtk_tree_selection_get_selected (selection
, NULL
, &iter
)) {
1287 gtk_tree_model_get (GTK_TREE_MODEL (state
->store
), &iter
,
1290 gtk_notebook_set_current_page (state
->notebook
, page
);
1292 dialog_pref_select_page (state
, 0);
1297 cb_preferences_destroy (PrefState
*state
)
1300 g_object_unref (state
->store
);
1301 state
->store
= NULL
;
1303 if (state
->gui
!= NULL
) {
1304 g_object_unref (state
->gui
);
1307 if (state
->app_wb_removed_sig
) {
1308 g_signal_handler_disconnect (gnm_app_get_app (),
1309 state
->app_wb_removed_sig
);
1310 state
->app_wb_removed_sig
= 0;
1312 g_object_set_data (gnm_app_get_app (), PREF_DIALOG_KEY
, NULL
);
1316 cb_close_clicked (PrefState
*state
)
1318 gtk_widget_destroy (GTK_WIDGET (state
->dialog
));
1322 cb_workbook_removed (PrefState
*state
)
1324 if (gnm_app_workbook_list () == NULL
)
1325 cb_close_clicked (state
);
1329 dialog_preferences (WBCGtk
*wbcg
, gchar
const *page
)
1335 GtkTreeViewColumn
*column
;
1336 GtkTreeSelection
*selection
;
1338 w
= g_object_get_data (gnm_app_get_app (), PREF_DIALOG_KEY
);
1340 gtk_widget_show (w
);
1341 gdk_window_raise (gtk_widget_get_window (w
));
1345 gui
= gnm_gtk_builder_load ("res:ui/preferences.ui", NULL
, GO_CMD_CONTEXT (wbcg
));
1349 state
= g_new0 (PrefState
, 1);
1351 state
->dialog
= go_gtk_builder_get_widget (gui
, "preferences");
1352 state
->notebook
= (GtkNotebook
*)go_gtk_builder_get_widget (gui
, "notebook");
1354 state
->view
= GTK_TREE_VIEW(go_gtk_builder_get_widget (gui
, "itemlist"));
1355 state
->store
= gtk_tree_store_new (NUM_COLUMNS
,
1359 gtk_tree_view_set_model (state
->view
, GTK_TREE_MODEL(state
->store
));
1360 selection
= gtk_tree_view_get_selection (state
->view
);
1361 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_BROWSE
);
1362 column
= gtk_tree_view_column_new_with_attributes ("",
1363 gtk_cell_renderer_pixbuf_new (),
1364 "pixbuf", ITEM_ICON
,
1366 gtk_tree_view_append_column (state
->view
, column
);
1367 column
= gtk_tree_view_column_new_with_attributes ("",
1368 gtk_cell_renderer_text_new (),
1371 gtk_tree_view_append_column (state
->view
, column
);
1372 gtk_tree_view_set_expander_column (state
->view
, column
);
1374 g_signal_connect (selection
,
1376 G_CALLBACK (cb_dialog_pref_selection_changed
), state
);
1378 g_signal_connect_swapped (G_OBJECT (go_gtk_builder_get_widget (gui
, "close_button")),
1380 G_CALLBACK (cb_close_clicked
), state
);
1382 gnm_init_help_button (
1383 go_gtk_builder_get_widget (state
->gui
, "help_button"),
1384 GNUMERIC_HELP_LINK_PREFERENCES
);
1385 g_signal_connect_swapped (G_OBJECT (state
->dialog
),
1387 G_CALLBACK(cb_preferences_destroy
),
1389 g_object_set_data_full (G_OBJECT (state
->dialog
),
1391 (GDestroyNotify
)g_free
);
1393 g_object_set_data (gnm_app_get_app (), PREF_DIALOG_KEY
, state
->dialog
);
1395 state
->app_wb_removed_sig
=
1396 g_signal_connect_swapped (gnm_app_get_app (),
1398 G_CALLBACK (cb_workbook_removed
),
1401 for (i
= 0; page_info
[i
].page_initializer
; i
++) {
1402 const page_info_t
*this_page
= &page_info
[i
];
1403 GtkWidget
*page_widget
=
1404 this_page
->page_initializer (state
, NULL
,
1405 state
->notebook
, i
);
1406 gtk_notebook_append_page (state
->notebook
, page_widget
, NULL
);
1407 dialog_pref_add_item (state
, this_page
->page_name
,
1408 this_page
->icon_name
, i
,
1409 this_page
->parent_path
);
1412 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (state
->store
),
1413 ITEM_NAME
, GTK_SORT_ASCENDING
);
1415 go_gtk_nonmodal_dialog (wbcg_toplevel (wbcg
),
1416 GTK_WINDOW (state
->dialog
));
1417 gtk_widget_show (GTK_WIDGET (state
->dialog
));
1419 dialog_pref_select_page (state
, page
);