21363284141ce1018ca6264809cd542db65747fb
[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 "../globals.h"
35 #include "../simple_dialog.h"
36
37 #include "gtk/prefs_gui.h"
38 #include "gtk/gtkglobals.h"
39 #include "gtk/help_dlg.h"
40 #include "gtk/supported_protos_dlg.h"
41 #include "gtk/prefs_dlg.h"
42 #include "gtk/gui_utils.h"
43 #include "gtk/dlg_utils.h"
44 #include "gtk/main.h"
45 #ifdef NEW_PACKET_LIST
46 #include "gtk/new_packet_list.h"
47 #else
48 #include "gtk/main_packet_list.h"
49 #endif
50 #include "gtk/main_proto_draw.h"
51 #include "gtk/main_toolbar.h"
52 #include "gtk/font_utils.h"
53 #include "gtk/recent.h"
54 #include "gtk/webbrowser.h"
55
56
57 static gint fetch_enum_value(gpointer control, const enum_val_t *enumvals);
58 static gint fileopen_dir_changed_cb(GtkWidget *myentry _U_, GdkEvent *event, gpointer parent_w);
59 static gint 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 gint recent_files_count_changed_cb(GtkWidget *recent_files_entry _U_, 
62                                           GdkEvent *event _U_, gpointer parent_w);
63 static gint 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 #ifdef HAVE_IGE_MAC_INTEGRATION
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 #ifdef HAVE_IGE_MAC_INTEGRATION
236         macosx_style_cb = create_preference_check_button(main_tb, pos++,
237             "MacOS X style", 
238             "Whether to create a MacOS 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 shows version:",
330             "Whether version should be shown in the start page or not.",
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 #ifdef HAVE_IGE_MAC_INTEGRATION
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         /* Redraw the help window(s). */
502         supported_redraw();
503         help_redraw();
504
505         /* XXX: redraw the toolbar only, if style changed */
506         toolbar_redraw_all();
507
508         set_scrollbar_placement_all();
509 #ifdef NEW_PACKET_LIST
510         new_packet_list_set_sel_browse(prefs.gui_plist_sel_browse, FALSE);
511 #else
512         packet_list_set_sel_browse(prefs.gui_plist_sel_browse, FALSE);
513 #endif
514         set_ptree_sel_browse_all(prefs.gui_ptree_sel_browse);
515         set_tree_styles_all();
516         main_widgets_rearrange();
517 }
518
519 void
520 gui_prefs_destroy(GtkWidget *w _U_)
521 {
522         /* Free up any saved font name. */
523         if (new_font_name != NULL) {
524                 g_free(new_font_name);
525                 new_font_name = NULL;
526         }
527 }
528
529 static gint
530 recent_df_entries_changed_cb(GtkWidget *recent_df_entry _U_,
531                               GdkEvent *event _U_, gpointer parent_w)
532 {
533         GtkWidget       *recent_df_entries_count_te;
534         guint newval;
535
536         recent_df_entries_count_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_RECENT_DF_ENTRIES_KEY);
537
538         /*
539          * Now, just convert the string to a number and store it in the prefs
540          * filed ...
541          */
542
543         newval = strtol(gtk_entry_get_text (GTK_ENTRY(recent_df_entries_count_te)), NULL, 10);
544
545         if (newval > 0) {
546                 prefs.gui_recent_df_entries_max = newval;
547         }
548
549         /* We really should pop up a nasty dialog box if newval <= 0 */
550
551         return FALSE;
552 }
553
554 static gint
555 recent_files_count_changed_cb(GtkWidget *recent_files_entry _U_, 
556                               GdkEvent *event _U_, gpointer parent_w)
557 {
558         GtkWidget       *recent_files_count_te;
559         guint newval;
560     
561         recent_files_count_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_RECENT_FILES_COUNT_KEY);
562
563         /*
564          * Now, just convert the string to a number and store it in the prefs
565          * filed ...
566          */
567
568         newval = strtol(gtk_entry_get_text (GTK_ENTRY(recent_files_count_te)), NULL, 10);
569
570         if (newval > 0) {
571                 prefs.gui_recent_files_count_max = newval;
572         }
573
574         /* We really should pop up a nasty dialog box if newval <= 0 */
575
576         return FALSE;
577 }
578
579 static gint
580 fileopen_preview_changed_cb(GtkWidget *recent_files_entry _U_, 
581                               GdkEvent *event _U_, gpointer parent_w)
582 {
583         GtkWidget       *fileopen_preview_te;
584         guint newval;
585     
586         fileopen_preview_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_FILEOPEN_PREVIEW_KEY);
587
588         /*
589          * Now, just convert the string to a number and store it in the prefs
590          * filed ...
591          */
592
593         newval = strtol(gtk_entry_get_text (GTK_ENTRY(fileopen_preview_te)), NULL, 10);
594
595         if (newval > 0) {
596                 prefs.gui_fileopen_preview = newval;
597         }
598
599         /* We really should pop up a nasty dialog box if newval <= 0 */
600
601         return FALSE;
602 }
603
604 static gint
605 fileopen_dir_changed_cb(GtkWidget *fileopen_entry _U_, GdkEvent *event _U_, gpointer parent_w)
606 {
607         GtkWidget       *fileopen_dir_te;
608         char *lastchar;
609         gint fileopen_dir_te_length;
610     
611         fileopen_dir_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_FILEOPEN_DIR_KEY);
612         fileopen_dir_te_length = (gint) strlen(gtk_entry_get_text (GTK_ENTRY(fileopen_entry)));
613         if (fileopen_dir_te_length == 0)
614                 return FALSE;
615         lastchar = gtk_editable_get_chars(GTK_EDITABLE(fileopen_entry), fileopen_dir_te_length-1, -1);
616         if (strcmp(lastchar, G_DIR_SEPARATOR_S) != 0){
617                 gtk_editable_insert_text(GTK_EDITABLE(fileopen_entry), G_DIR_SEPARATOR_S,
618             1, /* new_text_length */
619             &fileopen_dir_te_length); /* *position */
620         }
621         return FALSE;
622 }
623
624 static void
625 fileopen_selected_cb(GtkWidget *mybutton_rb _U_, gpointer parent_w)
626 {
627         GtkWidget       *fileopen_rb, *fileopen_dir_te;
628     
629         fileopen_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_FILEOPEN_KEY);
630         fileopen_dir_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), GUI_FILEOPEN_DIR_KEY);
631     
632         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fileopen_rb)))
633         {
634                 gtk_widget_set_sensitive(GTK_WIDGET(fileopen_dir_te), TRUE);
635         }
636         else
637         {
638                 gtk_widget_set_sensitive(GTK_WIDGET(fileopen_dir_te), FALSE);
639         }
640         return;
641 }
642