From Richard Urwin a great enhancement to the color filter dialogue to
authorsahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 18 Aug 2003 21:27:11 +0000 (21:27 +0000)
committersahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 18 Aug 2003 21:27:11 +0000 (21:27 +0000)
make it possible to import/export color filters

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

AUTHORS
color.h
doc/ethereal.pod.template
gtk/color_dlg.c
gtk/color_dlg.h
gtk/color_filters.c
gtk/color_filters.h
gtk/file_dlg.c
gtk/file_dlg.h

diff --git a/AUTHORS b/AUTHORS
index 57fad8b98cb4ff32edceca45acac73fdff2ef576..10736b293a091d0753eb3bce99032d3c3e4705a3 100644 (file)
--- 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 9eef8f8eddfff3262ffb72ac793117a811f8e433..cc71915cd090df4a83f7e2338efd7705ec877f84 100644 (file)
--- 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. */
index c2928bcc3447cbf1c8f363bd851fcf3b2521ef44..9c44235788edd003c03522edfdd0d2f2f988b75f 100644 (file)
@@ -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.
index 770a4c9ac8c148f25b37d08fa846a5cf7fe34cba..40f3681e73a70cd8cb2866a416da893e44fc2c1e 100644 (file)
@@ -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
index 483237fd035e579ce09e546fe998efc68584cd17..05b7198211234a4dcf60d3ed06146031d79e8a2b 100644 (file)
@@ -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 */
index 25cdc5ebc24e6a5a6f4dc771a9239f1716daa8c2..00e24d78a2fbcaef78ac039fcde17b8cfcb37391 100644 (file)
@@ -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;
 }
index 16154b3de42d1285eae3e7b0b158518df72b6720..5984ebf6ab37742ccb223e32b3c636f7524fd168 100644 (file)
@@ -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
index ea4e63d4aa13892c7f8a333d80ee695dc6aaa818..b62497f5e831440c5f5d9faa97fe3628cb6afbfd 100644 (file)
@@ -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>
 #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;
+}
+
+
index 8084dbff02ef4ed849e1b2e05460be4705578933..e6117e928e60d996cfecddb26111695e7d763e37 100644 (file)
@@ -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.