diff options
-rw-r--r-- | color_filters.c | 224 | ||||
-rw-r--r-- | color_filters.h | 126 | ||||
-rw-r--r-- | file.c | 12 | ||||
-rw-r--r-- | gtk/capture_file_dlg.c | 30 | ||||
-rw-r--r-- | gtk/color_dlg.c | 212 | ||||
-rw-r--r-- | gtk/win32-file-dlg.c | 10 | ||||
-rw-r--r-- | gtk/win32-file-dlg.h | 6 |
7 files changed, 386 insertions, 234 deletions
diff --git a/color_filters.c b/color_filters.c index ffc7561834..aaa132bccf 100644 --- a/color_filters.c +++ b/color_filters.c @@ -44,32 +44,37 @@ #include "simple_dialog.h" #include "ui_util.h" -static gboolean read_users_filters(void); -static gboolean read_global_filters(void); +static gboolean read_users_filters(GSList **cfl); -/* Variables and routines defined in color.h */ -GSList *color_filter_list = NULL; -GSList *removed_filter_list = NULL; +static GSList *color_filter_list = NULL; /* Color Filters can en-/disabled. */ gboolean filters_enabled = TRUE; -/* Remove the specified filter from the list of existing color filters, - * and add it to the list of removed color filters. - * This way, unmarking and marking a packet which matches a now removed - * color filter will still be colored correctly as the color filter is - * still reachable. */ -void color_filter_remove(color_filter_t *colorf) + +/* Create a new filter */ +color_filter_t * +color_filter_new(const gchar *name, /* The name of the filter to create */ + const gchar *filter_string, /* The string representing the filter */ + color_t *bg_color, /* The background color */ + color_t *fg_color) /* The foreground color */ { - /* Remove colorf from the list of color filters */ - color_filter_list = g_slist_remove(color_filter_list, colorf); - /* Add colorf to the list of removed color filters */ - removed_filter_list = g_slist_prepend(removed_filter_list, colorf); + color_filter_t *colorf; + + colorf = g_malloc(sizeof (color_filter_t)); + colorf->filter_name = g_strdup(name); + colorf->filter_text = g_strdup(filter_string); + colorf->bg_color = *bg_color; + colorf->fg_color = *fg_color; + colorf->c_colorfilter = NULL; + colorf->edit_dialog = NULL; + colorf->selected = FALSE; + return colorf; } /* delete the specified filter */ -static void +void color_filter_delete(color_filter_t *colorf) { if (colorf->filter_name != NULL) @@ -86,22 +91,55 @@ static void color_filter_delete_cb(gpointer filter_arg, gpointer unused _U_) { color_filter_t *colorf = filter_arg; + color_filter_delete(colorf); } -/* delete all the filters */ +/* delete the specified list */ +void +color_filter_list_delete(GSList **cfl) +{ + g_slist_foreach(*cfl, color_filter_delete_cb, NULL); + g_slist_free(*cfl); + *cfl = NULL; +} + +/* clone a single list entries from normal to edit list */ +static color_filter_t * +color_filter_clone(color_filter_t *colorf) +{ + color_filter_t *new_colorf; + + new_colorf = g_malloc(sizeof (color_filter_t)); + new_colorf->filter_name = g_strdup(colorf->filter_name); + new_colorf->filter_text = g_strdup(colorf->filter_text); + new_colorf->bg_color = colorf->bg_color; + new_colorf->fg_color = colorf->fg_color; + new_colorf->c_colorfilter = NULL; + new_colorf->edit_dialog = NULL; + new_colorf->selected = FALSE; + + return new_colorf; +} + static void -color_filters_delete_all(void) +color_filter_list_clone_cb(gpointer filter_arg, gpointer *cfl) { - /* delete the color_filter_list */ - g_slist_foreach(color_filter_list, color_filter_delete_cb, NULL); - g_slist_free(color_filter_list); - color_filter_list = NULL; - - /* delete the removed_filter_list */ - g_slist_foreach(removed_filter_list, color_filter_delete_cb, NULL); - g_slist_free(removed_filter_list); - removed_filter_list = NULL; + color_filter_t *new_colorf; + + new_colorf = color_filter_clone(filter_arg); + *cfl = g_slist_append(*cfl, new_colorf); +} + +/* clone the specified list */ +static GSList * +color_filter_list_clone(GSList *cfl) +{ + GSList *new_list = NULL; + + g_slist_foreach(cfl, color_filter_list_clone_cb, &new_list); + + return new_list; } /* Initialize the filter structures (reading from file) for general running, including app startup */ @@ -109,45 +147,68 @@ void color_filters_init(void) { /* delete all existing filters */ - color_filters_delete_all(); + color_filter_list_delete(&color_filter_list); - /* try to read the users filters */ - if (!read_users_filters()) + /* try to read the users filters */ + if (!read_users_filters(&color_filter_list)) /* if that failed, try to read the global filters */ - read_global_filters(); + color_filters_read_globals(&color_filter_list); } -/* Create a new filter */ -color_filter_t * -color_filter_new(const gchar *name, /* The name of the filter to create */ - const gchar *filter_string, /* The string representing the filter */ - color_t *bg_color, /* The background color */ - color_t *fg_color) /* The foreground color */ +static void +color_filters_clone_cb(gpointer filter_arg, gpointer user_data) { - color_filter_t *colorf; + color_filter_t * new_colorf = color_filter_clone(filter_arg); - colorf = g_malloc(sizeof (color_filter_t)); - colorf->filter_name = g_strdup(name); - colorf->filter_text = g_strdup(filter_string); - colorf->bg_color = *bg_color; - colorf->fg_color = *fg_color; - colorf->c_colorfilter = NULL; - colorf->edit_dialog = NULL; - colorf->selected = FALSE; - color_filter_list = g_slist_append(color_filter_list, colorf); - return colorf; + color_filter_add_cb (new_colorf, user_data); +} + +void +color_filters_clone(gpointer user_data) +{ + g_slist_foreach(color_filter_list, color_filters_clone_cb, user_data); +} + + +static void +color_filter_compile_cb(gpointer filter_arg, gpointer *cfl) +{ + color_filter_t *colorf = filter_arg; + + g_assert(colorf->c_colorfilter == NULL); + if (!dfilter_compile(colorf->filter_text, &colorf->c_colorfilter)) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "Could not compile color filter name: \"%s\" text: \"%s\".\n%s", + colorf->filter_name, colorf->filter_text, dfilter_error_msg); + /* this filter was compilable before, so this should never happen */ + g_assert_not_reached(); + } +} + +/* apply changes from the edit list */ +void +color_filters_apply(GSList *cfl) +{ + /* remove "old" entries */ + color_filter_list_delete(&color_filter_list); + + /* clone all list entries from edit to normal list */ + color_filter_list = color_filter_list_clone(cfl); + + /* compile all filter */ + g_slist_foreach(color_filter_list, color_filter_compile_cb, NULL); } gboolean color_filters_used(void) { - return color_filter_list != NULL && filters_enabled; + return color_filter_list != NULL && filters_enabled; } void color_filters_enable(gboolean enable) { - filters_enabled = enable; + filters_enabled = enable; } @@ -199,7 +260,7 @@ color_filters_colorize_packet(gint row, epan_dissect_t *edt) /* XXX - Would it make more sense to use GStrings here instead of reallocing our buffers? */ static gboolean -read_filters_file(FILE *f, gpointer arg) +read_filters_file(FILE *f, gpointer user_data) { #define INIT_BUF_SIZE 128 gchar *name = NULL; @@ -328,10 +389,18 @@ read_filters_file(FILE *f, gpointer arg) colorf = color_filter_new(name, filter_exp, &bg_color, &fg_color); - colorf->c_colorfilter = temp_dfilter; - - if (arg != NULL) - color_filter_add_cb (colorf, arg); + if(user_data == &color_filter_list) { + GSList **cfl = (GSList **)user_data; + + /* internal call */ + colorf->c_colorfilter = temp_dfilter; + *cfl = g_slist_append(*cfl, colorf); + } else { + /* external call */ + /* just editing, don't need the compiled filter */ + dfilter_free(temp_dfilter); + color_filter_add_cb (colorf, user_data); + } } /* if sscanf */ skip_end_of_line = TRUE; @@ -344,7 +413,7 @@ read_filters_file(FILE *f, gpointer arg) /* read filters from the user's filter file */ static gboolean -read_users_filters(void) +read_users_filters(GSList **cfl) { gchar *path; FILE *f; @@ -364,14 +433,14 @@ read_users_filters(void) g_free(path); path = NULL; - ret = read_filters_file(f, NULL); + ret = read_filters_file(f, cfl); fclose(f); return ret; } /* read filters from the filter file */ -static gboolean -read_global_filters(void) +gboolean +color_filters_read_globals(gpointer user_data) { gchar *path; FILE *f; @@ -391,14 +460,14 @@ read_global_filters(void) g_free(path); path = NULL; - ret = read_filters_file(f, NULL); + ret = read_filters_file(f, user_data); fclose(f); return ret; } /* read filters from some other filter file (import) */ gboolean -color_filters_import(gchar *path, gpointer arg) +color_filters_import(gchar *path, gpointer user_data) { FILE *f; gboolean ret; @@ -410,7 +479,7 @@ color_filters_import(gchar *path, gpointer arg) return FALSE; } - ret = read_filters_file(f, arg); + ret = read_filters_file(f, user_data); fclose(f); return ret; } @@ -444,7 +513,7 @@ write_filter(gpointer filter_arg, gpointer data_arg) /* save filters in a filter file */ static gboolean -write_filters_file(FILE *f, gboolean only_selected) +write_filters_file(GSList *cfl, FILE *f, gboolean only_selected) { struct write_filter_data data; @@ -452,13 +521,13 @@ write_filters_file(FILE *f, gboolean only_selected) data.only_selected = only_selected; fprintf(f,"# DO NOT EDIT THIS FILE! It was created by Wireshark\n"); - g_slist_foreach(color_filter_list, write_filter, &data); + g_slist_foreach(cfl, write_filter, &data); return TRUE; } /* save filters in users filter file */ gboolean -color_filters_write(void) +color_filters_write(GSList *cfl) { gchar *pf_dir_path; const gchar *path; @@ -481,14 +550,14 @@ color_filters_write(void) path, strerror(errno)); return FALSE; } - write_filters_file(f, FALSE); + write_filters_file(cfl, f, FALSE); fclose(f); return TRUE; } /* save filters in some other filter file (export) */ gboolean -color_filters_export(gchar *path, gboolean only_marked) +color_filters_export(gchar *path, GSList *cfl, gboolean only_marked) { FILE *f; @@ -498,27 +567,8 @@ color_filters_export(gchar *path, gboolean only_marked) path, strerror(errno)); return FALSE; } - write_filters_file(f, only_marked); + write_filters_file(cfl, f, only_marked); fclose(f); return TRUE; } -/* delete users filter file and reload global filters */ -gboolean -color_filters_revert(void) -{ - gchar *path; - - /* try to delete the "old" user color filter file */ - path = get_persconffile_path("colorfilters", TRUE); - if (!deletefile(path)) { - g_free(path); - return FALSE; - } - - g_free(path); - - /* Reload the (global) filters - Note: this does not update the dialog. */ - color_filters_init(); - return TRUE; -} diff --git a/color_filters.h b/color_filters.h index 50e32e3a42..b9b7d788b8 100644 --- a/color_filters.h +++ b/color_filters.h @@ -34,76 +34,111 @@ typedef struct _color_filter { gchar *filter_text; /* text of the filter expression */ color_t bg_color; /* background color for packets that match */ color_t fg_color; /* foreground color for packets that match */ + gboolean selected; /* set if the filter is selected in the color dialog box */ + + /* only used inside of color_filters.c */ dfilter_t *c_colorfilter; /* compiled filter expression */ + + /* only used outside of color_filters.c (beside init) */ void *edit_dialog; /* if filter is being edited, dialog * box for it */ - gboolean selected; /* set if the filter is selected in the color dialog box */ } color_filter_t; -/* List of all color filters. */ -extern GSList *color_filter_list; -/** Init the color filters. */ +/** Init the color filters (incl. initial read from file). */ void color_filters_init(void); -/** Save filters in users filter file. + + +/** Color filters currently used? * - * @return TRUE if write succeeded + * @return TRUE, if filters are used */ -gboolean color_filters_write(void); +gboolean color_filters_used(void); -/** Delete users filter file and reload global filters. +/** En-/disable color filters * - * @return TRUE if write succeeded + * @param enable TRUE to enable (default) */ -gboolean color_filters_revert(void); +void +color_filters_enable(gboolean enable); + + + +/* Prime the epan_dissect_t with all the compiler + * color filters of the current filter list. + * + * @param the epan dissector details + */ +void color_filters_prime_edt(epan_dissect_t *edt); + +/** Colorize a specific packet. + * + * @param row the row in the packet list + * @param edt the dissected packet + * @return the matching color filter or NULL + */ +color_filter_t * +color_filters_colorize_packet(gint row, epan_dissect_t *edt); + + + +/** Clone the currently active filter list. + * + * @param user_data will be returned by each call to to color_filter_add_cb() + */ +void color_filters_clone(gpointer user_data); /** Load filters (import) from some other filter file. * - * @param path the path to the filter file - * @param arg the color filter widget + * @param path the path to the import file + * @param user_data will be returned by each call to to color_filter_add_cb() * @return TRUE, if read succeeded */ -gboolean color_filters_import(gchar *path, gpointer arg); +gboolean color_filters_import(gchar *path, gpointer user_data); -/** Save filters (export) to some other filter file. +/** Read filters from the global filter file (not the users file). * - * @param path the path to the filter file - * @param only_selected TRUE if only the selected filters should be saved - * @return TRUE, if write succeeded + * @param user_data will be returned by each call to to color_filter_add_cb() + * @return TRUE, if read succeeded */ -gboolean color_filters_export(gchar *path, gboolean only_selected); +gboolean color_filters_read_globals(gpointer user_data); -/* Prime the epan_dissect_t with all the compiler - * color filters in 'color_filter_list'. +/** A color filter was added (while importing). + * (color_filters.c calls this for every filter coming in) * - * @param the epan dissector details + * @param colorf the new color filter + * @param user_data from caller */ -void color_filters_prime_edt(epan_dissect_t *edt); +void color_filter_add_cb (color_filter_t *colorf, gpointer user_data); -/** Color filters currently used? + + +/** Apply a changed filter list. * - * @return TRUE, if filters are used + * @param cfl the filter list to apply */ -gboolean color_filters_used(void); +void color_filters_apply(GSList *cfl); -/** En-/disable color filters +/** Save filters in users filter file. * - * @param enable TRUE to enable (default) + * @param cfl the filter list to write + * @return TRUE if write succeeded */ -void -color_filters_enable(gboolean enable); +gboolean color_filters_write(GSList *cfl); -/** Colorize a specific packet. +/** Save filters (export) to some other filter file. * - * @param row the row in the packet list - * @param edt the dissected packet - * @return the matching color filter or NULL + * @param path the path to the filter file + * @param cfl the filter list to write + * @param only_selected TRUE if only the selected filters should be saved + * @return TRUE, if write succeeded */ -color_filter_t * -color_filters_colorize_packet(gint row, epan_dissect_t *edt); +gboolean color_filters_export(gchar *path, GSList *cfl, gboolean only_selected); + + -/** Create a new color filter. +/** Create a new color filter (g_malloc'ed). * * @param name the name of the filter * @param filter_string the filter string @@ -111,20 +146,25 @@ color_filters_colorize_packet(gint row, epan_dissect_t *edt); * @param fg_color foreground color * @return the new color filter */ -color_filter_t *color_filter_new(const gchar *name, const gchar *filter_string, +color_filter_t *color_filter_new( + const gchar *name, const gchar *filter_string, color_t *bg_color, color_t *fg_color); -/** Remove the color filter. +/** Delete a single color filter (g_free'ed). * * @param colorf the color filter to be removed */ -void color_filter_remove(color_filter_t *colorf); +void color_filter_delete(color_filter_t *colorf); + + -/** A color filter was added (from import). + +/** Delete a filter list including all entries. * - * @param colorf the new color filter - * @param arg the color filter widget + * @param cfl the filter list to delete */ -void color_filter_add_cb (color_filter_t *colorf, gpointer arg); +void color_filter_list_delete(GSList **cfl); + + #endif @@ -818,6 +818,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf, if (cf->dfcode != NULL && refilter) { epan_dissect_prime_dfilter(edt, cf->dfcode); } + /* prepare color filters */ if (color_filters_used()) { color_filters_prime_edt(edt); } @@ -3066,6 +3067,17 @@ cf_select_packet(capture_file *cf, int row) } /* We don't need the columns here. */ cf->edt = epan_dissect_new(TRUE, TRUE); + + /* colorize packet: coloring rules might be changed (removed) since last run, + recalculate now. + if packet is marked, use preferences, otherwise try to apply color filters */ + if (fdata->flags.marked) { + fdata->color_filter = NULL; + packet_list_set_colors(row, &prefs.gui_marked_fg, &prefs.gui_marked_bg); + } else { + fdata->color_filter = color_filters_colorize_packet(row, cf->edt); + } + epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame, NULL); diff --git a/gtk/capture_file_dlg.c b/gtk/capture_file_dlg.c index 100e13675d..e118ef21ce 100644 --- a/gtk/capture_file_dlg.c +++ b/gtk/capture_file_dlg.c @@ -77,9 +77,9 @@ static void file_merge_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, gpointer fs); static void file_save_as_destroy_cb(GtkWidget *win, gpointer user_data); -static void file_color_import_ok_cb(GtkWidget *w, gpointer fs); +static void file_color_import_ok_cb(GtkWidget *w, gpointer filter_list); static void file_color_import_destroy_cb(GtkWidget *win, gpointer user_data); -static void file_color_export_ok_cb(GtkWidget *w, gpointer fs); +static void file_color_export_ok_cb(GtkWidget *w, gpointer filter_list); static void file_color_export_destroy_cb(GtkWidget *win, gpointer user_data); static void set_file_type_list(GtkWidget *option_menu); @@ -1623,10 +1623,10 @@ color_global_cb(GtkWidget *widget _U_, gpointer data) /* Import color filters */ void -file_color_import_cmd_cb(GtkWidget *w _U_, gpointer data) +file_color_import_cmd_cb(GtkWidget *color_filters, gpointer filter_list) { #if GTK_MAJOR_VERSION >= 2 && _WIN32 - win32_import_color_file(GDK_WINDOW_HWND(top_level->window)); + win32_import_color_file(GDK_WINDOW_HWND(top_level->window), color_filters); #else /* GTK_MAJOR_VERSION >= 2 && _WIN32 */ GtkWidget *main_vb, *cfglobal_but; #if GTK_MAJOR_VERSION < 2 @@ -1672,17 +1672,17 @@ file_color_import_cmd_cb(GtkWidget *w _U_, gpointer data) if (gtk_dialog_run(GTK_DIALOG(file_color_import_w)) == GTK_RESPONSE_ACCEPT) { - file_color_import_ok_cb(file_color_import_w, file_color_import_w); + file_color_import_ok_cb(file_color_import_w, color_filters); } else window_destroy(file_color_import_w); #else /* (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 */ /* 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); + file_color_import_ok_cb, color_filters); OBJECT_SET_DATA(GTK_FILE_SELECTION(file_color_import_w)->ok_button, - ARGUMENT_CL, data); + ARGUMENT_CL, color_filters); window_set_cancel_button(file_color_import_w, GTK_FILE_SELECTION(file_color_import_w)->cancel_button, window_cancel_button_cb); @@ -1697,9 +1697,10 @@ file_color_import_cmd_cb(GtkWidget *w _U_, gpointer data) } static void -file_color_import_ok_cb(GtkWidget *w, gpointer fs) { +file_color_import_ok_cb(GtkWidget *w, gpointer color_filters) { gchar *cf_name, *s; gpointer argument; + GtkWidget *fs = gtk_widget_get_toplevel(w); argument = OBJECT_GET_DATA(w, ARGUMENT_CL); /* to be passed back into color_filters_import */ @@ -1786,10 +1787,10 @@ color_toggle_selected_cb(GtkWidget *widget, gpointer data _U_) } void -file_color_export_cmd_cb(GtkWidget *w _U_, gpointer data _U_) +file_color_export_cmd_cb(GtkWidget *w _U_, gpointer filter_list) { #if GTK_MAJOR_VERSION >= 2 && _WIN32 - win32_export_color_file(GDK_WINDOW_HWND(top_level->window)); + win32_export_color_file(GDK_WINDOW_HWND(top_level->window), filter_list); #else /* GTK_MAJOR_VERSION >= 2 && _WIN32 */ GtkWidget *main_vb, *cfglobal_but; @@ -1829,14 +1830,14 @@ file_color_export_cmd_cb(GtkWidget *w _U_, gpointer data _U_) #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 if (gtk_dialog_run(GTK_DIALOG(file_color_export_w)) == GTK_RESPONSE_ACCEPT) { - file_color_export_ok_cb(file_color_export_w, file_color_export_w); + file_color_export_ok_cb(file_color_export_w, filter_list); } else window_destroy(file_color_export_w); #else /* (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 */ /* Connect the ok_button to file_export_ok_cb function and pass along a pointer to the file selection box widget */ SIGNAL_CONNECT(GTK_FILE_SELECTION (file_color_export_w)->ok_button, "clicked", - file_color_export_ok_cb, file_color_export_w); + file_color_export_ok_cb, filter_list); window_set_cancel_button(file_color_export_w, GTK_FILE_SELECTION(file_color_export_w)->cancel_button, window_cancel_button_cb); @@ -1853,9 +1854,10 @@ file_color_export_cmd_cb(GtkWidget *w _U_, gpointer data _U_) } static void -file_color_export_ok_cb(GtkWidget *w _U_, gpointer fs) { +file_color_export_ok_cb(GtkWidget *w, gpointer filter_list) { gchar *cf_name; gchar *dirname; + GtkWidget *fs = gtk_widget_get_toplevel(w); #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 cf_name = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs))); @@ -1877,7 +1879,7 @@ file_color_export_ok_cb(GtkWidget *w _U_, gpointer fs) { /* Write out the filters (all, or only the ones that are currently displayed or selected) to the file with the specified name. */ - if (!color_filters_export(cf_name, color_selected)) + if (!color_filters_export(cf_name, filter_list, color_selected)) { /* The write failed; don't dismiss the open dialog box, just leave it around so that the user can, after they diff --git a/gtk/color_dlg.c b/gtk/color_dlg.c index d36437645a..fe5cdcb716 100644 --- a/gtk/color_dlg.c +++ b/gtk/color_dlg.c @@ -89,21 +89,36 @@ 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_clear_cb(GtkWidget *button, gpointer user_data); +static void color_export_cb(GtkButton *button, gpointer user_data ); static void color_import_cb(GtkButton *button, gpointer user_data ); static GtkWidget* color_sel_win_new(color_filter_t *colorf, gboolean); static void color_sel_ok_cb(GtkButton *button, gpointer user_data); static void color_sel_cancel_cb(GtkObject *object, gpointer user_data); + static GtkWidget *colorize_win; gint num_of_filters; /* number of filters being displayed */ gint row_selected; /* row in color_filters that is selected */ +/* This is a list of all current color filters in the dialog + * (copied from color_filters.c and edited with the dialog). + * The color filter items are not identical to the ones used for the + * packet list display, so they can be safely edited. + * + * XXX - use the existing GTK list for this purpose and build temporary copies + * e.g. for the save/export functions. + * Problem: Don't know when able to safely throw away, e.g. while exporting. + */ +static GSList *color_filter_edit_list = NULL; + + #define COLOR_UP_LB "color_up_lb" #define COLOR_DOWN_LB "color_down_lb" #define COLOR_EDIT_LB "color_edit_lb" #define COLOR_DELETE_LB "color_delete_lb" #define COLOR_FILTERS_CL "color_filters_cl" +#define COLOR_FILTER_LIST "color_filter_list" /* Callback for the "Display:Coloring Rules" menu item. */ @@ -148,7 +163,7 @@ int color_selected_count(void) { int count = 0; - g_slist_foreach(color_filter_list, count_this_select, &count); + g_slist_foreach(color_filter_edit_list, count_this_select, &count); return count; } @@ -203,6 +218,8 @@ colorize_dialog_new (char *filter) const gchar *titles[] = { "Name", "String" }; + + num_of_filters = 0; row_selected = -1; /* no row selected */ tooltips = gtk_tooltips_new (); @@ -222,7 +239,6 @@ colorize_dialog_new (char *filter) ctrl_vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (main_hbox), ctrl_vbox, FALSE, FALSE, 0); - /* edit buttons frame */ edit_fr = gtk_frame_new("Edit"); gtk_box_pack_start (GTK_BOX (ctrl_vbox), edit_fr, TRUE, TRUE, 0); @@ -245,7 +261,8 @@ colorize_dialog_new (char *filter) WIDGET_SET_SIZE(color_edit, BUTTON_SIZE_X, BUTTON_SIZE_Y); #endif gtk_box_pack_start (GTK_BOX (edit_vbox), color_edit, FALSE, FALSE, 5); - gtk_tooltips_set_tip (tooltips, color_edit, ("Edit the properties of the selected filter"), NULL); + gtk_tooltips_set_tip (tooltips, color_edit, ("Edit the properties of the selected filter." + " If more than one filter is selected, edit the first selected one"), NULL); gtk_widget_set_sensitive (color_edit, FALSE); color_delete = BUTTON_NEW_FROM_STOCK(GTK_STOCK_DELETE); @@ -253,7 +270,7 @@ colorize_dialog_new (char *filter) #if GTK_MAJOR_VERSION < 2 WIDGET_SET_SIZE(color_delete, BUTTON_SIZE_X, BUTTON_SIZE_Y); #endif - gtk_tooltips_set_tip (tooltips, color_delete, ("Delete the selected filter"), NULL); + gtk_tooltips_set_tip (tooltips, color_delete, ("Delete the selected filter(s)"), NULL); gtk_widget_set_sensitive (color_delete, FALSE); /* End edit buttons frame */ @@ -278,14 +295,14 @@ colorize_dialog_new (char *filter) #if GTK_MAJOR_VERSION < 2 WIDGET_SET_SIZE(color_import, BUTTON_SIZE_X, BUTTON_SIZE_Y); #endif - gtk_tooltips_set_tip(tooltips, color_import, ("Load filters from a file"), NULL); + gtk_tooltips_set_tip(tooltips, color_import, ("Load filters from a file and append them to the list"), NULL); color_clear = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLEAR); gtk_box_pack_start(GTK_BOX (manage_vbox), color_clear, FALSE, FALSE, 5); #if GTK_MAJOR_VERSION < 2 WIDGET_SET_SIZE(color_clear, BUTTON_SIZE_X, BUTTON_SIZE_Y); #endif - gtk_tooltips_set_tip(tooltips, color_clear, ("Clear all filters in the user's colorfilters file and revert to system-wide default filter set"), NULL); + gtk_tooltips_set_tip(tooltips, color_clear, ("Clear the filter list and revert to system-wide default filter set"), NULL); /* filter list frame */ @@ -296,7 +313,7 @@ colorize_dialog_new (char *filter) gtk_container_set_border_width (GTK_CONTAINER (list_vbox), 5); gtk_container_add(GTK_CONTAINER(list_fr), list_vbox); - list_label = gtk_label_new (("[List is processed in order until match is found]")); + list_label = gtk_label_new (("List is processed in order until match is found")); gtk_box_pack_start (GTK_BOX (list_vbox), list_label, FALSE, FALSE, 0); /* create the list of filters */ @@ -332,9 +349,6 @@ colorize_dialog_new (char *filter) gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(color_filters), FALSE); #endif - num_of_filters = 0; - g_slist_foreach(color_filter_list, add_filter_to_list, color_filters); - #if GTK_MAJOR_VERSION < 2 gtk_clist_set_selection_mode (GTK_CLIST (color_filters),GTK_SELECTION_EXTENDED); #else @@ -380,9 +394,9 @@ colorize_dialog_new (char *filter) /* Button row: OK and cancel buttons */ if(topic_available(HELP_COLORING_RULES_DIALOG)) { - button_ok_hbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL); + button_ok_hbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL); } else { - button_ok_hbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CLOSE/*, GTK_STOCK_CANCEL*/, NULL); + button_ok_hbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CANCEL, NULL); } gtk_box_pack_start (GTK_BOX (dlg_vbox), button_ok_hbox, FALSE, FALSE, 5); @@ -390,14 +404,14 @@ colorize_dialog_new (char *filter) gtk_tooltips_set_tip (tooltips, color_ok, ("Apply the color filters to the display and close this dialog"), NULL); color_apply = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_APPLY); - gtk_tooltips_set_tip (tooltips, color_apply, ("Apply the color filters to the display but keep this dialog open"), NULL); + gtk_tooltips_set_tip (tooltips, color_apply, ("Apply the color filters to the display and keep this dialog open"), NULL); color_save = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_SAVE); gtk_tooltips_set_tip (tooltips, color_save, ("Save the color filters permanently and keep this dialog open"), NULL); - color_cancel = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_CLOSE); + color_cancel = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_CANCEL); window_set_cancel_button(color_win, color_cancel, color_cancel_cb); - gtk_tooltips_set_tip (tooltips, color_cancel, ("Close this dialog but don't apply the color filter changes to the display"), NULL); + gtk_tooltips_set_tip (tooltips, color_cancel, ("Cancel changes done (since last \"Apply\") and close this dialog"), NULL); if(topic_available(HELP_COLORING_RULES_DIALOG)) { color_help = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_HELP); @@ -430,9 +444,9 @@ colorize_dialog_new (char *filter) OBJECT_SET_DATA(color_delete, COLOR_EDIT_LB, color_edit); OBJECT_SET_DATA(color_delete, COLOR_FILTERS_CL, color_filters); SIGNAL_CONNECT(color_delete, "clicked", color_delete_cb, NULL); - SIGNAL_CONNECT(color_export, "clicked", file_color_export_cmd_cb, NULL); + SIGNAL_CONNECT(color_export, "clicked", color_export_cb, NULL); OBJECT_SET_DATA(color_import, COLOR_FILTERS_CL, color_filters); - SIGNAL_CONNECT(color_import, "clicked", color_import_cb, color_filters); + SIGNAL_CONNECT(color_import, "clicked", color_import_cb, NULL); OBJECT_SET_DATA(color_clear, COLOR_FILTERS_CL, color_filters); SIGNAL_CONNECT(color_clear, "clicked", color_clear_cb, NULL); SIGNAL_CONNECT(color_ok, "clicked", color_ok_cb, NULL); @@ -443,6 +457,10 @@ colorize_dialog_new (char *filter) gtk_widget_grab_focus(color_filters); + /* prepare filter list content */ + color_filters_clone(color_filters); + OBJECT_SET_DATA(color_win, COLOR_FILTER_LIST, &color_filter_edit_list); + gtk_widget_show_all(color_win); window_present(color_win); @@ -520,8 +538,8 @@ static void move_this_row (GtkWidget *color_filters, #endif - color_filter_list = g_slist_remove(color_filter_list, colorf); - color_filter_list = g_slist_insert(color_filter_list, colorf, filter_number + amount); + color_filter_edit_list = g_slist_remove(color_filter_edit_list, colorf); + color_filter_edit_list = g_slist_insert(color_filter_edit_list, colorf, filter_number + amount); } /* User pressed the "Up" button: Move the selected filters up in the list */ @@ -669,9 +687,9 @@ static void remember_this_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIt data->count++; } -/* clear the selection of this filter */ +/* clear the selection flag of this filter */ static void -clear_select(gpointer filter_arg, gpointer arg _U_) +clear_select_flag(gpointer filter_arg, gpointer arg _U_) { color_filter_t *colorf = filter_arg; @@ -689,7 +707,7 @@ remember_selected_row(GtkTreeSelection *sel, gpointer color_filters) data.count = 0; data.color_filters = color_filters; - g_slist_foreach(color_filter_list, clear_select, NULL); + g_slist_foreach(color_filter_edit_list, clear_select_flag, NULL); gtk_tree_selection_selected_foreach(sel,remember_this_row, &data); if (data.count > 0) @@ -769,6 +787,8 @@ unremember_selected_row (GtkCList *clist, } #endif + + /* destroy a single color edit dialog */ static void destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy _U_) @@ -780,19 +800,48 @@ destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy _U_) } /* Called when the dialog box is being destroyed; destroy any edit - * dialogs opened from this dialog, and null out the pointer to this - * dialog. + * dialogs opened from this dialog. */ static void color_destroy_cb (GtkButton *button _U_, gpointer user_data _U_) { /* Destroy any edit dialogs we have open. */ - g_slist_foreach(color_filter_list, destroy_edit_dialog_cb, NULL); + g_slist_foreach(color_filter_edit_list, destroy_edit_dialog_cb, NULL); + + /* destroy the filter list itself */ + color_filter_list_delete(&color_filter_edit_list); colorize_win = NULL; } + +static void +select_row(GtkWidget *color_filters, int row) +{ +#if GTK_MAJOR_VERSION < 2 +#else + GtkTreeModel *model; + gint num_filters; + GtkTreeIter iter; + GtkTreeSelection *sel; +#endif + +#if GTK_MAJOR_VERSION < 2 + /* select the new row */ + gtk_clist_select_row(GTK_CLIST(color_filters), row, -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, row); + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters)); + gtk_tree_selection_select_iter(sel, &iter); +#endif +} + + + /* add a single color filter to the list */ static void add_filter_to_list(gpointer filter_arg, gpointer list_arg) @@ -827,43 +876,20 @@ add_filter_to_list(gpointer filter_arg, gpointer list_arg) 1, colorf->filter_text, 2, fg_str, 3, bg_str, 4, colorf, -1); #endif + color_filter_edit_list = g_slist_append(color_filter_edit_list, colorf); + num_of_filters++; } -/* add a new filter to the list and select it */ -static void -color_add_colorf(GtkWidget *color_filters, color_filter_t *colorf) -{ -#if GTK_MAJOR_VERSION < 2 -#else - GtkTreeModel *model; - gint num_filters; - GtkTreeIter iter; - GtkTreeSelection *sel; -#endif - - 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 -} -/* a new color filter was read in from the filter file */ +/* a new color filter was read in from a filter file */ void -color_filter_add_cb(color_filter_t *colorf, gpointer arg) +color_filter_add_cb(color_filter_t *colorf, gpointer user_data) { - GtkWidget *color_filters = arg; + GtkWidget *color_filters = user_data; + + add_filter_to_list(colorf, color_filters); - color_add_colorf(color_filters, colorf); #if GTK_MAJOR_VERSION >= 2 gtk_widget_grab_focus(color_filters); #endif @@ -884,6 +910,7 @@ create_new_color_filter(GtkButton *button, const char *filter) color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL); + /* unselect all filters */ #if GTK_MAJOR_VERSION >= 2 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters)); gtk_tree_selection_unselect_all (sel); @@ -895,11 +922,15 @@ create_new_color_filter(GtkButton *button, const char *filter) style = gtk_widget_get_style(packet_list); gdkcolor_to_color_t(&bg_color, &style->base[GTK_STATE_NORMAL]); gdkcolor_to_color_t(&fg_color, &style->text[GTK_STATE_NORMAL]); - colorf = color_filter_new("name", filter, &bg_color, &fg_color); /* Adds at end! */ - color_add_colorf(color_filters, colorf); + colorf = color_filter_new("name", filter, &bg_color, &fg_color); + + add_filter_to_list(colorf, color_filters); - edit_color_filter_dialog(color_filters, TRUE); + select_row(color_filters, num_of_filters-1); + + /* open the edit dialog */ + edit_color_filter_dialog(color_filters, TRUE /* is a new filter */); #if GTK_MAJOR_VERSION >= 2 gtk_widget_grab_focus(color_filters); @@ -923,10 +954,10 @@ color_edit_cb(GtkButton *button, gpointer user_data _U_) color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL); g_assert(row_selected != -1); - edit_color_filter_dialog(color_filters, FALSE); + edit_color_filter_dialog(color_filters, FALSE /* is not a new filter */); } -/* Delete a single color filter from the list. */ +/* Delete a single color filter from the list and elsewhere. */ void color_delete(gint row, GtkWidget *color_filters) { @@ -950,9 +981,10 @@ color_delete(gint row, GtkWidget *color_filters) if (colorf->edit_dialog != NULL) window_destroy(colorf->edit_dialog); - /* Remove the color filter from the list of color filters. */ - color_filter_remove(colorf); - + /* Delete the color filter from the list of color filters. */ + color_filter_edit_list = g_slist_remove(color_filter_edit_list, colorf); + color_filter_delete(colorf); + /* If we grab the focus after updating the selection, the first * row is always selected, so we do it before */ gtk_widget_grab_focus(color_filters); @@ -968,13 +1000,13 @@ color_delete(gint row, GtkWidget *color_filters) if (colorf->edit_dialog != NULL) window_destroy(colorf->edit_dialog); - /* Remove the color filter from the list of color filters. */ - color_filter_remove(colorf); - + /* Delete the color filter from the list of color filters. */ + color_filter_edit_list = g_slist_remove(color_filter_edit_list, colorf); + color_filter_delete(colorf); #endif } -/* User pressed the "Delete" button: Delete the selected color from the list.*/ +/* User pressed the "Delete" button: Delete the selected filters from the list.*/ static void color_delete_cb(GtkWidget *widget, gpointer user_data _U_) { @@ -989,7 +1021,8 @@ color_delete_cb(GtkWidget *widget, gpointer user_data _U_) #endif color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL); - + + /* get the number of filters in the list */ #if GTK_MAJOR_VERSION < 2 num_filters = num_of_filters; #else @@ -998,6 +1031,7 @@ color_delete_cb(GtkWidget *widget, gpointer user_data _U_) sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters)); #endif + /* iterate through the list and delete the selected ones */ for (row = num_filters - 1; row >= 0; row--) { #if GTK_MAJOR_VERSION < 2 @@ -1012,9 +1046,23 @@ color_delete_cb(GtkWidget *widget, gpointer user_data _U_) } } +/* User pressed "Export": Pop up an "Export color filter" dialog box. */ +static void +color_export_cb(GtkButton *button, gpointer data _U_) +{ + GtkWidget *color_filters; +#if GTK_MAJOR_VERSION >= 2 + GtkTreeSelection *sel; +#endif + + color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL); + + file_color_export_cmd_cb(color_filters, &color_filter_edit_list); +} + /* User pressed "Import": Pop up an "Import color filter" dialog box. */ static void -color_import_cb(GtkButton *button, gpointer user_data ) +color_import_cb(GtkButton *button, gpointer data _U_) { GtkWidget *color_filters; #if GTK_MAJOR_VERSION >= 2 @@ -1030,7 +1078,7 @@ color_import_cb(GtkButton *button, gpointer user_data ) gtk_clist_unselect_all (GTK_CLIST(color_filters)); #endif - file_color_import_cmd_cb(GTK_WIDGET(button), user_data); + file_color_import_cmd_cb(color_filters, &color_filter_edit_list); } /* User confirmed the clear operation: Remove all user defined color filters and @@ -1047,16 +1095,8 @@ color_clear_cmd(GtkWidget *widget) color_delete (num_of_filters-1, color_filters); } - if (!color_filters_revert()) - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Could not delete filter file: %s", strerror(errno)); - - /* colorize list */ - cf_colorize_packets(&cfile); - - /* Destroy the dialog box. */ - /* XXX: is this useful? user might want to continue with editing new colors */ - window_destroy(colorize_win); + /* try to read the global filters */ + color_filters_read_globals(color_filters); } /* Clear button: user responded to question */ @@ -1087,11 +1127,15 @@ color_clear_cb(GtkWidget *widget, gpointer data _U_) { simple_dialog_set_cb(dialog, color_clear_answered_cb, widget); } + + /* User pressed "Ok" button: Exit dialog and apply new list of color filters to the capture. */ static void color_ok_cb(GtkButton *button _U_, gpointer user_data _U_) { + color_filters_apply(color_filter_edit_list); + /* colorize list */ cf_colorize_packets(&cfile); @@ -1104,6 +1148,8 @@ color_ok_cb(GtkButton *button _U_, gpointer user_data _U_) static void color_apply_cb(GtkButton *button _U_, gpointer user_data _U_) { + color_filters_apply(color_filter_edit_list); + cf_colorize_packets(&cfile); } @@ -1112,14 +1158,14 @@ color_apply_cb(GtkButton *button _U_, gpointer user_data _U_) static void color_save_cb(GtkButton *button _U_, gpointer user_data _U_) { - if (!color_filters_write()) + + if (!color_filters_write(color_filter_edit_list)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not open filter file: %s", strerror(errno)); } /* User pressed "Cancel" button (or "ESC" or the 'X'): - Exit dialog without colorizing packets with the new list. - XXX - should really undo any changes to the list.... */ + Exit dialog without colorizing packets with the new list. */ static void color_cancel_cb(GtkWidget *widget _U_, gpointer user_data _U_) { diff --git a/gtk/win32-file-dlg.c b/gtk/win32-file-dlg.c index 7ab088e0cb..fb24c61ac9 100644 --- a/gtk/win32-file-dlg.c +++ b/gtk/win32-file-dlg.c @@ -583,7 +583,7 @@ win32_export_raw_file(HWND h_wnd) { } void -win32_export_color_file(HWND h_wnd) { +win32_export_color_file(HWND h_wnd, gpointer filter_list) { static OPENFILENAME ofn; TCHAR file_name[MAX_PATH] = _T(""); gchar *dirname; @@ -613,7 +613,7 @@ win32_export_color_file(HWND h_wnd) { /* XXX - Support marked filters */ if (GetSaveFileName(&ofn)) { - if (!color_filters_export(utf_16to8(file_name), FALSE)) + if (!color_filters_export(utf_16to8(file_name), filter_list, FALSE /* all filters */)) return; /* Save the directory name for future file dialogs. */ @@ -623,7 +623,7 @@ win32_export_color_file(HWND h_wnd) { } void -win32_import_color_file(HWND h_wnd) { +win32_import_color_file(HWND h_wnd, gpointer color_filters) { static OPENFILENAME ofn; TCHAR file_name[MAX_PATH] = _T(""); gchar *dirname; @@ -649,9 +649,9 @@ win32_import_color_file(HWND h_wnd) { ofn.lpfnHook = NULL; ofn.lpTemplateName = NULL; - /* XXX - Support marked filters */ + /* XXX - Support export limited to selected filters */ if (GetOpenFileName(&ofn)) { - if (!color_filters_import(utf_16to8(file_name), NULL)) + if (!color_filters_import(utf_16to8(file_name), color_filters)) return; /* Save the directory name for future file dialogs. */ diff --git a/gtk/win32-file-dlg.h b/gtk/win32-file-dlg.h index ea6e30b74c..edce057cab 100644 --- a/gtk/win32-file-dlg.h +++ b/gtk/win32-file-dlg.h @@ -68,14 +68,16 @@ void win32_export_raw_file (HWND h_wnd); /** Open the "Export Color Filters" dialog box * * @param h_wnd HWND of the parent window + * @param filter_list the list to export */ -void win32_export_color_file(HWND h_wnd); +void win32_export_color_file(HWND h_wnd, gpointer filter_list); /** Open the "Import Color Filters" dialog box * * @param h_wnd HWND of the parent window + * @param color_filters the calling widget */ -void win32_import_color_file(HWND h_wnd); +void win32_import_color_file(HWND h_wnd, gpointer color_filters); /** Given a print_args_t struct, update a set of print/export format controls * accordingly. |