Fix build by #if 0 out unused de_sgsap_tmsi() function.
[obnox/wireshark/wip.git] / gtk / prefs_gui.c
1 /* gui_prefs.c
2  * Dialog box for GUI preferences
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
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.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 #include <string.h>
29
30 #include <gtk/gtk.h>
31
32 #include <epan/prefs.h>
33
34 #include "../simple_dialog.h"
35
36 #include "gtk/prefs_gui.h"
37 #include "gtk/gtkglobals.h"
38 #include "gtk/help_dlg.h"
39 #include "gtk/supported_protos_dlg.h"
40 #include "gtk/prefs_dlg.h"
41 #include "gtk/gui_utils.h"
42 #include "gtk/dlg_utils.h"
43 #include "gtk/main.h"
44 #ifdef NEW_PACKET_LIST
45 #include "gtk/new_packet_list.h"
46 #else
47 #include "gtk/main_packet_list.h"
48 #endif
49 #include "gtk/main_proto_draw.h"
50 #include "gtk/main_toolbar.h"
51 #include "gtk/font_utils.h"
52 #include "gtk/recent.h"
53 #include "gtk/webbrowser.h"
54 #include "gtk/main_welcome.h"
55
56
57 static gint fetch_enum_value(gpointer control, const enum_val_t *enumvals);
58 static gboolean fileopen_dir_changed_cb(GtkWidget *myentry _U_, GdkEvent *event, gpointer parent_w);
59 static gboolean fileopen_preview_changed_cb(GtkWidget *myentry _U_, GdkEvent *event, gpointer parent_w);
60 static void fileopen_selected_cb(GtkWidget *mybutton_rb _U_, gpointer parent_w);
61 static gboolean recent_files_count_changed_cb(GtkWidget *recent_files_entry _U_,
62                                               GdkEvent *event _U_, gpointer parent_w);
63 static gboolean recent_df_entries_changed_cb(GtkWidget *recent_df_entry _U_,
64                                              GdkEvent *event _U_, gpointer parent_w);
65 #define PLIST_SEL_BROWSE_KEY            "plist_sel_browse"
66 #define PTREE_SEL_BROWSE_KEY            "ptree_sel_browse"
67 #define GEOMETRY_POSITION_KEY           "geometry_position"
68 #define GEOMETRY_SIZE_KEY               "geometry_size"
69 #define GEOMETRY_MAXIMIZED_KEY          "geometry_maximized"
70
71 #define MACOSX_STYLE_KEY                "macosx_style"
72
73 #define GUI_CONSOLE_OPEN_KEY            "console_open"
74 #define GUI_FILEOPEN_KEY                "fileopen_behavior"
75 #define GUI_FILEOPEN_PREVIEW_KEY        "fileopen_preview_timeout"
76 #define GUI_RECENT_FILES_COUNT_KEY      "recent_files_count"
77 #define GUI_RECENT_DF_ENTRIES_KEY       "recent_display_filter_entries"
78 #define GUI_FILEOPEN_DIR_KEY            "fileopen_directory"
79 #define GUI_ASK_UNSAVED_KEY             "ask_unsaved"
80 #define GUI_WEBBROWSER_KEY              "webbrowser"
81 #define GUI_FIND_WRAP_KEY               "find_wrap"
82 #define GUI_USE_PREF_SAVE_KEY           "use_pref_save"
83 #define GUI_SHOW_VERSION_KEY            "show_version"
84
85 static const enum_val_t scrollbar_placement_vals[] _U_ = {
86         { "FALSE", "Left", FALSE },
87         { "TRUE",  "Right", TRUE },
88         { NULL,    NULL,    0 }
89 };
90
91 static const enum_val_t selection_mode_vals[] = {
92         { "FALSE", "Selects", FALSE },
93         { "TRUE",  "Browses", TRUE },
94         { NULL,    NULL,      0 }
95 };
96
97 static const enum_val_t altern_colors_vals[] _U_ = {
98         { "FALSE", "No",  FALSE },
99         { "TRUE",  "Yes", TRUE },
100         { NULL,    NULL,  0 }
101 };
102
103 static const enum_val_t filter_toolbar_placement_vals[] _U_ = {
104         { "FALSE", "Below the main toolbar", FALSE },
105         { "TRUE",  "Insert into statusbar",  TRUE },
106         { NULL,    NULL,                     0 }
107 };
108
109 static const enum_val_t highlight_style_vals[] _U_ = {
110         { "FALSE", "Bold",     FALSE },
111         { "TRUE",  "Inverse",  TRUE },
112         { NULL,    NULL,       0 }
113 };
114
115
116 static const enum_val_t toolbar_style_vals[] _U_ = {
117         { "ICONS", "Icons only",     TB_STYLE_ICONS },
118         { "TEXT",  "Text only",      TB_STYLE_TEXT },
119         { "BOTH",  "Icons & Text",   TB_STYLE_BOTH },
120         { NULL,    NULL,             0 }
121 };
122
123 #ifdef _WIN32
124 static const enum_val_t gui_console_open_vals[] = {
125         { "NEVER",     "Never",                      console_open_never },
126         { "AUTOMATIC", "Automatic (advanced user)",  console_open_auto },
127         { "ALWAYS",    "Always (debugging)",         console_open_always },
128         { NULL,        NULL,                         0 }
129 };
130 #endif
131
132 static const enum_val_t gui_fileopen_vals[] = {
133         { "LAST_OPENED", "Remember last directory", FO_STYLE_LAST_OPENED },
134         { "SPECIFIED",   "Always start in:",        FO_STYLE_SPECIFIED },
135         { NULL,          NULL,                      0 }
136 };
137
138 /* Set to FALSE initially; set to TRUE if the user ever hits "OK" on
139    the "Font..." dialog, so that we know that they (probably) changed
140    the font, and therefore that the "apply" function needs to take care
141    of that */
142 static gboolean font_changed;
143
144 /* Font name from the font dialog box; if "font_changed" is TRUE, this
145    has been set to the name of the font the user selected. */
146 static gchar *new_font_name;
147
148 static GtkWidget *font_browse_w;
149
150 /* Used to contain the string from the Recent Files Count Max pref item */
151 static char recent_files_count_max_str[128] = "";
152
153 /* Used to contain the string from the Recent Display Filter Max Entries pref item */
154 static char recent_df_entries_max_str[128] = "";
155
156 /* Used to contain the string from the Open File preview timeout pref item */
157 static char open_file_preview_str[128] = "";
158
159 #define GUI_TABLE_ROWS 4
160
161 GtkWidget*
162 gui_prefs_show(void)
163 {
164         GtkWidget *main_tb, *main_vb;
165         GtkWidget *plist_browse_om;
166         GtkWidget *ptree_browse_om;
167 #ifdef _WIN32
168         GtkWidget *console_open_om;
169 #endif
170         GtkWidget *fileopen_rb, *fileopen_dir_te, *fileopen_preview_te;
171         GtkWidget *recent_files_count_max_te, *recent_df_entries_max_te, *ask_unsaved_cb, *find_wrap_cb;
172         GtkWidget *use_pref_save_cb;
173         GtkWidget *show_version_cb;
174         GtkWidget *webbrowser_te;
175         GtkWidget *save_position_cb, *save_size_cb, *save_maximized_cb;
176 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
177         GtkWidget *macosx_style_cb;
178 #endif
179
180         GtkTooltips *tooltips = gtk_tooltips_new();
181
182         int        pos = 0;
183         char       current_val_str[128];
184
185         /* The font haven't been changed yet. */
186         font_changed = FALSE;
187
188         /* The columns haven't been changed yet */
189         cfile.cinfo.columns_changed = FALSE;
190
191         /* Main vertical box */
192         main_vb = gtk_vbox_new(FALSE, 7);
193         gtk_container_set_border_width( GTK_CONTAINER(main_vb), 5 );
194
195         /* Main table */
196         main_tb = gtk_table_new(GUI_TABLE_ROWS, 2, FALSE);
197         gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
198         gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
199         gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
200         g_object_set_data(G_OBJECT(main_tb), E_TOOLTIPS_KEY, tooltips);
201
202         /* Packet list selection browseable */
203         plist_browse_om = create_preference_option_menu(main_tb, pos++,
204             "Packet list selection mode:",
205             "Choose to browse or select a packet for detailed dissection.",
206             selection_mode_vals, prefs.gui_plist_sel_browse);
207         g_object_set_data(G_OBJECT(main_vb), PLIST_SEL_BROWSE_KEY, plist_browse_om);
208
209         /* Proto tree selection browseable */
210         ptree_browse_om = create_preference_option_menu(main_tb, pos++,
211             "Protocol tree selection mode:",
212             "Choose to browse or select.",
213             selection_mode_vals, prefs.gui_ptree_sel_browse);
214         g_object_set_data(G_OBJECT(main_vb), PTREE_SEL_BROWSE_KEY, ptree_browse_om);
215
216         /* Geometry prefs */
217         save_position_cb = create_preference_check_button(main_tb, pos++,
218             "Save window position:",
219             "Whether to save the position of the main window.",
220             prefs.gui_geometry_save_position);
221         g_object_set_data(G_OBJECT(main_vb), GEOMETRY_POSITION_KEY, save_position_cb);
222
223         save_size_cb = create_preference_check_button(main_tb, pos++,
224             "Save window size:",
225             "Whether to save the size of the main window.",
226             prefs.gui_geometry_save_size);
227         g_object_set_data(G_OBJECT(main_vb), GEOMETRY_SIZE_KEY, save_size_cb);
228
229         save_maximized_cb = create_preference_check_button(main_tb, pos++,
230             "Save maximized state:",
231             "Whether to save the maximized state of the main window.",
232             prefs.gui_geometry_save_maximized);
233         g_object_set_data(G_OBJECT(main_vb), GEOMETRY_MAXIMIZED_KEY, save_maximized_cb);
234
235 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
236         macosx_style_cb = create_preference_check_button(main_tb, pos++,
237             "Mac OS X style",
238             "Whether to create a Mac OS X look and feel. Checking this box will move the "
239             "menu bar to the top of the screen instead of the top of the Wireshark window. "
240             "Requires a restart of Wireshark to take effect.",
241             prefs.gui_macosx_style);
242         g_object_set_data(G_OBJECT(main_vb), MACOSX_STYLE_KEY, macosx_style_cb);
243 #endif
244
245 #ifdef _WIN32
246         /* How the console window should be opened */
247         console_open_om = create_preference_option_menu(main_tb, pos++,
248             "Open a console window",
249             "Whether to open a console window "
250             "(Automatic will open a console if messages appear).",
251             gui_console_open_vals, prefs.gui_console_open);
252         g_object_set_data(G_OBJECT(main_vb), GUI_CONSOLE_OPEN_KEY, console_open_om);
253 #endif
254
255         /* Allow user to select where they want the File Open dialog to open to
256          * by default */
257         fileopen_rb = create_preference_radio_buttons(main_tb, pos++,
258             "\"File Open\" dialog behavior:",
259             "Which directory the \"File Open\" dialog should start with.",
260             gui_fileopen_vals, prefs.gui_fileopen_style);
261
262         /* Directory to default File Open dialog to */
263         fileopen_dir_te = create_preference_entry(main_tb, pos++,
264             "Directory:",
265             "The \"File Open\" dialog defaults always to this directory.",
266             prefs.gui_fileopen_dir);
267         g_object_set_data(G_OBJECT(main_vb), GUI_FILEOPEN_KEY, fileopen_rb);
268         g_object_set_data(G_OBJECT(main_vb), GUI_FILEOPEN_DIR_KEY, fileopen_dir_te);
269         g_signal_connect(fileopen_rb, "clicked", G_CALLBACK(fileopen_selected_cb), main_vb);
270         g_signal_connect(fileopen_dir_te, "focus-out-event",
271             G_CALLBACK(fileopen_dir_changed_cb), main_vb);
272
273         /* File Open dialog preview timeout */
274         fileopen_preview_te = create_preference_entry(main_tb, pos++,
275             "\"File Open\" preview timeout:",
276             "Reading preview data in the \"File Open\" dialog will be stopped after given seconds.",
277             open_file_preview_str);
278         g_snprintf(current_val_str, sizeof(current_val_str), "%d", prefs.gui_fileopen_preview);
279         gtk_entry_set_text(GTK_ENTRY(fileopen_preview_te), current_val_str);
280         g_object_set_data(G_OBJECT(main_vb), GUI_FILEOPEN_PREVIEW_KEY, fileopen_preview_te);
281         g_signal_connect(fileopen_preview_te, "focus_out_event", G_CALLBACK(fileopen_preview_changed_cb), main_vb);
282
283         /* Number of recent entries in the display filter list ... */
284         recent_df_entries_max_te = create_preference_entry(main_tb, pos++,
285             "Filter display max. list entries:",
286             "Maximum number of recent entries in filter display list.",
287             recent_df_entries_max_str);
288         g_snprintf(current_val_str, sizeof(current_val_str), "%d", prefs.gui_recent_df_entries_max);
289         gtk_entry_set_text(GTK_ENTRY(recent_df_entries_max_te), current_val_str);
290         g_object_set_data(G_OBJECT(main_vb), GUI_RECENT_DF_ENTRIES_KEY, recent_df_entries_max_te);
291         g_signal_connect(recent_df_entries_max_te, "focus_out_event", G_CALLBACK(recent_df_entries_changed_cb), main_vb);
292
293         /* Number of entries in the recent_files list ... */
294         recent_files_count_max_te = create_preference_entry(main_tb, pos++,
295             "\"Open Recent\" max. list entries:",
296             "Maximum number of entries in the \"File/Open Recent\" list.",
297             recent_files_count_max_str);
298         g_snprintf(current_val_str, sizeof(current_val_str), "%d", prefs.gui_recent_files_count_max);
299         gtk_entry_set_text(GTK_ENTRY(recent_files_count_max_te), current_val_str);
300         g_object_set_data(G_OBJECT(main_vb), GUI_RECENT_FILES_COUNT_KEY, recent_files_count_max_te);
301         g_signal_connect(recent_files_count_max_te, "focus_out_event", G_CALLBACK(recent_files_count_changed_cb), main_vb);
302
303         fileopen_selected_cb(NULL, main_vb);
304
305         /* ask for unsaved capture files? */
306         ask_unsaved_cb = create_preference_check_button(main_tb, pos++,
307             "Ask for unsaved capture files:",
308             "Whether a dialog should pop up in case of an unsaved capture file.",
309             prefs.gui_ask_unsaved);
310         g_object_set_data(G_OBJECT(main_vb), GUI_ASK_UNSAVED_KEY, ask_unsaved_cb);
311
312         /* do we want to wrap when searching for data? */
313         find_wrap_cb = create_preference_check_button(main_tb, pos++,
314             "Wrap to end/beginning of file during a find:",
315             "Whether a search should wrap in a capture file.",
316             prefs.gui_find_wrap);
317         g_object_set_data(G_OBJECT(main_vb), GUI_FIND_WRAP_KEY, find_wrap_cb);
318
319         /* show an explicit Save button for settings dialogs (preferences and alike)? */
320         use_pref_save_cb = create_preference_check_button(main_tb, pos++,
321             "Settings dialogs show a save button:",
322             "Whether the various settings dialogs (e.g. Preferences) should "
323             "use an explicit save button - for advanced users.",
324             prefs.gui_use_pref_save);
325         g_object_set_data(G_OBJECT(main_vb), GUI_USE_PREF_SAVE_KEY, use_pref_save_cb);
326
327         /* Show version in welcome screen */
328         show_version_cb = create_preference_check_button(main_tb, pos++,
329             "Welcome screen and title bar shows version:",
330             "Whether version should be shown in the start page and main screen's title bar.",
331             prefs.gui_version_in_start_page );
332         g_object_set_data(G_OBJECT(main_vb), GUI_SHOW_VERSION_KEY, show_version_cb);
333
334         /* Webbrowser */
335         if (browser_needs_pref()) {
336             webbrowser_te = create_preference_entry(main_tb, pos++,
337                 "Web browser command:",
338                 "Command line to desired browser.",
339                 prefs.gui_webbrowser);
340             gtk_entry_set_text(GTK_ENTRY(webbrowser_te), prefs.gui_webbrowser);
341             g_object_set_data(G_OBJECT(main_vb), GUI_WEBBROWSER_KEY, webbrowser_te);
342         }
343
344         /* Show 'em what we got */
345         gtk_widget_show_all(main_vb);
346
347         return(main_vb);
348 }
349
350
351 /* Create a font widget for browsing. */
352 GtkWidget *
353 gui_font_prefs_show(void)
354 {
355         /* Create the font selection widget. */
356         font_browse_w = (GtkWidget *) gtk_font_selection_new();
357         gtk_widget_show(font_browse_w);
358
359         return font_browse_w;
360 }
361
362
363 static gboolean
364 font_fetch(void)
365 {
366         gchar   *font_name;
367
368         font_name = g_strdup(gtk_font_selection_get_font_name(
369               GTK_FONT_SELECTION(font_browse_w)));
370         if (font_name == NULL) {
371                 /* No font was selected; let the user know, but don't
372                    tear down the font selection dialog, so they can
373                    try again. */
374                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
375                    "You have not selected a font.");
376                 return FALSE;
377         }
378
379         if (!user_font_test(font_name)) {
380                 /* The font isn't usable; "user_font_test()" has already
381                    told the user why.  Don't tear down the font selection
382                    dialog. */
383                 g_free(font_name);
384                 return FALSE;
385         }
386         new_font_name = font_name;
387         return TRUE;
388 }
389
390
391 static gint
392 fetch_enum_value(gpointer control, const enum_val_t *enumvals)
393 {
394         return fetch_preference_option_menu_val(GTK_WIDGET(control), enumvals);
395 }
396
397 void
398 gui_prefs_fetch(GtkWidget *w)
399 {
400         prefs.gui_plist_sel_browse = fetch_enum_value(
401             g_object_get_data(G_OBJECT(w), PLIST_SEL_BROWSE_KEY), selection_mode_vals);
402         prefs.gui_ptree_sel_browse = fetch_enum_value(
403             g_object_get_data(G_OBJECT(w), PTREE_SEL_BROWSE_KEY), selection_mode_vals);
404         prefs.gui_geometry_save_position =
405             gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), GEOMETRY_POSITION_KEY));
406         prefs.gui_geometry_save_size =
407             gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), GEOMETRY_SIZE_KEY));
408         prefs.gui_geometry_save_maximized =
409             gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), GEOMETRY_MAXIMIZED_KEY));
410
411 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
412         prefs.gui_macosx_style =
413             gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), MACOSX_STYLE_KEY));
414 #endif
415
416 #ifdef _WIN32
417         prefs.gui_console_open = fetch_enum_value(
418             g_object_get_data(G_OBJECT(w), GUI_CONSOLE_OPEN_KEY), gui_console_open_vals);
419 #endif
420         prefs.gui_fileopen_style = fetch_preference_radio_buttons_val(
421             g_object_get_data(G_OBJECT(w), GUI_FILEOPEN_KEY), gui_fileopen_vals);
422
423         g_free(prefs.gui_fileopen_dir);
424         prefs.gui_fileopen_dir = g_strdup(gtk_entry_get_text(
425                                               GTK_ENTRY(g_object_get_data(G_OBJECT(w), GUI_FILEOPEN_DIR_KEY))));
426
427         prefs.gui_ask_unsaved =
428                 gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), GUI_ASK_UNSAVED_KEY));
429
430         prefs.gui_find_wrap =
431                 gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), GUI_FIND_WRAP_KEY));
432
433         prefs.gui_use_pref_save =
434                 gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), GUI_USE_PREF_SAVE_KEY));
435
436         prefs.gui_version_in_start_page  =
437                 gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), GUI_SHOW_VERSION_KEY));
438
439         if (browser_needs_pref()) {
440                 g_free(prefs.gui_webbrowser);
441                 prefs.gui_webbrowser = g_strdup(gtk_entry_get_text(
442                                                         GTK_ENTRY(g_object_get_data(G_OBJECT(w), GUI_WEBBROWSER_KEY))));
443         }
444         /*
445          * XXX - we need to have a way to fetch the preferences into
446          * local storage and only set the permanent preferences if there
447          * weren't any errors in those fetches, as there are several
448          * places where there *can* be a bad preference value.
449          */
450         if (font_fetch()) {
451                 if (strcmp(new_font_name, prefs.gui_font_name) != 0) {
452                         font_changed = TRUE;
453                         g_free(prefs.gui_font_name);
454                         prefs.gui_font_name = g_strdup(new_font_name);
455                 }
456         }
457 }
458
459
460
461 void
462 gui_prefs_apply(GtkWidget *w _U_ , gboolean redissect)
463 {
464
465 #ifdef _WIN32
466         /* user immediately wants to see a console */
467         if (prefs.gui_console_open == console_open_always) {
468                 create_console();
469         }
470 #endif
471
472         if (font_changed) {
473                 /* This redraws the packet bytes windows. */
474                 switch (user_font_apply()) {
475
476                 case FA_SUCCESS:
477                         break;
478
479                 case FA_FONT_NOT_RESIZEABLE:
480                         /* "user_font_apply()" popped up an alert box. */
481                         /* turn off zooming - font can't be resized */
482                         recent.gui_zoom_level = 0;
483                         break;
484
485                 case FA_FONT_NOT_AVAILABLE:
486                         /* We assume this means that the specified size
487                            isn't available. */
488                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
489                             "That font isn't available at the specified zoom level;\n"
490                             "turning zooming off.");
491                         recent.gui_zoom_level = 0;
492                         break;
493                 }
494         } else if (!redissect) {
495                 /* Redraw the packet bytes windows, in case the
496                    highlight style changed, only if we aren't redissecting the whole file.
497                    XXX - do it only if the highlight style *did* change. */
498                 redraw_packet_bytes_all();
499         }
500
501         /* Redisplay the main window's title */
502         update_main_window_title();
503
504         /* Redisplay the default welcome header message in case the "show 
505          * version" option was changed. */
506         welcome_header_set_message(NULL);
507
508         /* Redraw the help window(s). */
509         supported_redraw();
510         help_redraw();
511
512         /* XXX: redraw the toolbar only, if style changed */
513         toolbar_redraw_all();
514
515         set_scrollbar_placement_all();
516 #ifdef NEW_PACKET_LIST
517         new_packet_list_set_sel_browse(prefs.gui_plist_sel_browse, FALSE);
518 #else
519         packet_list_set_sel_browse(prefs.gui_plist_sel_browse, FALSE);
520 #endif
521         set_ptree_sel_browse_all(prefs.gui_ptree_sel_browse);
522         set_tree_styles_all();
523         main_widgets_rearrange();
524 }
525
526 void
527 gui_prefs_destroy(GtkWidget *w _U_)
528 {
529         /* Free up any saved font name. */
530         if (new_font_name != NULL) {
531                 g_free(new_font_name);
532                 new_font_name = NULL;
533         }
534 }
535
536 static gboolean
537 recent_df_entries_changed_cb(GtkWidget *recent_df_entry _U_,
538                               GdkEvent *event _U_, gpointer parent_w)
539 {
540         GtkWidget       *recent_df_entries_count_te;
541         guint newval;
542
543         recent_df_entries_count_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_RECENT_DF_ENTRIES_KEY);
544
545         /*
546          * Now, just convert the string to a number and store it in the prefs
547          * filed ...
548          */
549
550         newval = strtol(gtk_entry_get_text (GTK_ENTRY(recent_df_entries_count_te)), NULL, 10);
551
552         if (newval > 0) {
553                 prefs.gui_recent_df_entries_max = newval;
554         }
555
556         /* We really should pop up a nasty dialog box if newval <= 0 */
557
558         return FALSE;
559 }
560
561 static gboolean
562 recent_files_count_changed_cb(GtkWidget *recent_files_entry _U_,
563                               GdkEvent *event _U_, gpointer parent_w)
564 {
565         GtkWidget       *recent_files_count_te;
566         guint newval;
567
568         recent_files_count_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_RECENT_FILES_COUNT_KEY);
569
570         /*
571          * Now, just convert the string to a number and store it in the prefs
572          * filed ...
573          */
574
575         newval = strtol(gtk_entry_get_text (GTK_ENTRY(recent_files_count_te)), NULL, 10);
576
577         if (newval > 0) {
578                 prefs.gui_recent_files_count_max = newval;
579         }
580
581         /* We really should pop up a nasty dialog box if newval <= 0 */
582
583         return FALSE;
584 }
585
586 static gboolean
587 fileopen_preview_changed_cb(GtkWidget *recent_files_entry _U_,
588                               GdkEvent *event _U_, gpointer parent_w)
589 {
590         GtkWidget       *fileopen_preview_te;
591         guint newval;
592
593         fileopen_preview_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_FILEOPEN_PREVIEW_KEY);
594
595         /*
596          * Now, just convert the string to a number and store it in the prefs
597          * filed ...
598          */
599
600         newval = strtol(gtk_entry_get_text (GTK_ENTRY(fileopen_preview_te)), NULL, 10);
601
602         if (newval > 0) {
603                 prefs.gui_fileopen_preview = newval;
604         }
605
606         /* We really should pop up a nasty dialog box if newval <= 0 */
607
608         return FALSE;
609 }
610
611 static gboolean
612 fileopen_dir_changed_cb(GtkWidget *fileopen_entry _U_, GdkEvent *event _U_, gpointer parent_w)
613 {
614         GtkWidget       *fileopen_dir_te;
615         char *lastchar;
616         gint fileopen_dir_te_length;
617
618         fileopen_dir_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_FILEOPEN_DIR_KEY);
619         fileopen_dir_te_length = (gint) strlen(gtk_entry_get_text (GTK_ENTRY(fileopen_entry)));
620         if (fileopen_dir_te_length == 0)
621                 return FALSE;
622         lastchar = gtk_editable_get_chars(GTK_EDITABLE(fileopen_entry), fileopen_dir_te_length-1, -1);
623         if (strcmp(lastchar, G_DIR_SEPARATOR_S) != 0){
624                 gtk_editable_insert_text(GTK_EDITABLE(fileopen_entry), G_DIR_SEPARATOR_S,
625             1, /* new_text_length */
626             &fileopen_dir_te_length); /* *position */
627         }
628         return FALSE;
629 }
630
631 static void
632 fileopen_selected_cb(GtkWidget *mybutton_rb _U_, gpointer parent_w)
633 {
634         GtkWidget       *fileopen_rb, *fileopen_dir_te;
635
636         fileopen_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_FILEOPEN_KEY);
637         fileopen_dir_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_FILEOPEN_DIR_KEY);
638
639         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fileopen_rb)))
640         {
641                 gtk_widget_set_sensitive(GTK_WIDGET(fileopen_dir_te), TRUE);
642         }
643         else
644         {
645                 gtk_widget_set_sensitive(GTK_WIDGET(fileopen_dir_te), FALSE);
646         }
647         return;
648 }
649