Clean up indentation.
[obnox/wireshark/wip.git] / gtk / prefs_dlg.c
index af76be9e3f271770ffcf9c7b8cccf12c38b37a63..6c42bfba18dde38cd7a05f8666f5bffae22e8fbf 100644 (file)
@@ -1,7 +1,7 @@
 /* prefs_dlg.c
  * Routines for handling preferences
  *
- * $Id: prefs_dlg.c,v 1.84 2004/05/27 16:50:16 ulfl Exp $
+ * $Id$
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -35,7 +35,7 @@
 #include "main.h"
 #include <epan/packet.h>
 #include "file.h"
-#include "prefs.h"
+#include <epan/prefs.h>
 #include "column_prefs.h"
 #include "print.h"
 #include "prefs_dlg.h"
 #include "simple_dialog.h"
 #include "compat_macros.h"
 
-#include "prefs-int.h"
+#include <epan/prefs-int.h>
 
 #ifdef HAVE_LIBPCAP
-#ifdef WIN32
+#ifdef _WIN32
 #include "capture-wpcap.h"
 #endif /* _WIN32 */
 #endif /* HAVE_LIBPCAP */
@@ -62,7 +62,7 @@ static void     prefs_main_ok_cb(GtkWidget *, gpointer);
 static void     prefs_main_apply_cb(GtkWidget *, gpointer);
 static void     prefs_main_save_cb(GtkWidget *, gpointer);
 static void     prefs_main_cancel_cb(GtkWidget *, gpointer);
-static gboolean prefs_main_delete_cb(GtkWidget *, gpointer);
+static gboolean prefs_main_delete_event_cb(GtkWidget *, GdkEvent *, gpointer);
 static void     prefs_main_destroy_cb(GtkWidget *, gpointer);
 #if GTK_MAJOR_VERSION < 2
 static void    prefs_tree_select_cb(GtkCTree *, GtkCTreeNode *, gint,
@@ -202,6 +202,21 @@ pref_show(pref_t *pref, gpointer user_data)
                                            pref->saved_val.string);
     break;
 
+  case PREF_RANGE:
+  {
+    char *range_string;
+
+    if (pref->saved_val.range != NULL)
+      g_free(pref->saved_val.range);
+    pref->saved_val.range = range_copy(*pref->varp.range);
+    range_string = range_convert_range(*pref->varp.range);
+    pref->control = create_preference_entry(main_tb, pref->ordinal,
+                                           label_string, pref->description,
+                                           range_string);
+    g_free(range_string);
+    break;
+  }
+
   case PREF_OBSOLETE:
     g_assert_not_reached();
     break;
@@ -213,7 +228,7 @@ pref_show(pref_t *pref, gpointer user_data)
 
 #define MAX_TREE_NODE_NAME_LEN 64
 /* show prefs page for each registered module (protocol) */
-static void
+static guint
 module_prefs_show(module_t *module, gpointer user_data)
 {
   struct ct_struct *cts = user_data;
@@ -243,7 +258,7 @@ module_prefs_show(module_t *module, gpointer user_data)
        * nothing under it that will be displayed, don't put it into
        * the window.
        */
-      return;
+      return 0;
     }
   }
 
@@ -334,6 +349,8 @@ module_prefs_show(module_t *module, gpointer user_data)
     /* Show 'em what we got */
     gtk_widget_show_all(main_vb);
   }
+
+  return 0;
 }
 
 
