From Edwin Groothuis via bug 6207:
authorstig <stig@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 8 Sep 2011 09:35:10 +0000 (09:35 +0000)
committerstig <stig@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 8 Sep 2011 09:35:10 +0000 (09:35 +0000)
Added Filter Toolbar Save functionality.

From me:
Removed unused code.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@38937 f5534014-38df-0310-8fa8-9805f1628bb7

20 files changed:
AUTHORS
epan/CMakeLists.txt
epan/Makefile.common
epan/filter_expressions.c [new file with mode: 0644]
epan/filter_expressions.h [new file with mode: 0644]
epan/libwireshark.def
epan/prefs.c
epan/prefs.h
gtk/CMakeLists.txt
gtk/Makefile.common
gtk/filter_expression_save_dlg.c [new file with mode: 0644]
gtk/filter_expression_save_dlg.h [new file with mode: 0644]
gtk/help_dlg.h
gtk/main.c
gtk/main_filter_toolbar.c
gtk/main_filter_toolbar.h
gtk/prefs_dlg.c
gtk/prefs_filter_expressions.c [new file with mode: 0644]
gtk/prefs_filter_expressions.h [new file with mode: 0644]
services

diff --git a/AUTHORS b/AUTHORS
index 020f6d3f218e7b8b63e6f914e36cd77105ee9c54..8ed5c0ee514f18d06e95ecdf3ee1909640497f3a 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -3294,6 +3294,7 @@ Allison                   <aobourn [AT] isilon.com> {
 
 Edwin Groothuis                <wireshark [AT] mavetju.org> {
        Time Shift functionality
+       Filter Toolbar Save functionality
 }
 
 Andrew Kampjes         <andrew.kampjes [AT] endace.com> {
index 9d518de0a8c4e0d132203057b327eadf63638b79..89bcfe64429d44d5be215c92af32f11018b855e9 100644 (file)
@@ -1217,6 +1217,7 @@ set(LIBWIRESHARK_FILES
        except.c
        expert.c
        filesystem.c
+       filter_expressions.c
        follow.c
        frame_data.c
        frequency-utils.c
index 9ef81117babdaccf035e1ea60405d8da177c97ed..737e6a0f10398b8ed8676f36d06c3c4824fdcfb8 100644 (file)
@@ -50,6 +50,7 @@ LIBWIRESHARK_SRC =            \
        except.c                \
        expert.c                \
        filesystem.c            \
+       filter_expressions.c    \
        follow.c                \
        frame_data.c            \
        frequency-utils.c       \
@@ -163,6 +164,7 @@ LIBWIRESHARK_INCLUDES =     \
        except.h                \
        exceptions.h            \
        expert.h                \
+       filter_expressions.h    \
        filesystem.h            \
        follow.h                \
        frame_data.h            \
diff --git a/epan/filter_expressions.c b/epan/filter_expressions.c
new file mode 100644 (file)
index 0000000..92c9439
--- /dev/null
@@ -0,0 +1,80 @@
+/* filter_expressions.c
+ * Submitted by Edwin Groothuis <wireshark@mavetju.org>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <glib.h>
+
+#include <epan/prefs.h>
+
+#include "epan/filter_expressions.h"
+
+static struct filter_expression *_filter_expression_head = NULL;
+struct filter_expression **pfilter_expression_head = &_filter_expression_head;
+
+/*
+ * Create a new filter_expression and add it to the end of the list
+ * of filter_expressions.
+ */
+struct filter_expression *
+filter_expression_new(const gchar *label, const gchar *expr,
+    const gboolean enabled)
+{
+       struct filter_expression *expression;
+       struct filter_expression *prev;
+
+       expression = (struct filter_expression *)g_malloc(sizeof(struct filter_expression));
+       memset(expression, '\0', sizeof(struct filter_expression));
+       expression->button = NULL;
+       expression->label = g_strdup(label);
+       expression->expression = g_strdup(expr);
+       expression->enabled = enabled;
+       expression->deleted = FALSE;
+       expression->index = 0;
+
+       expression->next = NULL;
+
+       /* Add it at the end so the button order is always the same*/
+       if (*pfilter_expression_head == NULL) {
+               _filter_expression_head = expression;
+       } else {
+               prev = *pfilter_expression_head;
+               while (prev->next != NULL)
+                       prev = prev->next;
+               prev->next = expression;
+               expression->index = prev->index + 1;
+       }
+
+       return(expression);
+}
+
+void
+filter_expression_init(gboolean enable_prefs)
+{
+       if (enable_prefs)
+               prefs.filter_expressions = pfilter_expression_head;
+}
diff --git a/epan/filter_expressions.h b/epan/filter_expressions.h
new file mode 100644 (file)
index 0000000..05f66d3
--- /dev/null
@@ -0,0 +1,49 @@
+/* filter_expressions.h
+ * Submitted by Edwin Groothuis <wireshark@mavetju.org>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __FILTER_EXPRESSIONS_H__
+#define __FILTER_EXPRESSIONS_H__
+
+#include "globals.h"
+
+struct filter_expression {
+       gpointer button;        /* Filter toolbar */
+       gchar   *label;
+       gchar   *expression;
+
+       gint    index;
+       gboolean enabled;       /* Can be set to FALSE by Preferences Dialog */
+       gboolean deleted;       /* Can be set to TRUE by Preferences Dialog */
+
+       struct filter_expression *next;
+};
+
+WS_VAR_IMPORT struct filter_expression **pfilter_expression_head;
+
+struct filter_expression *filter_expression_new(const gchar *label,
+    const gchar *expr, const gboolean enabled);
+
+void filter_expression_init(gboolean prefs);
+
+#endif /* __FILTER_EXPRESSIONS_H__ */
index 7ec9c99cc7e7dbc4737113f9e8006980721f77ca..5dddcbcaa35f474e75972824d606eeb98b448c50 100644 (file)
@@ -443,6 +443,8 @@ file_open_error_message
 file_write_error_message
 files_identical
 filesystem_opt
+pfilter_expression_head                DATA
+filter_expression_new
 find_circuit
 find_codec
 find_conversation
index 73435e1ce3786a26bde37c0882ad41633516ddb3..20821098962b6c11cf4a2c5fed2432507683b06d 100644 (file)
@@ -53,6 +53,8 @@
 #include <epan/prefs-int.h>
 #include <epan/uat-int.h>
 
+#include "epan/filter_expressions.h"
+
 /* Internal functions */
 static module_t *find_subtree(module_t *parent, const char *tilte);
 static module_t *prefs_register_module_or_subtree(module_t *parent,
@@ -1322,6 +1324,7 @@ init_prefs(void) {
   prefs.rtp_player_max_visible = RTP_PLAYER_DEFAULT_VISIBLE;
 
   prefs.display_hidden_proto_items = FALSE;
+  filter_expression_init(TRUE);
 
   prefs_initialized = TRUE;
 }
@@ -1847,6 +1850,9 @@ prefs_capture_device_monitor_mode(const char *name)
 #define PRS_GUI_LAYOUT_CONTENT_2         "gui.layout_content_2"
 #define PRS_GUI_LAYOUT_CONTENT_3         "gui.layout_content_3"
 #define PRS_CONSOLE_LOG_LEVEL           "console.log.level"
+#define PRS_GUI_FILTER_LABEL             "gui.filter_expressions.label"
+#define PRS_GUI_FILTER_EXPR              "gui.filter_expressions.expr"
+#define PRS_GUI_FILTER_ENABLED           "gui.filter_expressions.enabled"
 
 /*
  * This applies to more than just captures, so it's not "capture.name_resolve";
@@ -2004,6 +2010,9 @@ set_pref(gchar *pref_name, gchar *value, void *private_data _U_,
   gint     enum_val;
   char     *p;
   gchar    *dotp, *last_dotp;
+  static gchar *filter_label = NULL;
+  static gboolean filter_enabled = FALSE;
+  gchar    *filter_expr = NULL;
   module_t *module;
   pref_t   *pref;
   gboolean had_a_dot;
@@ -2035,6 +2044,15 @@ set_pref(gchar *pref_name, gchar *value, void *private_data _U_,
     prefs.pr_cmd = g_strdup(value);
   } else if (strcmp(pref_name, PRS_COL_HIDDEN) == 0) {
     cols_hidden_list = g_strdup (value);
+  } else if (strcmp(pref_name, PRS_GUI_FILTER_LABEL) == 0) {
+    filter_label = g_strdup(value);
+  } else if (strcmp(pref_name, PRS_GUI_FILTER_ENABLED) == 0) {
+    filter_enabled = (strcmp(value, "TRUE") == 0) ? TRUE : FALSE;
+  } else if (strcmp(pref_name, PRS_GUI_FILTER_EXPR) == 0) {
+    filter_expr = g_strdup(value);
+    filter_expression_new(filter_label, filter_expr, filter_enabled);
+    g_free(filter_label);
+    g_free(filter_expr);
   } else if (strcmp(pref_name, PRS_COL_FMT) == 0) {
     col_l = prefs_get_string_list(value);
     if (col_l == NULL)
@@ -3381,6 +3399,22 @@ write_prefs(char **pf_path_return)
   fprintf(pf, PRS_RTP_PLAYER_MAX_VISIBLE ": %d\n",
          prefs.rtp_player_max_visible);
 
+  fprintf(pf, "\n####### Filter Expressions ########\n");
+  {
+    struct filter_expression *fe;
+
+    fe = *(struct filter_expression **)prefs.filter_expressions;
+    while (fe != NULL) {
+      if (fe->deleted == FALSE) {
+       fprintf(pf, "%s: %s\n", PRS_GUI_FILTER_LABEL, fe->label);
+       fprintf(pf, "%s: %s\n", PRS_GUI_FILTER_ENABLED,
+       fe->enabled == TRUE ? "TRUE" : "FALSE");
+       fprintf(pf, "%s: %s\n", PRS_GUI_FILTER_EXPR, fe->expression);
+      }
+      fe = fe->next;
+    }
+  }
+
   fprintf(pf, "\n####### Protocols ########\n");
 
   fprintf(pf, "\n# Display hidden items in packet details pane?\n");
index a7ab2450b33059e7e2517246121b78c9026b4537..395119c636e7aa4e3e456c42f569469c4dd072fd 100644 (file)
@@ -167,6 +167,7 @@ typedef struct _e_prefs {
   guint    rtp_player_max_visible;
   guint    tap_update_interval;
   gboolean display_hidden_proto_items;
+  gpointer filter_expressions; /* Actually points to &head */
 } e_prefs;
 
 WS_VAR_IMPORT e_prefs prefs;
index e743556ceb4f0cf34106bf5939b2544d7d925b56..2f658c52607e3a647e61529f8d903ef45ff3b18f 100644 (file)
@@ -53,6 +53,7 @@ set(WIRESHARK_GTK_SRC
        file_import_dlg.c
        fileset_dlg.c
        filter_dlg.c
+       filter_expression_save_dlg.c
        filter_utils.c
        find_dlg.c
        firewall_dlg.c
@@ -88,6 +89,7 @@ set(WIRESHARK_GTK_SRC
        prefs_capture.c
        prefs_column.c
        prefs_dlg.c
+       prefs_filter_expressions.c
        prefs_gui.c
        prefs_layout.c
        prefs_nameres.c
index f37fd0b8ae61768ac1d0fca5b023cd80951adf1c..d1e24b1e96fc57c57d8bc9cea86d4fc09a00335a 100644 (file)
@@ -81,6 +81,7 @@ WIRESHARK_GTK_SRC = \
        file_import_dlg.c       \
        fileset_dlg.c   \
        filter_dlg.c    \
+       filter_expression_save_dlg.c    \
        filter_utils.c  \
        find_dlg.c      \
        firewall_dlg.c  \
@@ -116,6 +117,7 @@ WIRESHARK_GTK_SRC = \
        prefs_capture.c \
        prefs_column.c  \
        prefs_dlg.c     \
+       prefs_filter_expressions.c      \
        prefs_gui.c     \
        prefs_layout.c  \
        prefs_nameres.c \
@@ -266,6 +268,7 @@ noinst_HEADERS = \
        fileset_dlg.h   \
        filter_autocomplete.h   \
        filter_dlg.h    \
+       filter_expression_save_dlg.h    \
        filter_utils.h  \
        find_dlg.h      \
        firewall_dlg.h  \
@@ -309,6 +312,7 @@ noinst_HEADERS = \
        prefs_capture.h \
        prefs_column.h  \
        prefs_dlg.h     \
+       prefs_filter_expressions.h      \
        prefs_gui.h     \
        prefs_layout.h  \
        prefs_nameres.h \
diff --git a/gtk/filter_expression_save_dlg.c b/gtk/filter_expression_save_dlg.c
new file mode 100644 (file)
index 0000000..1eab652
--- /dev/null
@@ -0,0 +1,357 @@
+/* filter_expression_save_dlg.c
+ * Routines for "Filter Save" window
+ * Submitted by Edwin Groothuis <wireshark@mavetju.org>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#include <gtk/gtk.h>
+
+#include <epan/proto.h>
+#include <epan/dfilter/dfilter.h>
+#include <epan/nstime.h>
+#include <epan/strutil.h>
+#include <epan/prefs.h>
+#include <epan/filter_expressions.h>
+
+#include "../globals.h"
+#include "../alert_box.h"
+#include "../simple_dialog.h"
+#include "../main_statusbar.h"
+
+#include "gtk/gui_utils.h"
+#include "gtk/filter_expression_save_dlg.h"
+#include "gtk/dlg_utils.h"
+#include "gtk/stock_icons.h"
+#include "gtk/prefs_dlg.h"
+#include "gtk/keys.h"
+#include "gtk/help_dlg.h"
+#include "ui_util.h"
+#include "main.h"
+
+#include "main_filter_toolbar.h"
+
+/* Capture callback data keys */
+#define E_FILTER_SAVE_EXPR_KEY     "filter_save_offset_expression"
+#define E_FILTER_SAVE_LABEL_KEY     "filter_save_offset_label"
+
+static void filter_save_ok_cb(GtkWidget *ok_bt, GtkWindow *parent_w);
+static void filter_save_close_cb(GtkWidget *close_bt, gpointer parent_w);
+static void filter_save_frame_destroy_cb(GtkWidget *win, gpointer user_data);
+static void filter_button_cb(GtkWidget *close_bt, gpointer parent_w);
+static int filter_button_add(const char *label, const char *expr, struct filter_expression *newbutton);
+
+/*
+ * Keep a static pointer to the current "Filter Save" window, if any, so
+ * that if somebody tries to do "Filter Save" while there's already a
+ * "Filter Save" window up, we just pop up the existing one, rather than
+ * creating a new one.
+ */
+static GtkWidget *filter_save_frame_w;
+
+GtkWidget *_filter_tb = NULL;
+GtkWidget *_filter_te = NULL;
+
+/*
+ * This does do two things:
+ * - Keep track of the various elements of the Filter Toolbar which will
+ *   be needed later when a new button has to be added.
+ * - Since it is called after the preferences are read from the configfile,
+ *   this is the one also which creates the initial buttons when the
+ *   Filter Toolbar has been created.
+ */
+void
+filter_expression_save_dlg_init(gpointer filter_tb, gpointer filter_te)
+{
+       struct filter_expression *fe;
+
+       _filter_tb = (GtkWidget *)filter_tb;
+       _filter_te = (GtkWidget *)filter_te;
+
+       fe = *pfilter_expression_head;
+       while (fe != NULL) {
+               filter_button_add(NULL, NULL, fe);
+               fe = fe->next;
+       }
+}
+
+void
+filter_expression_nuke(struct filter_expression *fe)
+{
+       if (fe == NULL)
+               return;
+       filter_expression_nuke(fe->next);
+       g_free(fe->label);
+       g_free(fe->expression);
+}
+
+void
+filter_expression_reinit(int what)
+{
+       struct filter_expression *fe, *prevhead;
+
+       if ((what & FILTER_EXPRESSION_REINIT_DESTROY) != 0) {
+               fe = *pfilter_expression_head;
+               while (fe != NULL) {
+                       if (fe->button != NULL) {
+                               gtk_widget_destroy(fe->button);
+                               fe->button = NULL;
+                       }
+                       fe = fe->next;
+               }
+       }
+       if (what == FILTER_EXPRESSION_REINIT_DESTROY) {
+               filter_expression_nuke(*pfilter_expression_head);
+               *pfilter_expression_head = NULL;
+               return;
+       }
+
+       if ((what & FILTER_EXPRESSION_REINIT_CREATE) != 0) {
+               gint maxindex = -1, index;
+               fe = *pfilter_expression_head;
+               while (fe != NULL) {
+                       maxindex = MAX(maxindex, fe->index);
+                       fe = fe->next;
+               }
+
+               prevhead = *pfilter_expression_head;
+               *pfilter_expression_head = NULL;
+
+               /*
+                * The list should be in the order identified by the
+                * index member.
+                */
+               for (index = 0; index <= maxindex; index++) {
+                       if (prevhead != NULL) {
+                               fe = prevhead;
+                               while (fe != NULL && fe->index != index)
+                                       fe = fe->next;
+                       }
+                       if (fe == NULL)
+                               continue;       /* Shouldn't happen */
+                       if (fe->deleted)
+                               continue;       /* Could happen */
+                       filter_expression_new(fe->label, fe->expression,
+                           fe->enabled);
+               }
+               filter_expression_nuke(prevhead);
+
+               /* Create the buttons again */
+               fe = *pfilter_expression_head;
+               while (fe != NULL) {
+                       if (fe->enabled && !fe->deleted)
+                               filter_button_add(NULL, NULL, fe);
+                       fe = fe->next;
+               }
+       }
+}
+
+static int
+filter_button_add(const char *label, const char *expr, struct filter_expression *newfe)
+{
+       struct filter_expression *fe;
+
+       /* No duplicate buttons when adding a new one  */
+       if (newfe == NULL)
+               fe = filter_expression_new(label, expr, TRUE);
+       else
+               fe = newfe;
+
+       if (fe->enabled == FALSE)
+               return(0);
+
+       /* Create the "Label" button */
+       fe->button = gtk_tool_button_new(NULL, fe->label);
+       g_signal_connect(fe->button, "clicked", G_CALLBACK(filter_button_cb),
+           NULL);
+       gtk_widget_set_sensitive(GTK_WIDGET(fe->button), FALSE);
+       gtk_widget_show(GTK_WIDGET(fe->button));
+
+       gtk_toolbar_insert(GTK_TOOLBAR(_filter_tb), fe->button, -1);
+       gtk_widget_set_sensitive(GTK_WIDGET(fe->button), TRUE);
+       gtk_widget_set_tooltip_text(GTK_WIDGET(fe->button), fe->expression);
+
+       return(0);
+}
+
+static void
+filter_button_cb(GtkWidget *this_button, gpointer parent_w _U_)
+{
+       struct filter_expression *fe;
+
+       fe = *pfilter_expression_head;
+       while (fe != NULL) {
+               if ((void *)fe->button == (void *)this_button) {
+                       gtk_entry_set_text(GTK_ENTRY(_filter_te),
+                           fe->expression);
+                       main_filter_packets(&cfile, fe->expression, FALSE);
+                       return;
+               }
+               fe = fe->next;
+       }
+       printf("No Callback\n");
+}
+
+void
+filter_expression_save_dlg(gpointer data)
+{
+       GtkWidget   *main_vb, *main_filter_save_hb, *filter_save_frame,
+                   *filter_save_type_vb, *filter_save_type_hb, *entry_hb,
+                   *bbox, *ok_bt, *cancel_bt, *help_bt, *filter_text_box,
+                   *label_text_box;
+       const char *expr;
+
+       /* The filter requested */
+       expr = gtk_entry_get_text(GTK_ENTRY(data));
+
+       if (filter_save_frame_w != NULL) {
+               /* There's already a "Filter Save" dialog box; reactivate it. */
+               reactivate_window(filter_save_frame_w);
+               return;
+       }
+
+       filter_save_frame_w = dlg_window_new("Wireshark: Save Filter");
+
+       /* Container for each row of widgets */
+       main_vb = gtk_vbox_new(FALSE, 3);
+       gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
+       gtk_container_add(GTK_CONTAINER(filter_save_frame_w), main_vb);
+       gtk_widget_show(main_vb);
+
+
+       /* */
+       main_filter_save_hb = gtk_hbox_new(FALSE, 3);
+       gtk_container_add(GTK_CONTAINER(main_vb), main_filter_save_hb);
+       gtk_widget_show(main_filter_save_hb);
+
+       /* Filter Save frame */
+       filter_save_frame = gtk_frame_new("Save Filter as...");
+       gtk_box_pack_start(GTK_BOX(main_filter_save_hb), filter_save_frame,
+           TRUE, TRUE, 0);
+       gtk_widget_show(filter_save_frame);
+
+       filter_save_type_vb = gtk_vbox_new(FALSE, 3);
+       gtk_container_set_border_width(GTK_CONTAINER(filter_save_type_vb), 3);
+       gtk_container_add(GTK_CONTAINER(filter_save_frame),
+           filter_save_type_vb);
+       gtk_widget_show(filter_save_type_vb);
+
+       /* filter_save type row */
+       filter_save_type_hb = gtk_hbox_new(FALSE, 3);
+       gtk_container_add(GTK_CONTAINER(filter_save_type_vb),
+           filter_save_type_hb);
+       gtk_widget_show(filter_save_type_hb);
+
+       /* filter_save row */
+       entry_hb = gtk_hbox_new(FALSE, 3);
+       gtk_box_pack_start(GTK_BOX(filter_save_type_vb), entry_hb, FALSE,
+           FALSE, 0);
+       gtk_widget_show(entry_hb);
+
+       filter_text_box = gtk_entry_new();
+       gtk_box_pack_start(GTK_BOX(entry_hb), filter_text_box, TRUE, TRUE, 0);
+       gtk_entry_set_text(GTK_ENTRY(filter_text_box), expr);
+       gtk_widget_show(filter_text_box);
+
+       label_text_box = gtk_entry_new();
+       gtk_box_pack_start(GTK_BOX(entry_hb), label_text_box, TRUE, TRUE, 0);
+       gtk_entry_set_text(GTK_ENTRY(label_text_box), "Filter");
+       gtk_widget_show(label_text_box);
+
+       /* Button row */
+       bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL,
+           GTK_STOCK_HELP, NULL);
+       gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
+       gtk_widget_show(bbox);
+
+       ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
+       g_signal_connect(ok_bt, "clicked", G_CALLBACK(filter_save_ok_cb),
+       filter_save_frame_w);
+
+       cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
+       g_signal_connect(cancel_bt, "clicked", G_CALLBACK(filter_save_close_cb),
+       filter_save_frame_w);
+
+       help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
+       g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb),
+       (gpointer)HELP_FILTER_SAVE_DIALOG);
+
+       g_object_set_data(G_OBJECT(filter_save_frame_w),
+           E_FILTER_SAVE_EXPR_KEY, filter_text_box);
+       g_object_set_data(G_OBJECT(filter_save_frame_w),
+           E_FILTER_SAVE_LABEL_KEY, label_text_box);
+
+       dlg_set_activate(label_text_box, ok_bt);
+
+       /* Give the initial focus to the "offset" entry box. */
+       gtk_widget_grab_focus(label_text_box);
+
+       g_signal_connect(filter_save_frame_w, "delete_event",
+       G_CALLBACK(window_delete_event_cb), NULL);
+       g_signal_connect(filter_save_frame_w, "destroy",
+       G_CALLBACK(filter_save_frame_destroy_cb), NULL);
+
+       gtk_widget_show(filter_save_frame_w);
+       window_present(filter_save_frame_w);
+}
+
+static void
+filter_save_ok_cb(GtkWidget *ok_bt _U_, GtkWindow *parent_w)
+{
+       GtkWidget *expr_te, *label_te;
+       const char *expr, *label;
+
+       /* The filter requested */
+       expr_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w),
+           E_FILTER_SAVE_EXPR_KEY);
+       label_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w),
+           E_FILTER_SAVE_LABEL_KEY);
+       expr = gtk_entry_get_text(GTK_ENTRY(expr_te));
+       label = gtk_entry_get_text(GTK_ENTRY(label_te));
+
+       if (filter_button_add(label, expr, NULL) == 0) {
+               prefs_main_write();
+               filter_save_close_cb(NULL, parent_w);
+       }
+}
+
+static void
+filter_save_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
+{
+       gtk_grab_remove(GTK_WIDGET(parent_w));
+       window_destroy(GTK_WIDGET(parent_w));
+}
+
+static void
+filter_save_frame_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
+{
+       /* Note that we no longer have a "Filter Save" dialog box. */
+       filter_save_frame_w = NULL;
+}
diff --git a/gtk/filter_expression_save_dlg.h b/gtk/filter_expression_save_dlg.h
new file mode 100644 (file)
index 0000000..8c36e7e
--- /dev/null
@@ -0,0 +1,47 @@
+/* filter_expression_save_dlg.h
+ * Submitted by Edwin Groothuis <wireshark@mavetju.org>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __FILTER_EXPRESSIONS_SAVE_DLG_H__
+#define __FILTER_EXPRESSIONS_SAVE_DLG_H__
+
+#include "globals.h"
+#include "epan/filter_expressions.h"
+
+enum {
+       FILTER_EXPRESSION_REINIT_DESTROY = 1,
+       FILTER_EXPRESSION_REINIT_CREATE = 2
+};
+
+/** User requested to shift the time of the trace
+ *
+ * @param widget parent widget (unused)
+ * @param data unused
+ * @param action the function to use
+ */
+
+extern void filter_expression_save_dlg(gpointer data);
+void filter_expression_save_dlg_init(gpointer filter_tb, gpointer filter_te);
+void filter_expression_reinit(int what);
+
+#endif /* __FILTER_EXPRESSIONS_SAVE_DLG_H__ */
index 988bed5d3432ffe7f7ef98ba93e82253e3f45531..1626ff50934f9410d175802c16409185ffa795eb 100644 (file)
@@ -101,7 +101,8 @@ typedef enum {
     HELP_OPEN_WIN32_DIALOG,
     HELP_MERGE_WIN32_DIALOG,
     HELP_SAVE_WIN32_DIALOG,
-    HELP_TIME_SHIFT_DIALOG
+    HELP_TIME_SHIFT_DIALOG,
+    HELP_FILTER_SAVE_DIALOG
 } topic_action_e;
 
 
