From: stig Date: Thu, 8 Sep 2011 09:35:10 +0000 (+0000) Subject: From Edwin Groothuis via bug 6207: X-Git-Url: http://git.samba.org/samba.git/?p=obnox%2Fwireshark%2Fwip.git;a=commitdiff_plain;h=2c10f37a6fd068957c2320aa23fbf405b35c636b From Edwin Groothuis via bug 6207: 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 --- diff --git a/AUTHORS b/AUTHORS index 020f6d3f21..8ed5c0ee51 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3294,6 +3294,7 @@ Allison { Edwin Groothuis { Time Shift functionality + Filter Toolbar Save functionality } Andrew Kampjes { diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index 9d518de0a8..89bcfe6442 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -1217,6 +1217,7 @@ set(LIBWIRESHARK_FILES except.c expert.c filesystem.c + filter_expressions.c follow.c frame_data.c frequency-utils.c diff --git a/epan/Makefile.common b/epan/Makefile.common index 9ef81117ba..737e6a0f10 100644 --- a/epan/Makefile.common +++ b/epan/Makefile.common @@ -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 index 0000000000..92c9439ff8 --- /dev/null +++ b/epan/filter_expressions.c @@ -0,0 +1,80 @@ +/* filter_expressions.c + * Submitted by Edwin Groothuis + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 +#include + +#include + +#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 index 0000000000..05f66d3c68 --- /dev/null +++ b/epan/filter_expressions.h @@ -0,0 +1,49 @@ +/* filter_expressions.h + * Submitted by Edwin Groothuis + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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__ */ diff --git a/epan/libwireshark.def b/epan/libwireshark.def index 7ec9c99cc7..5dddcbcaa3 100644 --- a/epan/libwireshark.def +++ b/epan/libwireshark.def @@ -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 diff --git a/epan/prefs.c b/epan/prefs.c index 73435e1ce3..2082109896 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -53,6 +53,8 @@ #include #include +#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"); diff --git a/epan/prefs.h b/epan/prefs.h index a7ab2450b3..395119c636 100644 --- a/epan/prefs.h +++ b/epan/prefs.h @@ -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; diff --git a/gtk/CMakeLists.txt b/gtk/CMakeLists.txt index e743556ceb..2f658c5260 100644 --- a/gtk/CMakeLists.txt +++ b/gtk/CMakeLists.txt @@ -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 diff --git a/gtk/Makefile.common b/gtk/Makefile.common index f37fd0b8ae..d1e24b1e96 100644 --- a/gtk/Makefile.common +++ b/gtk/Makefile.common @@ -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 index 0000000000..1eab652195 --- /dev/null +++ b/gtk/filter_expression_save_dlg.c @@ -0,0 +1,357 @@ +/* filter_expression_save_dlg.c + * Routines for "Filter Save" window + * Submitted by Edwin Groothuis + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#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 index 0000000000..8c36e7e060 --- /dev/null +++ b/gtk/filter_expression_save_dlg.h @@ -0,0 +1,47 @@ +/* filter_expression_save_dlg.h + * Submitted by Edwin Groothuis + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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__ */ diff --git a/gtk/help_dlg.h b/gtk/help_dlg.h index 988bed5d34..1626ff5093 100644 --- a/gtk/help_dlg.h +++ b/gtk/help_dlg.h @@ -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; diff --git a/gtk/main.c b/gtk/main.c index ffdc062db2..7095801170 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -162,6 +162,7 @@ #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 */ diff --git a/gtk/main_filter_toolbar.c b/gtk/main_filter_toolbar.c index 3d81fa3d27..1a5728fd5f 100644 --- a/gtk/main_filter_toolbar.c +++ b/gtk/main_filter_toolbar.c @@ -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); } } diff --git a/gtk/main_filter_toolbar.h b/gtk/main_filter_toolbar.h index e85aba6163..e90b6d2271 100644 --- a/gtk/main_filter_toolbar.h +++ b/gtk/main_filter_toolbar.h @@ -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); diff --git a/gtk/prefs_dlg.c b/gtk/prefs_dlg.c index 2dab83f1da..cec0e2d442 100644 --- a/gtk/prefs_dlg.c +++ b/gtk/prefs_dlg.c @@ -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 index 0000000000..cfde1bc3eb --- /dev/null +++ b/gtk/prefs_filter_expressions.c @@ -0,0 +1,387 @@ +/* prefs_filter_expressions.c + * Submitted by Edwin Groothuis + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 + +#include + +#include +#include +#include +#include +#include + +#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 index 0000000000..6db77da9f8 --- /dev/null +++ b/gtk/prefs_filter_expressions.h @@ -0,0 +1,45 @@ +/* prefs_filter_expressions.h + * Submitted by Edwin Groothuis + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 diff --git a/services b/services index 58d782c8d8..52f6ee93b7 100644 --- 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=