2 * dialog-preferences.c: Dialog to edit application wide preferences and default values
5 * Andreas J. Guelzow <aguelzow@taliesin.ca>
7 * (C) Copyright 2000-2002 Jody Goldberg <jody@gnome.org>
8 * (C) Copyright 2003-2004 Andreas J. Guelzow <aguelzow@taliesin.ca>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <https://www.gnu.org/licenses/>.
24 #include <gnumeric-config.h>
26 #include <application.h>
27 #include <dialogs/dialogs.h>
28 #include <dialogs/help.h>
32 #include <gnm-format.h>
34 #include <workbook-control.h>
36 #include <number-match.h>
37 #include <widgets/gnm-cell-renderer-text.h>
39 #include <gnumeric-conf.h>
42 #include <glib/gi18n-lib.h>
45 #define PREF_DIALOG_KEY "pref-dialog"
57 GtkNotebook
*notebook
;
60 gulong app_wb_removed_sig
;
63 typedef void (* double_conf_setter_t
) (double value
);
64 typedef void (* gint_conf_setter_t
) (gint value
);
65 typedef void (* gboolean_conf_setter_t
) (gboolean value
);
66 typedef void (* enum_conf_setter_t
) (int value
);
67 typedef void (* wordlist_conf_setter_t
) (GSList
*value
);
69 typedef gboolean (* gboolean_conf_getter_t
) (void);
70 typedef GSList
* (* wordlist_conf_getter_t
) (void);
71 typedef int (* enum_conf_getter_t
) (void);
72 typedef gint (* gint_conf_getter_t
) (void);
73 typedef double (* double_conf_getter_t
) (void);
76 dialog_pref_add_item (PrefState
*state
, char const *page_name
,
77 char const *icon_name
,
78 int page
, char const* parent_path
)
80 GtkTreeIter iter
, parent
;
81 GdkPixbuf
* icon
= NULL
;
83 if (icon_name
!= NULL
)
84 icon
= gtk_widget_render_icon_pixbuf (state
->dialog
, icon_name
,
86 if ((parent_path
!= NULL
) && gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (state
->store
),
87 &parent
, parent_path
))
88 gtk_tree_store_append (state
->store
, &iter
, &parent
);
90 gtk_tree_store_append (state
->store
, &iter
, NULL
);
92 gtk_tree_store_set (state
->store
, &iter
,
94 ITEM_NAME
, _(page_name
),
98 g_object_unref (icon
);
102 set_tip (GOConfNode
*node
, GtkWidget
*w
)
104 const char *desc
= gnm_conf_get_long_desc (node
);
106 gtk_widget_set_tooltip_text (w
, desc
);
110 cb_pref_notification_destroy (gpointer handle
)
112 go_conf_remove_monitor (GPOINTER_TO_UINT (handle
));
116 connect_notification (GOConfNode
*node
, GOConfMonitorFunc func
,
117 gpointer data
, GtkWidget
*container
)
119 guint handle
= go_conf_add_monitor (node
, NULL
, func
, data
);
120 g_signal_connect_swapped (G_OBJECT (container
), "destroy",
121 G_CALLBACK (cb_pref_notification_destroy
),
122 GUINT_TO_POINTER (handle
));
125 /*************************************************************************/
128 pref_create_label (GOConfNode
*node
, GtkWidget
*grid
,
129 gint row
, gchar
const *default_label
, GtkWidget
*w
)
133 if (NULL
== default_label
) {
134 const char *desc
= gnm_conf_get_short_desc (node
);
135 label
= gtk_label_new (desc
);
137 label
= gtk_label_new_with_mnemonic (default_label
);
139 gtk_label_set_justify (GTK_LABEL (label
), GTK_JUSTIFY_LEFT
);
140 gtk_misc_set_alignment (GTK_MISC (label
), 0, 0.5);
141 gtk_widget_set_hexpand (label
, TRUE
);
142 gtk_grid_attach (GTK_GRID (grid
), label
, 0, row
, 1, 1);
144 gtk_label_set_mnemonic_widget (GTK_LABEL (label
), w
);
145 go_atk_setup_label (label
, w
);
148 /*************************************************************************/
151 bool_pref_widget_to_conf (GtkToggleButton
*button
,
152 gboolean_conf_setter_t setter
)
154 gboolean_conf_getter_t getter
155 = g_object_get_data (G_OBJECT (button
), "getter");
156 gboolean val_in_button
= gtk_toggle_button_get_active (button
);
157 gboolean val_in_conf
= getter ();
158 if ((!val_in_button
) != (!val_in_conf
))
159 setter (val_in_button
);
163 bool_pref_conf_to_widget (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
164 GtkToggleButton
*button
)
166 gboolean val_in_button
= gtk_toggle_button_get_active (button
);
168 /* We can't use the getter here since the main preferences */
169 /* may be notified after us */
170 gboolean val_in_conf
= go_conf_get_bool (node
, NULL
);
172 if ((!val_in_button
) != (!val_in_conf
))
173 gtk_toggle_button_set_active (button
, val_in_conf
);
177 bool_pref_create_widget (GOConfNode
*node
, GtkWidget
*grid
,
178 gint row
, gboolean_conf_setter_t setter
,
179 gboolean_conf_getter_t getter
,
180 char const *default_label
)
182 const char *desc
= gnm_conf_get_short_desc (node
);
183 GtkWidget
*item
= gtk_check_button_new_with_label (
184 (desc
!= NULL
) ? desc
: default_label
);
186 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item
), getter ());
188 g_object_set_data (G_OBJECT (item
), "getter", getter
);
189 g_signal_connect (G_OBJECT (item
), "toggled",
190 G_CALLBACK (bool_pref_widget_to_conf
),
192 gtk_grid_attach (GTK_GRID (grid
), item
, 0, row
, 2, 1);
194 connect_notification (node
, (GOConfMonitorFunc
)bool_pref_conf_to_widget
,
196 set_tip (node
, item
);
199 /*************************************************************************/
202 cb_enum_changed (GtkComboBox
*combo
, enum_conf_setter_t setter
)
205 if (gtk_combo_box_get_active_iter (combo
, &iter
)) {
206 GtkTreeModel
*model
= gtk_combo_box_get_model (combo
);
207 GEnumValue
*enum_val
;
208 gtk_tree_model_get (model
, &iter
, 1, &enum_val
, -1);
209 (*setter
) (enum_val
->value
);
219 cb_find_enum (GtkTreeModel
*model
, GtkTreePath
*path
, GtkTreeIter
*iter
,
220 FindEnumClosure
*cls
)
222 gboolean res
= FALSE
;
225 g_return_val_if_fail (model
!= NULL
, FALSE
);
226 g_return_val_if_fail (cls
->val
!= NULL
, FALSE
);
228 gtk_tree_model_get (model
, iter
, 0, &combo_val
, -1);
230 if (0 == strcmp (cls
->val
, combo_val
)) {
232 gtk_combo_box_set_active_iter (cls
->combo
, iter
);
240 enum_pref_conf_to_widget (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
244 GtkTreeModel
*model
= gtk_combo_box_get_model (combo
);
247 /* We can't use the getter here since the main preferences */
248 /* may be notified after us */
249 cls
.val
= go_conf_get_enum_as_str (node
, NULL
);
250 if (NULL
!= cls
.val
) { /* in case go_conf fails */
251 gtk_tree_model_foreach (model
,
252 (GtkTreeModelForeachFunc
)cb_find_enum
,
259 enum_pref_create_widget (GOConfNode
*node
, GtkWidget
*grid
,
260 gint row
, GType enum_type
,
261 enum_conf_setter_t setter
,
262 enum_conf_getter_t getter
,
263 gchar
const *default_label
,
264 char const *(*label_getter
)(int))
268 GtkCellRenderer
*renderer
;
269 GEnumClass
*enum_class
= G_ENUM_CLASS (g_type_class_ref (enum_type
));
270 GtkWidget
*combo
= gtk_combo_box_new ();
271 GtkListStore
*model
= gtk_list_store_new (2,
272 G_TYPE_STRING
, G_TYPE_POINTER
);
273 gint current
= getter ();
274 gint current_index
= -1;
276 for (i
= 0; i
< enum_class
->n_values
; i
++) {
277 gtk_list_store_append (model
, &iter
);
278 gtk_list_store_set (model
, &iter
,
279 0, label_getter ((int) enum_class
->values
[i
].value
),
280 1, enum_class
->values
+ i
,
282 if (enum_class
->values
[i
].value
== current
)
286 g_type_class_unref (enum_class
);
288 gtk_combo_box_set_model (GTK_COMBO_BOX (combo
), GTK_TREE_MODEL (model
));
289 g_object_unref (model
);
290 renderer
= gtk_cell_renderer_text_new ();
291 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo
), renderer
, TRUE
);
292 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo
), renderer
, "text", 0, NULL
);
294 gtk_combo_box_set_active (GTK_COMBO_BOX (combo
), current_index
);
296 gtk_grid_attach (GTK_GRID (grid
), combo
, 1, row
, 1, 1);
298 g_signal_connect (G_OBJECT (combo
), "changed",
299 G_CALLBACK (cb_enum_changed
), (gpointer
) setter
);
300 connect_notification (node
, (GOConfMonitorFunc
)enum_pref_conf_to_widget
,
303 pref_create_label (node
, grid
, row
, default_label
, combo
);
304 set_tip (node
, combo
);
307 /*************************************************************************/
310 int_pref_widget_to_conf (GtkSpinButton
*button
, gint_conf_setter_t setter
)
312 gint_conf_getter_t getter
313 = g_object_get_data (G_OBJECT (button
), "getter");
314 gint val_in_button
= gtk_spin_button_get_value_as_int (button
);
315 gint val_in_conf
= getter ();
317 if (val_in_conf
!= val_in_button
)
318 setter (val_in_button
);
322 int_pref_conf_to_widget (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
323 GtkSpinButton
*button
)
325 gint val_in_button
= gtk_spin_button_get_value_as_int (button
);
327 /* We can't use the getter here since the main preferences */
328 /* may be notified after us */
329 gint val_in_conf
= go_conf_get_int (node
, NULL
);
331 if (val_in_conf
!= val_in_button
)
332 gtk_spin_button_set_value (button
, (gdouble
) val_in_conf
);
336 int_pref_create_widget (GOConfNode
*node
, GtkWidget
*grid
,
337 gint row
, gint val
, gint from
, gint to
, gint step
,
338 gint_conf_setter_t setter
, gint_conf_getter_t getter
,
339 char const *default_label
)
341 GtkAdjustment
*adj
= GTK_ADJUSTMENT
342 (gtk_adjustment_new (val
, from
, to
, step
, step
, 0));
343 GtkWidget
*w
= gtk_spin_button_new (adj
, 1, 0);
345 gtk_spin_button_set_value (GTK_SPIN_BUTTON (w
), (gdouble
) getter ());
347 g_object_set_data (G_OBJECT (w
), "node", node
);
348 gtk_widget_set_hexpand (w
, TRUE
);
349 gtk_grid_attach (GTK_GRID (grid
), w
, 1, row
, 1, 1);
351 g_object_set_data (G_OBJECT (w
), "getter", getter
);
352 g_signal_connect (G_OBJECT (w
), "value-changed",
353 G_CALLBACK (int_pref_widget_to_conf
),
355 connect_notification (node
, (GOConfMonitorFunc
)int_pref_conf_to_widget
,
358 pref_create_label (node
, grid
, row
, default_label
, w
);
366 return i
> 0 && (i
& (i
- 1)) == 0;
370 cb_power_of_2 (GtkAdjustment
*adj
)
372 int val
= (int)gtk_adjustment_get_value (adj
);
374 if (powerof_2 (val
- 1))
375 gtk_adjustment_set_value (adj
, (val
- 1) * 2);
376 else if (powerof_2 (val
+ 1))
377 gtk_adjustment_set_value (adj
, (val
+ 1) / 2);
381 power_of_2_handlers (GtkWidget
*w
)
383 GtkSpinButton
*spin
= GTK_SPIN_BUTTON (w
);
384 GtkAdjustment
*adj
= gtk_spin_button_get_adjustment (spin
);
385 g_signal_connect (G_OBJECT (adj
), "value_changed",
386 G_CALLBACK (cb_power_of_2
), NULL
);
389 /*************************************************************************/
392 double_pref_widget_to_conf (GtkSpinButton
*button
, double_conf_setter_t setter
)
394 double_conf_getter_t getter
395 = g_object_get_data (G_OBJECT (button
), "getter");
396 double val_in_button
= gtk_spin_button_get_value (button
);
397 double val_in_conf
= getter();
399 if (fabs (val_in_conf
- val_in_button
) > 1e-10) /* dead simple */
400 setter (val_in_button
);
404 double_pref_conf_to_widget (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
405 GtkSpinButton
*button
)
407 double val_in_button
= gtk_spin_button_get_value (button
);
409 /* We can't use the getter here since the main preferences */
410 /* may be notified after us */
411 double val_in_conf
= go_conf_get_double (node
, NULL
);
413 if (fabs (val_in_conf
- val_in_button
) > 1e-10) /* dead simple */
414 gtk_spin_button_set_value (button
, val_in_conf
);
417 double_pref_create_widget (GOConfNode
*node
, GtkWidget
*grid
,
418 gint row
, gnm_float val
, gnm_float from
, gnm_float to
,
419 gnm_float step
, gint digits
,
420 double_conf_setter_t setter
,
421 double_conf_getter_t getter
,
422 char const *default_label
)
424 GtkWidget
*w
= gtk_spin_button_new (GTK_ADJUSTMENT (
425 gtk_adjustment_new (val
, from
, to
, step
, step
, 0)),
427 gtk_spin_button_set_value (GTK_SPIN_BUTTON (w
), getter ());
428 g_object_set_data (G_OBJECT (w
), "node", node
);
429 gtk_widget_set_hexpand (w
, TRUE
);
430 gtk_grid_attach (GTK_GRID (grid
), w
, 1, row
, 1, 1);
432 g_object_set_data (G_OBJECT (w
), "getter", getter
);
433 g_signal_connect (G_OBJECT (w
), "value-changed",
434 G_CALLBACK (double_pref_widget_to_conf
), (gpointer
) setter
);
435 connect_notification (node
,
436 (GOConfMonitorFunc
)double_pref_conf_to_widget
,
439 pref_create_label (node
, grid
, row
, default_label
, w
);
444 /*************************************************************************/
449 wordlist_pref_conf_to_widget (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
452 /* We can't use the getter here since the main preferences */
453 /* may be notified after us */
454 GSList
*l
, *list
= go_conf_get_str_list (node
, NULL
);
457 gtk_list_store_clear (store
);
459 for (l
= list
; l
!= NULL
; l
= l
->next
) {
460 gtk_list_store_append (store
, &iter
);
461 gtk_list_store_set (store
, &iter
,
470 wordlist_pref_remove (GtkButton
*button
, wordlist_conf_setter_t setter
) {
471 GtkTreeView
*tree
= g_object_get_data (G_OBJECT (button
), "treeview");
472 GtkTreeSelection
*select
= gtk_tree_view_get_selection (tree
);
476 if (gtk_tree_selection_get_selected (select
, &model
, &iter
)) {
478 wordlist_conf_getter_t getter
= g_object_get_data (G_OBJECT (button
), "getter");
479 GSList
*l
, *list
= getter ();
481 list
= go_string_slist_copy (list
);
483 gtk_tree_model_get (model
, &iter
,
486 l
= g_slist_find_custom (list
, text
, (GCompareFunc
)strcmp
);
489 list
= g_slist_delete_link (list
, l
);
492 g_slist_free_full (list
, g_free
);
498 wordlist_pref_add (GtkButton
*button
, wordlist_conf_setter_t setter
)
500 GtkEntry
*entry
= g_object_get_data (G_OBJECT (button
), "entry");
501 const gchar
*text
= gtk_entry_get_text (entry
);
504 wordlist_conf_getter_t getter
= g_object_get_data (G_OBJECT (button
), "getter");
505 GSList
*l
, *list
= getter ();
506 l
= g_slist_find_custom (list
, text
, (GCompareFunc
)strcmp
);
508 list
= go_string_slist_copy (list
);
509 list
= g_slist_append (list
, g_strdup (text
));
511 g_slist_free_full (list
, g_free
);
517 wordlist_pref_update_remove_button (GtkTreeSelection
*selection
, GtkButton
*button
)
519 gtk_widget_set_sensitive (GTK_WIDGET (button
),
520 gtk_tree_selection_get_selected (selection
, NULL
, NULL
));
524 wordlist_pref_create_widget (GOConfNode
*node
, GtkWidget
*grid
,
525 gint row
, wordlist_conf_setter_t setter
,
526 wordlist_conf_getter_t getter
,
527 char const *default_label
)
529 GtkWidget
*w
= gtk_grid_new ();
530 GtkWidget
*sw
= gtk_scrolled_window_new (NULL
, NULL
);
531 GtkWidget
*tv
= gtk_tree_view_new ();
532 GtkWidget
*entry
= gtk_entry_new ();
533 GtkWidget
*add_button
= gtk_button_new_from_stock (GTK_STOCK_ADD
);
534 GtkWidget
*remove_button
= gtk_button_new_from_stock (GTK_STOCK_REMOVE
);
535 GtkListStore
*model
= gtk_list_store_new (1, G_TYPE_STRING
);
536 GtkTreeSelection
*selection
;
538 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw
),
539 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
540 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw
),
541 GTK_SHADOW_ETCHED_IN
);
542 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tv
), FALSE
);
543 gtk_container_add (GTK_CONTAINER (sw
), tv
);
545 g_object_set (w
, "column-spacing", 12, "row-spacing", 6,
546 "hexpand", TRUE
, "vexpand", TRUE
, NULL
);
547 gtk_grid_attach (GTK_GRID (grid
), w
, 0, row
, 2, 1);
548 g_object_set (sw
, "hexpand", TRUE
, "vexpand", TRUE
, NULL
);
549 gtk_grid_attach (GTK_GRID (w
), sw
, 0, 1, 1, 3);
550 gtk_widget_set_hexpand (entry
, TRUE
);
551 gtk_grid_attach (GTK_GRID (w
), entry
, 0, 4, 1, 1);
552 gtk_widget_set_valign (remove_button
, GTK_ALIGN_END
);
553 gtk_grid_attach (GTK_GRID (w
), remove_button
, 1, 3, 1, 1);
554 gtk_grid_attach (GTK_GRID (w
), add_button
, 1, 4, 1, 1);
556 gtk_tree_view_set_model (GTK_TREE_VIEW (tv
),
557 GTK_TREE_MODEL (model
));
558 g_object_unref (model
);
559 gtk_tree_view_append_column (GTK_TREE_VIEW (tv
),
560 gtk_tree_view_column_new_with_attributes
562 gtk_cell_renderer_text_new (),
565 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tv
));
566 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
567 wordlist_pref_conf_to_widget (node
, "", model
);
569 g_object_set_data (G_OBJECT (remove_button
), "treeview", tv
);
570 g_object_set_data (G_OBJECT (add_button
), "entry", entry
);
571 g_object_set_data (G_OBJECT (remove_button
), "getter", getter
);
572 g_object_set_data (G_OBJECT (add_button
), "getter", getter
);
573 g_signal_connect (G_OBJECT (remove_button
), "clicked",
574 G_CALLBACK (wordlist_pref_remove
), setter
);
575 g_signal_connect (G_OBJECT (add_button
), "clicked",
576 G_CALLBACK (wordlist_pref_add
), setter
);
577 g_signal_connect (G_OBJECT (selection
), "changed",
578 G_CALLBACK (wordlist_pref_update_remove_button
), remove_button
);
579 wordlist_pref_update_remove_button (selection
,
580 GTK_BUTTON (remove_button
));
582 connect_notification (node
, (GOConfMonitorFunc
)wordlist_pref_conf_to_widget
,
585 pref_create_label (node
, w
, 0, default_label
, tv
);
590 /*******************************************************************************************/
591 /* Default Font Selector */
592 /*******************************************************************************************/
595 do_set_font (GOFontSel
*fs
,
596 const char *name
, double size
,
597 gboolean is_bold
, gboolean is_italic
)
599 PangoFontDescription
*desc
;
601 desc
= pango_font_description_new ();
602 pango_font_description_set_family (desc
, name
);
603 pango_font_description_set_size (desc
, PANGO_SCALE
* size
);
604 pango_font_description_set_weight
606 is_bold
? PANGO_WEIGHT_BOLD
: PANGO_WEIGHT_NORMAL
);
607 pango_font_description_set_style
609 is_italic
? PANGO_STYLE_ITALIC
: PANGO_STYLE_NORMAL
);
611 go_font_sel_set_font_desc (fs
, desc
);
612 pango_font_description_free (desc
);
617 cb_pref_font_set_fonts (G_GNUC_UNUSED GOConfNode
*node
,
618 G_GNUC_UNUSED
char const *key
,
621 GOFontSel
*fs
= GO_FONT_SEL (page
);
624 gnm_conf_get_core_defaultfont_name (),
625 gnm_conf_get_core_defaultfont_size (),
626 gnm_conf_get_core_defaultfont_bold (),
627 gnm_conf_get_core_defaultfont_italic ());
631 cb_pref_font_has_changed (GOFontSel
*fs
, G_GNUC_UNUSED PangoAttrList
*attrs
,
634 PangoFontDescription
*desc
= go_font_sel_get_font_desc (fs
);
635 PangoFontMask fields
= pango_font_description_get_set_fields (desc
);
637 if (fields
& PANGO_FONT_MASK_FAMILY
)
638 gnm_conf_set_core_defaultfont_name
639 (pango_font_description_get_family (desc
));
640 if (fields
& PANGO_FONT_MASK_SIZE
)
641 gnm_conf_set_core_defaultfont_size
642 (pango_font_description_get_size (desc
) / (double)PANGO_SCALE
);
643 if (fields
& PANGO_FONT_MASK_WEIGHT
)
644 gnm_conf_set_core_defaultfont_bold
645 (pango_font_description_get_weight (desc
) >= PANGO_WEIGHT_BOLD
);
646 if (fields
& PANGO_FONT_MASK_STYLE
)
647 gnm_conf_set_core_defaultfont_italic
648 (pango_font_description_get_style (desc
) != PANGO_STYLE_NORMAL
);
650 pango_font_description_free (desc
);
656 pref_font_initializer (PrefState
*state
,
657 G_GNUC_UNUSED gpointer data
,
658 G_GNUC_UNUSED GtkNotebook
*notebook
,
659 G_GNUC_UNUSED gint page_num
)
661 GtkWidget
*page
= g_object_new (GO_TYPE_FONT_SEL
,
665 cb_pref_font_set_fonts (NULL
, NULL
, page
);
667 connect_notification (gnm_conf_get_core_defaultfont_dir_node (),
668 (GOConfMonitorFunc
) cb_pref_font_set_fonts
,
670 g_signal_connect (G_OBJECT (page
),
672 G_CALLBACK (cb_pref_font_has_changed
), state
);
674 gtk_widget_show_all (page
);
679 /*******************************************************************************************/
680 /* Default Header/Footer Font Selector */
681 /*******************************************************************************************/
684 cb_pref_font_hf_set_fonts (G_GNUC_UNUSED GOConfNode
*node
,
685 G_GNUC_UNUSED
char const *key
,
688 GOFontSel
*fs
= GO_FONT_SEL (page
);
690 gnm_conf_get_printsetup_hf_font_name (),
691 gnm_conf_get_printsetup_hf_font_size (),
692 gnm_conf_get_printsetup_hf_font_bold (),
693 gnm_conf_get_printsetup_hf_font_italic ());
697 cb_pref_font_hf_has_changed (GOFontSel
*fs
, G_GNUC_UNUSED PangoAttrList
*attrs
,
700 PangoFontDescription
*desc
= go_font_sel_get_font_desc (fs
);
701 PangoFontMask fields
= pango_font_description_get_set_fields (desc
);
703 if (fields
& PANGO_FONT_MASK_FAMILY
)
704 gnm_conf_set_printsetup_hf_font_name
705 (pango_font_description_get_family (desc
));
706 if (fields
& PANGO_FONT_MASK_SIZE
)
707 gnm_conf_set_printsetup_hf_font_size
708 (pango_font_description_get_size (desc
) / (double)PANGO_SCALE
);
709 if (fields
& PANGO_FONT_MASK_WEIGHT
)
710 gnm_conf_set_printsetup_hf_font_bold
711 (pango_font_description_get_weight (desc
) >= PANGO_WEIGHT_BOLD
);
712 if (fields
& PANGO_FONT_MASK_STYLE
)
713 gnm_conf_set_printsetup_hf_font_italic
714 (pango_font_description_get_style (desc
) != PANGO_STYLE_NORMAL
);
716 pango_font_description_free (desc
);
722 pref_font_hf_initializer (PrefState
*state
,
723 G_GNUC_UNUSED gpointer data
,
724 G_GNUC_UNUSED GtkNotebook
*notebook
,
725 G_GNUC_UNUSED gint page_num
)
727 GtkWidget
*page
= g_object_new (GO_TYPE_FONT_SEL
,
731 cb_pref_font_hf_set_fonts (NULL
, NULL
, page
);
732 connect_notification (gnm_conf_get_printsetup_dir_node (),
733 (GOConfMonitorFunc
) cb_pref_font_hf_set_fonts
,
735 g_signal_connect (G_OBJECT (page
),
737 G_CALLBACK (cb_pref_font_hf_has_changed
), state
);
739 gtk_widget_show_all (page
);
744 /*******************************************************************************************/
745 /* Undo Preferences Page */
746 /*******************************************************************************************/
749 pref_undo_page_initializer (PrefState
*state
,
750 G_GNUC_UNUSED gpointer data
,
751 G_GNUC_UNUSED GtkNotebook
*notebook
,
752 G_GNUC_UNUSED gint page_num
)
754 GtkWidget
*page
= gtk_grid_new ();
757 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
758 "vexpand", TRUE
, NULL
);
759 int_pref_create_widget (gnm_conf_get_undo_max_descriptor_width_node (),
760 page
, row
++, 5, 5, 200, 1,
761 gnm_conf_set_undo_max_descriptor_width
,
762 gnm_conf_get_undo_max_descriptor_width
,
763 _("Length of Undo Descriptors"));
764 int_pref_create_widget (gnm_conf_get_undo_size_node (),
765 page
, row
++, 1000, 0, 30000, 100,
766 gnm_conf_set_undo_size
,
767 gnm_conf_get_undo_size
,
768 _("Maximal Undo Size"));
769 int_pref_create_widget (gnm_conf_get_undo_maxnum_node (),
770 page
, row
++, 20, 1, 200, 1,
771 gnm_conf_set_undo_maxnum
,
772 gnm_conf_get_undo_maxnum
,
773 _("Number of Undo Items"));
774 bool_pref_create_widget (gnm_conf_get_undo_show_sheet_name_node (),
776 gnm_conf_set_undo_show_sheet_name
,
777 gnm_conf_get_undo_show_sheet_name
,
778 _("Show Sheet Name in Undo List"));
780 gtk_widget_show_all (page
);
784 /*******************************************************************************************/
785 /* Sort Preferences Page */
786 /*******************************************************************************************/
789 pref_sort_page_initializer (PrefState
*state
,
790 G_GNUC_UNUSED gpointer data
,
791 G_GNUC_UNUSED GtkNotebook
*notebook
,
792 G_GNUC_UNUSED gint page_num
)
794 GtkWidget
*page
= gtk_grid_new ();
797 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
798 "vexpand", TRUE
, NULL
);
799 int_pref_create_widget (gnm_conf_get_core_sort_dialog_max_initial_clauses_node (),
800 page
, row
++, 10, 0, 50, 1,
801 gnm_conf_set_core_sort_dialog_max_initial_clauses
,
802 gnm_conf_get_core_sort_dialog_max_initial_clauses
,
803 _("Number of Automatic Clauses"));
804 bool_pref_create_widget (gnm_conf_get_core_sort_default_retain_formats_node (),
806 gnm_conf_set_core_sort_default_retain_formats
,
807 gnm_conf_get_core_sort_default_retain_formats
,
808 _("Sorting Preserves Formats"));
809 bool_pref_create_widget (gnm_conf_get_core_sort_default_by_case_node (),
811 gnm_conf_set_core_sort_default_by_case
,
812 gnm_conf_get_core_sort_default_by_case
,
813 _("Sorting is Case-Sensitive"));
814 bool_pref_create_widget (gnm_conf_get_core_sort_default_ascending_node (),
816 gnm_conf_set_core_sort_default_ascending
,
817 gnm_conf_get_core_sort_default_ascending
,
818 _("Sort Ascending"));
820 gtk_widget_show_all (page
);
824 /*******************************************************************************************/
825 /* Window Preferences Page */
826 /*******************************************************************************************/
829 pref_window_page_initializer (PrefState
*state
,
830 G_GNUC_UNUSED gpointer data
,
831 G_GNUC_UNUSED GtkNotebook
*notebook
,
832 G_GNUC_UNUSED gint page_num
)
834 GtkWidget
*page
= gtk_grid_new ();
838 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
839 "vexpand", TRUE
, NULL
);
840 double_pref_create_widget (gnm_conf_get_core_gui_window_y_node (),
841 page
, row
++, 0.75, 0.25, 1, 0.05, 2,
842 gnm_conf_set_core_gui_window_y
,
843 gnm_conf_get_core_gui_window_y
,
844 _("Default Vertical Window Size"));
845 double_pref_create_widget (gnm_conf_get_core_gui_window_x_node (),
846 page
, row
++, 0.75, 0.25, 1, 0.05, 2,
847 gnm_conf_set_core_gui_window_x
,
848 gnm_conf_get_core_gui_window_x
,
849 _("Default Horizontal Window Size"));
850 double_pref_create_widget (gnm_conf_get_core_gui_window_zoom_node (),
851 page
, row
++, 1.00, 0.10, 5.00, 0.05, 2,
852 gnm_conf_set_core_gui_window_zoom
,
853 gnm_conf_get_core_gui_window_zoom
,
854 _("Default Zoom Factor"));
855 int_pref_create_widget (gnm_conf_get_core_workbook_n_sheet_node (),
856 page
, row
++, 1, 1, 64, 1,
857 gnm_conf_set_core_workbook_n_sheet
,
858 gnm_conf_get_core_workbook_n_sheet
,
859 _("Default Number of Sheets"));
861 w
= int_pref_create_widget (gnm_conf_get_core_workbook_n_rows_node (),
863 GNM_DEFAULT_ROWS
, GNM_MIN_ROWS
, GNM_MAX_ROWS
, 1,
864 gnm_conf_set_core_workbook_n_rows
,
865 gnm_conf_get_core_workbook_n_rows
,
866 _("Default Number of Rows in a Sheet"));
867 power_of_2_handlers (w
);
869 w
= int_pref_create_widget (gnm_conf_get_core_workbook_n_cols_node (),
871 GNM_DEFAULT_COLS
, GNM_MIN_COLS
, GNM_MAX_COLS
, 1,
872 gnm_conf_set_core_workbook_n_cols
,
873 gnm_conf_get_core_workbook_n_cols
,
874 _("Default Number of Columns in a Sheet"));
875 power_of_2_handlers (w
);
877 bool_pref_create_widget (gnm_conf_get_core_gui_cells_function_markers_node (),
879 gnm_conf_set_core_gui_cells_function_markers
,
880 gnm_conf_get_core_gui_cells_function_markers
,
881 _("By default, mark cells with spreadsheet functions"));
882 bool_pref_create_widget (gnm_conf_get_core_gui_cells_extension_markers_node (),
884 gnm_conf_set_core_gui_cells_extension_markers
,
885 gnm_conf_get_core_gui_cells_extension_markers
,
886 _("By default, mark cells with truncated content"));
888 gtk_widget_show_all (page
);
892 /*******************************************************************************************/
893 /* File/XML Preferences Page */
894 /*******************************************************************************************/
897 gnm_conf_set_core_file_save_extension_check_disabled_wrap (gboolean val
)
902 list
= g_slist_prepend (NULL
, (char *)"Gnumeric_stf:stf_assistant");
903 gnm_conf_set_core_file_save_extension_check_disabled (list
);
907 gnm_conf_get_core_file_save_extension_check_disabled_wrap (void)
909 GSList
*list
= gnm_conf_get_core_file_save_extension_check_disabled ();
910 return (NULL
!= g_slist_find_custom (list
, "Gnumeric_stf:stf_assistant", go_str_compare
));
914 custom_pref_conf_to_widget_ecd (GOConfNode
*node
, G_GNUC_UNUSED
char const *key
,
915 GtkToggleButton
*button
)
917 gboolean val_in_button
= gtk_toggle_button_get_active (button
);
919 /* We can't use the getter here since the main preferences */
920 /* may be notified after us */
921 GSList
*list
= go_conf_get_str_list (node
, NULL
);
923 = (NULL
!= g_slist_find_custom (list
, "Gnumeric_stf:stf_assistant", go_str_compare
));
925 if ((!val_in_button
) != (!val_in_conf
))
926 gtk_toggle_button_set_active (button
, val_in_conf
);
929 custom_pref_create_widget_ecd (GOConfNode
*node
, GtkWidget
*grid
,
930 gint row
, gboolean_conf_setter_t setter
,
931 gboolean_conf_getter_t getter
,
932 char const *default_label
)
934 GtkWidget
*item
= gtk_check_button_new_with_label (default_label
);
936 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item
), getter ());
938 g_object_set_data (G_OBJECT (item
), "getter", getter
);
939 g_signal_connect (G_OBJECT (item
), "toggled",
940 G_CALLBACK (bool_pref_widget_to_conf
),
942 gtk_grid_attach (GTK_GRID (grid
), item
, 0, row
, 2, 1);
944 connect_notification (node
, (GOConfMonitorFunc
)custom_pref_conf_to_widget_ecd
,
952 pref_file_page_initializer (PrefState
*state
,
953 G_GNUC_UNUSED gpointer data
,
954 G_GNUC_UNUSED GtkNotebook
*notebook
,
955 G_GNUC_UNUSED gint page_num
)
957 GtkWidget
*page
= gtk_grid_new ();
960 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
961 "vexpand", TRUE
, NULL
);
962 int_pref_create_widget (gnm_conf_get_core_xml_compression_level_node (),
963 page
, row
++, 9, 0, 9, 1,
964 gnm_conf_set_core_xml_compression_level
,
965 gnm_conf_get_core_xml_compression_level
,
966 _("Default Compression Level For "
968 int_pref_create_widget (gnm_conf_get_core_workbook_autosave_time_node (),
969 page
, row
++, 0, 0, 365*24*60*60, 60,
970 gnm_conf_set_core_workbook_autosave_time
,
971 gnm_conf_get_core_workbook_autosave_time
,
972 _("Default autosave frequency in seconds"));
973 bool_pref_create_widget (gnm_conf_get_core_file_save_def_overwrite_node (),
975 gnm_conf_set_core_file_save_def_overwrite
,
976 gnm_conf_get_core_file_save_def_overwrite
,
977 _("Default To Overwriting Files"));
978 bool_pref_create_widget (gnm_conf_get_core_file_save_single_sheet_node (),
980 gnm_conf_set_core_file_save_single_sheet
,
981 gnm_conf_get_core_file_save_single_sheet
,
982 _("Warn When Exporting Into Single "
984 bool_pref_create_widget (gnm_conf_get_plugin_latex_use_utf8_node (),
986 gnm_conf_set_plugin_latex_use_utf8
,
987 gnm_conf_get_plugin_latex_use_utf8
,
988 _("Use UTF-8 in LaTeX Export"));
989 custom_pref_create_widget_ecd ( gnm_conf_get_core_file_save_extension_check_disabled_node (),
991 gnm_conf_set_core_file_save_extension_check_disabled_wrap
,
992 gnm_conf_get_core_file_save_extension_check_disabled_wrap
,
993 _("Disable Extension Check for Configurable Text Exporter"));
995 gtk_widget_show_all (page
);
999 /*******************************************************************************************/
1000 /* Screen Preferences Page */
1001 /*******************************************************************************************/
1004 pref_screen_page_initializer (PrefState
*state
,
1005 G_GNUC_UNUSED gpointer data
,
1006 G_GNUC_UNUSED GtkNotebook
*notebook
,
1007 G_GNUC_UNUSED gint page_num
)
1009 GtkWidget
*page
= gtk_grid_new ();
1012 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
1013 "vexpand", TRUE
, NULL
);
1014 double_pref_create_widget (gnm_conf_get_core_gui_screen_horizontaldpi_node (),
1015 page
, row
++, 96, 50, 250, 1, 1,
1016 gnm_conf_set_core_gui_screen_horizontaldpi
,
1017 gnm_conf_get_core_gui_screen_horizontaldpi
,
1018 _("Horizontal DPI"));
1019 double_pref_create_widget (gnm_conf_get_core_gui_screen_verticaldpi_node (),
1020 page
, row
++, 96, 50, 250, 1, 1,
1021 gnm_conf_set_core_gui_screen_verticaldpi
,
1022 gnm_conf_get_core_gui_screen_verticaldpi
,
1025 gtk_widget_show_all (page
);
1029 /*******************************************************************************************/
1030 /* Tool Preferences Page */
1031 /*******************************************************************************************/
1034 pref_tool_page_initializer (PrefState
*state
,
1035 G_GNUC_UNUSED gpointer data
,
1036 G_GNUC_UNUSED GtkNotebook
*notebook
,
1037 G_GNUC_UNUSED gint page_num
)
1039 GtkWidget
*page
= gtk_grid_new ();
1042 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
1043 "vexpand", TRUE
, NULL
);
1044 enum_pref_create_widget (gnm_conf_get_core_gui_editing_enter_moves_dir_node (),
1047 (enum_conf_setter_t
)gnm_conf_set_core_gui_editing_enter_moves_dir
,
1048 (enum_conf_getter_t
)gnm_conf_get_core_gui_editing_enter_moves_dir
,
1049 _("Enter _Moves Selection"), (char const *(*) (int)) go_direction_get_name
);
1050 bool_pref_create_widget (gnm_conf_get_core_gui_editing_transitionkeys_node (),
1052 gnm_conf_set_core_gui_editing_transitionkeys
,
1053 gnm_conf_get_core_gui_editing_transitionkeys
,
1054 _("Transition Keys"));
1055 bool_pref_create_widget (gnm_conf_get_core_gui_editing_autocomplete_node (),
1057 gnm_conf_set_core_gui_editing_autocomplete
,
1058 gnm_conf_get_core_gui_editing_autocomplete
,
1060 int_pref_create_widget (gnm_conf_get_core_gui_editing_autocomplete_min_chars_node (),
1061 page
, row
++, 3, 1, 10, 1,
1062 gnm_conf_set_core_gui_editing_autocomplete_min_chars
,
1063 gnm_conf_get_core_gui_editing_autocomplete_min_chars
,
1064 _("Minimum Number of Characters for Autocompletion"));
1065 bool_pref_create_widget (gnm_conf_get_core_gui_editing_function_name_tooltips_node (),
1067 gnm_conf_set_core_gui_editing_function_name_tooltips
,
1068 gnm_conf_get_core_gui_editing_function_name_tooltips
,
1069 _("Show Function Name Tooltips"));
1070 bool_pref_create_widget (gnm_conf_get_core_gui_editing_function_argument_tooltips_node (),
1072 gnm_conf_set_core_gui_editing_function_argument_tooltips
,
1073 gnm_conf_get_core_gui_editing_function_argument_tooltips
,
1074 _("Show Function Argument Tooltips"));
1075 bool_pref_create_widget (gnm_conf_get_dialogs_rs_unfocused_node (),
1077 gnm_conf_set_dialogs_rs_unfocused
,
1078 gnm_conf_get_dialogs_rs_unfocused
,
1079 _("Allow Unfocused Range Selections"));
1080 int_pref_create_widget (gnm_conf_get_functionselector_num_of_recent_node (),
1081 page
, row
++, 10, 0, 40, 1,
1082 gnm_conf_set_functionselector_num_of_recent
,
1083 gnm_conf_get_functionselector_num_of_recent
,
1084 _("Maximum Length of Recently "
1085 "Used Functions List"));
1087 gtk_widget_show_all (page
);
1091 /*******************************************************************************************/
1092 /* Copy/Paste Preferences Page */
1093 /*******************************************************************************************/
1098 pref_copypaste_page_initializer (PrefState
*state
,
1099 G_GNUC_UNUSED gpointer data
,
1100 G_GNUC_UNUSED GtkNotebook
*notebook
,
1101 G_GNUC_UNUSED gint page_num
)
1103 GtkWidget
*page
= gtk_grid_new ();
1106 g_object_set (page
, "column-spacing", 12, "row-spacing", 6,
1107 "vexpand", TRUE
, NULL
);
1108 bool_pref_create_widget (gnm_conf_get_cut_and_paste_prefer_clipboard_node (),
1110 gnm_conf_set_cut_and_paste_prefer_clipboard
,
1111 gnm_conf_get_cut_and_paste_prefer_clipboard
,
1112 /* xgettext : see https://en.wikipedia.org/wiki/X_Window_selection#Clipboard */
1113 _("Prefer CLIPBOARD Over PRIMARY Selection"));
1115 gtk_widget_show_all (page
);
1121 /*******************************************************************************************/
1122 /* AutoCorrect Preferences Page (General) */
1123 /*******************************************************************************************/
1126 pref_autocorrect_general_page_initializer (PrefState
*state
,
1127 G_GNUC_UNUSED gpointer data
,
1128 G_GNUC_UNUSED GtkNotebook
*notebook
,
1129 G_GNUC_UNUSED gint page_num
)
1131 GtkWidget
*page
= gtk_grid_new ();
1134 bool_pref_create_widget (gnm_conf_get_autocorrect_names_of_days_node (),
1136 gnm_conf_set_autocorrect_names_of_days
,
1137 gnm_conf_get_autocorrect_names_of_days
,
1138 _("Capitalize _names of days"));
1140 gtk_widget_show_all (page
);
1144 /*******************************************************************************************/
1145 /* AutoCorrect Preferences Page (InitialCaps) */
1146 /*******************************************************************************************/
1149 pref_autocorrect_initialcaps_page_initializer (PrefState
*state
,
1150 G_GNUC_UNUSED gpointer data
,
1151 G_GNUC_UNUSED GtkNotebook
*notebook
,
1152 G_GNUC_UNUSED gint page_num
)
1154 GtkWidget
*page
= gtk_grid_new ();
1157 bool_pref_create_widget (gnm_conf_get_autocorrect_init_caps_node (),
1159 gnm_conf_set_autocorrect_init_caps
,
1160 gnm_conf_get_autocorrect_init_caps
,
1161 _("Correct _TWo INitial CApitals"));
1162 wordlist_pref_create_widget (gnm_conf_get_autocorrect_init_caps_list_node (), page
,
1163 row
++, gnm_conf_set_autocorrect_init_caps_list
,
1164 gnm_conf_get_autocorrect_init_caps_list
,
1165 _("Do _not correct:"));
1167 gtk_widget_show_all (page
);
1171 /*******************************************************************************************/
1172 /* AutoCorrect Preferences Page (FirstLetter) */
1173 /*******************************************************************************************/
1176 pref_autocorrect_firstletter_page_initializer (PrefState
*state
,
1177 G_GNUC_UNUSED gpointer data
,
1178 G_GNUC_UNUSED GtkNotebook
*notebook
,
1179 G_GNUC_UNUSED gint page_num
)
1181 GtkWidget
*page
= gtk_grid_new ();
1184 bool_pref_create_widget (gnm_conf_get_autocorrect_first_letter_node (),
1186 gnm_conf_set_autocorrect_first_letter
,
1187 gnm_conf_get_autocorrect_first_letter
,
1188 _("Capitalize _first letter of sentence"));
1189 wordlist_pref_create_widget (gnm_conf_get_autocorrect_first_letter_list_node (), page
,
1190 row
++, gnm_conf_set_autocorrect_first_letter_list
,
1191 gnm_conf_get_autocorrect_first_letter_list
,
1192 _("Do _not capitalize after:"));
1194 gtk_widget_show_all (page
);
1200 /*******************************************************************************************/
1201 /* General Preference Dialog Routines */
1202 /*******************************************************************************************/
1205 char const *page_name
;
1206 char const *icon_name
;
1207 char const *parent_path
;
1208 GtkWidget
* (*page_initializer
) (PrefState
*state
, gpointer data
,
1209 GtkNotebook
*notebook
, gint page_num
);
1212 /* Note that the page names are used in calls to dialog_preferences and as default in dialog_pref_select_page! */
1213 static page_info_t
const page_info
[] = {
1214 {N_("Auto Correct"), GTK_STOCK_DIALOG_ERROR
, NULL
, &pref_autocorrect_general_page_initializer
},
1215 {N_("Font"), GTK_STOCK_ITALIC
, NULL
, &pref_font_initializer
},
1216 {N_("Files"), GTK_STOCK_FLOPPY
, NULL
, &pref_file_page_initializer
},
1217 {N_("Tools"), GTK_STOCK_EXECUTE
, NULL
, &pref_tool_page_initializer
},
1218 {N_("Undo"), GTK_STOCK_UNDO
, NULL
, &pref_undo_page_initializer
},
1219 {N_("Windows"), "gnumeric-object-combo", NULL
, &pref_window_page_initializer
},
1220 {N_("Header/Footer"), GTK_STOCK_ITALIC
, "1", &pref_font_hf_initializer
},
1222 {N_("Copy and Paste"),GTK_STOCK_PASTE
, "3", &pref_copypaste_page_initializer
},
1224 {N_("Sorting"), GTK_STOCK_SORT_ASCENDING
, "3", &pref_sort_page_initializer
},
1225 {N_("Screen"), GTK_STOCK_PREFERENCES
, "5", &pref_screen_page_initializer
},
1226 {N_("INitial CApitals"), NULL
, "0", &pref_autocorrect_initialcaps_page_initializer
},
1227 {N_("First Letter"), NULL
, "0", &pref_autocorrect_firstletter_page_initializer
},
1228 {NULL
, NULL
, NULL
, NULL
},
1237 dialog_pref_select_page_search (GtkTreeModel
*model
,
1243 gtk_tree_model_get (model
, iter
, ITEM_NAME
, &page
, -1);
1244 if (0 == strcmp (page
, pst
->page
)) {
1246 pst
->path
= gtk_tree_path_copy (path
);
1255 dialog_pref_select_page (PrefState
*state
, gchar
const *page
)
1257 page_search_t pst
= {NULL
, NULL
};
1263 gtk_tree_model_foreach (GTK_TREE_MODEL (state
->store
),
1264 (GtkTreeModelForeachFunc
) dialog_pref_select_page_search
,
1267 if (pst
.path
== NULL
)
1268 pst
.path
= gtk_tree_path_new_first ();
1270 if (pst
.path
!= NULL
) {
1271 gtk_tree_view_set_cursor (state
->view
, pst
.path
, NULL
, FALSE
);
1272 gtk_tree_view_expand_row (state
->view
, pst
.path
, TRUE
);
1273 gtk_tree_path_free (pst
.path
);
1278 cb_dialog_pref_selection_changed (GtkTreeSelection
*selection
,
1284 if (gtk_tree_selection_get_selected (selection
, NULL
, &iter
)) {
1285 gtk_tree_model_get (GTK_TREE_MODEL (state
->store
), &iter
,
1288 gtk_notebook_set_current_page (state
->notebook
, page
);
1290 dialog_pref_select_page (state
, 0);
1295 cb_preferences_destroy (PrefState
*state
)
1298 g_object_unref (state
->store
);
1299 state
->store
= NULL
;
1301 if (state
->gui
!= NULL
) {
1302 g_object_unref (state
->gui
);
1305 if (state
->app_wb_removed_sig
) {
1306 g_signal_handler_disconnect (gnm_app_get_app (),
1307 state
->app_wb_removed_sig
);
1308 state
->app_wb_removed_sig
= 0;
1310 g_object_set_data (gnm_app_get_app (), PREF_DIALOG_KEY
, NULL
);
1314 cb_close_clicked (PrefState
*state
)
1316 gtk_widget_destroy (GTK_WIDGET (state
->dialog
));
1320 cb_workbook_removed (PrefState
*state
)
1322 if (gnm_app_workbook_list () == NULL
)
1323 cb_close_clicked (state
);
1327 dialog_preferences (WBCGtk
*wbcg
, gchar
const *page
)
1333 GtkTreeViewColumn
*column
;
1334 GtkTreeSelection
*selection
;
1336 w
= g_object_get_data (gnm_app_get_app (), PREF_DIALOG_KEY
);
1338 gtk_widget_show (w
);
1339 gdk_window_raise (gtk_widget_get_window (w
));
1343 gui
= gnm_gtk_builder_load ("res:ui/preferences.ui", NULL
, GO_CMD_CONTEXT (wbcg
));
1347 state
= g_new0 (PrefState
, 1);
1349 state
->dialog
= go_gtk_builder_get_widget (gui
, "preferences");
1350 state
->notebook
= (GtkNotebook
*)go_gtk_builder_get_widget (gui
, "notebook");
1352 state
->view
= GTK_TREE_VIEW(go_gtk_builder_get_widget (gui
, "itemlist"));
1353 state
->store
= gtk_tree_store_new (NUM_COLUMNS
,
1357 gtk_tree_view_set_model (state
->view
, GTK_TREE_MODEL(state
->store
));
1358 selection
= gtk_tree_view_get_selection (state
->view
);
1359 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_BROWSE
);
1360 column
= gtk_tree_view_column_new_with_attributes ("",
1361 gtk_cell_renderer_pixbuf_new (),
1362 "pixbuf", ITEM_ICON
,
1364 gtk_tree_view_append_column (state
->view
, column
);
1365 column
= gtk_tree_view_column_new_with_attributes ("",
1366 gtk_cell_renderer_text_new (),
1369 gtk_tree_view_append_column (state
->view
, column
);
1370 gtk_tree_view_set_expander_column (state
->view
, column
);
1372 g_signal_connect (selection
,
1374 G_CALLBACK (cb_dialog_pref_selection_changed
), state
);
1376 g_signal_connect_swapped (G_OBJECT (go_gtk_builder_get_widget (gui
, "close_button")),
1378 G_CALLBACK (cb_close_clicked
), state
);
1380 gnm_init_help_button (
1381 go_gtk_builder_get_widget (state
->gui
, "help_button"),
1382 GNUMERIC_HELP_LINK_PREFERENCES
);
1383 g_signal_connect_swapped (G_OBJECT (state
->dialog
),
1385 G_CALLBACK(cb_preferences_destroy
),
1387 g_object_set_data_full (G_OBJECT (state
->dialog
),
1389 (GDestroyNotify
)g_free
);
1391 g_object_set_data (gnm_app_get_app (), PREF_DIALOG_KEY
, state
->dialog
);
1393 state
->app_wb_removed_sig
=
1394 g_signal_connect_swapped (gnm_app_get_app (),
1396 G_CALLBACK (cb_workbook_removed
),
1399 for (i
= 0; page_info
[i
].page_initializer
; i
++) {
1400 const page_info_t
*this_page
= &page_info
[i
];
1401 GtkWidget
*page_widget
=
1402 this_page
->page_initializer (state
, NULL
,
1403 state
->notebook
, i
);
1404 gtk_notebook_append_page (state
->notebook
, page_widget
, NULL
);
1405 dialog_pref_add_item (state
, this_page
->page_name
,
1406 this_page
->icon_name
, i
,
1407 this_page
->parent_path
);
1410 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (state
->store
),
1411 ITEM_NAME
, GTK_SORT_ASCENDING
);
1413 go_gtk_nonmodal_dialog (wbcg_toplevel (wbcg
),
1414 GTK_WINDOW (state
->dialog
));
1415 gtk_widget_show (GTK_WIDGET (state
->dialog
));
1417 dialog_pref_select_page (state
, page
);