index ffdc062db216cc55c91ee5a947461d335d543550..709580117075a521abdee2a44108548abc007e5f 100644 (file)
 #include "gtk/prefs_dlg.h"
 #include "gtk/proto_help.h"
 #include "gtk/new_packet_list.h"
+#include "gtk/filter_expression_save_dlg.h"
 
 #include "gtk/old-gtk-compat.h"
 
@@ -3779,6 +3780,7 @@ void change_configuration_profile (const gchar *profile_name)
    /* Set profile name and update the status bar */
    set_profile_name (profile_name);
    profile_bar_update ();
+   filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
 
    /* Reset current preferences and apply the new */
    prefs_reset();
@@ -3806,6 +3808,7 @@ void change_configuration_profile (const gchar *profile_name)
 
    /* Update window view and redraw the toolbar */
    update_main_window_title();
+   filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
    toolbar_redraw_all();
 
    /* Enable all protocols and disable from the disabled list */
index 3d81fa3d276325d1c8a0a34f10ba68487d4b69b4..1a5728fd5f798de169ebe58d134a370fe401ec33 100644 (file)
@@ -50,6 +50,7 @@
 #include "menus.h"
 #include "main_toolbar.h"
 #include "main_filter_toolbar.h"
+#include "filter_expression_save_dlg.h"
 
 #ifdef MAIN_MENU_USE_UIMANAGER
 # define MENU_BAR_PATH_FILE_OPEN                               "/Menubar/FileMenu/Open"
