diff --git a/AUTHORS b/AUTHORS index 57fad8b98c..10736b293a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1422,9 +1422,10 @@ Liviu Daia { from the command line } -Richard Urwin { +Richard Urwin { 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 { 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 @@ -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 @@ -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,110 +555,152 @@ add_filter_to_list(gpointer filter_arg, gpointer list_arg) num_of_filters++; } -/* Move the selected filter up in the list */ +void move_this_row (GtkWidget *color_filters, + gint filter_number, + gint amount) /* only tested with +1(down) and -1(up) */ +{ + color_filter_t *colorf; +#if GTK_MAJOR_VERSION < 2 + gint lower, higher; +#else + GtkTreeModel *model; + GtkTreeIter iter1, iter2; + gchar *name, *string, *fg_str, *bg_str; +#endif + + g_assert(amount == +1 || amount == -1); + g_assert(amount == +1 || filter_number > 0); + g_assert(amount == -1 || filter_number < num_of_filters - 1); + +#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), higher, lower); + + /* + * That row is still selected, but it's now moved. + */ + 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, 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); + 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); + g_free(string); + g_free(fg_str); + g_free(bg_str); + + /* + * 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); + +#endif + + filter_list = g_slist_remove(filter_list, colorf); + filter_list = g_slist_insert(filter_list, colorf, filter_number + amount); +} + +/* Move the selected filters up in the list */ static void 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; -#endif - - filter_number = row_selected; - g_assert(filter_number > 0); - - 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, filter_number-1); - - /* - * 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); #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_before(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); - - /* - * 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); + GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeSelection *sel; #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), 0); + if (colorf->marked) + return; +#endif + + 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, &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 + } } -/* Move the selected filter down in the list */ +/* Move the selected filters down in the list */ static void color_filter_down_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; -#endif - - filter_number = row_selected; - g_assert(filter_number < num_of_filters - 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); - - /* - * 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); #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); - - /* - * 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); + 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; + 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); + /* + * 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! */ - - 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); -#else add_filter_to_list(colorf, color_filters); +#if GTK_MAJOR_VERSION < 2 + + /* select the new row */ + gtk_clist_select_row(GTK_CLIST(color_filters), num_of_filters - 1, -1); +#else /* 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 @@ -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 @@ -39,6 +39,7 @@ #include "colors.h" #include "color_filters.h" #include "color_utils.h" +#include "color_dlg.h" #include "file.h" #include #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); } -static void -write_filter(gpointer filter_arg, gpointer file_arg) -{ - color_filter_t *colorf = filter_arg; - FILE *f = file_arg; +/* save filters in some other filter file */ - 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); +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 data_arg) +{ + struct write_filter_data *data = data_arg; + color_filter_t *colorf = filter_arg; + 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 @@ -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 @@ -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+ is a mnemonic, + Ctrl+ 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 @@ -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.