@@ -346,7 +363,12 @@ module_prefs_show(module_t *module, gpointer user_data)
 /* add a page to the tree */
 prefs_tree_iter
 prefs_tree_page_add(const gchar *title, gint page_nr, 
-                    gpointer store, prefs_tree_iter *parent_iter, gboolean has_child)
+                    gpointer store, prefs_tree_iter *parent_iter,
+                    gboolean has_child
+#if GTK_MAJOR_VERSION >= 2
+                    _U_
+#endif
+                    )
 {
 #if GTK_MAJOR_VERSION < 2
   const gchar       *label_ptr = title;
@@ -391,7 +413,6 @@ prefs_cb(GtkWidget *w _U_, gpointer dummy _U_)
   gchar             label_str[MAX_TREE_NODE_NAME_LEN];
   struct ct_struct  cts;
 #if GTK_MAJOR_VERSION < 2
-  gchar             *label_ptr = label_str;
   gpointer          store = NULL;
   static gchar *fixedwidths[] = { "c", "m", NULL };
 #else
@@ -606,7 +627,7 @@ prefs_cb(GtkWidget *w _U_, gpointer dummy _U_)
 
   gtk_widget_grab_default(ok_bt);
 
-  SIGNAL_CONNECT(prefs_w, "delete_event", prefs_main_delete_cb, prefs_w);
+  SIGNAL_CONNECT(prefs_w, "delete_event", prefs_main_delete_event_cb, prefs_w);
   SIGNAL_CONNECT(prefs_w, "destroy", prefs_main_destroy_cb, prefs_w);
 
   gtk_widget_show(prefs_w);
@@ -848,6 +869,68 @@ create_preference_entry(GtkWidget *main_tb, int table_position,
        return entry;
 }
 
+static guint
+pref_check(pref_t *pref, gpointer user_data)
+{
+  const char *str_val;
+  char *p;
+  guint uval;
+  pref_t **badpref = user_data;
+
+  /* Fetch the value of the preference, and check whether it's valid. */
+  switch (pref->type) {
+
+  case PREF_UINT:
+    str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
+    uval = strtoul(str_val, &p, pref->info.base);
+    if (p == str_val || *p != '\0') {
+      *badpref = pref;
+      return PREFS_SET_SYNTAX_ERR;     /* number was bad */
+    }
+    break;
+
+  case PREF_BOOL:
+    /* Value can't be bad. */
+    break;
+
+  case PREF_ENUM:
+    /* Value can't be bad. */
+    break;
+
+  case PREF_STRING:
+    /* Value can't be bad. */
+    break;
+
+  case PREF_RANGE:
+    str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
+
+    if (strlen(str_val) != 0) {
+       range_t *newrange;
+
+       if (range_convert_str(&newrange, str_val, pref->info.max_value) !=
+           CVT_NO_ERROR) {
+           *badpref = pref;
+           return PREFS_SET_SYNTAX_ERR;        /* range was bad */
+       }
+       g_free(newrange);
+    }
+    break;
+
+  case PREF_OBSOLETE:
+    g_assert_not_reached();
+    break;
+  }
+  return 0;
+}
+
+static guint
+module_prefs_check(module_t *module, gpointer user_data)
+{
+  /* For all preferences in this module, fetch its value from this
+     module's notebook page and check whether it's valid. */
+  return prefs_pref_foreach(module, pref_check, user_data);
+}
+
 static guint
 pref_fetch(pref_t *pref, gpointer user_data)
 {
@@ -907,6 +990,30 @@ pref_fetch(pref_t *pref, gpointer user_data)
     }
     break;
 
+  case PREF_RANGE:
+  {
+    range_t *newrange;
+    convert_ret_t ret;
+
+    str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
+    ret = range_convert_str(&newrange, str_val, pref->info.max_value);
+    if (ret != CVT_NO_ERROR)
+#if 0
+      return PREFS_SET_SYNTAX_ERR;     /* range was bad */
+#else
+      return 0;        /* XXX - should fail */
+#endif
+
+    if (!ranges_are_equal(*pref->varp.range, newrange)) {
+      *pref_changed_p = TRUE;
+      g_free(*pref->varp.range);
+      *pref->varp.range = newrange;
+    } else
+      g_free(newrange);
+
+    break;
+  }
+
   case PREF_OBSOLETE:
     g_assert_not_reached();
     break;
@@ -914,7 +1021,7 @@ pref_fetch(pref_t *pref, gpointer user_data)
   return 0;
 }
 