@@ -64,7 +65,6 @@
 # define MENU_BAR_PATH_ANALYZE_APL_AS_FLT_OR_SEL               "/Menubar/AnalyzeMenu/ApplyAsFilter/OrSelected"
 # define MENU_BAR_PATH_ANALYZE_APL_AS_FLT_AND_NOT_SEL          "/Menubar/AnalyzeMenu/ApplyAsFilter/AndNotSelected"
 # define MENU_BAR_PATH_ANALYZE_APL_AS_FLT_OR_NOT_SEL           "/Menubar/AnalyzeMenu/ApplyAsFilter/OrNotSelected"
-
 # define MENU_BAR_PATH_ANALYZE_PREP_A_FLT_SEL                  "/Menubar/AnalyzeMenu/PrepareaFilter/Selected"
 # define MENU_BAR_PATH_ANALYZE_PREP_A_FLT_NOT_SEL              "/Menubar/AnalyzeMenu/PrepareaFilter/NotSelected"
 # define MENU_BAR_PATH_ANALYZE_PREP_A_FLT_AND_SEL              "/Menubar/AnalyzeMenu/PrepareaFilter/AndSelected"
@@ -123,6 +123,7 @@ filter_changed_cb(GtkWidget *w _U_, gpointer data)
 {
     gtk_widget_set_sensitive (g_object_get_data (G_OBJECT(data), E_DFILTER_APPLY_KEY), TRUE);
     gtk_widget_set_sensitive (g_object_get_data (G_OBJECT(data), E_DFILTER_CLEAR_KEY), TRUE);
+    gtk_widget_set_sensitive (g_object_get_data (G_OBJECT(data), E_DFILTER_SAVE_KEY), TRUE);
 }
 
 /* redisplay with no display filter */
