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