-static void
+static guint
 module_prefs_fetch(module_t *module, gpointer user_data)
 {
   gboolean *must_redissect_p = user_data;
@@ -929,6 +1036,8 @@ module_prefs_fetch(module_t *module, gpointer user_data)
      could cause packets to be dissected differently. */
   if (module->prefs_changed)
     *must_redissect_p = TRUE;
+
+  return 0;    /* keep fetching module preferences */
 }
 
 static guint
@@ -952,6 +1061,13 @@ pref_clean(pref_t *pref, gpointer user_data _U_)
     }
     break;
 
+  case PREF_RANGE:
+    if (pref->saved_val.range != NULL) {
+      g_free(pref->saved_val.range);
+      pref->saved_val.range = NULL;
+    }
+    break;
+
   case PREF_OBSOLETE:
     g_assert_not_reached();
     break;
@@ -959,19 +1075,46 @@ pref_clean(pref_t *pref, gpointer user_data _U_)
   return 0;
 }
 
-static void
+static guint
 module_prefs_clean(module_t *module, gpointer user_data _U_)
 {
   /* For all preferences in this module, clean up any cruft allocated for
      use by the GUI code. */
   prefs_pref_foreach(module, pref_clean, NULL);
+  return 0;    /* keep cleaning modules */
 }
 
-
 /* fetch all pref values from all pages */
-static void
+static gboolean
 prefs_main_fetch_all(GtkWidget *dlg, gboolean *must_redissect)
 {
+  pref_t *badpref;
+
+  /* First, check that the values are all valid. */
+  /* XXX - check the non-registered preferences too */
+  switch (prefs_modules_foreach(module_prefs_check, (gpointer)&badpref)) {
+
+  case PREFS_SET_SYNTAX_ERR:
+    switch (badpref->type) {
+
+    case PREF_UINT:
+      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                    "The value for \"%s\" isn't a valid number.",
+                    badpref->title);
+      return FALSE;
+
+    case PREF_RANGE:
+      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                    "The value for \"%s\" isn't a valid range.",
+                    badpref->title);
+      return FALSE;
+
+    default:
+      g_assert_not_reached();
+      break;
+    }
+  }
+
   /* Fetch the preferences (i.e., make sure all the values set in all of
      the preferences panes have been copied to "prefs" and the registered
      preferences). */
@@ -994,14 +1137,21 @@ prefs_main_fetch_all(GtkWidget *dlg, gboolean *must_redissect)
   nameres_prefs_fetch(OBJECT_GET_DATA(dlg, E_NAMERES_PAGE_KEY));
 
   prefs_modules_foreach(module_prefs_fetch, must_redissect);
-}
 
+  return TRUE;
+}
 
 /* apply all pref values to the real world */
 static void
 prefs_main_apply_all(GtkWidget *dlg)
 {
-  /* Now apply those preferences. */
+  /*
+   * Apply the protocol preferences first - "gui_prefs_apply()" could
+   * cause redissection, and we have to make sure the protocol
+   * preference changes have been fully applied.
+   */
+  prefs_apply_all();
+
   gui_prefs_apply(OBJECT_GET_DATA(dlg, E_GUI_PAGE_KEY));
   layout_prefs_apply(OBJECT_GET_DATA(dlg, E_GUI_LAYOUT_PAGE_KEY));
   column_prefs_apply(OBJECT_GET_DATA(dlg, E_GUI_COLUMN_PAGE_KEY));
@@ -1019,8 +1169,6 @@ prefs_main_apply_all(GtkWidget *dlg)
 #endif /* HAVE_LIBPCAP */
   printer_prefs_apply(OBJECT_GET_DATA(dlg, E_PRINT_PAGE_KEY));
   nameres_prefs_apply(OBJECT_GET_DATA(dlg, E_NAMERES_PAGE_KEY));
-
-  prefs_apply_all();
 }
 
 
@@ -1058,7 +1206,8 @@ prefs_main_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
 {
   gboolean must_redissect = FALSE;
 
-  prefs_main_fetch_all(parent_w, &must_redissect);
+  if (!prefs_main_fetch_all(parent_w, &must_redissect))
+    return; /* Errors in some preference setting */
 
   prefs_main_apply_all(parent_w);
 
@@ -1067,7 +1216,7 @@ prefs_main_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
 
   if (must_redissect) {
     /* Redissect all the packets, and re-evaluate the display filter. */
-    redissect_packets(&cfile);
+    cf_redissect_packets(&cfile);
   }
 }
 
