Since ethereal is now dependent on GTK+-1.2.x (because of proto_tree and
[obnox/wireshark/wip.git] / filter.c
index 479cf59a34bf52e183e3545597a6e0dad80f1760..8fb29f97b57270999219d6e8d0e4067eab1dddd9 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -1,7 +1,7 @@
 /* filter.c
  * Routines for managing filter sets
  *
- * $Id: filter.c,v 1.3 1998/09/27 22:12:24 gerald Exp $
+ * $Id: filter.c,v 1.14 1999/07/13 03:08:05 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
 
 #include <gtk/gtk.h>
 
+#include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 #include <ctype.h>
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
 
 #include "ethereal.h"
 #include "filter.h"
 #include "packet.h"
 #include "file.h"
 #include "menu.h"
+#include "prefs.h"
 
-extern capture_file cf;
+#define E_FILT_NAME_KEY "filter_name"
+#define E_FILT_LBL_KEY  "filter_label"
+#define E_FILT_CM_KEY   "in_cancel_mode"
 
-const gchar *fn_key = "filter_name";
-const gchar *fl_key = "filter_label";
 GtkWidget   *filter_l, *chg_bt, *copy_bt, *del_bt, *name_te, *filter_te;
-gint         in_cancel = FALSE;
 GList       *fl = NULL;
 
-GList *
-read_filter_list() {
+void get_filter_list();
+
+void
+get_filter_list() {
   filter_def *filt;
   FILE       *ff;
-  gchar      *ff_path, *ff_name = ".ethereal/filters", f_buf[256];
+  gchar      *ff_path, *ff_name = PF_DIR "/filters", f_buf[256];
   gchar      *name_begin, *name_end, *filt_begin;
   int         len, line = 0;
-  
-  in_cancel = FALSE;
+
+  if (fl) return;
   
   /* To do: generalize this */
   ff_path = (gchar *) g_malloc(strlen(getenv("HOME")) + strlen(ff_name) +  4);
@@ -64,7 +72,7 @@ read_filter_list() {
 
   if ((ff = fopen(ff_path, "r")) == NULL) {
     g_free(ff_path);
-    return NULL;
+    return;
   }
 
   while (fgets(f_buf, 256, ff)) {
@@ -100,30 +108,30 @@ read_filter_list() {
   }
   fclose(ff);
   g_free(ff_path);
-  return fl;
 }
 
-/* filter_sel_cb - Create and display the filter selection dialog. */
-/* Called when the 'Filter' menu item is selected. */
-void
-filter_sel_cb(GtkWidget *w, gpointer d) {
-  GtkWidget      *filter_w, *main_vb, *top_hb, *list_bb, *bbox,
-                 *new_bt, *ok_bt, *save_bt, *cancel_bt, *filter_sc, *nl_item,
-                 *nl_lb, *middle_hb, *name_lb, *bottom_hb, *filter_lb;
-  GtkWidget      *l_select = NULL;
-  GList          *flp = NULL;
-  filter_def     *filt;
-  
-  fl = read_filter_list();
+/* Create and display the filter selection widgets. */
+/* Called when the 'Filter' preference notebook page is selected. */
+GtkWidget *
+filter_prefs_show(GtkWidget *w) {
+  GtkWidget  *main_vb, *top_hb, *list_bb, *new_bt, *filter_sc,
+             *nl_item, *nl_lb, *middle_hb, *name_lb, *bottom_hb,
+             *filter_lb;
+  GtkWidget  *l_select = NULL;
+  GList      *flp = NULL;
+  filter_def *filt;
+  gchar      *filter_te_str = NULL;
+
+  /* Make sure everything is set up */  
+  get_filter_list();
+  if (w)
+    filter_te_str = gtk_entry_get_text(GTK_ENTRY(w));
 
-  filter_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-  gtk_window_set_title(GTK_WINDOW(filter_w), "Ethereal: Filters");
-  
   /* Container for each row of widgets */
   main_vb = gtk_vbox_new(FALSE, 5);
   gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
-  gtk_container_add(GTK_CONTAINER(filter_w), main_vb);
   gtk_widget_show(main_vb);
+  gtk_object_set_data(GTK_OBJECT(main_vb), E_FILT_CM_KEY, (gpointer)FALSE);
   
   /* Top row: Filter list and buttons */
   top_hb = gtk_hbox_new(FALSE, 5);
@@ -170,9 +178,11 @@ filter_sel_cb(GtkWidget *w, gpointer d) {
   gtk_widget_show(filter_sc);
 
   filter_l = gtk_list_new();
+  gtk_list_set_selection_mode(GTK_LIST(filter_l), GTK_SELECTION_SINGLE);
   gtk_signal_connect(GTK_OBJECT(filter_l), "selection_changed",
-    GTK_SIGNAL_FUNC(filter_sel_list_cb), NULL);
-  gtk_container_add(GTK_CONTAINER(filter_sc), filter_l);
+    GTK_SIGNAL_FUNC(filter_sel_list_cb), main_vb);
+  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(filter_sc),
+    filter_l);
   gtk_widget_show(filter_l);
 
   flp = g_list_first(fl);
@@ -185,11 +195,13 @@ filter_sel_cb(GtkWidget *w, gpointer d) {
     gtk_widget_show(nl_lb);
     gtk_container_add(GTK_CONTAINER(filter_l), nl_item);
     gtk_widget_show(nl_item);
-    gtk_object_set_data(GTK_OBJECT(nl_item), fl_key, nl_lb);
-    gtk_object_set_data(GTK_OBJECT(nl_item), fn_key, flp);
-    if (cf.filter && filt->strval)
-      if (strcmp(cf.filter, filt->strval) == 0)
+    gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_LBL_KEY, nl_lb);
+    gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_NAME_KEY, flp);
+    if (filter_te_str && filt->strval)
+      if (strcmp(filter_te_str, filt->strval) == 0)
         l_select = nl_item;
+
     flp = flp->next;
   }
   
@@ -219,36 +231,15 @@ filter_sel_cb(GtkWidget *w, gpointer d) {
   gtk_box_pack_start(GTK_BOX(bottom_hb), filter_te, TRUE, TRUE, 3);
   gtk_widget_show(filter_te);
 
-  /* Button row: OK and cancel buttons */
-  bbox = gtk_hbutton_box_new();
-  gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
-  gtk_container_add(GTK_CONTAINER(main_vb), bbox);
-  gtk_widget_show(bbox);
-  
-  ok_bt = gtk_button_new_with_label ("OK");
-  gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked",
-    GTK_SIGNAL_FUNC(filter_sel_ok_cb), (gpointer) filter_w);
-  gtk_container_add(GTK_CONTAINER(bbox), ok_bt);
-  GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
-  gtk_widget_grab_default(ok_bt);  
-  gtk_widget_show(ok_bt);
-
-  save_bt = gtk_button_new_with_label ("Save");
-  gtk_signal_connect(GTK_OBJECT(save_bt), "clicked",
-    GTK_SIGNAL_FUNC(filter_sel_save_cb), (gpointer) fl);
-  gtk_container_add(GTK_CONTAINER(bbox), save_bt);
-  gtk_widget_show(save_bt);
-  
-  cancel_bt = gtk_button_new_with_label ("Cancel");
-  gtk_signal_connect(GTK_OBJECT(cancel_bt), "clicked",
-    GTK_SIGNAL_FUNC(filter_sel_cancel_cb), (gpointer) filter_w);
-  gtk_container_add(GTK_CONTAINER(bbox), cancel_bt);
-  gtk_widget_show(cancel_bt);
-  
-  gtk_widget_show(filter_w);
-
   if (l_select)
+  {
     gtk_list_select_child(GTK_LIST(filter_l), l_select);
+  } else if (filter_te_str && filter_te_str[0]) {
+    gtk_entry_set_text(GTK_ENTRY(name_te), "New filter");
+    gtk_entry_set_text(GTK_ENTRY(filter_te), filter_te_str);
+  }
+    
+  return(main_vb);
 }
 
 void
