r345: Fixed a bug that prevented i18n from working.
[rox-filer/dt.git] / ROX-Filer / src / options.c
blobaf43cc1108aef38ab6c8368512692dff16f32d30
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2000, Thomas Leonard, <tal197@users.sourceforge.net>.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* options.c - code for handling user choices */
24 #include "config.h"
26 #include <stdio.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <gtk/gtk.h>
31 #include "global.h"
33 #include "gui_support.h"
34 #include "choices.h"
35 #include "options.h"
37 /* Add OptionsSection structs to this list in your _init() functions */
38 GSList *options_sections = NULL;
40 /* Add all option tooltips to this group */
41 GtkTooltips *option_tooltips = NULL;
43 static GtkWidget *window, *sections_vbox;
44 static FILE *save_file = NULL;
45 static GHashTable *option_hash = NULL;
47 enum {BUTTON_SAVE, BUTTON_OK, BUTTON_APPLY};
49 /* Static prototypes */
50 static void save_options(GtkWidget *widget, gpointer data);
51 static char *process_option_line(guchar *line);
53 void options_init()
55 GtkWidget *tl_vbox, *scrolled_area;
56 GtkWidget *border, *label;
57 GtkWidget *actions, *button;
58 char *string, *save_path;
60 option_tooltips = gtk_tooltips_new();
62 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
63 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
64 gtk_window_set_title(GTK_WINDOW(window), _("ROX-Filer options"));
65 gtk_signal_connect(GTK_OBJECT(window), "delete_event",
66 GTK_SIGNAL_FUNC(hide_dialog_event), window);
67 gtk_container_set_border_width(GTK_CONTAINER(window), 4);
68 gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
70 tl_vbox = gtk_vbox_new(FALSE, 4);
71 gtk_container_add(GTK_CONTAINER(window), tl_vbox);
73 scrolled_area = gtk_scrolled_window_new(NULL, NULL);
74 gtk_container_set_border_width(GTK_CONTAINER(scrolled_area), 4);
75 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_area),
76 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
77 gtk_box_pack_start(GTK_BOX(tl_vbox), scrolled_area, TRUE, TRUE, 0);
79 border = gtk_frame_new(NULL);
80 gtk_frame_set_shadow_type(GTK_FRAME(border), GTK_SHADOW_NONE);
81 gtk_container_set_border_width(GTK_CONTAINER(border), 4);
82 gtk_scrolled_window_add_with_viewport(
83 GTK_SCROLLED_WINDOW(scrolled_area), border);
85 sections_vbox = gtk_vbox_new(FALSE, 4);
86 gtk_container_add(GTK_CONTAINER(border), sections_vbox);
88 save_path = choices_find_path_save("...", PROJECT, FALSE);
89 if (save_path)
91 string = g_strconcat(_("Choices will be saved as "),
92 save_path,
93 NULL);
94 label = gtk_label_new(string);
95 g_free(string);
97 else
98 label = gtk_label_new(_("Choices saving is disabled by "
99 "CHOICESPATH variable"));
100 gtk_box_pack_start(GTK_BOX(tl_vbox), label, FALSE, TRUE, 0);
102 actions = gtk_hbox_new(TRUE, 16);
103 gtk_box_pack_start(GTK_BOX(tl_vbox), actions, FALSE, TRUE, 0);
105 button = gtk_button_new_with_label(_("Save"));
106 gtk_box_pack_start(GTK_BOX(actions), button, FALSE, TRUE, 0);
107 if (!save_path)
108 gtk_widget_set_sensitive(button, FALSE);
109 gtk_signal_connect(GTK_OBJECT(button), "clicked",
110 GTK_SIGNAL_FUNC(save_options), (gpointer) BUTTON_SAVE);
112 button = gtk_button_new_with_label(_("OK"));
113 gtk_box_pack_start(GTK_BOX(actions), button, FALSE, TRUE, 0);
114 gtk_signal_connect(GTK_OBJECT(button), "clicked",
115 GTK_SIGNAL_FUNC(save_options), (gpointer) BUTTON_OK);
117 button = gtk_button_new_with_label(_("Apply"));
118 gtk_box_pack_start(GTK_BOX(actions), button, FALSE, TRUE, 0);
119 gtk_signal_connect(GTK_OBJECT(button), "clicked",
120 GTK_SIGNAL_FUNC(save_options), (gpointer) BUTTON_APPLY);
122 button = gtk_button_new_with_label(_("Cancel"));
123 gtk_box_pack_start(GTK_BOX(actions), button, FALSE, TRUE, 0);
124 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
125 GTK_SIGNAL_FUNC(gtk_widget_hide), GTK_OBJECT(window));
128 void options_load(void)
130 static gboolean need_init = TRUE;
131 char *path;
133 if (need_init)
135 GtkWidget *group;
136 GSList *next = options_sections;
138 while (next)
140 OptionsSection *section = (OptionsSection *) next->data;
142 group = gtk_frame_new(_(section->name));
143 gtk_box_pack_start(GTK_BOX(sections_vbox), group,
144 FALSE, TRUE, 4);
145 gtk_container_add(GTK_CONTAINER(group),
146 section->create());
147 next = next->next;
150 need_init = FALSE;
153 path = choices_find_path_load("options", PROJECT);
154 if (!path)
155 return; /* Nothing to load */
157 parse_file(path, process_option_line);
161 /* Call this on init to register a handler for a key (thing before the = in
162 * the config file).
163 * The function returns a pointer to an error messages (which will
164 * NOT be free()d), or NULL on success.
166 void option_register(char *key, OptionFunc *func)
168 if (!option_hash)
169 option_hash = g_hash_table_new(g_str_hash, g_str_equal);
170 g_hash_table_insert(option_hash, key, func);
173 /* Process one line from the options file (\0 term'd).
174 * Returns NULL on success, or a pointer to an error message.
175 * The line is modified.
177 static char *process_option_line(guchar *line)
179 guchar *eq, *c;
180 OptionFunc *func;
182 g_return_val_if_fail(option_hash != NULL, "No registered functions!");
184 eq = strchr(line, '=');
185 if (!eq)
186 return _("Missing '='");
188 c = eq - 1;
189 while (c > line && (*c == ' ' || *c == '\t'))
190 c--;
191 c[1] = '\0';
192 c = eq + 1;
193 while (*c == ' ' || *c == '\t')
194 c++;
196 func = (OptionFunc *) g_hash_table_lookup(option_hash, line);
197 if (!func)
198 return _("Unknown option");
200 return func(c);
203 static void save_options(GtkWidget *widget, gpointer data)
205 int button = (int) data;
206 GSList *next = options_sections;
208 while (next)
210 OptionsSection *section = (OptionsSection *) next->data;
211 section->set();
212 next = next->next;
215 if (button == BUTTON_SAVE)
217 char *path;
219 path = choices_find_path_save("options", PROJECT, TRUE);
220 g_return_if_fail(path != NULL);
222 save_file = fopen(path, "wb");
223 if (!save_file)
225 char *str;
226 str = g_strdup_printf(
227 _("Unable to open '%s' for writing: %s"),
228 path, g_strerror(errno));
229 report_error(PROJECT, str);
230 g_free(str);
231 return;
234 next = options_sections;
235 while (next)
237 OptionsSection *section = (OptionsSection *) next->data;
238 section->save();
239 next = next->next;
242 if (save_file && fclose(save_file) == EOF)
244 report_error(PROJECT, g_strerror(errno));
245 return;
249 if (button != BUTTON_APPLY)
250 gtk_widget_hide(window);
253 void options_show(void)
255 GSList *next = options_sections;
257 if (GTK_WIDGET_MAPPED(window))
258 gtk_widget_hide(window);
260 while (next)
262 OptionsSection *section = (OptionsSection *) next->data;
263 section->update();
264 next = next->next;
267 gtk_widget_show_all(window);
270 void option_write(char *name, char *value)
272 char *string;
273 int len;
275 if (!save_file)
276 return; /* Error already reported hopefully */
278 string = g_strconcat(name, " = ", value, "\n", NULL);
279 len = strlen(string);
280 if (fwrite(string, sizeof(char), len, save_file) < len)
282 delayed_error(_("Saving options"), g_strerror(errno));
283 fclose(save_file);
284 save_file = NULL;
286 g_free(string);