@@ -137,13 +138,20 @@ filter_reset_cb(GtkWidget *w, gpointer data _U_)
     main_filter_packets(&cfile, NULL, FALSE);
 }
 
+static void
+filter_save_cb(GtkWidget *w _U_, GtkWindow *parent_w)
+{
+    filter_expression_save_dlg(parent_w);
+}
+
+
 GtkWidget *filter_toolbar_new(void)
 {
     GtkWidget     *filter_cm;
     GtkWidget     *filter_te;
     GtkWidget     *filter_tb;
-    GtkToolItem   *filter_bt, *filter_add_expr_bt, *filter_reset;
-    GtkToolItem   *filter_apply, *item;
+    GtkToolItem          *filter_bt, *filter_add_expr_bt, *filter_reset;
+    GtkToolItem   *filter_apply, *filter_save, *item;
 
 
     /* Display filter construct dialog has an Apply button, and "OK" not
@@ -217,7 +225,7 @@ GtkWidget *filter_toolbar_new(void)
                        filter_add_expr_bt,
                        -1);
 
-       gtk_widget_set_tooltip_text(GTK_WIDGET(filter_add_expr_bt), "Add an expression to this filter string");
+    gtk_widget_set_tooltip_text(GTK_WIDGET(filter_add_expr_bt), "Add an expression to this filter string");
 
     /* Create the "Clear" button */
     filter_reset = gtk_tool_button_new_from_stock(WIRESHARK_STOCK_CLEAR_EXPRESSION);
@@ -230,7 +238,7 @@ GtkWidget *filter_toolbar_new(void)
                        filter_reset,
                        -1);
 
