aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS5
-rw-r--r--color.h3
-rw-r--r--doc/ethereal.pod.template83
-rw-r--r--gtk/color_dlg.c571
-rw-r--r--gtk/color_dlg.h5
-rw-r--r--gtk/color_filters.c86
-rw-r--r--gtk/color_filters.h5
-rw-r--r--gtk/file_dlg.c305
-rw-r--r--gtk/file_dlg.h5
9 files changed, 865 insertions, 203 deletions
diff --git a/AUTHORS b/AUTHORS
index 57fad8b98c..10736b293a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1422,9 +1422,10 @@ Liviu Daia <Liviu.Daia[AT]imar.ro> {
from the command line
}
-Richard Urwin <rurwin[AT]schenck.co.uk> {
+Richard Urwin <richard[AT]soronlin.org.uk> {
Developer documentation fixes and updates
- Support for a system-wide color filter file
+ Support for a system-wide color filter file and color filter
+ import and export
}
Prabhakar Krishnan <Prabhakar.Krishnan[AT]netapp.com> {
diff --git a/color.h b/color.h
index 9eef8f8edd..cc71915cd0 100644
--- a/color.h
+++ b/color.h
@@ -1,7 +1,7 @@
/* color.h
* Definitions for "toolkit-independent" colors
*
- * $Id: color.h,v 1.3 2002/09/23 19:09:47 oabad Exp $
+ * $Id: color.h,v 1.4 2003/08/18 21:27:07 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -53,6 +53,7 @@ typedef struct _color_filter {
dfilter_t *c_colorfilter; /* compiled filter expression */
void *edit_dialog; /* if filter is being edited, dialog
* box for it */
+ gboolean marked; /* set if the filter is marked in the color dialog box */
} color_filter_t;
/* List of all color filters. */
diff --git a/doc/ethereal.pod.template b/doc/ethereal.pod.template
index c2928bcc34..9c44235788 100644
--- a/doc/ethereal.pod.template
+++ b/doc/ethereal.pod.template
@@ -551,6 +551,89 @@ ignored. Therefore, if you are filtering on the existence of protocols,
you should list the higher-level protocols first, and the lower-level
protocols last.
+How Colorization Works
+----------------------
+Packets are colored according to a list of color filters. Each filter
+consists of a name, a filter expression and a coloration. A packet is
+colored according to the first filter that it matches, Color filter
+expressions use exactly the same syntax as display filter expressions.
+
+When Ethereal starts the color filters are loaded from:
+1. The user's personal colorfilters file or, if that does not exist,
+2. The global colorfilters file.
+If neither of these exist then the packets will not be colored.
+
+The Color Filters Dialog
+------------------------
+This dialog displays a list of color filters and allows it to be
+modified.
+
+THE FILTER LIST
+Single rows may be selected by clicking. Multiple rows may be selected
+by using the ctrl and shift keys in combination with the mouse button.
+
+UP
+Moves the selected filter(s) up the list, making it more likely that
+they will be used to color packets.
+
+DOWN
+Moves the selected filter(s) down the list, making it less likely that
+they will be used to color packets.
+
+NEW
+Adds a new filter at the bottom of the list and opens the Edit Color
+Filter dialog box. You will have to alter the filter expression at
+least before the filter will be accepted. The format of color filter
+expressions is identical to that of display filters. The new filter is
+selected, so it may immediately be moved up and down, deleted or edited.
+To avoid confusion all filters are unselected before the new filter is
+created.
+
+EDIT
+Opens the Edit Color Filter dialog box for the selected filter. (If this
+button is disabled you may have more than one filter selected, making it
+ambiguous which is to be edited.)
+
+DELETE
+Deletes the selected color filter(s).
+
+OK
+Closes the dialog and uses the color filters as they stand.
+
+APPLY
+Colors the packets according to the current list of color filters, but
+does not close the dialog.
+
+SAVE
+Saves the current list of color filters in your personal colorfilters
+file. Unless you do this they will not be used the next time you start
+Ethereal.
+
+REVERT
+Deletes your personal colorfilters file, reloads the global
+colorfilters file, if any, and closes the dialog.
+
+EXPORT (Save As if using GTK2+)
+Allows you to choose a file in which to save the current list of color
+filters. You may also choose to save only the selected filters. A
+button is provided to save the filters in the global colorfilter file,
+(you must have sufficient permissions to write this file, of course.)
+
+IMPORT (Open if using GTK2+)
+Allows you to choose a file containing color filters which are then
+added to the bottom of the current list. All the added filters are
+selected, so they may be moved to the correct position in the list as a
+group. To avoid confusion all filters are unselected before the new
+filters are imported. A button is provided to load the filters from the
+global colorfilter file.
+
+CANCEL
+Closes the dialog without changing the coloration of the packets. Note
+that changes you have made to the current list of color filters is not
+undone.
+
+
+
=item Display:Collapse All
Collapse the protocol tree branches.
diff --git a/gtk/color_dlg.c b/gtk/color_dlg.c
index 770a4c9ac8..40f3681e73 100644
--- a/gtk/color_dlg.c
+++ b/gtk/color_dlg.c
@@ -1,7 +1,7 @@
/* color_dlg.c
* Definitions for dialog boxes for color filters
*
- * $Id: color_dlg.c,v 1.24 2003/05/15 07:44:54 guy Exp $
+ * $Id: color_dlg.c,v 1.25 2003/08/18 21:27:09 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -44,6 +44,7 @@
#include "ui_util.h"
#include "dfilter_expr_dlg.h"
#include "compat_macros.h"
+#include "file_dlg.h"
static GtkWidget* colorize_dialog_new(void);
static void add_filter_to_list(gpointer filter_arg, gpointer list_arg);
@@ -67,7 +68,7 @@ static void color_ok_cb(GtkButton *button, gpointer user_data);
static void color_cancel_cb(GtkWidget *widget, gpointer user_data);
static void color_apply_cb(GtkButton *button, gpointer user_data);
static void color_revert_cb(GtkWidget *button, gpointer user_data);
-
+static void color_import_cb(GtkButton *button, gpointer user_data );
static void edit_color_filter_dialog_new(GtkWidget *color_filters,
GtkWidget **colorize_filter_name,
@@ -123,6 +124,27 @@ color_display_cb(GtkWidget *w _U_, gpointer d _U_)
}
}
+/* if this filter is marked count it in the given int* */
+static void
+count_this_mark(gpointer filter_arg, gpointer counter_arg)
+{
+ color_filter_t *colorf = filter_arg;
+ int * cnt = counter_arg;
+
+ if (colorf->marked)
+ (*cnt)++;
+}
+
+/* TODO: implement count of selected filters. Plug in to file_dlg update of "export selected" checkbox. */
+int color_marked_count(void)
+{
+ int count = 0;
+
+ g_slist_foreach(filter_list, count_this_mark, &count);
+
+ return count;
+}
+
/* Create the "Apply Color Filters" dialog. */
static GtkWidget*
colorize_dialog_new (void)
@@ -151,9 +173,14 @@ colorize_dialog_new (void)
GtkWidget *color_delete;
GtkWidget *button_ok_hbox;
+ GtkWidget *importexport_vbox;
+ GtkWidget *okapply_vbox;
+ GtkWidget *saverevert_vbox;
GtkWidget *color_ok;
GtkWidget *color_apply;
GtkWidget *color_save;
+ GtkWidget *color_export;
+ GtkWidget *color_import;
GtkWidget *color_revert;
GtkWidget *color_cancel;
@@ -236,6 +263,12 @@ colorize_dialog_new (void)
gtk_widget_show (list_vbox);
gtk_container_add(GTK_CONTAINER(list_fr), list_vbox);
+ list_label = gtk_label_new (("[List is processed in order until match is found]"));
+ gtk_widget_ref (list_label);
+ OBJECT_SET_DATA_FULL(color_win, "list_label", list_label, gtk_widget_unref);
+ gtk_widget_show (list_label);
+ gtk_box_pack_start (GTK_BOX (list_vbox), list_label, FALSE, FALSE, 0);
+
/* create the list of filters */
scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
#if GTK_MAJOR_VERSION >= 2
@@ -276,7 +309,9 @@ colorize_dialog_new (void)
g_slist_foreach(filter_list, add_filter_to_list, color_filters);
#if GTK_MAJOR_VERSION >= 2
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
- gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
+#else
+ gtk_clist_set_selection_mode (GTK_CLIST (color_filters),GTK_SELECTION_EXTENDED);
#endif
gtk_widget_show (color_filters);
@@ -287,11 +322,6 @@ colorize_dialog_new (void)
gtk_clist_column_titles_show (GTK_CLIST (color_filters));
#endif
- list_label = gtk_label_new (("[List is processed in order until match is found]"));
- gtk_widget_ref (list_label);
- OBJECT_SET_DATA_FULL(color_win, "list_label", list_label, gtk_widget_unref);
- gtk_widget_show (list_label);
- gtk_box_pack_start (GTK_BOX (list_vbox), list_label, FALSE, FALSE, 0);
/* end list_frame */
/* edit buttons frame */
@@ -354,6 +384,12 @@ colorize_dialog_new (void)
gtk_widget_show (button_ok_hbox);
gtk_box_pack_start (GTK_BOX (dlg_vbox), button_ok_hbox, FALSE, FALSE, 5);
+ okapply_vbox = gtk_vbox_new (FALSE, 0);
+ gtk_widget_ref (okapply_vbox);
+ OBJECT_SET_DATA_FULL(color_win, "okapply_vbox", okapply_vbox, gtk_widget_unref);
+ gtk_widget_show (okapply_vbox);
+ gtk_box_pack_start (GTK_BOX (button_ok_hbox), okapply_vbox, TRUE, TRUE, 0);
+
#if GTK_MAJOR_VERSION < 2
color_ok = gtk_button_new_with_label (("OK"));
#else
@@ -362,7 +398,7 @@ colorize_dialog_new (void)
gtk_widget_ref (color_ok);
OBJECT_SET_DATA_FULL(color_win, "color_ok", color_ok, gtk_widget_unref);
gtk_widget_show (color_ok);
- gtk_box_pack_start (GTK_BOX (button_ok_hbox), color_ok, TRUE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (okapply_vbox), color_ok, FALSE, FALSE, 0);
gtk_tooltips_set_tip (tooltips, color_ok, ("Accept filter list; apply changes"), NULL);
#if GTK_MAJOR_VERSION < 2
@@ -373,9 +409,15 @@ colorize_dialog_new (void)
gtk_widget_ref (color_apply);
OBJECT_SET_DATA_FULL(color_win, "color_apply", color_apply, gtk_widget_unref);
gtk_widget_show (color_apply);
- gtk_box_pack_start (GTK_BOX (button_ok_hbox), color_apply, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (okapply_vbox), color_apply, FALSE, FALSE, 0);
gtk_tooltips_set_tip (tooltips, color_apply, ("Apply filters in list"), NULL);
+ saverevert_vbox = gtk_vbox_new (FALSE, 0);
+ gtk_widget_ref (saverevert_vbox);
+ OBJECT_SET_DATA_FULL(color_win, "saverevert_vbox", saverevert_vbox, gtk_widget_unref);
+ gtk_widget_show (saverevert_vbox);
+ gtk_box_pack_start (GTK_BOX (button_ok_hbox), saverevert_vbox, TRUE, TRUE, 0);
+
#if GTK_MAJOR_VERSION < 2
color_save = gtk_button_new_with_label (("Save"));
#else
@@ -384,7 +426,7 @@ colorize_dialog_new (void)
gtk_widget_ref(color_save);
OBJECT_SET_DATA_FULL(color_win, "color_save", color_save, gtk_widget_unref);
gtk_widget_show(color_save);
- gtk_box_pack_start(GTK_BOX (button_ok_hbox), color_save, FALSE, FALSE, 5);
+ gtk_box_pack_start(GTK_BOX (saverevert_vbox), color_save, FALSE, FALSE, 0);
gtk_tooltips_set_tip(tooltips, color_save, ("Save all filters to disk"), NULL);
#if GTK_MAJOR_VERSION < 2
@@ -395,9 +437,35 @@ colorize_dialog_new (void)
gtk_widget_ref(color_revert);
OBJECT_SET_DATA_FULL(color_win, "color_revert", color_revert, gtk_widget_unref);
gtk_widget_show(color_revert);
- gtk_box_pack_start(GTK_BOX (button_ok_hbox), color_revert, FALSE, FALSE, 5);
+ gtk_box_pack_start(GTK_BOX (saverevert_vbox), color_revert, FALSE, FALSE, 0);
gtk_tooltips_set_tip(tooltips, color_revert, ("Delete filter file and revert to system-wide default filter set"), NULL);
+ importexport_vbox = gtk_vbox_new (FALSE, 0);
+ gtk_widget_ref (importexport_vbox);
+ OBJECT_SET_DATA_FULL(color_win, "importexport_vbox", importexport_vbox, gtk_widget_unref);
+ gtk_widget_show (importexport_vbox);
+ gtk_box_pack_start (GTK_BOX (button_ok_hbox), importexport_vbox, TRUE, TRUE, 0);
+
+#if GTK_MAJOR_VERSION < 2
+ color_export = gtk_button_new_with_label (("Export"));
+#else
+ color_export = gtk_button_new_from_stock(GTK_STOCK_SAVE_AS);
+#endif
+ gtk_widget_ref(color_export);
+ gtk_widget_show(color_export);
+ gtk_box_pack_start(GTK_BOX (importexport_vbox), color_export, FALSE, FALSE, 0);
+ gtk_tooltips_set_tip(tooltips, color_export, ("Save filters to specified file"), NULL);
+
+#if GTK_MAJOR_VERSION < 2
+ color_import = gtk_button_new_with_label (("Import"));
+#else
+ color_import = gtk_button_new_from_stock(GTK_STOCK_OPEN);
+#endif
+ gtk_widget_ref(color_import);
+ gtk_widget_show(color_import);
+ gtk_box_pack_start(GTK_BOX (importexport_vbox), color_import, FALSE, FALSE, 0);
+ gtk_tooltips_set_tip(tooltips, color_import, ("Load filters from specified file"), NULL);
+
#if GTK_MAJOR_VERSION < 2
color_cancel = gtk_button_new_with_label (("Cancel"));
#else
@@ -433,8 +501,11 @@ colorize_dialog_new (void)
OBJECT_SET_DATA(color_delete, COLOR_FILTERS_CL, color_filters);
SIGNAL_CONNECT(color_delete, "clicked", color_delete_cb, NULL);
SIGNAL_CONNECT(color_save, "clicked", color_save_cb, NULL);
- SIGNAL_CONNECT(color_revert, "clicked", color_revert_cb, NULL);
+ SIGNAL_CONNECT(color_export, "clicked", file_color_export_cmd_cb, NULL);
+ OBJECT_SET_DATA(color_import, COLOR_FILTERS_CL, color_filters);
+ SIGNAL_CONNECT(color_import, "clicked", color_import_cb, color_filters);
OBJECT_SET_DATA(color_revert, COLOR_FILTERS_CL, color_filters);
+ SIGNAL_CONNECT(color_revert, "clicked", color_revert_cb, NULL);
SIGNAL_CONNECT(color_ok, "clicked", color_ok_cb, NULL);
SIGNAL_CONNECT(color_apply, "clicked", color_apply_cb, NULL);
SIGNAL_CONNECT(color_cancel, "clicked", color_cancel_cb, NULL);
@@ -484,40 +555,55 @@ add_filter_to_list(gpointer filter_arg, gpointer list_arg)
num_of_filters++;
}
-/* Move the selected filter up in the list */
-static void
-color_filter_up_cb(GtkButton *button, gpointer user_data _U_)
+void move_this_row (GtkWidget *color_filters,
+ gint filter_number,
+ gint amount) /* only tested with +1(down) and -1(up) */
{
- gint filter_number;
- GtkWidget *color_filters;
color_filter_t *colorf;
-#if GTK_MAJOR_VERSION >= 2
+#if GTK_MAJOR_VERSION < 2
+ gint lower, higher;
+#else
GtkTreeModel *model;
GtkTreeIter iter1, iter2;
gchar *name, *string, *fg_str, *bg_str;
#endif
- filter_number = row_selected;
- g_assert(filter_number > 0);
+ g_assert(amount == +1 || amount == -1);
+ g_assert(amount == +1 || filter_number > 0);
+ g_assert(amount == -1 || filter_number < num_of_filters - 1);
- color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
#if GTK_MAJOR_VERSION < 2
+ if (amount > 0)
+ {
+ lower = filter_number;
+ higher = filter_number + amount;
+ }
+ else
+ {
+ higher = filter_number;
+ lower = filter_number + amount;
+ }
+
colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
- gtk_clist_swap_rows(GTK_CLIST(color_filters), filter_number, filter_number-1);
+ gtk_clist_swap_rows(GTK_CLIST(color_filters), higher, lower);
/*
- * That row is still selected, but it's now row N-1.
+ * That row is still selected, but it's now moved.
*/
- remember_selected_row(GTK_CLIST(color_filters), filter_number-1, 0, NULL,
- NULL);
+ remember_selected_row(GTK_CLIST(color_filters), filter_number + amount, 0, NULL, NULL);
#else
+
model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
- gtk_tree_model_iter_nth_child(model, &iter1, NULL, row_selected);
- gtk_tree_model_iter_nth_child(model, &iter2, NULL, row_selected-1);
+ gtk_tree_model_iter_nth_child(model, &iter1, NULL, filter_number);
+ gtk_tree_model_iter_nth_child(model, &iter2, NULL, filter_number + amount);
+
gtk_tree_model_get(model, &iter1, 0, &name, 1, &string,
2, &fg_str, 3, &bg_str, 4, &colorf, -1);
gtk_list_store_remove(GTK_LIST_STORE(model), &iter1);
- gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter1, &iter2);
+ if (amount < 0)
+ gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter1, &iter2);
+ else
+ gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter1, &iter2);
gtk_list_store_set(GTK_LIST_STORE(model), &iter1, 0, name, 1, string,
2, fg_str, 3, bg_str, 4, colorf, -1);
g_free(name);
@@ -530,64 +616,91 @@ color_filter_up_cb(GtkButton *button, gpointer user_data _U_)
*/
gtk_widget_grab_focus(color_filters);
gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters)), &iter1);
+
#endif
filter_list = g_slist_remove(filter_list, colorf);
- filter_list = g_slist_insert(filter_list, colorf, filter_number-1);
+ filter_list = g_slist_insert(filter_list, colorf, filter_number + amount);
}
-/* Move the selected filter down in the list */
+/* Move the selected filters up in the list */
static void
-color_filter_down_cb(GtkButton *button, gpointer user_data _U_)
+color_filter_up_cb(GtkButton *button, gpointer user_data _U_)
{
- gint filter_number;
- GtkWidget *color_filters;
+ gint amount;
+ gint filter_number;
+ GtkWidget * color_filters;
color_filter_t *colorf;
-#if GTK_MAJOR_VERSION >= 2
- GtkTreeModel *model;
- GtkTreeIter iter1, iter2;
- gchar *name, *string, *fg_str, *bg_str;
+#if GTK_MAJOR_VERSION < 2
+#else
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ GtkTreeSelection *sel;
#endif
- filter_number = row_selected;
- g_assert(filter_number < num_of_filters - 1);
-
+ amount = -1;
color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
+
#if GTK_MAJOR_VERSION < 2
- colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
- gtk_clist_swap_rows(GTK_CLIST(color_filters), filter_number+1, filter_number);
+ colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), 0);
+ if (colorf->marked)
+ return;
+#endif
- /*
- * That row is still selected, but it's now row N+1.
- */
- remember_selected_row(GTK_CLIST(color_filters), filter_number+1, 0, NULL,
- NULL);
+ for (filter_number = 0; filter_number < num_of_filters; filter_number++)
+ {
+#if GTK_MAJOR_VERSION < 2
+ colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
+ if (colorf->marked)
+ move_this_row (color_filters, filter_number, amount);
#else
- model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
- gtk_tree_model_iter_nth_child(model, &iter1, NULL, row_selected);
- gtk_tree_model_iter_nth_child(model, &iter2, NULL, row_selected+1);
- gtk_tree_model_get(model, &iter1, 0, &name, 1, &string,
- 2, &fg_str, 3, &bg_str, 4, &colorf, -1);
- gtk_list_store_remove(GTK_LIST_STORE(model), &iter1);
- gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter1, &iter2);
- gtk_list_store_set(GTK_LIST_STORE(model), &iter1, 0, name, 1, string,
- 2, fg_str, 3, bg_str, 4, colorf, -1);
- g_free(name);
- g_free(string);
- g_free(fg_str);
- g_free(bg_str);
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
+ gtk_tree_model_iter_nth_child(model, &iter, NULL, filter_number);
+ gtk_tree_model_get(model, &iter, 4, &colorf, -1);
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
+ if (gtk_tree_selection_iter_is_selected(sel, &iter))
+ move_this_row (color_filters, filter_number, amount);
+#endif
+ }
+}
- /*
- * re-select the initial row
- */
- gtk_widget_grab_focus(color_filters);
- gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters)), &iter1);
+/* Move the selected filters down in the list */
+static void
+color_filter_down_cb(GtkButton *button, gpointer user_data _U_)
+{
+ gint amount;
+ gint filter_number;
+ GtkWidget * color_filters;
+ color_filter_t *colorf;
+#if GTK_MAJOR_VERSION < 2
+#else
+ GtkTreeIter iter;
+ GtkTreeModel *model;
#endif
- filter_list = g_slist_remove(filter_list, colorf);
- filter_list = g_slist_insert(filter_list, colorf, filter_number+1);
-}
+ amount = +1;
+ color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
+#if GTK_MAJOR_VERSION < 2
+ colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), num_of_filters - 1);
+ if (colorf->marked)
+ return;
+#endif
+
+ for (filter_number = num_of_filters - 1; filter_number >= 0; filter_number--)
+ {
+#if GTK_MAJOR_VERSION < 2
+ colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
+#else
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
+ gtk_tree_model_iter_nth_child(model, &iter, NULL, filter_number);
+ gtk_tree_model_get(model, &iter, 4, &colorf, -1);
+#endif
+ if (colorf->marked)
+ move_this_row (color_filters, filter_number, amount);
+ }
+}
+
/* A row was selected; remember its row number */
#if GTK_MAJOR_VERSION < 2
static void
@@ -595,9 +708,13 @@ remember_selected_row(GtkCList *clist, gint row, gint column _U_,
GdkEvent *event _U_, gpointer user_data _U_)
{
GtkWidget *button;
+ color_filter_t *colorf;
row_selected = row;
+ colorf = gtk_clist_get_row_data(clist, row);
+ colorf->marked = TRUE;
+
/*
* A row is selected, so we can move it up *if* it's not at the top
* and move it down *if* it's not at the bottom.
@@ -614,58 +731,111 @@ remember_selected_row(GtkCList *clist, gint row, gint column _U_,
gtk_widget_set_sensitive (button, TRUE);
button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DELETE_LB);
gtk_widget_set_sensitive(button, TRUE);
+
}
#else
+
+struct remember_data
+{
+ gint count; /* count of selected filters */
+ gboolean first_marked; /* true if the first filter in the list is marked */
+ gboolean last_marked; /* true if the last filter in the list is marked */
+ gpointer color_filters;
+};
+/* called for each selected row in the tree. The first call is detected and does
+the stuff that only needs to be done once. If we are never called the visited
+variable stays false and means that no rows are selected.
+*/
+void remember_this_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer arg)
+{
+ GtkWidget *button;
+ gchar *path_str;
+ color_filter_t *colorf;
+ struct remember_data *data = arg;
+
+ gtk_tree_model_get(model, iter, 4, &colorf, -1);
+ colorf->marked = TRUE;
+
+ path_str = gtk_tree_path_to_string(path);
+ row_selected = atoi(path_str);
+ g_free(path_str);
+
+ /*
+ * A row is selected, so we can move it up *if* it's not at the top
+ * and move it down *if* it's not at the bottom.
+ */
+ button = (GtkWidget *)OBJECT_GET_DATA(data->color_filters, COLOR_UP_LB);
+ gtk_widget_set_sensitive(button, row_selected > 0);
+ if (row_selected == 0)
+ data->first_marked = TRUE;
+ if (row_selected == num_of_filters - 1)
+ data->last_marked = TRUE;
+
+ data->count++;
+}
+
+/* clear the mark on this filter */
+static void
+clear_mark(gpointer filter_arg, gpointer arg _U_)
+{
+ color_filter_t *colorf = filter_arg;
+
+ colorf->marked = FALSE;
+}
+
+/* The gtk+2.0 version gets called for, (maybe multiple,) changes in the selection. */
static void
remember_selected_row(GtkTreeSelection *sel, gpointer color_filters)
{
GtkWidget *button;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkTreePath *path;
- gchar *path_str;
+ struct remember_data data;
+
+ data.first_marked = data.last_marked = FALSE;
+ data.count = 0;
+ data.color_filters = color_filters;
+
- if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
- path = gtk_tree_model_get_path(model, &iter);
- path_str = gtk_tree_path_to_string(path);
- row_selected = atoi(path_str);
- g_free(path_str);
- gtk_tree_path_free(path);
-
- /*
- * A row is selected, so we can move it up *if* it's not at the top
- * and move it down *if* it's not at the bottom.
- */
- button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_UP_LB);
- gtk_widget_set_sensitive(button, row_selected > 0);
- button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DOWN_LB);
- gtk_widget_set_sensitive(button, row_selected < num_of_filters - 1);
-
- /*
- * A row is selected, so we can operate on it.
- */
- button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_EDIT_LB);
- gtk_widget_set_sensitive (button, TRUE);
- button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DELETE_LB);
- gtk_widget_set_sensitive (button, TRUE);
+ g_slist_foreach(filter_list, clear_mark, NULL);
+ gtk_tree_selection_selected_foreach(sel,remember_this_row, &data);
+
+ if (data.count > 0)
+ {
+ /*
+ * One or more rows are selected, so we can operate on them.
+ */
+
+ /* We can only edit if there is exactly one filter selected */
+ button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_EDIT_LB);
+ gtk_widget_set_sensitive (button, data.count == 1);
+
+ /* We can delete any number of filters */
+ button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DELETE_LB);
+ gtk_widget_set_sensitive (button, TRUE);
+ /*
+ * We can move them up *if* one of them isn't the top row,
+ * and move them down *if* one of them isn't the bottom row.
+ */
+ button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_UP_LB);
+ gtk_widget_set_sensitive(button, !data.first_marked);
+ button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DOWN_LB);
+ gtk_widget_set_sensitive(button, !data.last_marked);
}
- /* A row was unselected; un-remember its row number */
else
{
- row_selected = -1;
-
- /*
- * No row is selected, so we can't do operations that affect the
- * selected row.
- */
- button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_UP_LB);
- gtk_widget_set_sensitive (button, FALSE);
- button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DOWN_LB);
- gtk_widget_set_sensitive (button, FALSE);
- button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_EDIT_LB);
- gtk_widget_set_sensitive (button, FALSE);
- button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DELETE_LB);
- gtk_widget_set_sensitive (button, FALSE);
+ row_selected = -1;
+
+ /*
+ * No row is selected, so we can't do operations that affect the
+ * selected row.
+ */
+ button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_UP_LB);
+ gtk_widget_set_sensitive (button, FALSE);
+ button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DOWN_LB);
+ gtk_widget_set_sensitive (button, FALSE);
+ button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_EDIT_LB);
+ gtk_widget_set_sensitive (button, FALSE);
+ button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DELETE_LB);
+ gtk_widget_set_sensitive (button, FALSE);
}
}
#endif
@@ -680,21 +850,28 @@ unremember_selected_row (GtkCList *clist,
gpointer user_data _U_)
{
GtkWidget *button;
+ color_filter_t *colorf;
row_selected = -1;
- /*
- * No row is selected, so we can't do operations that affect the
- * selected row.
- */
- button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_UP_LB);
- gtk_widget_set_sensitive (button, FALSE);
- button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DOWN_LB);
- gtk_widget_set_sensitive (button, FALSE);
- button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_EDIT_LB);
- gtk_widget_set_sensitive (button, FALSE);
- button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DELETE_LB);
- gtk_widget_set_sensitive(button, FALSE);
+ colorf = gtk_clist_get_row_data(clist, row);
+ colorf->marked = FALSE;
+
+ if (color_marked_count() == 0)
+ {
+ /*
+ * No row is selected, so we can't do operations that affect the
+ * selected row.
+ */
+ button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_UP_LB);
+ gtk_widget_set_sensitive (button, FALSE);
+ button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DOWN_LB);
+ gtk_widget_set_sensitive (button, FALSE);
+ button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_EDIT_LB);
+ gtk_widget_set_sensitive (button, FALSE);
+ button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DELETE_LB);
+ gtk_widget_set_sensitive(button, FALSE);
+ }
}
#endif
@@ -726,16 +903,10 @@ destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy _U_)
static GtkWidget *filt_name_entry;
static GtkWidget *filt_text_entry;
-/* Create a new filter in the list, and pop up an "Edit color filter"
- dialog box to edit it. */
static void
-color_new_cb(GtkButton *button, gpointer user_data _U_)
+color_add_colorf(GtkWidget *color_filters, color_filter_t *colorf)
{
- color_filter_t *colorf;
- GtkWidget *color_filters;
#if GTK_MAJOR_VERSION < 2
- gchar *data[2];
- gint row;
#else
GtkTreeModel *model;
gint num_filters;
@@ -743,31 +914,82 @@ color_new_cb(GtkButton *button, gpointer user_data _U_)
GtkTreeSelection *sel;
#endif
- colorf = new_color_filter("name", "filter"); /* Adds at end! */
+ add_filter_to_list(colorf, color_filters);
- color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
#if GTK_MAJOR_VERSION < 2
- data[0] = colorf->filter_name;
- data[1] = colorf->filter_text;
- row = gtk_clist_append(GTK_CLIST(color_filters), data);
- gtk_clist_set_row_data(GTK_CLIST(color_filters), row, colorf);
- num_of_filters++;
/* select the new row */
- gtk_clist_select_row(GTK_CLIST(color_filters), row, -1);
- edit_color_filter_dialog_new(color_filters, &filt_name_entry,
- &filt_text_entry);
+ gtk_clist_select_row(GTK_CLIST(color_filters), num_of_filters - 1, -1);
#else
- add_filter_to_list(colorf, color_filters);
-
/* select the new row */
model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
num_filters = gtk_tree_model_iter_n_children(model, NULL);
gtk_tree_model_iter_nth_child(model, &iter, NULL, num_filters - 1);
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
gtk_tree_selection_select_iter(sel, &iter);
+#endif
+}
+
+void
+color_add_filter_cb (color_filter_t *colorf, gpointer arg)
+{
+ GtkWidget *color_filters = arg;
+
+ color_add_colorf(color_filters, colorf);
+#if GTK_MAJOR_VERSION >= 2
+ gtk_widget_grab_focus(color_filters);
+#endif
+}
+
+/* Pop up an "Export color filter" dialog box. */
+static void
+color_import_cb(GtkButton *button, gpointer user_data )
+{
+ GtkWidget *color_filters;
+#if GTK_MAJOR_VERSION >= 2
+ GtkTreeSelection *sel;
+#endif
+
+ color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
+
+#if GTK_MAJOR_VERSION >= 2
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
+ gtk_tree_selection_unselect_all (sel);
+#else
+ gtk_clist_unselect_all (GTK_CLIST(color_filters));
+#endif
+
+ file_color_import_cmd_cb(GTK_WIDGET(button), user_data);
+}
+
+/* Create a new filter in the list, and pop up an "Edit color filter"
+ dialog box to edit it. */
+static void
+color_new_cb(GtkButton *button, gpointer user_data _U_)
+{
+ color_filter_t *colorf;
+ GtkWidget *color_filters;
+#if GTK_MAJOR_VERSION >= 2
+ GtkTreeSelection *sel;
+#endif
+
+ color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
+
+#if GTK_MAJOR_VERSION >= 2
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
+ gtk_tree_selection_unselect_all (sel);
+#else
+ gtk_clist_unselect_all (GTK_CLIST(color_filters));
+#endif
+
+ colorf = new_color_filter("name", "filter"); /* Adds at end! */
+
+ color_add_colorf(color_filters, colorf);
+
edit_color_filter_dialog_new(color_filters, &filt_name_entry,
&filt_text_entry);
+
+#if GTK_MAJOR_VERSION >= 2
gtk_widget_grab_focus(color_filters);
#endif
}
@@ -793,8 +1015,6 @@ color_delete(gint row, GtkWidget *color_filters)
#if GTK_MAJOR_VERSION >= 2
GtkTreeModel *model;
GtkTreeIter iter;
- gint rowsel;
- GtkTreeSelection *sel;
/* The "selection changed" callback is called when the row is
@@ -819,16 +1039,6 @@ color_delete(gint row, GtkWidget *color_filters)
* row is always selected, so we do it before */
gtk_widget_grab_focus(color_filters);
/* Update the selection */
- if (row_selected <= (num_of_filters-1)) {
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
- gtk_tree_model_iter_nth_child(model, &iter, NULL, row_selected);
- gtk_tree_selection_select_iter(sel, &iter);
- }
- else if (num_of_filters > 0) {
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
- gtk_tree_model_iter_nth_child(model, &iter, NULL, num_of_filters-1);
- gtk_tree_selection_select_iter(sel, &iter);
- }
#else
colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row);
@@ -844,24 +1054,44 @@ color_delete(gint row, GtkWidget *color_filters)
/* Remove the color filter from the list of color filters. */
delete_color_filter(colorf);
- /* Select the previous row, if there is one. */
- if (row <= row_selected && row_selected > 0) {
- row_selected--;
- gtk_clist_select_row(GTK_CLIST(color_filters), row_selected, 0);
- }
#endif
}
/* Delete the selected color from the list.*/
static void
color_delete_cb(GtkWidget *widget, gpointer user_data _U_)
{
- GtkWidget *color_filters;
+ GtkWidget *color_filters;
+ gint row, num_filters;
+#if GTK_MAJOR_VERSION < 2
+ color_filter_t *colorf;
+#else
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreeSelection *sel;
+#endif
+
+ color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL);
- if(row_selected != -1)
- {
- color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL);
- color_delete (row_selected, color_filters);
- }
+#if GTK_MAJOR_VERSION < 2
+ num_filters = num_of_filters;
+#else
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
+ num_filters = gtk_tree_model_iter_n_children(model, NULL);
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
+#endif
+
+ for (row = num_filters - 1; row >= 0; row--)
+ {
+#if GTK_MAJOR_VERSION < 2
+ colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row);
+ if (colorf->marked)
+ color_delete (row, color_filters);
+#else
+ gtk_tree_model_iter_nth_child(model, &iter, NULL, row);
+ if (gtk_tree_selection_iter_is_selected(sel, &iter))
+ color_delete (row, color_filters);
+#endif
+ }
}
/* Save color filters to the color filter file. */
@@ -957,15 +1187,16 @@ edit_color_filter_dialog_new(GtkWidget *color_filters,
GtkWidget *edit_color_filter_cancel;
#if GTK_MAJOR_VERSION >= 2
- GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
+#endif
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
- /* should never happen */
- if (!gtk_tree_selection_get_selected(sel, &model, &iter))
- return;
+#if GTK_MAJOR_VERSION >= 2
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
+
+ gtk_tree_model_iter_nth_child(model, &iter, NULL, row_selected);
gtk_tree_model_get(model, &iter, 4, &colorf, -1);
+
#else
colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row_selected);
#endif
diff --git a/gtk/color_dlg.h b/gtk/color_dlg.h
index 483237fd03..05b7198211 100644
--- a/gtk/color_dlg.h
+++ b/gtk/color_dlg.h
@@ -1,7 +1,7 @@
/* color_dlg.h
* Definitions for dialog boxes for color filters
*
- * $Id: color_dlg.h,v 1.2 2002/08/28 21:03:46 jmayer Exp $
+ * $Id: color_dlg.h,v 1.3 2003/08/18 21:27:10 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -27,5 +27,6 @@
#define __COLOR_DLG_H__
void color_display_cb(GtkWidget *w, gpointer d);
-
+int color_marked_count(void);
+void color_add_filter_cb (color_filter_t *colorf, gpointer arg);
#endif /* color_dlg.h */
diff --git a/gtk/color_filters.c b/gtk/color_filters.c
index 25cdc5ebc2..00e24d78a2 100644
--- a/gtk/color_filters.c
+++ b/gtk/color_filters.c
@@ -1,7 +1,7 @@
/* color_filters.c
* Routines for color filters
*
- * $Id: color_filters.c,v 1.2 2003/05/15 07:44:54 guy Exp $
+ * $Id: color_filters.c,v 1.3 2003/08/18 21:27:10 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -39,6 +39,7 @@
#include "colors.h"
#include "color_filters.h"
#include "color_utils.h"
+#include "color_dlg.h"
#include "file.h"
#include <epan/dfilter/dfilter.h>
#include "simple_dialog.h"
@@ -105,6 +106,7 @@ new_color_filter(gchar *name, /* The name of the filter to create */
gdkcolor_to_color_t(&colorf->fg_color, &style->text[GTK_STATE_NORMAL]);
colorf->c_colorfilter = NULL;
colorf->edit_dialog = NULL;
+ colorf->marked = FALSE;
filter_list = g_slist_append(filter_list, colorf);
return colorf;
}
@@ -131,7 +133,7 @@ filter_list_prime_edt(epan_dissect_t *edt)
/* read filters from the given file */
static gboolean
-read_filters_file(gpointer file_arg)
+read_filters_file(FILE *f, gpointer arg)
{
/* TODO: Lots more syntax checking on the file */
/* I hate these fixed length names! TODO: make more dynamic */
@@ -143,7 +145,6 @@ read_filters_file(gpointer file_arg)
GdkColor fg_color, bg_color;
color_filter_t *colorf;
dfilter_t *temp_dfilter;
- FILE *f = file_arg;
do {
if (fgets(buf,sizeof buf, f) == NULL)
@@ -194,10 +195,14 @@ read_filters_file(gpointer file_arg)
bg_color.red = bg_r;
bg_color.green = bg_g;
bg_color.blue = bg_b;
-
+
gdkcolor_to_color_t(&colorf->bg_color, &bg_color);
gdkcolor_to_color_t(&colorf->fg_color, &fg_color);
- } /* if sscanf */
+
+ if (arg != NULL)
+ color_add_filter_cb (colorf, arg);
+
+ } /* if sscanf */
} while(!feof(f));
fclose(f);
return TRUE;
@@ -228,7 +233,7 @@ read_filters(void)
g_free((gchar *)path);
path = NULL;
- return read_filters_file(f);
+ return read_filters_file(f, NULL);
}
/* read filters from the filter file */
@@ -252,32 +257,65 @@ read_global_filters(void)
g_free((gchar *)path);
path = NULL;
- return read_filters_file(f);
+ return read_filters_file(f, NULL);
}
+/* save filters in some other filter file */
+
+gboolean
+read_other_filters(gchar *path, gpointer arg)
+{
+ FILE *f;
+
+ if ((f = fopen(path, "r")) == NULL) {
+ simple_dialog(ESD_TYPE_CRIT, NULL,
+ "Could not open\n%s\nfor reading: %s.",
+ path, strerror(errno));
+ return FALSE;
+ }
+
+ read_filters_file(f, arg);
+ fclose(f);
+ return TRUE;
+}
+
+struct write_filter_data
+{
+ FILE * f;
+ gboolean only_marked;
+};
+
static void
-write_filter(gpointer filter_arg, gpointer file_arg)
+write_filter(gpointer filter_arg, gpointer data_arg)
{
+ struct write_filter_data *data = data_arg;
color_filter_t *colorf = filter_arg;
- FILE *f = file_arg;
-
- fprintf(f,"@%s@%s@[%d,%d,%d][%d,%d,%d]\n",
- colorf->filter_name,
- colorf->filter_text,
- colorf->bg_color.red,
- colorf->bg_color.green,
- colorf->bg_color.blue,
- colorf->fg_color.red,
- colorf->fg_color.green,
- colorf->fg_color.blue);
+ FILE *f = data->f;
+
+ if (colorf->marked || !data->only_marked)
+ {
+ fprintf(f,"@%s@%s@[%d,%d,%d][%d,%d,%d]\n",
+ colorf->filter_name,
+ colorf->filter_text,
+ colorf->bg_color.red,
+ colorf->bg_color.green,
+ colorf->bg_color.blue,
+ colorf->fg_color.red,
+ colorf->fg_color.green,
+ colorf->fg_color.blue);
+ }
}
/* save filters in a filter file */
gboolean
-write_filters_file(FILE *f)
+write_filters_file(FILE *f, gboolean only_marked)
{
+ struct write_filter_data data;
+ data.f = f;
+ data.only_marked = only_marked;
+
fprintf(f,"# DO NOT EDIT THIS FILE! It was created by Ethereal\n");
- g_slist_foreach(filter_list, write_filter, f);
+ g_slist_foreach(filter_list, write_filter, &data);
return TRUE;
}
@@ -307,7 +345,7 @@ write_filters(void)
path, strerror(errno));
return FALSE;
}
- write_filters_file(f);
+ write_filters_file(f, FALSE);
fclose(f);
return TRUE;
}
@@ -343,7 +381,7 @@ revert_filters(void)
/* save filters in some other filter file */
gboolean
-write_other_filters(gchar *path)
+write_other_filters(gchar *path, gboolean only_marked)
{
FILE *f;
@@ -353,7 +391,7 @@ write_other_filters(gchar *path)
path, strerror(errno));
return FALSE;
}
- write_filters_file(f);
+ write_filters_file(f, only_marked);
fclose(f);
return TRUE;
}
diff --git a/gtk/color_filters.h b/gtk/color_filters.h
index 16154b3de4..5984ebf6ab 100644
--- a/gtk/color_filters.h
+++ b/gtk/color_filters.h
@@ -1,7 +1,7 @@
/* color_filters.h
* Definitions for color filters
*
- * $Id: color_filters.h,v 1.2 2003/05/15 07:44:54 guy Exp $
+ * $Id: color_filters.h,v 1.3 2003/08/18 21:27:10 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -38,5 +38,6 @@ gboolean revert_filters(void);
color_filter_t *new_color_filter(gchar *name, gchar *filter_string);
void delete_color_filter(color_filter_t *colorf);
-gboolean write_other_filters(gchar *path);
+gboolean read_other_filters(gchar *path, gpointer arg);
+gboolean write_other_filters(gchar *path, gboolean only_marked);
#endif
diff --git a/gtk/file_dlg.c b/gtk/file_dlg.c
index ea4e63d4aa..b62497f5e8 100644
--- a/gtk/file_dlg.c
+++ b/gtk/file_dlg.c
@@ -1,7 +1,7 @@
/* file_dlg.c
* Dialog boxes for handling files
*
- * $Id: file_dlg.c,v 1.57 2003/07/22 03:14:30 gerald Exp $
+ * $Id: file_dlg.c,v 1.58 2003/08/18 21:27:10 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -43,17 +43,26 @@
#include "main.h"
#include "compat_macros.h"
#include "prefs.h"
+#include "color.h"
+#include "gtk/color_filters.h"
+#include "gtk/color_dlg.h"
static void file_open_ok_cb(GtkWidget *w, GtkFileSelection *fs);
static void file_open_destroy_cb(GtkWidget *win, gpointer user_data);
static void select_file_type_cb(GtkWidget *w, gpointer data);
static void file_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs);
static void file_save_as_destroy_cb(GtkWidget *win, gpointer user_data);
+static void file_color_import_ok_cb(GtkWidget *w, GtkFileSelection *fs);
+static void file_color_import_destroy_cb(GtkWidget *win, gpointer user_data);
+static void file_color_export_ok_cb(GtkWidget *w, GtkFileSelection *fs);
+static void file_color_export_destroy_cb(GtkWidget *win, gpointer user_data);
#define E_FILE_M_RESOLVE_KEY "file_dlg_mac_resolve_key"
#define E_FILE_N_RESOLVE_KEY "file_dlg_network_resolve_key"
#define E_FILE_T_RESOLVE_KEY "file_dlg_transport_resolve_key"
+#define ARGUMENT_CL "argument_cl"
+
/*
* Keep a static pointer to the current "Open Capture File" window, if
* any, so that if somebody tries to do "File:Open" while there's already
@@ -301,9 +310,11 @@ file_save_cmd_cb(GtkWidget *w, gpointer data) {
/* XXX - can we make these not be static? */
static gboolean filtered;
static gboolean marked;
+static gboolean color_marked;
static int filetype;
static GtkWidget *filter_cb;
static GtkWidget *mark_cb;
+static GtkWidget *cfmark_cb;
static GtkWidget *ft_om;
static gboolean
@@ -661,3 +672,295 @@ file_reload_cmd_cb(GtkWidget *w, gpointer data _U_) {
we should free up our copy. */
g_free(filename);
}
+
+/******************** Color Filters *********************************/
+/*
+ * Keep a static pointer to the current "Color Export" window, if
+ * any, so that if somebody tries to do "Export"
+ * while there's already a "Color Export" window up, we just pop
+ * up the existing one, rather than creating a new one.
+ */
+static GtkWidget *file_color_import_w;
+
+/* sets the file path to the global color filter file.
+ WARNING: called by both the import and the export dialog.
+*/
+static void
+color_global_cb(GtkWidget *widget _U_, gpointer data)
+{
+ GtkWidget *fs_widget = data;
+
+ gchar *path;
+
+ /* decide what file to open (from dfilter code) */
+ path = get_datafile_path("colorfilters");
+
+ gtk_file_selection_set_filename (GTK_FILE_SELECTION(fs_widget), path);
+
+ g_free((gchar *)path);
+}
+
+/* Import color filters */
+void
+file_color_import_cmd_cb(GtkWidget *w _U_, gpointer data)
+{
+ GtkWidget *main_vb, *cfglobal_but;
+#if GTK_MAJOR_VERSION < 2
+ GtkAccelGroup *accel_group;
+#endif
+ /* No Apply button, and "OK" just sets our text widget, it doesn't
+ activate it (i.e., it doesn't cause us to try to open the file). */
+
+ if (file_color_import_w != NULL) {
+ /* There's already an "Import Color Filters" dialog box; reactivate it. */
+ reactivate_window(file_color_import_w);
+ return;
+ }
+
+ file_color_import_w = gtk_file_selection_new ("Ethereal: Import Color Filters");
+ SIGNAL_CONNECT(file_color_import_w, "destroy", file_color_import_destroy_cb, NULL);
+
+#if GTK_MAJOR_VERSION < 2
+ /* Accelerator group for the accelerators (or, as they're called in
+ Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
+ Ctrl+<key> is an accelerator). */
+ accel_group = gtk_accel_group_new();
+ gtk_window_add_accel_group(GTK_WINDOW(file_color_import_w), accel_group);
+#endif
+
+ /* If we've opened a file, start out by showing the files in the directory
+ in which that file resided. */
+ if (last_open_dir)
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_color_import_w), last_open_dir);
+
+ /* Container for each row of widgets */
+ main_vb = gtk_vbox_new(FALSE, 3);
+ gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
+ gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(file_color_import_w)->action_area),
+ main_vb, FALSE, FALSE, 0);
+ gtk_widget_show(main_vb);
+
+
+ cfglobal_but = gtk_button_new_with_label("Global Color Filter File");
+ gtk_container_add(GTK_CONTAINER(main_vb), cfglobal_but);
+ SIGNAL_CONNECT(cfglobal_but, "clicked", color_global_cb, file_color_import_w);
+ gtk_widget_show(cfglobal_but);
+
+ /* Connect the ok_button to file_open_ok_cb function and pass along a
+ pointer to the file selection box widget */
+ SIGNAL_CONNECT(GTK_FILE_SELECTION(file_color_import_w)->ok_button, "clicked",
+ file_color_import_ok_cb, file_color_import_w);
+
+ OBJECT_SET_DATA(GTK_FILE_SELECTION(file_color_import_w)->ok_button,
+ ARGUMENT_CL, data);
+
+ /* Connect the cancel_button to destroy the widget */
+ SIGNAL_CONNECT_OBJECT(GTK_FILE_SELECTION(file_color_import_w)->cancel_button,
+ "clicked", (GtkSignalFunc)gtk_widget_destroy,
+ file_color_import_w);
+
+ /* Catch the "key_press_event" signal in the window, so that we can catch
+ the ESC key being pressed and act as if the "Cancel" button had
+ been selected. */
+ dlg_set_cancel(file_color_import_w, GTK_FILE_SELECTION(file_color_import_w)->cancel_button);
+
+ gtk_widget_show(file_color_import_w);
+}
+
+static void
+file_color_import_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
+ gchar *cf_name, *s;
+ gpointer argument;
+
+ argument = OBJECT_GET_DATA(w, ARGUMENT_CL); /* to be passed back into read_other_filters */
+
+ cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs)));
+ /* Perhaps the user specified a directory instead of a file.
+ Check whether they did. */
+ if (test_for_directory(cf_name) == EISDIR) {
+ /* It's a directory - set the file selection box to display that
+ directory, don't try to open the directory as a capture file. */
+ set_last_open_dir(cf_name);
+ g_free(cf_name);
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
+ return;
+ }
+
+ /* Try to open the capture file. */
+
+ if (!read_other_filters(cf_name, argument)) {
+ /* We couldn't open it; don't dismiss the open dialog box,
+ just leave it around so that the user can, after they
+ dismiss the alert box popped up for the open error,
+ try again. */
+ g_free(cf_name);
+ return;
+ }
+
+ /* We've crossed the Rubicon; get rid of the file selection box. */
+ gtk_widget_hide(GTK_WIDGET (fs));
+ gtk_widget_destroy(GTK_WIDGET (fs));
+
+ /* Save the name of the containing directory specified in the path name,
+ if any; we can write over cf_name, which is a good thing, given that
+ "get_dirname()" does write over its argument. */
+ s = get_dirname(cf_name);
+ set_last_open_dir(s);
+ gtk_widget_grab_focus(packet_list);
+
+ g_free(cf_name);
+}
+
+static void
+file_color_import_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
+{
+ /* Note that we no longer have a "Open Capture File" dialog box. */
+ file_color_import_w = NULL;
+}
+
+static GtkWidget *file_color_export_w;
+/*
+ * Set the "Export only marked filters" toggle button as appropriate for
+ * the current output file type and count of marked filters.
+ *
+ * Called when the "Export" dialog box is created and when the marked
+ * count changes.
+ */
+void
+color_set_export_marked_sensitive(GtkWidget * cfmark_cb)
+{
+ if (file_color_export_w == NULL) {
+ /* We don't currently have an "Export" dialog box up. */
+ return;
+ }
+
+ /* We can request that only the marked filters be saved only if
+ there *are* marked filters. */
+ if (color_marked_count() != 0)
+ gtk_widget_set_sensitive(cfmark_cb, TRUE);
+ else {
+ /* Force the "Export only marked filters" toggle to "false", turn
+ off the flag it controls. */
+ color_marked = FALSE;
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(cfmark_cb), FALSE);
+ gtk_widget_set_sensitive(cfmark_cb, FALSE);
+ }
+}
+
+static void
+color_toggle_marked_cb(GtkWidget *widget, gpointer data _U_)
+{
+ color_marked = GTK_TOGGLE_BUTTON (widget)->active;
+}
+
+void
+file_color_export_cmd_cb(GtkWidget *w _U_, gpointer data _U_)
+{
+ GtkWidget *ok_bt, *main_vb, *cfglobal_but;
+
+ if (file_color_export_w != NULL) {
+ /* There's already an "Color Filter Export" dialog box; reactivate it. */
+ reactivate_window(file_color_export_w);
+ return;
+ }
+
+ /* Default to saving all packets, in the file's current format. */
+ filtered = FALSE;
+ color_marked = FALSE;
+ filetype = cfile.cd_t;
+
+ file_color_export_w = gtk_file_selection_new ("Ethereal: Export Color Filters");
+ SIGNAL_CONNECT(file_color_export_w, "destroy", file_color_export_destroy_cb, NULL);
+
+ /* If we've opened a file, start out by showing the files in the directory
+ in which that file resided. */
+ if (last_open_dir)
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_color_export_w), last_open_dir);
+
+ /* Connect the ok_button to file_export_ok_cb function and pass along a
+ pointer to the file selection box widget */
+ ok_bt = GTK_FILE_SELECTION (file_color_export_w)->ok_button;
+ SIGNAL_CONNECT(ok_bt, "clicked", file_color_export_ok_cb, file_color_export_w);
+
+ /* Container for each row of widgets */
+ main_vb = gtk_vbox_new(FALSE, 3);
+ gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
+ gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(file_color_export_w)->action_area),
+ main_vb, FALSE, FALSE, 0);
+ gtk_widget_show(main_vb);
+
+ cfmark_cb = gtk_check_button_new_with_label("Export only marked filters");
+ gtk_container_add(GTK_CONTAINER(main_vb), cfmark_cb);
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(cfmark_cb), FALSE);
+ SIGNAL_CONNECT(cfmark_cb, "toggled", color_toggle_marked_cb, NULL);
+ gtk_widget_show(cfmark_cb);
+ color_set_export_marked_sensitive(cfmark_cb);
+
+ cfglobal_but = gtk_button_new_with_label("Global Color Filter File");
+ gtk_container_add(GTK_CONTAINER(main_vb), cfglobal_but);
+ SIGNAL_CONNECT(cfglobal_but, "clicked", color_global_cb, file_color_export_w);
+ gtk_widget_show(cfglobal_but);
+
+ /* Connect the cancel_button to destroy the widget */
+ SIGNAL_CONNECT_OBJECT(GTK_FILE_SELECTION(file_color_export_w)->cancel_button,
+ "clicked", (GtkSignalFunc)gtk_widget_destroy,
+ file_color_export_w);
+
+ /* Catch the "key_press_event" signal in the window, so that we can catch
+ the ESC key being pressed and act as if the "Cancel" button had
+ been selected. */
+ dlg_set_cancel(file_color_export_w, GTK_FILE_SELECTION(file_color_export_w)->cancel_button);
+
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_color_export_w), "");
+
+ gtk_widget_show(file_color_export_w);
+}
+
+static void
+file_color_export_ok_cb(GtkWidget *w _U_, GtkFileSelection *fs) {
+ gchar *cf_name;
+ gchar *dirname;
+
+ cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
+
+ /* Perhaps the user specified a directory instead of a file.
+ Check whether they did. */
+ if (test_for_directory(cf_name) == EISDIR) {
+ /* It's a directory - set the file selection box to display that
+ directory, and leave the selection box displayed. */
+ set_last_open_dir(cf_name);
+ g_free(cf_name);
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
+ return;
+ }
+
+ /* Write out the filters (all, or only the ones that are currently
+ displayed or marked) to the file with the specified name. */
+
+ if (!write_other_filters(cf_name, color_marked))
+ {
+ /* The write failed; don't dismiss the open dialog box,
+ just leave it around so that the user can, after they
+ dismiss the alert box popped up for the error, try again. */
+
+ g_free(cf_name);
+ return;
+ }
+
+ /* The write succeeded; get rid of the file selection box. */
+ gtk_widget_hide(GTK_WIDGET (fs));
+ gtk_widget_destroy(GTK_WIDGET (fs));
+
+ /* Save the directory name for future file dialogs. */
+ dirname = get_dirname(cf_name); /* Overwrites cf_name */
+ set_last_open_dir(dirname);
+ g_free(cf_name);
+}
+
+static void
+file_color_export_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
+{
+ file_color_export_w = NULL;
+}
+
+
diff --git a/gtk/file_dlg.h b/gtk/file_dlg.h
index 8084dbff02..e6117e928e 100644
--- a/gtk/file_dlg.h
+++ b/gtk/file_dlg.h
@@ -1,7 +1,7 @@
/* file_dlg.h
* Definitions for dialog boxes for handling files
*
- * $Id: file_dlg.h,v 1.3 2002/08/28 21:03:47 jmayer Exp $
+ * $Id: file_dlg.h,v 1.4 2003/08/18 21:27:11 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -31,6 +31,9 @@ void file_save_as_cmd_cb(GtkWidget *, gpointer);
void file_close_cmd_cb(GtkWidget *, gpointer);
void file_reload_cmd_cb(GtkWidget *, gpointer);
+void file_color_import_cmd_cb(GtkWidget *w, gpointer data);
+void file_color_export_cmd_cb(GtkWidget *, gpointer);
+
/*
* Set the "Save only marked packets" toggle button as appropriate for
* the current output file type and count of marked packets.