4 * ROX-Filer, filer for the ROX desktop project
5 * By Thomas Leonard, <tal197@ecs.soton.ac.uk>.
8 /* options.c - code for handling user choices */
16 #include "gui_support.h"
20 /* Add OptionsSection structs to this list in your _init() functions */
21 GSList
*options_sections
= NULL
;
23 static GtkWidget
*window
, *sections_vbox
;
24 static FILE *save_file
= NULL
;
25 static GHashTable
*option_hash
= NULL
;
27 /* Static prototypes */
28 static void save_options(GtkWidget
*widget
, gpointer data
);
29 static char *process_option_line(char *line
);
33 GtkWidget
*tl_vbox
, *scrolled_area
;
34 GtkWidget
*border
, *label
;
35 GtkWidget
*actions
, *button
;
36 char *string
, *save_path
;
38 window
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
39 gtk_window_set_title(GTK_WINDOW(window
), "ROX-Filer options");
40 gtk_signal_connect(GTK_OBJECT(window
), "delete_event",
41 GTK_SIGNAL_FUNC(hide_dialog_event
), window
);
42 gtk_container_set_border_width(GTK_CONTAINER(window
), 4);
43 gtk_window_set_default_size(GTK_WINDOW(window
), 400, 400);
45 tl_vbox
= gtk_vbox_new(FALSE
, 4);
46 gtk_container_add(GTK_CONTAINER(window
), tl_vbox
);
48 scrolled_area
= gtk_scrolled_window_new(NULL
, NULL
);
49 gtk_container_set_border_width(GTK_CONTAINER(scrolled_area
), 4);
50 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_area
),
51 GTK_POLICY_NEVER
, GTK_POLICY_ALWAYS
);
52 gtk_box_pack_start(GTK_BOX(tl_vbox
), scrolled_area
, TRUE
, TRUE
, 0);
54 border
= gtk_frame_new(NULL
);
55 gtk_frame_set_shadow_type(GTK_FRAME(border
), GTK_SHADOW_NONE
);
56 gtk_container_set_border_width(GTK_CONTAINER(border
), 4);
57 gtk_scrolled_window_add_with_viewport(
58 GTK_SCROLLED_WINDOW(scrolled_area
), border
);
60 sections_vbox
= gtk_vbox_new(FALSE
, 4);
61 gtk_container_add(GTK_CONTAINER(border
), sections_vbox
);
63 save_path
= choices_find_path_save("...");
66 string
= g_strconcat("Choices will be saved as ",
69 label
= gtk_label_new(string
);
73 label
= gtk_label_new("Choices saving is disabled by "
74 "CHOICESPATH variable");
75 gtk_box_pack_start(GTK_BOX(tl_vbox
), label
, FALSE
, TRUE
, 0);
77 actions
= gtk_hbox_new(TRUE
, 16);
78 gtk_box_pack_start(GTK_BOX(tl_vbox
), actions
, FALSE
, TRUE
, 0);
80 button
= gtk_button_new_with_label("Save");
81 gtk_box_pack_start(GTK_BOX(actions
), button
, FALSE
, TRUE
, 0);
83 gtk_widget_set_sensitive(button
, FALSE
);
84 gtk_signal_connect(GTK_OBJECT(button
), "clicked",
85 GTK_SIGNAL_FUNC(save_options
), (gpointer
) TRUE
);
87 button
= gtk_button_new_with_label("OK");
88 gtk_box_pack_start(GTK_BOX(actions
), button
, FALSE
, TRUE
, 0);
89 gtk_signal_connect(GTK_OBJECT(button
), "clicked",
90 GTK_SIGNAL_FUNC(save_options
), (gpointer
) FALSE
);
92 button
= gtk_button_new_with_label("Cancel");
93 gtk_box_pack_start(GTK_BOX(actions
), button
, FALSE
, TRUE
, 0);
94 gtk_signal_connect_object(GTK_OBJECT(button
), "clicked",
95 GTK_SIGNAL_FUNC(gtk_widget_hide
), GTK_OBJECT(window
));
98 void options_load(void)
100 static gboolean need_init
= TRUE
;
106 GSList
*next
= options_sections
;
110 OptionsSection
*section
= (OptionsSection
*) next
->data
;
112 group
= gtk_frame_new(section
->name
);
113 gtk_box_pack_start(GTK_BOX(sections_vbox
), group
,
115 gtk_container_add(GTK_CONTAINER(group
),
123 path
= choices_find_path_load("options");
125 return; /* Nothing to load */
127 parse_file(path
, process_option_line
);
130 void parse_file(char *path
, ParseFunc
*parse_line
)
135 if (load_file(path
, &data
, &length
))
141 while (line
&& *line
)
143 eol
= strchr(line
, '\n');
147 error
= parse_line(line
);
153 message
= g_string_new(NULL
);
154 g_string_sprintf(message
,
155 "Error in options file at "
156 "line %d: %s", line_number
,
158 delayed_error("ROX-Filer", message
->str
);
159 g_string_free(message
, TRUE
);
172 /* Call this on init to register a handler for a key.
173 * The function returns a pointer to an error messages (which will
174 * NOT be free()d, or NULL on success.
176 void option_register(char *key
, OptionFunc
*func
)
179 option_hash
= g_hash_table_new(g_str_hash
, g_str_equal
);
180 g_hash_table_insert(option_hash
, key
, func
);
183 /* Process one line from the options file (\0 term'd).
184 * Returns NULL on success, or a pointer to an error message.
185 * The line is modified.
187 static char *process_option_line(char *line
)
192 g_return_val_if_fail(option_hash
!= NULL
, "No registered functions!");
194 eq
= strchr(line
, '=');
196 return "Missing '='";
199 while (c
> line
&& (*c
== ' ' || *c
== '\t'))
203 while (*c
== ' ' || *c
== '\t')
206 func
= (OptionFunc
*) g_hash_table_lookup(option_hash
, line
);
208 return "Bad key (no such option name)";
213 static void save_options(GtkWidget
*widget
, gpointer data
)
215 gboolean save
= (gboolean
) data
;
216 GSList
*next
= options_sections
;
220 OptionsSection
*section
= (OptionsSection
*) next
->data
;
229 path
= choices_find_path_save("options");
230 g_return_if_fail(path
!= NULL
);
232 save_file
= fopen(path
, "wb");
236 str
= g_strconcat("Unable to open '", path
,
240 report_error("ROX-Filer", str
);
245 next
= options_sections
;
248 OptionsSection
*section
= (OptionsSection
*) next
->data
;
253 if (save_file
&& fclose(save_file
) == EOF
)
255 report_error("ROX-Filer", g_strerror(errno
));
260 gtk_widget_hide(window
);
263 void options_show(FilerWindow
*filer_window
)
265 GSList
*next
= options_sections
;
267 if (GTK_WIDGET_MAPPED(window
))
268 gtk_widget_hide(window
);
272 OptionsSection
*section
= (OptionsSection
*) next
->data
;
277 gtk_widget_show_all(window
);
280 void option_write(char *name
, char *value
)
286 return; /* Error already reported hopefully */
288 string
= g_strconcat(name
, " = ", value
, "\n", NULL
);
289 len
= strlen(string
);
290 if (fwrite(string
, sizeof(char), len
, save_file
) < len
)
292 delayed_error("Saving options", g_strerror(errno
));