-       gtk_widget_set_tooltip_text(GTK_WIDGET(filter_reset), "Clear this filter string and update the display");
+    gtk_widget_set_tooltip_text(GTK_WIDGET(filter_reset), "Clear this filter string and update the display");
 
     /* Create the "Apply" button */
     filter_apply = gtk_tool_button_new_from_stock(WIRESHARK_STOCK_APPLY_EXPRESSION);
@@ -244,7 +252,21 @@ GtkWidget *filter_toolbar_new(void)
                        filter_apply,
                        -1);
 
-       gtk_widget_set_tooltip_text(GTK_WIDGET(filter_apply), "Apply this filter string to the display");
+    gtk_widget_set_tooltip_text(GTK_WIDGET(filter_apply), "Apply this filter string to the display");
+
+    /* Create the "Save" button */
+    filter_save = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE);
+    g_object_set_data(G_OBJECT(filter_save), E_DFILTER_CM_KEY, filter_cm);
+    g_object_set_data(G_OBJECT(filter_cm), E_DFILTER_SAVE_KEY, filter_save);
+    g_signal_connect(filter_save, "clicked", G_CALLBACK(filter_save_cb), filter_te);
+    gtk_widget_set_sensitive (GTK_WIDGET(filter_save), FALSE);
+    gtk_widget_show(GTK_WIDGET(filter_save));
+
+    gtk_toolbar_insert(GTK_TOOLBAR(filter_tb),
+                       filter_save,
+                       -1);
+
+    gtk_widget_set_tooltip_text(GTK_WIDGET(filter_save), "Save this filter string");
 
     /* Sets the text entry widget pointer as the E_DILTER_TE_KEY data
      * of any widget that ends up calling a callback which needs
@@ -288,6 +310,8 @@ GtkWidget *filter_toolbar_new(void)
     set_toolbar_object_data(E_DFILTER_TE_KEY, filter_te);
     g_object_set_data(G_OBJECT(popup_menu_object), E_DFILTER_TE_KEY, filter_te);
 
+    filter_expression_save_dlg_init(filter_tb, filter_te);
+
     /* make current preferences effective */
     toolbar_redraw_all();
 
@@ -392,6 +416,7 @@ main_filter_packets(capture_file *cf, const gchar *dftext, gboolean force)
         gtk_widget_set_sensitive (g_object_get_data (G_OBJECT(filter_cm), E_DFILTER_APPLY_KEY), FALSE);
        if (!s || strlen (s) == 0) {
            gtk_widget_set_sensitive (g_object_get_data (G_OBJECT(filter_cm), E_DFILTER_CLEAR_KEY), FALSE);
+           gtk_widget_set_sensitive (g_object_get_data (G_OBJECT(filter_cm), E_DFILTER_SAVE_KEY), FALSE);
        }
     }
 
index e85aba61636e789d6c2892459433c879622dcfd7..e90b6d22717d82358eb2f80bdfc035a345c8911a 100644 (file)
@@ -28,6 +28,7 @@
 
 #define E_DFILTER_APPLY_KEY       "display_filter_apply"
 #define E_DFILTER_CLEAR_KEY       "display_filter_clear"
+#define E_DFILTER_SAVE_KEY        "display_filter_save"
 
 extern GtkWidget *filter_toolbar_new(void);
 
index 2dab83f1dafffc234cdf0c4d89c19c1527467e0e..cec0e2d442436d04c702e737463ec4bff4561f02 100644 (file)
@@ -43,6 +43,7 @@
 #include "gtk/main.h"
 #include "gtk/prefs_column.h"
 #include "gtk/prefs_dlg.h"
+#include "gtk/prefs_filter_expressions.h"
 #include "gtk/prefs_print.h"
 #include "gtk/prefs_stream.h"
 #include "gtk/prefs_gui.h"
@@ -97,6 +98,7 @@ static void     prefs_tree_select_cb(GtkTreeSelection *, gpointer);
 #define E_NAMERES_PAGE_KEY      "nameres_options_page"
 #define E_TAPS_PAGE_KEY         "taps_options_page"
 #define E_PROTOCOLS_PAGE_KEY    "protocols_options_page"
+#define E_FILTER_EXPRESSIONS_PAGE_KEY  "filter_expressions_page"
 
 /*
  * Keep a static pointer to the current "Preferences" window, if any, so that
@@ -578,6 +580,13 @@ prefs_page_cb(GtkWidget *w _U_, gpointer dummy _U_, PREFS_PAGE_E prefs_page)
   prefs_tree_page_add(label_str, cts.page, store, NULL);
   cts.page++;
 
+  /* Saved filter prefs */
+  g_strlcpy(label_str, "Filter Expressions", MAX_TREE_NODE_NAME_LEN);
+  prefs_nb_page_add(prefs_nb, label_str, filter_expressions_prefs_show(),
+    E_FILTER_EXPRESSIONS_PAGE_KEY);
+  prefs_tree_page_add(label_str, cts.page, store, NULL);
+  cts.page++;
+
   /* TAPS player prefs */
   g_strlcpy(label_str, "Statistics", MAX_TREE_NODE_NAME_LEN);
   prefs_nb_page_add(prefs_nb, label_str, stats_prefs_show(), E_TAPS_PAGE_KEY);
@@ -1255,6 +1264,8 @@ prefs_main_fetch_all(GtkWidget *dlg, gboolean *must_redissect)
 #endif /* HAVE_LIBPCAP */
   printer_prefs_fetch(g_object_get_data(G_OBJECT(dlg), E_PRINT_PAGE_KEY));
   nameres_prefs_fetch(g_object_get_data(G_OBJECT(dlg), E_NAMERES_PAGE_KEY));