@@ -259,11 +250,14 @@ filter_sel_list_cb(GtkWidget *l, gpointer data) {
   GtkObject  *l_item;
   gint        sensitivity = FALSE;
 
-  sl = GTK_LIST(l)->selection;
+  if (l)
+         sl = GTK_LIST(l)->selection;
+  else
+         sl = NULL;
           
   if (sl) {  /* Something was selected */
     l_item = GTK_OBJECT(sl->data);
-    flp    = (GList *) gtk_object_get_data(l_item, fn_key);
+    flp    = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
     if (flp) {
       filt   = (filter_def *) flp->data;
       name   = filt->name;
@@ -274,7 +268,7 @@ filter_sel_list_cb(GtkWidget *l, gpointer data) {
 
   /* Did you know that this function is called when the window is destroyed? */
   /* Funny, that. */
-  if (!in_cancel) {
+  if (!gtk_object_get_data(GTK_OBJECT(data), E_FILT_CM_KEY)) {
     gtk_entry_set_text(GTK_ENTRY(name_te), name);
     gtk_entry_set_text(GTK_ENTRY(filter_te), strval);
     gtk_widget_set_sensitive(chg_bt, sensitivity);
@@ -306,8 +300,9 @@ filter_sel_new_cb(GtkWidget *w, gpointer data) {
     gtk_widget_show(nl_lb);
     gtk_container_add(GTK_CONTAINER(filter_l), nl_item);
     gtk_widget_show(nl_item);
-    gtk_object_set_data(GTK_OBJECT(nl_item), fl_key, nl_lb);
-    gtk_object_set_data(GTK_OBJECT(nl_item), fn_key, g_list_last(fl));
+    gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_LBL_KEY, nl_lb);
+    gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_NAME_KEY, g_list_last(fl));
+    gtk_list_select_child(GTK_LIST(filter_l), nl_item);
   }
 }
 
@@ -325,8 +320,8 @@ filter_sel_chg_cb(GtkWidget *w, gpointer data) {
 
   if (sl) {  /* Something was selected */
     l_item = GTK_OBJECT(sl->data);
-    flp    = (GList *) gtk_object_get_data(l_item, fn_key);
-    nl_lb  = (GtkLabel *) gtk_object_get_data(l_item, fl_key);
+    flp    = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
+    nl_lb  = (GtkLabel *) gtk_object_get_data(l_item, E_FILT_LBL_KEY);
     if (flp && nl_lb) {
       filt = (filter_def *) flp->data;
       
@@ -352,7 +347,7 @@ filter_sel_copy_cb(GtkWidget *w, gpointer data) {
   sl     = GTK_LIST(filter_l)->selection;
   if (sl) {  /* Something was selected */
     l_item = GTK_OBJECT(sl->data);
-    flp    = (GList *) gtk_object_get_data(l_item, fn_key);
+    flp    = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
     if (flp) {
       filt          = (filter_def *) flp->data;
       nfilt         = (filter_def *) g_malloc(sizeof(filter_def));
@@ -367,8 +362,9 @@ filter_sel_copy_cb(GtkWidget *w, gpointer data) {
       gtk_widget_show(nl_lb);
       gtk_container_add(GTK_CONTAINER(filter_l), nl_item);
       gtk_widget_show(nl_item);
-      gtk_object_set_data(GTK_OBJECT(nl_item), fl_key, nl_lb);
-      gtk_object_set_data(GTK_OBJECT(nl_item), fn_key, g_list_last(fl));
+      gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_LBL_KEY, nl_lb);
+      gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_NAME_KEY, g_list_last(fl));
+      gtk_list_select_child(GTK_LIST(filter_l), nl_item);
     }
   }
 }
@@ -385,47 +381,43 @@ filter_sel_del_cb(GtkWidget *w, gpointer data) {
     l_item = GTK_OBJECT(sl->data);
     pos    = gtk_list_child_position(GTK_LIST(filter_l),
       GTK_WIDGET(l_item));
-    flp    = (GList *) gtk_object_get_data(l_item, fn_key);
+    flp    = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
     if (flp) {
       filt = (filter_def *) flp->data;
       g_free(filt->name);
       g_free(filt->strval);
       g_free(filt);
-      fl = g_list_remove_link(fl, flp);
+      fl = g_list_remove(fl, flp);
       gtk_list_clear_items(GTK_LIST(filter_l), pos, pos + 1);
     } 
   }
 }
 
 void
-filter_sel_ok_cb(GtkWidget *w, gpointer data) {
+filter_prefs_ok(GtkWidget *w) {
   GList      *flp, *sl;
   GtkObject  *l_item;
   filter_def *filt;
+  GtkWidget  *mw_filt = gtk_object_get_data(GTK_OBJECT(w), E_FILT_TE_PTR_KEY);
 
-  if (cf.filter) {
-    g_free(cf.filter);
-    cf.filter = NULL;
-  }
-    
   sl = GTK_LIST(filter_l)->selection;
-  if (sl) {  /* Something was selected */
+  if (sl && mw_filt) {  /* Place something in the filter box. */
     l_item = GTK_OBJECT(sl->data);
-    flp    = (GList *) gtk_object_get_data(l_item, fn_key);
+    flp    = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
     if (flp) {
       filt = (filter_def *) flp->data;
-      cf.filter = g_strdup(filt->strval);
+      gtk_entry_set_text(GTK_ENTRY(mw_filt), filt->strval);
     }
   }
 
-  filter_sel_cancel_cb(w, data);
+  filter_prefs_cancel(w);
 }
 
 void
-filter_sel_save_cb(GtkWidget *w, gpointer data) {
+filter_prefs_save(GtkWidget *w) {
   GList       *flp;
   filter_def  *filt;
-  gchar       *ff_path, *ff_dir = ".ethereal", *ff_name = "filters";
+  gchar       *ff_path, *ff_dir = PF_DIR, *ff_name = "filters";
   FILE        *ff;
   struct stat  s_buf;
   
@@ -434,7 +426,11 @@ filter_sel_save_cb(GtkWidget *w, gpointer data) {
   sprintf(ff_path, "%s/%s", getenv("HOME"), ff_dir);
 
   if (stat(ff_path, &s_buf) != 0)
+#ifdef WIN32
+    mkdir(ff_path);
+#else
     mkdir(ff_path, 0755);
+#endif
     
   sprintf(ff_path, "%s/%s/%s", getenv("HOME"), ff_dir, ff_name);
 
@@ -452,21 +448,10 @@ filter_sel_save_cb(GtkWidget *w, gpointer data) {
 }
 
 void
-filter_sel_cancel_cb(GtkWidget *w, gpointer win) {
-  filter_def *filt;
-  
-  while (fl) {
-    if (fl->data) {
-      filt = (filter_def *) fl->data;
-      g_free(filt->name);
-      g_free(filt->strval);
-      g_free(filt);
-    }
-    fl = g_list_remove_link(fl, fl);
-  }
-
+filter_prefs_cancel(GtkWidget *w) {
   /* Let the list cb know we're about to destroy the widget tree, so it */
   /* doesn't operate on widgets that don't exist. */  
-  in_cancel = TRUE;    
-  gtk_widget_destroy(GTK_WIDGET(win));
+  gtk_object_set_data(GTK_OBJECT(w), E_FILT_CM_KEY, (gpointer)TRUE);
+  gtk_widget_destroy(GTK_WIDGET(w));
 }