@@ -1076,13 +1225,14 @@ prefs_main_apply_cb(GtkWidget *apply_bt _U_, gpointer parent_w)
 {
   gboolean must_redissect = FALSE;
 
-  prefs_main_fetch_all(parent_w, &must_redissect);
+  if (!prefs_main_fetch_all(parent_w, &must_redissect))
+    return; /* Errors in some preference setting */
 
   prefs_main_apply_all(parent_w);
 
   if (must_redissect) {
     /* Redissect all the packets, and re-evaluate the display filter. */
-    redissect_packets(&cfile);
+    cf_redissect_packets(&cfile);
   }
 }
 
@@ -1094,7 +1244,8 @@ prefs_main_save_cb(GtkWidget *save_bt _U_, gpointer parent_w)
   char *pf_dir_path;
   char *pf_path;
 
-  prefs_main_fetch_all(parent_w, &must_redissect);
+  if (!prefs_main_fetch_all(parent_w, &must_redissect))
+    return; /* Errors in some preference setting */
 
   /* Create the directory that holds personal configuration files, if
      necessary.  */
@@ -1132,7 +1283,7 @@ prefs_main_save_cb(GtkWidget *save_bt _U_, gpointer parent_w)
 
   if (must_redissect) {
     /* Redissect all the packets, and re-evaluate the display filter. */
-    redissect_packets(&cfile);
+    cf_redissect_packets(&cfile);
   }
 }
 
@@ -1173,6 +1324,14 @@ pref_revert(pref_t *pref, gpointer user_data)
     }
     break;
 
+  case PREF_RANGE:
+    if (!ranges_are_equal(*pref->varp.range, pref->saved_val.range)) {
+      *pref_changed_p = TRUE;
+      g_free(*pref->varp.range);
+      *pref->varp.range = range_copy(pref->saved_val.range);
+    }
+    break;
+
   case PREF_OBSOLETE:
     g_assert_not_reached();
     break;
@@ -1180,7 +1339,7 @@ pref_revert(pref_t *pref, gpointer user_data)
   return 0;
 }
 
-static void
+static guint
 module_prefs_revert(module_t *module, gpointer user_data)
 {
   gboolean *must_redissect_p = user_data;
@@ -1196,6 +1355,7 @@ module_prefs_revert(module_t *module, gpointer user_data)
      could cause packets to be dissected differently. */
   if (module->prefs_changed)
     *must_redissect_p = TRUE;
+  return 0;    /* keep processing modules */
 }
 
 /* cancel button pressed, revert prefs to saved and exit dialog */
@@ -1219,15 +1379,16 @@ prefs_main_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
 
   if (must_redissect) {
     /* Redissect all the packets, and re-evaluate the display filter. */
-    redissect_packets(&cfile);
+    cf_redissect_packets(&cfile);
   }
 }
 
 /* Treat this as a cancel, by calling "prefs_main_cancel_cb()" */
 static gboolean
-prefs_main_delete_cb(GtkWidget *prefs_w, gpointer parent_w)
+prefs_main_delete_event_cb(GtkWidget *prefs_w, GdkEvent *event _U_,
+                           gpointer parent_w _U_)
 {
-  prefs_main_cancel_cb(NULL, parent_w);
+  prefs_main_cancel_cb(NULL, prefs_w);
   return FALSE;
 }
 
@@ -1247,14 +1408,17 @@ struct properties_data {
   module_t *module;
 };
 
-static void
+static guint
 module_search_properties(module_t *module, gpointer user_data)
 {
   struct properties_data *p = (struct properties_data *)user_data;
 
   /* If this module has the specified title, remember it. */
-  if (strcmp(module->title, p->title) == 0)
+  if (strcmp(module->title, p->title) == 0) {
     p->module = module;
+    return 1;  /* stops the search */
+  }
+  return 0;
 }
 
 void