+  filter_expressions_prefs_fetch(g_object_get_data(G_OBJECT(dlg),
+    E_FILTER_EXPRESSIONS_PAGE_KEY));
   stats_prefs_fetch(g_object_get_data(G_OBJECT(dlg), E_TAPS_PAGE_KEY));
   protocols_prefs_fetch(g_object_get_data(G_OBJECT(dlg), E_PROTOCOLS_PAGE_KEY));
   prefs_modules_foreach(module_prefs_fetch, must_redissect);
diff --git a/gtk/prefs_filter_expressions.c b/gtk/prefs_filter_expressions.c
new file mode 100644 (file)
index 0000000..cfde1bc
--- /dev/null
@@ -0,0 +1,387 @@
+/* prefs_filter_expressions.c
+ * Submitted by Edwin Groothuis <wireshark@mavetju.org>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <epan/prefs.h>
+#include <epan/column_info.h>
+#include <epan/column.h>
+#include <epan/strutil.h>
+#include <epan/filter_expressions.h>
+
+#include "../globals.h"
+
+#include "gtk/gtkglobals.h"
+#include "gtk/gui_utils.h"
+#include "gtk/new_packet_list.h"
+#include "gtk/filter_dlg.h"
+#include "gtk/filter_autocomplete.h"
+#include "gtk/filter_expression_save_dlg.h"
+#include "gtk/old-gtk-compat.h"
+
+static void filter_expressions_list_new_cb(GtkWidget *, gpointer);
+static void filter_expressions_list_remove_cb(GtkWidget *, gpointer);
+static gboolean filter_expressions_label_changed_cb(GtkCellRendererText *, const gchar *, const gchar *, gpointer);
+static gboolean filter_expressions_expression_changed_cb(GtkCellRendererText *, const gchar *, const gchar *, gpointer);
+
+#define E_FILTER_EXPRESSION_COLUMNL     "filter_expression_columnl"
+#define E_FILTER_EXPRESSION_STORE       "filter_expression_store"
+
+enum {
+    ENABLED_COLUMN,
+    LABEL_COLUMN,
+    EXPRESSION_COLUMN,
+    DATA_COLUMN,
+    N_COLUMN /* The number of columns */
+};
+
+/* Visible toggled */
+static void
+enable_toggled(GtkCellRendererToggle *cell _U_, gchar *path_str, gpointer data)
+{
+    GtkTreeModel    *model = (GtkTreeModel *)data;
+    GtkTreeIter      iter;
+    GtkTreePath     *path = gtk_tree_path_new_from_string(path_str);
+    struct filter_expression *fe;
+
+    gtk_tree_model_get_iter(model, &iter, path);
+    gtk_tree_model_get(model, &iter, DATA_COLUMN, &fe, -1);
+
+    fe->enabled = !fe->enabled;
+
+    gtk_list_store_set(GTK_LIST_STORE(model), &iter, ENABLED_COLUMN,
+       fe->enabled, -1);
+
+    gtk_tree_path_free(path);
+} /* visible_toggled */
+
+/*
+ * Create and display the column selection widgets.
+ * Called as part of the creation of the Preferences notebook ( Edit ! Preferences )
+ */
+GtkWidget *
+filter_expressions_prefs_show(void) {
+    GtkWidget         *main_vb, *bottom_hb, *column_l, *add_bt, *remove_bt;
+    GtkWidget         *list_vb, *list_lb, *list_sc;
+    GtkWidget         *add_remove_hb;
+    GtkListStore      *store;
+    GtkCellRenderer   *renderer;
+    GtkTreeViewColumn *column;
+    GtkTreeSelection  *sel;
+    GtkTreeIter        iter;
+    GtkTreeIter        first_iter;
+    gint               first_row = TRUE;
+    struct filter_expression *fe;
+    const gchar       *column_titles[] = {"Enabled", "Label",
+                                         "Filter Expression"};
+
+    /* Container for each row of widgets */
+    main_vb = gtk_vbox_new(FALSE, 5);
+    gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
+    gtk_widget_show(main_vb);
+
+    list_vb = gtk_vbox_new(FALSE, 0);
+    gtk_container_set_border_width(GTK_CONTAINER(list_vb), 5);
+    gtk_widget_show(list_vb);
+    gtk_box_pack_start(GTK_BOX(main_vb), list_vb, TRUE, TRUE, 0);
+
+    list_lb = gtk_label_new(("[The first list entry will be displayed as the "
+       "first button right of the Save button - Drag and drop entries to "
+       "change column order]"));
+    gtk_widget_show(list_lb);
+    gtk_box_pack_start(GTK_BOX(list_vb), list_lb, FALSE, FALSE, 0);
+
+    list_sc = scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(list_sc),
+       GTK_SHADOW_IN);
+    gtk_container_add(GTK_CONTAINER(list_vb), list_sc);
+    gtk_widget_show(list_sc);
+
+    store = gtk_list_store_new(N_COLUMN,
+                              G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING,
+                              G_TYPE_POINTER);
+
+    column_l = tree_view_new(GTK_TREE_MODEL(store));
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(column_l), TRUE);
+    gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(column_l), FALSE);
+    gtk_tree_view_set_reorderable(GTK_TREE_VIEW(column_l), TRUE);
+    gtk_widget_set_tooltip_text(column_l, "Click on a label or expression to "
+       "change its name.\nDrag an item to change its order.\nTick 'Enable' "
+       "to enable the filter in the buttons.");
+
+    /* Enabled buton */
+    renderer = gtk_cell_renderer_toggle_new();
+    g_signal_connect(renderer, "toggled", G_CALLBACK(enable_toggled), store);
+    column = gtk_tree_view_column_new_with_attributes(
+       column_titles[ENABLED_COLUMN], renderer, "active", ENABLED_COLUMN,
+       NULL);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(column_l), column);
+
+    /* Label editor */
+    renderer = gtk_cell_renderer_text_new();
+    g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL);
+    g_signal_connect(renderer, "edited",
+       G_CALLBACK(filter_expressions_label_changed_cb), GTK_TREE_MODEL(store));
+    column = gtk_tree_view_column_new_with_attributes(
+       column_titles[LABEL_COLUMN], renderer, "text", LABEL_COLUMN, NULL);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(column_l), column);
+
+    /* Expression editor */
+    renderer = gtk_cell_renderer_text_new();
+    g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL);
+    g_signal_connect(renderer, "edited",
+       G_CALLBACK(filter_expressions_expression_changed_cb),
+       GTK_TREE_MODEL(store));
+    column = gtk_tree_view_column_new_with_attributes(
+       column_titles[EXPRESSION_COLUMN], renderer, "text", EXPRESSION_COLUMN,
+       NULL);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(column_l), column);
+
+    /* XXX - make this match the packet list prefs? */
+    sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(column_l));
+    gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+
+    gtk_container_add(GTK_CONTAINER(list_sc), column_l);
+    gtk_widget_show(column_l);
+
+    fe = *pfilter_expression_head;
+    while (fe != NULL) {
+       fe->index = -1;
+        gtk_list_store_insert_with_values(store, &iter, G_MAXINT,
+           ENABLED_COLUMN, fe->enabled,
+           LABEL_COLUMN, fe->label,
+           EXPRESSION_COLUMN, fe->expression,
+           DATA_COLUMN, fe,
+           -1);
+
+        if (first_row) {
+            first_iter = iter;
+            first_row = FALSE;
+        }
+       fe = fe->next;
+    }
+    g_object_unref(G_OBJECT(store));
+
+    /* Bottom row: Add/remove buttons */
+    bottom_hb = gtk_hbox_new(FALSE, 5);
+    gtk_box_pack_start(GTK_BOX(main_vb), bottom_hb, FALSE, TRUE, 0);
+    gtk_widget_show(bottom_hb);
+
+    /* Add button */
+    add_remove_hb = gtk_hbox_new(TRUE, 0);
+    gtk_container_set_border_width(GTK_CONTAINER(add_remove_hb), 5);
+    gtk_box_pack_start(GTK_BOX(bottom_hb), add_remove_hb, FALSE, FALSE, 0);
+    gtk_widget_show(add_remove_hb);
+
+    add_bt = gtk_button_new_from_stock(GTK_STOCK_ADD);
+    g_signal_connect(add_bt, "clicked",
+       G_CALLBACK(filter_expressions_list_new_cb), column_l);
+    gtk_box_pack_start(GTK_BOX(add_remove_hb), add_bt, FALSE, FALSE, 0);
+    gtk_widget_set_tooltip_text(add_bt,
+       "Add a new row at the end of the list.");
+    gtk_widget_show(add_bt);
+
+    /* Remove button */
+    remove_bt = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
+    g_signal_connect(remove_bt, "clicked",
+       G_CALLBACK(filter_expressions_list_remove_cb), column_l);
+    gtk_box_pack_start(GTK_BOX(add_remove_hb), remove_bt, FALSE, FALSE, 0);
+    gtk_widget_set_tooltip_text(remove_bt, "Remove the selected row.");
+    gtk_widget_show(remove_bt);
+
+    /* select the first menu list row.             */
+    /*  Triggers call to column_list_select_cb().  */
+    if (first_row == FALSE)
+       gtk_tree_selection_select_iter(sel, &first_iter);
+
+    g_object_set_data(G_OBJECT(main_vb), E_FILTER_EXPRESSION_COLUMNL,
+       column_l);
+    g_object_set_data(G_OBJECT(main_vb), E_FILTER_EXPRESSION_STORE,
+       store);
+
+    return(main_vb);
+}
+
+static void
+filter_expressions_list_remove_cb(GtkWidget *w _U_, gpointer data)
+{
+    GtkTreeView      *column_l = GTK_TREE_VIEW(data);
+    GtkTreeSelection *sel;
+    GtkTreeModel     *model;
+    GtkTreeIter       iter;
+    struct filter_expression *fe;
+
+    sel = gtk_tree_view_get_selection(column_l);
+    if (!gtk_tree_selection_get_selected(sel, &model, &iter))
+       return;
+
+    gtk_tree_model_get(model, &iter, DATA_COLUMN, &fe, -1);
+    fe->deleted = TRUE;
+
+    gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+}
+
+static void
+filter_expressions_list_new_cb(GtkWidget *w _U_, gpointer data _U_)
+{
+    const gchar       *label = "New Label";
+    const gchar       *expression = "New Expression";
+    GtkTreeView       *fe_l = GTK_TREE_VIEW(data);
+    GtkTreeModel      *model;
+    GtkTreeIter        iter;
+    GtkTreePath       *path;
+    GtkTreeViewColumn *label_column;
+    struct filter_expression *fe;
+
+    fe = filter_expression_new(label, expression, TRUE);
+
+    model = gtk_tree_view_get_model(fe_l);
+    gtk_list_store_insert_with_values(GTK_LIST_STORE(model), &iter, G_MAXINT,
+       ENABLED_COLUMN, fe->enabled,
+       LABEL_COLUMN, fe->label,
+       EXPRESSION_COLUMN, fe->expression,
+       DATA_COLUMN, fe,
+       -1);
+
+    /* Triggers call to column_list_select_cb()   */
+    gtk_tree_selection_select_iter(gtk_tree_view_get_selection(fe_l), &iter);
+
+    /* Set the cursor to the 'Title' column of the newly added row and enable
+     * editing
+     * XXX: If displaying the new title ["New column"] widens the title column
+     * of the treeview, then the set_cursor below doesn't properly generate an
+     * entry box around the title text. The width of the box appears to be the
+     * column width before the treeview title column was widened. Seems like a
+     * bug...
+     *
+     *      I haven't found a work-around.
+     */
+    path = gtk_tree_model_get_path(model, &iter);
+    label_column = gtk_tree_view_get_column(fe_l, 2);
+    gtk_tree_view_set_cursor(fe_l, path, label_column, TRUE);
+    gtk_tree_path_free(path);
+}
+
+
+static gboolean
+filter_expressions_expression_changed_cb(GtkCellRendererText *cell _U_, const gchar *str_path, const gchar *new_expression, gpointer data)
+{
+    struct filter_expression *fe;
+    GtkTreeModel *model = (GtkTreeModel *)data;
+    GtkTreePath  *path = gtk_tree_path_new_from_string(str_path);
+    GtkTreeIter   iter;
+
+    gtk_tree_model_get_iter(model, &iter, path);
+    gtk_list_store_set(GTK_LIST_STORE(model), &iter, EXPRESSION_COLUMN,
+       new_expression, -1);
+
+    gtk_tree_model_get(model, &iter, DATA_COLUMN, &fe, -1);
+    if (fe != NULL) {
+        g_free(fe->expression);
+        fe->expression = g_strdup(new_expression);
+    }
+
+    gtk_tree_path_free(path);
+    return(TRUE);
+}
+
+static gboolean
+filter_expressions_label_changed_cb(GtkCellRendererText *cell _U_, const gchar *str_path, const gchar *new_label, gpointer data)
+{
+    struct filter_expression *fe;
+    GtkTreeModel *model = (GtkTreeModel *)data;
+    GtkTreePath  *path = gtk_tree_path_new_from_string(str_path);
+    GtkTreeIter   iter;
+
+    gtk_tree_model_get_iter(model, &iter, path);
+    gtk_list_store_set(GTK_LIST_STORE(model), &iter, LABEL_COLUMN, new_label,
+       -1);
+
+    gtk_tree_model_get(model, &iter, DATA_COLUMN, &fe, -1);
+    if (fe != NULL) {
+        g_free(fe->label);
+        fe->label = g_strdup(new_label);
+    }
+
+    gtk_tree_path_free(path);
+    return TRUE;
+}
+
+
+void
+filter_expressions_prefs_fetch(GtkWidget *w)
+{
+    gboolean      items_left;
+    GtkTreeModel *model;
+    GtkTreeView  *column_l;
+    GtkTreeIter   iter, first_iter;
+    GtkListStore *store;
+    struct filter_expression *fe;
+    gint          first_row = TRUE;
+    gint         index = 0;
+
+    column_l = (GtkTreeView *)g_object_get_data(G_OBJECT(w),
+       E_FILTER_EXPRESSION_COLUMNL);
+    model = gtk_tree_view_get_model(column_l);
+    store = (GtkListStore *)g_object_get_data(G_OBJECT(w),
+       E_FILTER_EXPRESSION_STORE);
+
+    /* Record the order of the items in the list.  */
+    items_left = gtk_tree_model_get_iter_first(model, &iter);
+    while (items_left) {
+        gtk_tree_model_get(model, &iter, DATA_COLUMN, &fe, -1);
+        if (fe != NULL)
+           fe->index = index++;
+       items_left = gtk_tree_model_iter_next (model, &iter);
+    }
+
+    filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY | FILTER_EXPRESSION_REINIT_CREATE);
+
+    gtk_list_store_clear(store);
+    fe = *pfilter_expression_head;
+    while (fe != NULL) {
+       fe->index = -1;
+        gtk_list_store_insert_with_values(store, &iter, G_MAXINT,
+           ENABLED_COLUMN, fe->enabled,
+           LABEL_COLUMN, fe->label,
+           EXPRESSION_COLUMN, fe->expression,
+           DATA_COLUMN, fe,
+           -1);
+
+        if (first_row) {
+            first_iter = iter;
+            first_row = FALSE;
+        }
+       fe = fe->next;
+    }
+}
diff --git a/gtk/prefs_filter_expressions.h b/gtk/prefs_filter_expressions.h
new file mode 100644 (file)
index 0000000..6db77da
--- /dev/null
@@ -0,0 +1,45 @@
+/* prefs_filter_expressions.h
+ * Submitted by Edwin Groothuis <wireshark@mavetju.org>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __PREFS_FILTER_EXPRESSIONS_H__
+#define __PREFS_FILTER_EXPRESSIONS_H__
+
+/** @file
+ *  "Name resolution" preferences page.
+ *  @ingroup prefs_group
+ */
+
+/** Build a Filter Save preferences page.
+ *
+ * @return the new preferences page
+ */
+GtkWidget *filter_expressions_prefs_show(void);
+
+/** Fetch preference values from page.
+ *
+ * @param widget widget from filtersave_prefs_show()
+ */
+void filter_expressions_prefs_fetch(GtkWidget *widget);
+
+#endif
index 58d782c8d82a86eed69e2d4ba3eaa62c2e5a70a9..52f6ee93b78cd8ad840b2c7bbf5444bebde30b98 100644 (file)
--- a/services
+++ b/services
@@ -14,7 +14,7 @@
 # Service Name and Transport Protocol Port Number Registry
 # 
 # Last Updated
-# 2011-08-31
+# 2011-09-07
 # 
 # Note
 # 
@@ -1491,8 +1491,8 @@ keyserver 584/udp # Key Server                   [Gary_Howland]
 # 585               De-registered                                                                                                                           2006-04-25                                                             Use of 585 is not recommended, use 993 instead
 password-chg   586/tcp # Password Change
 password-chg   586/udp # Password Change
-submission     587/tcp # Submission                                                                                                                                           [RFC4409]
-submission     587/udp # Submission                                                                                                                                           [RFC4409]
+submission     587/tcp # Message Submission                                                                                                                                   [RFC-ietf-yam-rfc4409bis-03]
+submission     587/udp # Message Submission                                                                                                                                   [RFC-ietf-yam-rfc4409bis-03]
 cal    588/tcp # CAL                          [Myron_Hattig]                      [Myron_Hattig]
 cal    588/udp # CAL                          [Myron_Hattig]                      [Myron_Hattig]
 eyelink        589/tcp # EyeLink                      [Dave_Stampe]                       [Dave_Stampe]
@@ -15242,7 +15242,18 @@ EtherNet-IP-2  44818/udp       # IANA assigned this           [Brian_Batke_2]
 # New contact added for port 44818 on 2008-02-01 This entry is
 EtherNet/IP-2  44818/udp       # EtherNet/IP messaging        [Brian_Batke_2]                     [Brian_Batke_2]                                                                                                                               an alias to "EtherNet-IP-2". This entry is now historic, not
 # usable for use with many common service discovery mechanisms.
-# 44819-45053           Unassigned
+# 44819-44999           Unassigned
+# NSi AutoStore Status
+asmp   45000/tcp       # Monitoring Protocol data     [Notable_Solutions_Inc]             [Andrew_Andrews]                                          2011-09-01
+# transfer
+# NSi AutoStore Status
+asmp-mon       45000/udp       # Monitoring Protocol device   [Notable_Solutions_Inc]             [Andrew_Andrews]                                          2011-09-01
+# monitoring
+# NSi AutoStore Status
+asmps  45001/tcp       # Monitoring Protocol secure   [Notable_Solutions_Inc]             [Andrew_Andrews]                                          2011-09-01
+# data transfer
+# 45001       udp    Reserved
+# 45002-45053           Unassigned
 invision-ag    45054/tcp       # InVision AG                  [Matthias_Schroer]                  [Matthias_Schroer]
 invision-ag    45054/udp       # InVision AG                  [Matthias_Schroer]                  [Matthias_Schroer]
 # 45055-45677           Unassigned
@@ -15954,8 +15965,6 @@ matahari        49000/tcp       # Matahari Broker              [Matahari_Project]
 # Java Bonjour application)
 # panoply                        tcp    Panoply multimedia composite [Natarajan_Balasundar]              [Natarajan_Balasundar]                                                                                                                        Defined TXT keys: None
 # transfer protocol
-# panoply                        udp    Panoply multimedia composite [Natarajan_Balasundar]              [Natarajan_Balasundar]                                                                                                                        Defined TXT keys: None
-# transfer protocol
 # parabay-p2p                    tcp    Parabay P2P protocol         [Vishnu_Varadaraj]                  [Vishnu_Varadaraj]                                                                                                                            Defined TXT keys: None
 # pgpkey-hkp                            Horowitz Key Protocol (HKP)  [Marc_Horowitz]                     [Marc_Horowitz]                                                                                                                               Defined TXT keys: None
 # pgpkey-http                           PGP Keyserver using HTTP/1.1 [Jeroen_Massar_3]                   [Jeroen_Massar_3]                                                                                                                             Defined TXT keys: path=<path on the server where the HKP
@@ -16513,6 +16522,7 @@ matahari        49000/tcp       # Matahari Broker              [Matahari_Project]
 # [Andrei_Vilkotski]                                        Andrei Vilkotski                          mailto:andreiv&sgi.com                                        2003-06
 # [Andres_Seco_Hernande]                                    Andres Seco Hernandez                     mailto:AndresSH&alamin.org
 # [Andrew_Aksyonoff]                                        Andrew Aksyonoff                          mailto:shodan&sphinxsearch.com                                2009-10-20
+# [Andrew_Andrews]                                          Andrew Andrews                            mailto:Andrew.Andrews&nsius.com                               2011-09-01
 # [Andrew_Borisov]                                          Andrew Borisov                            mailto:hdr&chat.ru
 # [Andrew_Chernow]                                          Andrew Chernow                            mailto:andrew&esilo.com                                       2007-01
 # [Andrew_Crockford]                                        Andrew Crockford                          mailto:andrew.crockford&modus-interactive.co.uk
@@ -19293,6 +19303,8 @@ matahari        49000/tcp       # Matahari Broker              [Matahari_Project]
 # [Norman_Brie]                                             Norman Brie                               mailto:norm_brie&sns.ca
 # [Norman_Wilson]                                           Norman Wilson                             mailto:nwilson&programmar.com                                 2010-10-06
 # [Northon_Rodrigues]                                       Northon Rodrigues                         mailto:northon.rodrigues&thomson.net                          2004-02
+# [Notable_Solutions_Inc]                                                             Notable         mailto:dev&nsius.com                                          2011-09-01
+# Solutions, Inc.
 # [NovaWiz_LTD]                                             NovaWiz LTD                               mailto:Moshe&novawiz.com
 # OASIS KMIP
 # [OASIS_KMIP_Technical_Committee]                                                    Technical       mailto:robin&oasis-open.org                                   2011-07-25