code cleanup: the term filter_list was used with different meanings throughout the...
[obnox/wireshark/wip.git] / gtk / color_dlg.c
1 /* color_dlg.c
2  * Definitions for dialog boxes for color filters
3  *
4  * $Id$
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <gtk/gtk.h>
30
31 #include <string.h>
32
33 #include "gtk/main.h"
34 #include <epan/packet.h>
35 #include "color.h"
36 #include "colors.h"
37 #include "color_filters.h"
38 #include "color_dlg.h"
39 #include "file.h"
40 #include <epan/dfilter/dfilter.h>
41 #include "simple_dialog.h"
42 #include "dlg_utils.h"
43 #include "ui_util.h"
44 #include "dfilter_expr_dlg.h"
45 #include "compat_macros.h"
46 #include "filter_dlg.h"
47 #include "file_dlg.h"
48 #include "gtkglobals.h"
49 #include <epan/prefs.h>
50 #include "help_dlg.h"
51
52 static GtkWidget* colorize_dialog_new(char *filter);
53 static void add_filter_to_list(gpointer filter_arg, gpointer list_arg);
54 static void color_filter_up_cb(GtkButton *button, gpointer user_data);
55 static void color_filter_down_cb(GtkButton *button, gpointer user_data);
56 #if GTK_MAJOR_VERSION < 2
57 static void remember_selected_row(GtkCList *clist, gint row, gint column,
58                                   GdkEvent *event, gpointer user_data);
59 static void unremember_selected_row(GtkCList *clist, gint row, gint column,
60                                     GdkEvent *event, gpointer user_data);
61 #else
62 static void remember_selected_row(GtkTreeSelection *sel, gpointer list);
63 #endif
64 static void color_destroy_cb(GtkButton *button, gpointer user_data);
65 static void destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy);
66 static void create_new_color_filter(GtkButton *button, char *filter);
67 static void color_new_cb(GtkButton *button, gpointer user_data);
68 static void color_props_cb(GtkButton *button, gpointer user_data);
69 static void color_delete_cb(GtkWidget *widget, gpointer user_data);
70 static void color_save_cb(GtkButton *button, gpointer user_data);
71 static void color_ok_cb(GtkButton *button, gpointer user_data);
72 static void color_cancel_cb(GtkWidget *widget, gpointer user_data);
73 static void color_apply_cb(GtkButton *button, gpointer user_data);
74 static void color_clear_cb(GtkWidget *button, gpointer user_data);
75 static void color_import_cb(GtkButton *button, gpointer user_data );
76
77 static void edit_color_filter_dialog(GtkWidget *color_filters,
78                                      GtkWidget **colorize_filter_name,
79                                      GtkWidget **colorize_filter_text,
80                                      guchar is_new_filter);
81
82 #if GTK_MAJOR_VERSION < 2
83 static void edit_color_filter_destroy_cb(GtkObject *object, gpointer user_data);
84 #else
85 static void edit_color_filter_destroy_cb(GObject *object, gpointer user_data);
86 #endif
87 static void edit_color_filter_fg_cb(GtkButton *button, gpointer user_data);
88 static void edit_color_filter_bg_cb(GtkButton *button, gpointer user_data);
89 static void edit_color_filter_ok_cb(GtkButton *button, gpointer user_data);
90 static void edit_new_color_filter_cancel_cb(GtkButton *button, gpointer user_data);
91
92 static GtkWidget* color_sel_win_new(color_filter_t *colorf, gboolean);
93 static void color_sel_ok_cb(GtkButton *button, gpointer user_data);
94 static void color_sel_cancel_cb(GtkObject *object, gpointer user_data);
95
96 static GtkWidget *colorize_win;
97 static gint       num_of_filters;  /* number of filters being displayed */
98 static gint       row_selected;    /* row in color_filters that is selected */
99
100 #define COLOR_UP_LB             "color_up_lb"
101 #define COLOR_DOWN_LB           "color_down_lb"
102 #define COLOR_PROPS_LB          "color_props_lb"
103 #define COLOR_DELETE_LB         "color_delete_lb"
104 #define COLOR_FILTERS_CL        "color_filters_cl"
105 #define COLOR_FILTER            "color_filter"
106 #define COLOR_SELECTION_FG      "color_selection_fg"
107 #define COLOR_SELECTION_BG      "color_selection_bg"
108 #define COLOR_SELECTION_PARENT  "color_selection_parent"
109
110 static void
111 filter_expr_cb(GtkWidget *w _U_, gpointer filter_te)
112 {
113
114         dfilter_expr_dlg_new(GTK_WIDGET(filter_te));
115 }
116
117
118 /* Callback for the "Display:Colorize Display" menu item. */
119 void
120 color_display_cb(GtkWidget *w _U_, gpointer d _U_)
121 {
122   if (colorize_win != NULL) {
123     /* There's already a color dialog box active; reactivate it. */
124     reactivate_window(colorize_win);
125   } else {
126     /* Create a new "Colorize Display" dialog. */
127     colorize_win = colorize_dialog_new(NULL);
128   }
129 }
130
131 /* this opens the colorize dialogue and presets the filter string */
132 void
133 color_display_with_filter(char *filter)
134 {
135   if (colorize_win != NULL) {
136     /* There's already a color dialog box active; reactivate it. */
137     reactivate_window(colorize_win);
138   } else {
139     /* Create a new "Colorize Display" dialog. */
140     colorize_win = colorize_dialog_new(filter);
141   }
142 }
143
144 /* if this filter is marked count it in the given int* */
145 static void
146 count_this_mark(gpointer filter_arg, gpointer counter_arg)
147 {
148   color_filter_t *colorf = filter_arg;
149   int * cnt = counter_arg;
150
151   if (colorf->marked)
152     (*cnt)++;
153 }
154
155 /* TODO: implement count of selected filters. Plug in to file_dlg update of "export selected" checkbox. */
156 int color_marked_count(void)
157 {
158   int count = 0;
159
160   g_slist_foreach(color_filter_list, count_this_mark, &count);
161
162   return count;
163 }
164
165 /* Create the "Coloring Rules" dialog. */
166 static GtkWidget*
167 colorize_dialog_new (char *filter)
168 {
169   GtkWidget *color_win;
170   GtkWidget *dlg_vbox;
171   GtkWidget *main_hbox;
172   GtkWidget *ctrl_vbox;
173   GtkTooltips *tooltips;
174
175   GtkWidget *order_fr;
176   GtkWidget *order_vbox;
177   GtkWidget *color_filter_up;
178   GtkWidget *order_move_label;
179   GtkWidget *color_filter_down;
180
181   GtkWidget *list_fr;
182   GtkWidget *list_vbox;
183   GtkWidget *scrolledwindow1;
184   GtkWidget *color_filters;
185   GtkWidget *list_label;
186
187   GtkWidget *edit_fr;
188   GtkWidget *edit_vbox;
189   GtkWidget *color_new;
190   GtkWidget *color_props;
191   GtkWidget *color_delete;
192
193   GtkWidget *manage_fr;
194   GtkWidget *manage_vbox;
195   GtkWidget *color_export;
196   GtkWidget *color_import;
197   GtkWidget *color_clear;
198
199   GtkWidget *button_ok_hbox;
200   GtkWidget *color_ok;
201   GtkWidget *color_apply;
202   GtkWidget *color_save;
203   GtkWidget *color_cancel;
204   GtkWidget *color_help;
205
206 #if GTK_MAJOR_VERSION >= 2
207   GtkListStore      *store;
208   GtkCellRenderer   *renderer;
209   GtkTreeViewColumn *column;
210   GtkTreeSelection  *selection;
211 #endif
212   gchar *titles[] = { "Name", "String" };
213
214
215   row_selected = -1; /* no row selected */
216   tooltips = gtk_tooltips_new ();
217
218   /* Resizing of the dialog window is now reasonably done.
219    * Default size is set so that it should fit into every usual screen resolution.
220    * All other widgets are always packed depending on the current window size. */
221   color_win = dlg_window_new ("Ethereal: Coloring Rules");
222   OBJECT_SET_DATA(color_win, "color_win", color_win);
223   gtk_window_set_default_size(GTK_WINDOW(color_win), DEF_WIDTH, DEF_HEIGHT * 2/3);
224   dlg_vbox = gtk_vbox_new (FALSE, 0);
225   gtk_container_set_border_width  (GTK_CONTAINER (dlg_vbox), 5);
226   gtk_container_add (GTK_CONTAINER (color_win), dlg_vbox);
227
228   main_hbox = gtk_hbox_new (FALSE, 0);
229   gtk_box_pack_start (GTK_BOX (dlg_vbox), main_hbox, TRUE, TRUE, 0);
230
231   ctrl_vbox = gtk_vbox_new (FALSE, 0);
232   gtk_box_pack_start (GTK_BOX (main_hbox), ctrl_vbox, FALSE, FALSE, 0);
233
234
235   /* edit buttons frame */
236   edit_fr = gtk_frame_new("Edit");
237   gtk_box_pack_start (GTK_BOX (ctrl_vbox), edit_fr, TRUE, TRUE, 0);
238
239   /* edit_vbox is first button column (containing: new, edit and such) */
240   edit_vbox = gtk_vbutton_box_new();
241   gtk_button_box_set_child_size(GTK_BUTTON_BOX(edit_vbox), 50, 20);
242   gtk_container_set_border_width  (GTK_CONTAINER (edit_vbox), 5);
243   gtk_container_add(GTK_CONTAINER(edit_fr), edit_vbox);
244
245   color_new = BUTTON_NEW_FROM_STOCK(GTK_STOCK_NEW);
246 #if GTK_MAJOR_VERSION < 2
247   WIDGET_SET_SIZE(color_new, 50, 20);
248 #endif
249   gtk_box_pack_start (GTK_BOX (edit_vbox), color_new, FALSE, FALSE, 5);
250   gtk_tooltips_set_tip (tooltips, color_new, ("Create a new filter at the end of the list"), NULL);
251
252   color_props = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_EDIT);
253 #if GTK_MAJOR_VERSION < 2
254   WIDGET_SET_SIZE(color_props, 50, 20);
255 #endif
256   gtk_box_pack_start (GTK_BOX (edit_vbox), color_props, FALSE, FALSE, 5);
257   gtk_tooltips_set_tip (tooltips, color_props, ("Edit the properties of the selected filter"), NULL);
258   gtk_widget_set_sensitive (color_props, FALSE);
259
260   color_delete = BUTTON_NEW_FROM_STOCK(GTK_STOCK_DELETE);
261   gtk_box_pack_start (GTK_BOX (edit_vbox), color_delete, FALSE, FALSE, 5);
262 #if GTK_MAJOR_VERSION < 2
263   WIDGET_SET_SIZE(color_delete, 50, 20);
264 #endif
265   gtk_tooltips_set_tip (tooltips, color_delete, ("Delete the selected filter"), NULL);
266   gtk_widget_set_sensitive (color_delete, FALSE);
267   /* End edit buttons frame */
268
269
270   /* manage buttons frame */
271   manage_fr = gtk_frame_new("Manage");
272   gtk_box_pack_start (GTK_BOX (ctrl_vbox), manage_fr, FALSE, FALSE, 0);
273   
274   manage_vbox = gtk_vbox_new (FALSE, 0);
275   gtk_container_set_border_width  (GTK_CONTAINER (manage_vbox), 5);
276   gtk_container_add(GTK_CONTAINER(manage_fr), manage_vbox);
277
278   color_export = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_EXPORT);
279   gtk_box_pack_start (GTK_BOX (manage_vbox), color_export, FALSE, FALSE, 5);
280 #if GTK_MAJOR_VERSION < 2
281   WIDGET_SET_SIZE(color_export, 50, 20);
282 #endif
283   gtk_tooltips_set_tip(tooltips, color_export, ("Save all/marked filters to a file"), NULL);
284
285   color_import = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_IMPORT);
286   gtk_box_pack_start (GTK_BOX (manage_vbox), color_import, FALSE, FALSE, 5);
287 #if GTK_MAJOR_VERSION < 2
288   WIDGET_SET_SIZE(color_import, 50, 20);
289 #endif
290   gtk_tooltips_set_tip(tooltips, color_import, ("Load filters from a file"), NULL);
291
292   color_clear = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLEAR);
293   gtk_box_pack_start(GTK_BOX (manage_vbox), color_clear, FALSE, FALSE, 5);
294 #if GTK_MAJOR_VERSION < 2
295   WIDGET_SET_SIZE(color_clear, 50, 20);
296 #endif
297   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);
298
299
300   /* filter list frame */
301   list_fr = gtk_frame_new("Filter");
302   gtk_box_pack_start (GTK_BOX (main_hbox), list_fr, TRUE, TRUE, 0);
303
304   list_vbox = gtk_vbox_new (FALSE, 0);
305   gtk_container_set_border_width  (GTK_CONTAINER (list_vbox), 5);
306   gtk_container_add(GTK_CONTAINER(list_fr), list_vbox);
307
308   list_label = gtk_label_new (("[List is processed in order until match is found]"));
309   gtk_box_pack_start (GTK_BOX (list_vbox), list_label, FALSE, FALSE, 0);
310
311   /* create the list of filters */
312   scrolledwindow1 = scrolled_window_new(NULL, NULL);
313 #if GTK_MAJOR_VERSION >= 2
314   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow1), 
315                                    GTK_SHADOW_IN);
316 #endif
317   gtk_box_pack_start (GTK_BOX (list_vbox), scrolledwindow1, TRUE, TRUE, 0);
318
319 #if GTK_MAJOR_VERSION < 2
320   color_filters = gtk_clist_new_with_titles(2, titles);
321 #else
322   /* the list store contains : filter name, filter string, foreground
323    * color, background color, pointer to color filter */
324   store = gtk_list_store_new(5, G_TYPE_STRING, G_TYPE_STRING,
325                              G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
326   color_filters = tree_view_new(GTK_TREE_MODEL(store));
327   g_object_unref(store);
328   renderer = gtk_cell_renderer_text_new();
329   column = gtk_tree_view_column_new_with_attributes(titles[0], renderer, "text",
330                                                     0, "foreground", 2,
331                                                     "background", 3, NULL);
332   gtk_tree_view_column_set_fixed_width(column, 80);
333   gtk_tree_view_append_column(GTK_TREE_VIEW(color_filters), column);
334   renderer = gtk_cell_renderer_text_new();
335   column = gtk_tree_view_column_new_with_attributes(titles[1], renderer, "text",
336                                                     1, "foreground", 2,
337                                                     "background", 3, NULL);
338   gtk_tree_view_column_set_fixed_width(column, 300);
339   gtk_tree_view_append_column(GTK_TREE_VIEW(color_filters), column);
340   gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(color_filters), TRUE);
341   gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(color_filters), FALSE);
342 #endif
343
344   num_of_filters = 0;
345   g_slist_foreach(color_filter_list, add_filter_to_list, color_filters);
346
347 #if GTK_MAJOR_VERSION < 2
348   gtk_clist_set_selection_mode    (GTK_CLIST (color_filters),GTK_SELECTION_EXTENDED);
349 #else
350   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
351   gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
352 #endif
353
354   gtk_container_add (GTK_CONTAINER (scrolledwindow1), color_filters);
355 #if GTK_MAJOR_VERSION < 2
356   gtk_clist_set_column_width (GTK_CLIST (color_filters), 0, 80);
357   gtk_clist_set_column_width (GTK_CLIST (color_filters), 1, 300);
358   gtk_clist_column_titles_show (GTK_CLIST (color_filters));
359 #endif
360
361
362   /* order frame */
363   order_fr = gtk_frame_new("Order");
364   gtk_box_pack_start (GTK_BOX (main_hbox), order_fr, FALSE, FALSE, 0);
365
366   order_vbox = gtk_vbox_new (TRUE, 0);
367   gtk_container_set_border_width  (GTK_CONTAINER (order_vbox), 5);
368   gtk_container_add(GTK_CONTAINER(order_fr), order_vbox);
369
370   color_filter_up = BUTTON_NEW_FROM_STOCK(GTK_STOCK_GO_UP);
371 #if GTK_MAJOR_VERSION < 2
372   WIDGET_SET_SIZE(color_filter_up, 50, 20);
373 #endif
374   gtk_box_pack_start (GTK_BOX (order_vbox), color_filter_up, FALSE, FALSE, 0);
375   gtk_tooltips_set_tip (tooltips, color_filter_up, ("Move filter higher in list"), NULL);
376   gtk_widget_set_sensitive (color_filter_up, FALSE);
377
378   order_move_label = gtk_label_new (("Move\nselected filter\nup or down"));
379   gtk_box_pack_start (GTK_BOX (order_vbox), order_move_label, FALSE, FALSE, 0);
380
381   color_filter_down = BUTTON_NEW_FROM_STOCK(GTK_STOCK_GO_DOWN);
382 #if GTK_MAJOR_VERSION < 2
383   WIDGET_SET_SIZE(color_filter_down, 50, 20);
384 #endif
385   gtk_box_pack_start (GTK_BOX (order_vbox), color_filter_down, FALSE, FALSE, 0);
386   gtk_tooltips_set_tip (tooltips, color_filter_down, ("Move filter lower in list"), NULL);
387   gtk_widget_set_sensitive (color_filter_down, FALSE);
388
389
390   /* Button row: OK and cancel buttons */
391   if(topic_available(HELP_COLORING_RULES_DIALOG)) {
392     button_ok_hbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL);
393   } else {
394     button_ok_hbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CLOSE/*, GTK_STOCK_CANCEL*/, NULL);
395   }
396   gtk_box_pack_start (GTK_BOX (dlg_vbox), button_ok_hbox, FALSE, FALSE, 5);
397
398   color_ok = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_OK);
399   gtk_tooltips_set_tip (tooltips, color_ok, ("Apply the color filters to the display and close this dialog"), NULL);
400
401   color_apply = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_APPLY);
402   gtk_tooltips_set_tip (tooltips, color_apply, ("Apply the color filters to the display but keep this dialog open"), NULL);
403
404   color_save = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_SAVE);
405   gtk_tooltips_set_tip (tooltips, color_save, ("Save the color filters permanently and keep this dialog open"), NULL);
406
407   color_cancel = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_CLOSE);
408   window_set_cancel_button(color_win, color_cancel, color_cancel_cb);
409   gtk_tooltips_set_tip (tooltips, color_cancel, ("Close this dialog but don't apply the color filter changes to the display"), NULL);
410
411   if(topic_available(HELP_COLORING_RULES_DIALOG)) {
412       color_help = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_HELP);
413       gtk_tooltips_set_tip (tooltips, color_help, ("Get help about this dialog"), NULL);
414       SIGNAL_CONNECT(color_help, "clicked", topic_cb, HELP_COLORING_RULES_DIALOG);
415   }
416
417   gtk_widget_grab_default(color_ok);
418
419   /* signals and such */
420   SIGNAL_CONNECT(color_win, "destroy", color_destroy_cb, NULL);
421   OBJECT_SET_DATA(color_filter_up, COLOR_FILTERS_CL, color_filters);
422   SIGNAL_CONNECT(color_filter_up, "clicked", color_filter_up_cb, NULL);
423   OBJECT_SET_DATA(color_filter_down, COLOR_FILTERS_CL, color_filters);
424   SIGNAL_CONNECT(color_filter_down, "clicked", color_filter_down_cb, NULL);
425 #if GTK_MAJOR_VERSION < 2
426   SIGNAL_CONNECT(color_filters, "select_row", remember_selected_row, NULL);
427   SIGNAL_CONNECT(color_filters, "unselect_row", unremember_selected_row, NULL);
428 #else
429   SIGNAL_CONNECT(selection, "changed", remember_selected_row, color_filters);
430 #endif
431   OBJECT_SET_DATA(color_filters, COLOR_UP_LB, color_filter_up);
432   OBJECT_SET_DATA(color_filters, COLOR_DOWN_LB, color_filter_down);
433   OBJECT_SET_DATA(color_filters, COLOR_PROPS_LB, color_props);
434   OBJECT_SET_DATA(color_filters, COLOR_DELETE_LB, color_delete);
435   OBJECT_SET_DATA(color_new, COLOR_FILTERS_CL, color_filters);
436   SIGNAL_CONNECT(color_new, "clicked", color_new_cb, NULL);
437   OBJECT_SET_DATA(color_props, COLOR_FILTERS_CL, color_filters);
438   SIGNAL_CONNECT(color_props, "clicked", color_props_cb, NULL);
439   OBJECT_SET_DATA(color_delete, COLOR_PROPS_LB, color_props);
440   OBJECT_SET_DATA(color_delete, COLOR_FILTERS_CL, color_filters);
441   SIGNAL_CONNECT(color_delete, "clicked", color_delete_cb, NULL);
442   SIGNAL_CONNECT(color_save, "clicked", color_save_cb, NULL);
443   SIGNAL_CONNECT(color_export, "clicked", file_color_export_cmd_cb, NULL);
444   OBJECT_SET_DATA(color_import, COLOR_FILTERS_CL, color_filters);
445   SIGNAL_CONNECT(color_import, "clicked", color_import_cb, color_filters);
446   OBJECT_SET_DATA(color_clear, COLOR_FILTERS_CL, color_filters);
447   SIGNAL_CONNECT(color_clear, "clicked", color_clear_cb, NULL);
448   SIGNAL_CONNECT(color_ok, "clicked", color_ok_cb, NULL);
449   SIGNAL_CONNECT(color_apply, "clicked", color_apply_cb, NULL);
450
451   SIGNAL_CONNECT(color_win, "delete_event", window_delete_event_cb, NULL);
452
453   gtk_widget_grab_focus(color_filters);
454
455   gtk_widget_show_all(color_win);
456   window_present(color_win);
457
458   if(filter){
459     /* if we specified a preset filter string, open the new dialog and
460        set the filter */
461     create_new_color_filter(GTK_BUTTON(color_new), filter);
462   }
463
464   return color_win;
465 }
466
467 static void
468 add_filter_to_list(gpointer filter_arg, gpointer list_arg)
469 {
470   color_filter_t *colorf = filter_arg;
471 #if GTK_MAJOR_VERSION < 2
472   GtkWidget      *color_filters = list_arg;
473   gchar          *data[2];
474   gint            row;
475   GdkColor        bg, fg;
476
477   data[0] = colorf->filter_name;
478   data[1] = colorf->filter_text;
479   row = gtk_clist_append(GTK_CLIST(color_filters), data);
480   color_t_to_gdkcolor(&fg, &colorf->fg_color);
481   color_t_to_gdkcolor(&bg, &colorf->bg_color);
482   gtk_clist_set_row_data(GTK_CLIST(color_filters), row, colorf);
483   gtk_clist_set_foreground(GTK_CLIST(color_filters), row, &fg);
484   gtk_clist_set_background(GTK_CLIST(color_filters), row, &bg);
485 #else
486   gchar           fg_str[14], bg_str[14];
487   GtkListStore   *store;
488   GtkTreeIter     iter;
489
490   store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list_arg)));
491   gtk_list_store_append(store, &iter);
492   g_snprintf(fg_str, 14, "#%04X%04X%04X",
493           colorf->fg_color.red, colorf->fg_color.green, colorf->fg_color.blue);
494   g_snprintf(bg_str, 14, "#%04X%04X%04X",
495           colorf->bg_color.red, colorf->bg_color.green, colorf->bg_color.blue);
496   gtk_list_store_set(store, &iter, 0, colorf->filter_name,
497                      1, colorf->filter_text, 2, fg_str, 3, bg_str,
498                      4, colorf, -1);
499 #endif
500   num_of_filters++;
501 }
502
503 void move_this_row (GtkWidget   *color_filters, 
504                      gint         filter_number,
505                      gint         amount)            /* only tested with +1(down) and -1(up) */
506 {
507   color_filter_t *colorf;
508 #if GTK_MAJOR_VERSION < 2
509   gint            lower, higher;
510 #else
511   GtkTreeModel   *model;
512   GtkTreeIter     iter1, iter2;
513   gchar          *name, *string, *fg_str, *bg_str;
514 #endif
515
516   g_assert(amount == +1 || amount == -1);
517   g_assert(amount == +1 || filter_number > 0);
518   g_assert(amount == -1 || filter_number < num_of_filters - 1);
519
520 #if GTK_MAJOR_VERSION < 2
521   if (amount > 0)
522   {
523     lower = filter_number;
524     higher = filter_number + amount;
525   }
526   else
527   {
528     higher = filter_number;
529     lower = filter_number + amount;
530   }
531
532   colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
533   gtk_clist_swap_rows(GTK_CLIST(color_filters), higher, lower);
534
535   /*
536    * That row is still selected, but it's now moved.
537    */
538   remember_selected_row(GTK_CLIST(color_filters), filter_number + amount, 0, NULL, NULL);
539 #else
540
541   model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
542   gtk_tree_model_iter_nth_child(model, &iter1, NULL, filter_number);
543   gtk_tree_model_iter_nth_child(model, &iter2, NULL, filter_number + amount);
544   
545   gtk_tree_model_get(model, &iter1, 0, &name, 1, &string,
546                      2, &fg_str, 3, &bg_str, 4, &colorf, -1);
547   gtk_list_store_remove(GTK_LIST_STORE(model), &iter1);
548   if (amount < 0)
549     gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter1, &iter2);
550   else
551     gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter1, &iter2);
552   gtk_list_store_set(GTK_LIST_STORE(model), &iter1, 0, name, 1, string,
553                      2, fg_str, 3, bg_str, 4, colorf, -1);
554   g_free(name);
555   g_free(string);
556   g_free(fg_str);
557   g_free(bg_str);
558
559   /*
560    * re-select the initial row
561    */
562   gtk_widget_grab_focus(color_filters);
563   gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters)), &iter1);
564   
565 #endif
566
567   color_filter_list = g_slist_remove(color_filter_list, colorf);
568   color_filter_list = g_slist_insert(color_filter_list, colorf, filter_number + amount);
569 }
570
571 /* Move the selected filters up in the list */
572 static void
573 color_filter_up_cb(GtkButton *button, gpointer user_data _U_)
574 {
575   gint amount;
576   gint filter_number;
577   GtkWidget * color_filters;
578   color_filter_t *colorf;
579 #if GTK_MAJOR_VERSION < 2
580 #else
581   GtkTreeIter       iter;
582   GtkTreeModel     *model;
583   GtkTreeSelection *sel;
584 #endif
585
586   amount = -1;
587   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
588
589 #if GTK_MAJOR_VERSION < 2
590   colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), 0);
591   if (colorf->marked)
592     return;
593 #endif
594
595   for (filter_number = 0; filter_number < num_of_filters; filter_number++)
596   {
597 #if GTK_MAJOR_VERSION < 2
598     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
599     if (colorf->marked)
600       move_this_row (color_filters, filter_number, amount);
601 #else
602     model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
603     gtk_tree_model_iter_nth_child(model, &iter, NULL, filter_number);
604     gtk_tree_model_get(model, &iter, 4, &colorf, -1);
605     sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
606     if (gtk_tree_selection_iter_is_selected(sel, &iter))
607       move_this_row (color_filters, filter_number, amount);
608 #endif
609   }
610 }
611
612 /* Move the selected filters down in the list */
613 static void
614 color_filter_down_cb(GtkButton *button, gpointer user_data _U_)
615 {
616   gint amount;
617   gint filter_number;
618   GtkWidget * color_filters;
619   color_filter_t *colorf;
620 #if GTK_MAJOR_VERSION < 2
621 #else
622   GtkTreeIter     iter;
623   GtkTreeModel   *model;
624 #endif
625
626   amount = +1;
627   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
628
629 #if GTK_MAJOR_VERSION < 2
630     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), num_of_filters - 1);
631     if (colorf->marked)
632       return;
633 #endif
634
635   for (filter_number = num_of_filters - 1; filter_number >= 0; filter_number--)
636   {
637 #if GTK_MAJOR_VERSION < 2
638     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
639 #else
640     model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
641     gtk_tree_model_iter_nth_child(model, &iter, NULL, filter_number);
642     gtk_tree_model_get(model, &iter, 4, &colorf, -1);
643 #endif
644     if (colorf->marked)
645       move_this_row (color_filters, filter_number, amount);
646   }
647 }
648  
649 /* A row was selected; remember its row number */
650 #if GTK_MAJOR_VERSION < 2
651 static void
652 remember_selected_row(GtkCList *clist, gint row, gint column _U_,
653                       GdkEvent *event _U_, gpointer user_data _U_)
654 {
655     GtkWidget    *button;
656     color_filter_t *colorf;
657
658     row_selected = row;
659
660     colorf = gtk_clist_get_row_data(clist, row);
661     colorf->marked = TRUE;
662     
663     /*
664      * A row is selected, so we can move it up *if* it's not at the top
665      * and move it down *if* it's not at the bottom.
666      */
667     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_UP_LB);
668     gtk_widget_set_sensitive (button, row > 0);
669     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DOWN_LB);
670     gtk_widget_set_sensitive(button, row < num_of_filters - 1);
671
672     /*
673      * A row is selected, so we can operate on it.
674      */
675     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_PROPS_LB);
676     gtk_widget_set_sensitive (button, TRUE);
677     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DELETE_LB);
678     gtk_widget_set_sensitive(button, TRUE);
679     
680 }
681 #else
682
683 struct remember_data
684 {
685     gint count;               /* count of selected filters */
686     gboolean first_marked;    /* true if the first filter in the list is marked */
687     gboolean last_marked;     /* true if the last filter in the list is marked */
688     gpointer color_filters;
689 };
690 /* called for each selected row in the tree.
691 */
692 void remember_this_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer arg)
693 {
694     gint         *path_index;
695     color_filter_t *colorf;
696     struct remember_data *data = arg;
697     
698     gtk_tree_model_get(model, iter, 4, &colorf, -1);
699     colorf->marked = TRUE;
700         
701     path_index = gtk_tree_path_get_indices(path);   /* not to be freed */
702     if (path_index == NULL)       /* can return NULL according to API doc.*/
703     {
704       return;
705     }
706     row_selected = path_index[0];
707
708     if (row_selected == 0)
709       data->first_marked = TRUE;
710     if (row_selected == num_of_filters - 1)
711       data->last_marked = TRUE;
712
713     data->count++;
714 }
715
716 /* clear the mark on this filter */
717 static void
718 clear_mark(gpointer filter_arg, gpointer arg _U_)
719 {
720   color_filter_t *colorf = filter_arg;
721
722   colorf->marked = FALSE;
723 }
724
725 /* The gtk+2.0 version gets called for, (maybe multiple,) changes in the selection. */
726 static void
727 remember_selected_row(GtkTreeSelection *sel, gpointer color_filters)
728 {
729     GtkWidget    *button;
730     struct remember_data data;
731
732     data.first_marked = data.last_marked = FALSE;
733     data.count = 0; 
734     data.color_filters = color_filters;
735
736     g_slist_foreach(color_filter_list, clear_mark, NULL);
737     gtk_tree_selection_selected_foreach(sel,remember_this_row, &data);
738                                       
739     if (data.count > 0)
740     {
741       /*
742        * One or more rows are selected, so we can operate on them.
743       */
744        
745       /* We can only edit if there is exactly one filter selected */
746       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_PROPS_LB);
747       gtk_widget_set_sensitive (button, data.count == 1);
748       
749       /* We can delete any number of filters */
750       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DELETE_LB);
751       gtk_widget_set_sensitive (button, TRUE);
752       /*
753        * We can move them up *if* one of them isn't the top row,
754        * and move them down *if* one of them isn't the bottom row.
755       */
756       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_UP_LB);
757       gtk_widget_set_sensitive(button, !data.first_marked);
758       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DOWN_LB);
759       gtk_widget_set_sensitive(button, !data.last_marked);
760     }
761     else
762     {
763       row_selected = -1;
764
765       /*
766        * No row is selected, so we can't do operations that affect the
767        * selected row.
768       */
769       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_UP_LB);
770       gtk_widget_set_sensitive (button, FALSE);
771       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DOWN_LB);
772       gtk_widget_set_sensitive (button, FALSE);
773       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_PROPS_LB);
774       gtk_widget_set_sensitive (button, FALSE);
775       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DELETE_LB);
776       gtk_widget_set_sensitive (button, FALSE);
777     }
778 }
779 #endif
780
781 #if GTK_MAJOR_VERSION < 2
782 /* A row was unselected; un-remember its row number */
783 static void
784 unremember_selected_row                 (GtkCList        *clist,
785                                          gint             row _U_,
786                                          gint             column _U_,
787                                          GdkEvent        *event _U_,
788                                          gpointer         user_data _U_)
789 {
790   GtkWidget *button;
791   color_filter_t *colorf;
792
793   row_selected = -1;
794
795   colorf = gtk_clist_get_row_data(clist, row);
796   colorf->marked = FALSE;
797
798   if (color_marked_count() == 0)
799   {
800     /*
801      * No row is selected, so we can't do operations that affect the
802      * selected row.
803      */
804     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_UP_LB);
805     gtk_widget_set_sensitive (button, FALSE);
806     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DOWN_LB);
807     gtk_widget_set_sensitive (button, FALSE);
808     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_PROPS_LB);
809     gtk_widget_set_sensitive (button, FALSE);
810     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DELETE_LB);
811     gtk_widget_set_sensitive(button, FALSE);
812   }
813 }
814 #endif
815
816 /* Called when the dialog box is being destroyed; destroy any edit
817  * dialogs opened from this dialog, and null out the pointer to this
818  * dialog.
819  jjj*/
820 static void
821 color_destroy_cb                       (GtkButton       *button _U_,
822                                         gpointer         user_data _U_)
823 {
824   /* Destroy any edit dialogs we have open. */
825   g_slist_foreach(color_filter_list, destroy_edit_dialog_cb, NULL);
826
827   colorize_win = NULL;
828 }
829
830 static void
831 destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy _U_)
832 {
833   color_filter_t *colorf = (color_filter_t *)filter_arg;
834
835   if (colorf->edit_dialog != NULL)
836     window_destroy(colorf->edit_dialog);
837 }
838
839 /* XXX - we don't forbid having more than one "Edit color filter" dialog
840    open, so these shouldn't be static. */
841 static GtkWidget *filt_name_entry;
842 static GtkWidget *filt_text_entry;
843
844 static void
845 color_add_colorf(GtkWidget *color_filters, color_filter_t *colorf)
846 {
847 #if GTK_MAJOR_VERSION < 2
848 #else
849   GtkTreeModel     *model;
850   gint              num_filters;
851   GtkTreeIter       iter;
852   GtkTreeSelection *sel;
853 #endif
854
855   add_filter_to_list(colorf, color_filters);
856
857 #if GTK_MAJOR_VERSION < 2
858
859   /* select the new row */
860   gtk_clist_select_row(GTK_CLIST(color_filters), num_of_filters - 1, -1);
861 #else
862   /* select the new row */
863   model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
864   num_filters = gtk_tree_model_iter_n_children(model, NULL);
865   gtk_tree_model_iter_nth_child(model, &iter, NULL, num_filters - 1);
866   sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
867   gtk_tree_selection_select_iter(sel, &iter);
868 #endif
869 }
870
871 void
872 color_add_filter_cb (color_filter_t *colorf, gpointer arg)
873 {
874   GtkWidget        *color_filters = arg;
875
876   color_add_colorf(color_filters, colorf);
877 #if GTK_MAJOR_VERSION >= 2
878   gtk_widget_grab_focus(color_filters);
879 #endif
880 }
881
882 /* Pop up an "Export color filter" dialog box. */
883 static void
884 color_import_cb(GtkButton *button, gpointer user_data )
885 {
886   GtkWidget        *color_filters;
887 #if GTK_MAJOR_VERSION >= 2
888   GtkTreeSelection *sel;
889 #endif
890
891   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
892
893 #if GTK_MAJOR_VERSION >= 2
894   sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
895   gtk_tree_selection_unselect_all (sel);
896 #else
897   gtk_clist_unselect_all (GTK_CLIST(color_filters));
898 #endif
899
900   file_color_import_cmd_cb(GTK_WIDGET(button), user_data);
901 }
902
903 /* Create a new filter in the list, and pop up an "Edit color filter"
904    dialog box to edit it. */
905 static void
906 create_new_color_filter(GtkButton *button, char *filter)
907 {
908   color_filter_t   *colorf;
909   GtkStyle         *style;
910   color_t          bg_color, fg_color;
911   GtkWidget        *color_filters;
912 #if GTK_MAJOR_VERSION >= 2
913   GtkTreeSelection *sel;
914 #endif
915
916   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
917
918 #if GTK_MAJOR_VERSION >= 2
919   sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
920   gtk_tree_selection_unselect_all (sel);
921 #else
922   gtk_clist_unselect_all (GTK_CLIST(color_filters));
923 #endif
924
925   /* Use the default background and foreground colors as the colors. */
926   style = gtk_widget_get_style(packet_list);
927   gdkcolor_to_color_t(&bg_color, &style->base[GTK_STATE_NORMAL]);
928   gdkcolor_to_color_t(&fg_color, &style->text[GTK_STATE_NORMAL]);
929   colorf = new_color_filter("name", filter, &bg_color, &fg_color); /* Adds at end! */
930
931   color_add_colorf(color_filters, colorf);
932
933   edit_color_filter_dialog(color_filters, &filt_name_entry, &filt_text_entry, TRUE);
934   
935   /* Show the (in)validity of the default filter string */
936   filter_te_syntax_check_cb(filt_text_entry);
937
938
939
940 #if GTK_MAJOR_VERSION >= 2
941   gtk_widget_grab_focus(color_filters);
942 #endif
943 }
944
945 /* Create a new filter in the list, and pop up an "Edit color filter"
946    dialog box to edit it. */
947 static void
948 color_new_cb(GtkButton *button, gpointer user_data _U_)
949 {
950   create_new_color_filter(button, "filter");
951 }
952
953 /* Pop up an "Edit color filter" dialog box to edit an existing filter. */
954 static void
955 color_props_cb(GtkButton *button, gpointer user_data _U_)
956 {
957   GtkWidget *color_filters;
958
959   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
960   g_assert(row_selected != -1);
961   edit_color_filter_dialog(color_filters, &filt_name_entry, &filt_text_entry, FALSE);
962 }
963
964 /* Delete a color from the list. */
965 static void
966 color_delete(gint row, GtkWidget  *color_filters)
967 {
968     color_filter_t *colorf;
969     
970 #if GTK_MAJOR_VERSION >= 2
971     GtkTreeModel     *model;
972     GtkTreeIter       iter;
973
974     
975     model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
976     gtk_tree_model_iter_nth_child(model, &iter, NULL, row);
977     gtk_tree_model_get(model, &iter, 4, &colorf, -1);
978     
979     /* Remove this color filter from the CList displaying the
980     color filters. */
981     gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
982     num_of_filters--;
983     
984     /* Destroy any "Edit color filter" dialog boxes editing it. */
985     if (colorf->edit_dialog != NULL)
986     window_destroy(colorf->edit_dialog);
987     
988     /* Remove the color filter from the list of color filters. */
989     remove_color_filter(colorf);
990     
991     /* If we grab the focus after updating the selection, the first
992     * row is always selected, so we do it before */
993     gtk_widget_grab_focus(color_filters);
994 #else
995     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row);
996
997     /* Remove this color filter from the CList displaying the
998        color filters. */
999     gtk_clist_remove(GTK_CLIST(color_filters), row);
1000     num_of_filters--;
1001
1002     /* Destroy any "Edit color filter" dialog boxes editing it. */
1003     if (colorf->edit_dialog != NULL)
1004         window_destroy(colorf->edit_dialog);
1005
1006     /* Remove the color filter from the list of color filters. */
1007     remove_color_filter(colorf);
1008
1009 #endif
1010 }
1011 /* Delete the selected color from the list.*/
1012 static void
1013 color_delete_cb(GtkWidget *widget, gpointer user_data _U_)
1014 {
1015   GtkWidget  *color_filters;
1016   gint row, num_filters;
1017 #if GTK_MAJOR_VERSION < 2
1018   color_filter_t *colorf;
1019 #else
1020     GtkTreeModel     *model;
1021     GtkTreeIter       iter;
1022     GtkTreeSelection *sel;
1023 #endif
1024
1025   color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL);
1026     
1027 #if GTK_MAJOR_VERSION < 2
1028   num_filters = num_of_filters;
1029 #else
1030   model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
1031   num_filters = gtk_tree_model_iter_n_children(model, NULL);
1032   sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
1033 #endif
1034
1035   for (row = num_filters - 1; row >= 0; row--)
1036   {
1037 #if GTK_MAJOR_VERSION < 2
1038     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row);
1039     if (colorf->marked)
1040       color_delete (row, color_filters);
1041 #else
1042     gtk_tree_model_iter_nth_child(model, &iter, NULL, row);
1043     if (gtk_tree_selection_iter_is_selected(sel, &iter))
1044       color_delete (row, color_filters);
1045 #endif
1046   }
1047 }
1048
1049 /* Save color filters to the color filter file. */
1050 static void
1051 color_save_cb(GtkButton *button _U_, gpointer user_data _U_)
1052 {
1053   if (!write_filters())
1054         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1055             "Could not open filter file: %s", strerror(errno));
1056 }
1057
1058 /* Remove all user defined color filters and revert to the global file. */
1059 static void
1060 color_clear_cmd(GtkWidget *widget)
1061 {
1062     GtkWidget * color_filters;
1063     
1064     color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL);
1065     
1066     while (num_of_filters > 0)
1067     {
1068         color_delete (num_of_filters-1, color_filters);
1069     }
1070
1071     if (!revert_filters())
1072         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1073             "Could not delete filter file: %s", strerror(errno));
1074
1075     /* colorize list */
1076     cf_colorize_packets(&cfile);
1077
1078     /* Destroy the dialog box. */
1079     /* XXX: is this useful? user might want to continue with editing new colors */
1080     window_destroy(colorize_win);
1081 }
1082
1083 /* clear button: user responded to question */
1084 void color_clear_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
1085 {
1086     switch(btn) {
1087     case(ESD_BTN_CLEAR):
1088         color_clear_cmd(data);
1089         break;
1090     case(ESD_BTN_CANCEL):
1091         break;
1092     default:
1093         g_assert_not_reached();
1094     }
1095 }
1096
1097 /* clear button: ask user before really doing it */
1098 void
1099 color_clear_cb(GtkWidget *widget, gpointer data _U_) {
1100     gpointer  dialog;
1101
1102     /* ask user, if he/she is really sure */
1103     dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTN_CLEAR | ESD_BTN_CANCEL, 
1104                 PRIMARY_TEXT_START "Remove all your personal color settings?" PRIMARY_TEXT_END "\n\n"
1105                 "This will revert the color settings to global defaults.\n\n"
1106                 "Are you really sure?");
1107
1108     simple_dialog_set_cb(dialog, color_clear_answered_cb, widget);
1109 }
1110
1111 /* Exit dialog and apply new list of color filters to the capture. */
1112 static void
1113 color_ok_cb(GtkButton *button _U_, gpointer user_data _U_)
1114 {
1115   /* colorize list */
1116   cf_colorize_packets(&cfile);
1117
1118   /* Destroy the dialog box. */
1119   window_destroy(colorize_win);
1120 }
1121
1122 /* Exit dialog without colorizing packets with the new list.
1123    XXX - should really undo any changes to the list.... */
1124 static void
1125 color_cancel_cb(GtkWidget *widget _U_, gpointer user_data _U_)
1126 {
1127   /* Destroy the dialog box. */
1128   window_destroy(colorize_win);
1129 }
1130
1131 /* Apply new list of color filters to the capture. */
1132 static void
1133 color_apply_cb(GtkButton *button _U_, gpointer user_data _U_)
1134 {
1135   cf_colorize_packets(&cfile);
1136 }
1137
1138 /* Create an "Edit Color Filter" dialog for a given color filter, and
1139    associate it with that color filter. */
1140 static void
1141 edit_color_filter_dialog(GtkWidget *color_filters,
1142                          GtkWidget **colorize_filter_name,
1143                          GtkWidget **colorize_filter_text,
1144                          guchar is_new_filter)
1145 {
1146     color_filter_t *colorf;
1147     GtkWidget      *edit_dialog;
1148     GtkWidget      *dialog_vbox;
1149     GtkTooltips    *tooltips;
1150     GtkStyle       *style;
1151
1152     GtkWidget *filter_fr;
1153     GtkWidget *filter_fr_vbox;
1154     GtkWidget *filter_name_hbox;
1155     GtkWidget *color_filter_name;
1156     GtkWidget *filter_string_hbox;
1157     GtkWidget *add_expression_bt;
1158     GtkWidget *color_filter_text;
1159
1160     GtkWidget *colorize_fr;
1161     GtkWidget *colorize_hbox;
1162     GtkWidget *colorize_filter_fg;
1163     GtkWidget *colorize_filter_bg;
1164
1165     GtkWidget *bbox;
1166     GtkWidget *edit_color_filter_ok;
1167     GtkWidget *edit_color_filter_cancel;
1168
1169 #if GTK_MAJOR_VERSION >= 2
1170     GtkTreeModel     *model;
1171     GtkTreeIter       iter;
1172 #endif
1173
1174 #if GTK_MAJOR_VERSION >= 2
1175     model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
1176
1177     gtk_tree_model_iter_nth_child(model, &iter, NULL, row_selected);
1178     gtk_tree_model_get(model, &iter, 4, &colorf, -1);
1179
1180 #else
1181     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row_selected);
1182 #endif
1183     if (colorf->edit_dialog != NULL) {
1184         /* There's already an edit box open for this filter; reactivate it. */
1185         reactivate_window(colorf->edit_dialog);
1186         return;
1187     }
1188
1189     tooltips = gtk_tooltips_new ();
1190
1191     /* dialog window */
1192     edit_dialog = dlg_window_new ("Ethereal: Edit Color Filter");
1193     gtk_window_set_default_size(GTK_WINDOW(edit_dialog), 500, -1);  
1194     OBJECT_SET_DATA(edit_dialog, "edit_dialog", edit_dialog);
1195     colorf->edit_dialog = edit_dialog;
1196
1197     dialog_vbox = gtk_vbox_new (FALSE, 0);
1198     gtk_container_set_border_width  (GTK_CONTAINER (dialog_vbox), 5);
1199     gtk_container_add (GTK_CONTAINER (edit_dialog), dialog_vbox);
1200
1201     /* Filter frame */
1202     filter_fr = gtk_frame_new("Filter");
1203     gtk_box_pack_start (GTK_BOX (dialog_vbox), filter_fr, FALSE, FALSE, 0);
1204
1205     filter_fr_vbox = gtk_vbox_new (FALSE, 0);
1206     gtk_container_set_border_width  (GTK_CONTAINER (filter_fr_vbox), 5);
1207     gtk_container_add(GTK_CONTAINER(filter_fr), filter_fr_vbox);
1208
1209     /* filter name hbox */
1210     filter_name_hbox = gtk_hbox_new (FALSE, 0);
1211     gtk_box_pack_start (GTK_BOX (filter_fr_vbox), filter_name_hbox, TRUE, FALSE, 3);
1212
1213     color_filter_name = gtk_label_new (("Name: "));
1214     gtk_box_pack_start (GTK_BOX (filter_name_hbox), color_filter_name, FALSE, FALSE, 0);
1215
1216     *colorize_filter_name = gtk_entry_new ();
1217     gtk_entry_set_text(GTK_ENTRY(*colorize_filter_name), colorf->filter_name);
1218
1219     style = gtk_style_copy(gtk_widget_get_style(*colorize_filter_name));
1220     color_t_to_gdkcolor(&style->base[GTK_STATE_NORMAL], &colorf->bg_color);
1221 #if GTK_MAJOR_VERSION < 2
1222     color_t_to_gdkcolor(&style->fg[GTK_STATE_NORMAL], &colorf->fg_color);
1223 #else
1224     color_t_to_gdkcolor(&style->text[GTK_STATE_NORMAL], &colorf->fg_color);
1225 #endif
1226     gtk_widget_set_style(*colorize_filter_name, style);
1227
1228     gtk_box_pack_start (GTK_BOX (filter_name_hbox), *colorize_filter_name, TRUE, TRUE, 0);
1229     gtk_tooltips_set_tip (tooltips, *colorize_filter_name, ("This is the editable name of the filter. (No @ characters allowed.)"), NULL);
1230
1231
1232     /* filter string hbox */
1233     filter_string_hbox = gtk_hbox_new (FALSE, 0);
1234     gtk_box_pack_start (GTK_BOX (filter_fr_vbox), filter_string_hbox, TRUE, FALSE, 3);
1235
1236     color_filter_text = gtk_label_new (("String: "));
1237     gtk_box_pack_start (GTK_BOX (filter_string_hbox), color_filter_text, FALSE, FALSE, 0);
1238
1239     *colorize_filter_text = gtk_entry_new ();
1240     SIGNAL_CONNECT(*colorize_filter_text, "changed", filter_te_syntax_check_cb, NULL);
1241     gtk_entry_set_text(GTK_ENTRY(*colorize_filter_text), colorf->filter_text);
1242
1243 #if 0
1244     style = gtk_style_copy(gtk_widget_get_style(*colorize_filter_text));
1245     style->base[GTK_STATE_NORMAL] = colorf->bg_color;
1246     style->fg[GTK_STATE_NORMAL]   = colorf->fg_color;
1247 #endif
1248     gtk_widget_set_style(*colorize_filter_text, style);
1249     gtk_style_unref(style);
1250     gtk_box_pack_start (GTK_BOX (filter_string_hbox), *colorize_filter_text, TRUE, TRUE, 0);
1251     gtk_tooltips_set_tip (tooltips, *colorize_filter_text, ("This is the editable text of the filter"), NULL);
1252
1253     /* Create the "Add Expression..." button, to pop up a dialog
1254        for constructing filter comparison expressions. */
1255     add_expression_bt = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_ADD_EXPRESSION);
1256     SIGNAL_CONNECT(add_expression_bt, "clicked", filter_expr_cb, *colorize_filter_text);
1257     gtk_box_pack_start (GTK_BOX(filter_string_hbox), add_expression_bt, FALSE, FALSE, 3);
1258     gtk_tooltips_set_tip (tooltips, add_expression_bt, ("Add an expression to the filter string"), NULL);
1259
1260
1261     /* choose color frame */
1262     colorize_fr = gtk_frame_new("Display Colors");
1263     gtk_box_pack_start (GTK_BOX (dialog_vbox), colorize_fr, FALSE, FALSE, 0);
1264
1265     colorize_hbox = gtk_hbox_new (FALSE, 0);
1266     gtk_container_set_border_width  (GTK_CONTAINER (colorize_hbox), 5);
1267     gtk_container_add(GTK_CONTAINER(colorize_fr), colorize_hbox);
1268
1269     colorize_filter_fg = gtk_button_new_with_label (("Foreground Color..."));
1270     gtk_box_pack_start (GTK_BOX (colorize_hbox), colorize_filter_fg, TRUE, FALSE, 0);
1271     gtk_tooltips_set_tip (tooltips, colorize_filter_fg, ("Select foreground color for data display"), NULL);
1272
1273     colorize_filter_bg = gtk_button_new_with_label (("Background Color..."));
1274     gtk_box_pack_start (GTK_BOX (colorize_hbox), colorize_filter_bg, TRUE, FALSE, 0);
1275     gtk_tooltips_set_tip (tooltips, colorize_filter_bg, ("Select background color for data display"), NULL);
1276
1277
1278     /* button box */
1279     bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL);
1280         gtk_box_pack_start(GTK_BOX(dialog_vbox), bbox, FALSE, FALSE, 0);
1281     gtk_container_set_border_width  (GTK_CONTAINER (bbox), 0);
1282
1283     edit_color_filter_ok = OBJECT_GET_DATA(bbox, GTK_STOCK_OK);
1284     gtk_tooltips_set_tip (tooltips, edit_color_filter_ok, ("Accept filter color change"), NULL);
1285
1286     edit_color_filter_cancel = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
1287     gtk_tooltips_set_tip (tooltips, edit_color_filter_cancel, ("Reject filter color change"), NULL);
1288
1289     gtk_widget_grab_default(edit_color_filter_ok);
1290
1291     /* signals and such */
1292     OBJECT_SET_DATA(edit_dialog, COLOR_FILTER, colorf);
1293     SIGNAL_CONNECT(edit_dialog, "destroy", edit_color_filter_destroy_cb, NULL);
1294     OBJECT_SET_DATA(colorize_filter_fg, COLOR_FILTER, colorf);
1295     SIGNAL_CONNECT(colorize_filter_fg, "clicked", edit_color_filter_fg_cb, NULL);
1296     OBJECT_SET_DATA(colorize_filter_bg, COLOR_FILTER, colorf);
1297     SIGNAL_CONNECT(colorize_filter_bg, "clicked", edit_color_filter_bg_cb, NULL);
1298     OBJECT_SET_DATA(edit_color_filter_ok, COLOR_FILTERS_CL, color_filters);
1299     OBJECT_SET_DATA(edit_color_filter_ok, COLOR_FILTER, colorf);
1300     SIGNAL_CONNECT(edit_color_filter_ok, "clicked", edit_color_filter_ok_cb, edit_dialog);
1301
1302     /* set callback to delete new filters if cancel chosen */
1303     if (is_new_filter)
1304     {
1305         OBJECT_SET_DATA(edit_color_filter_cancel, COLOR_FILTERS_CL, color_filters);
1306         SIGNAL_CONNECT(edit_color_filter_cancel, "clicked",
1307                        edit_new_color_filter_cancel_cb, edit_dialog);
1308     }
1309     /* escape will select cancel */
1310     window_set_cancel_button(edit_dialog, edit_color_filter_cancel, window_cancel_button_cb);
1311
1312     SIGNAL_CONNECT(edit_dialog, "delete_event", window_delete_event_cb, NULL);
1313
1314     gtk_widget_show_all(edit_dialog);
1315     window_present(edit_dialog);
1316 }
1317
1318 /* Called when the dialog box is being destroyed; destroy any color
1319    selection dialogs opened from this dialog, and null out the pointer
1320    to this dialog. */
1321 #if GTK_MAJOR_VERSION < 2
1322 static void
1323 edit_color_filter_destroy_cb(GtkObject *object, gpointer user_data _U_)
1324 #else
1325 static void
1326 edit_color_filter_destroy_cb(GObject *object, gpointer user_data _U_)
1327 #endif
1328 {
1329   color_filter_t *colorf;
1330   GtkWidget *color_sel;
1331
1332   colorf = (color_filter_t *)OBJECT_GET_DATA(object, COLOR_FILTER);
1333   colorf->edit_dialog = NULL;
1334
1335   /* Destroy any color selection dialogs this dialog had open. */
1336   color_sel = (GtkWidget *)OBJECT_GET_DATA(object, COLOR_SELECTION_FG);
1337   if (color_sel != NULL)
1338     window_destroy(color_sel);
1339   color_sel = (GtkWidget *)OBJECT_GET_DATA(object, COLOR_SELECTION_BG);
1340   if (color_sel != NULL)
1341     window_destroy(color_sel);
1342 }
1343
1344 /* Pop up a color selection box to choose the foreground color. */
1345 static void
1346 edit_color_filter_fg_cb(GtkButton *button, gpointer user_data _U_)
1347 {
1348   color_filter_t *colorf;
1349   GtkWidget *color_selection_fg;
1350
1351   colorf = (color_filter_t *)OBJECT_GET_DATA(button, COLOR_FILTER);
1352   /* Do we already have one open for this dialog? */
1353   color_selection_fg = OBJECT_GET_DATA(colorf->edit_dialog, COLOR_SELECTION_FG);
1354   if (color_selection_fg != NULL) {
1355     /* Yes.  Just reactivate it. */
1356     reactivate_window(color_selection_fg);
1357   } else {
1358     /* No.  Create a new color selection box, and associate it with
1359        this dialog. */
1360     color_selection_fg = color_sel_win_new(colorf, FALSE);
1361     OBJECT_SET_DATA(colorf->edit_dialog, COLOR_SELECTION_FG, color_selection_fg);
1362     OBJECT_SET_DATA(color_selection_fg, COLOR_SELECTION_PARENT, colorf->edit_dialog);
1363   }
1364 }
1365
1366 /* Pop up a color selection box to choose the background color. */
1367 static void
1368 edit_color_filter_bg_cb                (GtkButton       *button,
1369                                         gpointer         user_data _U_)
1370 {
1371   color_filter_t *colorf;
1372   GtkWidget *color_selection_bg;
1373
1374   colorf = (color_filter_t *)OBJECT_GET_DATA(button, COLOR_FILTER);
1375   /* Do we already have one open for this dialog? */
1376   color_selection_bg = OBJECT_GET_DATA(colorf->edit_dialog, COLOR_SELECTION_BG);
1377   if (color_selection_bg != NULL) {
1378     /* Yes.  Just reactivate it. */
1379     reactivate_window(color_selection_bg);
1380   } else {
1381     /* No.  Create a new color selection box, and associate it with
1382        this dialog. */
1383     color_selection_bg = color_sel_win_new(colorf, TRUE);
1384     OBJECT_SET_DATA(colorf->edit_dialog, COLOR_SELECTION_BG, color_selection_bg);
1385     OBJECT_SET_DATA(color_selection_bg, COLOR_SELECTION_PARENT, colorf->edit_dialog);
1386   }
1387 }
1388
1389 /* accept color (and potential content) change */
1390 static void
1391 edit_color_filter_ok_cb                (GtkButton       *button,
1392                                         gpointer         user_data)
1393 {
1394     GtkWidget      *dialog;
1395     GtkStyle       *style;
1396     GdkColor        new_fg_color;
1397     GdkColor        new_bg_color;
1398     gchar          *filter_name;
1399     gchar          *filter_text;
1400     color_filter_t *colorf;
1401     dfilter_t      *compiled_filter;
1402     GtkWidget      *color_filters;
1403 #if GTK_MAJOR_VERSION >= 2
1404     GtkTreeModel   *model;
1405     GtkTreeIter     iter;
1406     gchar           fg_str[14], bg_str[14];
1407 #endif
1408
1409     dialog = (GtkWidget *)user_data;
1410
1411     style = gtk_widget_get_style(filt_name_entry);
1412     new_bg_color = style->base[GTK_STATE_NORMAL];
1413 #if GTK_MAJOR_VERSION < 2
1414     new_fg_color = style->fg[GTK_STATE_NORMAL];
1415 #else
1416     new_fg_color = style->text[GTK_STATE_NORMAL];
1417 #endif
1418
1419     filter_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(filt_name_entry)));
1420     filter_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(filt_text_entry)));
1421
1422     if(strchr(filter_name,'@') || strchr(filter_text,'@')){
1423         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1424                       "Filter names and strings must not"
1425                       " use the '@' character. Filter unchanged.");
1426         g_free(filter_name);
1427         g_free(filter_text);
1428         return;
1429     }
1430
1431     if(!dfilter_compile(filter_text, &compiled_filter)) {
1432         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1433                       "Filter \"%s\" didn't compile correctly.\n"
1434                       " Please try again. Filter unchanged.\n%s\n", filter_name,
1435                       dfilter_error_msg);
1436     } else {
1437         color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
1438         colorf = (color_filter_t *)OBJECT_GET_DATA(button, COLOR_FILTER);
1439
1440         if (colorf->filter_name != NULL)
1441             g_free(colorf->filter_name);
1442         colorf->filter_name = filter_name;
1443         if (colorf->filter_text != NULL)
1444             g_free(colorf->filter_text);
1445         colorf->filter_text = filter_text;
1446         gdkcolor_to_color_t(&colorf->fg_color, &new_fg_color);
1447         gdkcolor_to_color_t(&colorf->bg_color, &new_bg_color);
1448 #if GTK_MAJOR_VERSION < 2
1449         gtk_clist_set_foreground(GTK_CLIST(color_filters), row_selected,
1450                                  &new_fg_color);
1451         gtk_clist_set_background(GTK_CLIST(color_filters), row_selected,
1452                                  &new_bg_color);
1453 #else
1454         g_snprintf(fg_str, 14, "#%04X%04X%04X",
1455                 new_fg_color.red, new_fg_color.green, new_fg_color.blue);
1456         g_snprintf(bg_str, 14, "#%04X%04X%04X",
1457                 new_bg_color.red, new_bg_color.green, new_bg_color.blue);
1458         model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
1459         gtk_tree_model_iter_nth_child(model, &iter, NULL, row_selected);
1460         gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, filter_name,
1461                            1, filter_text, 2, fg_str, 3, bg_str, -1);
1462 #endif
1463         if(colorf->c_colorfilter != NULL)
1464             dfilter_free(colorf->c_colorfilter);
1465         colorf->c_colorfilter = compiled_filter;
1466 #if GTK_MAJOR_VERSION < 2
1467         /* gtk_clist_set_text frees old text (if any) and allocates new space */
1468         gtk_clist_set_text(GTK_CLIST(color_filters), row_selected, 0,
1469                            filter_name);
1470         gtk_clist_set_text(GTK_CLIST(color_filters), row_selected, 1,
1471                            filter_text);
1472 #endif
1473
1474         /* Destroy the dialog box. */
1475         window_destroy(dialog);
1476     }
1477 }
1478
1479 /* reject new color filter addition */
1480 static void
1481 edit_new_color_filter_cancel_cb(GtkButton *button, gpointer user_data _U_)
1482 {
1483     /* Delete the entry.  N.B. this already destroys the edit_dialog window. */
1484     color_delete(num_of_filters-1, (GtkWidget*)OBJECT_GET_DATA(button, COLOR_FILTERS_CL));
1485 }
1486
1487 static GtkWidget*
1488 color_sel_win_new(color_filter_t *colorf, gboolean is_bg)
1489 {
1490   gchar *title;
1491   GtkWidget *color_sel_win;
1492   color_t   *color;
1493 #if GTK_MAJOR_VERSION >= 2
1494   GdkColor   gcolor;
1495 #endif
1496   GtkWidget *color_sel_ok;
1497   GtkWidget *color_sel_cancel;
1498   GtkWidget *color_sel_help;
1499
1500   if (is_bg) {
1501     color = &colorf->bg_color;
1502     title = g_strdup_printf("Ethereal: Choose background color for \"%s\"",
1503         colorf->filter_name);
1504   } else {
1505     color = &colorf->fg_color;
1506     title = g_strdup_printf("Ethereal: Choose foreground color for \"%s\"", 
1507         colorf->filter_name);
1508   }
1509   color_sel_win = gtk_color_selection_dialog_new(title);
1510   g_free(title);
1511   OBJECT_SET_DATA(color_sel_win, "color_sel_win", color_sel_win);
1512   gtk_container_set_border_width (GTK_CONTAINER (color_sel_win), 10);
1513
1514   if (color != NULL) {
1515 #if GTK_MAJOR_VERSION < 2
1516     gdouble cols[3];
1517
1518     cols[0] = (gdouble)color->red / 65536.0;
1519     cols[1] = (gdouble)color->green / 65536.0;
1520     cols[2] = (gdouble)color->blue / 65536.0;
1521
1522     gtk_color_selection_set_color(
1523                     GTK_COLOR_SELECTION(
1524                             GTK_COLOR_SELECTION_DIALOG(color_sel_win)->colorsel), cols);
1525 #else
1526     color_t_to_gdkcolor(&gcolor, color);
1527     gtk_color_selection_set_current_color(
1528                     GTK_COLOR_SELECTION(
1529                             GTK_COLOR_SELECTION_DIALOG(color_sel_win)->colorsel), &gcolor);
1530 #endif
1531   }
1532
1533   color_sel_ok = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->ok_button;
1534   OBJECT_SET_DATA(color_sel_win, "color_sel_ok", color_sel_ok);
1535   GTK_WIDGET_SET_FLAGS (color_sel_ok, GTK_CAN_DEFAULT);
1536
1537   color_sel_cancel = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->cancel_button;
1538   OBJECT_SET_DATA(color_sel_win, "color_sel_cancel", color_sel_cancel);
1539   GTK_WIDGET_SET_FLAGS (color_sel_cancel, GTK_CAN_DEFAULT);
1540
1541
1542   color_sel_help = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->help_button;
1543   OBJECT_SET_DATA(color_sel_win, "color_sel_help", color_sel_help);
1544
1545
1546   GTK_WIDGET_SET_FLAGS (color_sel_help, GTK_CAN_DEFAULT);
1547
1548   SIGNAL_CONNECT(color_sel_ok, "clicked", color_sel_ok_cb, color_sel_win);
1549   SIGNAL_CONNECT(color_sel_cancel, "clicked", color_sel_cancel_cb, color_sel_win);
1550
1551   gtk_widget_show_all(color_sel_win);
1552   return color_sel_win;
1553 }
1554
1555 static void
1556 color_sel_win_destroy(GtkWidget *sel_win)
1557 {
1558   GtkWidget *parent;
1559   GtkWidget *color_selection_fg, *color_selection_bg;
1560
1561   /* Find the "Edit color filter" dialog box with which this is associated. */
1562   parent = (GtkWidget *)OBJECT_GET_DATA(sel_win, COLOR_SELECTION_PARENT);
1563
1564   /* Find that dialog box's foreground and background color selection
1565      boxes, if any. */
1566   color_selection_fg = OBJECT_GET_DATA(parent, COLOR_SELECTION_FG);
1567   color_selection_bg = OBJECT_GET_DATA(parent, COLOR_SELECTION_BG);
1568
1569   if (sel_win == color_selection_fg) {
1570     /* This was its foreground color selection box; it isn't, anymore. */
1571     OBJECT_SET_DATA(parent, COLOR_SELECTION_FG, NULL);
1572   }
1573   if (sel_win == color_selection_bg) {
1574     /* This was its background color selection box; it isn't, anymore. */
1575     OBJECT_SET_DATA(parent, COLOR_SELECTION_BG, NULL);
1576   }
1577
1578   /* Now destroy it. */
1579   window_destroy(sel_win);
1580 }
1581
1582 /* Retrieve selected color */
1583 static void
1584 color_sel_ok_cb                        (GtkButton       *button _U_,
1585                                         gpointer         user_data)
1586 {
1587   GdkColor new_color; /* Color from color selection dialog */
1588 #if GTK_MAJOR_VERSION < 2
1589   gdouble new_colors[3];
1590 #endif
1591   GtkWidget *color_dialog;
1592   GtkStyle  *style;
1593   GtkWidget *parent;
1594   GtkWidget *color_selection_fg, *color_selection_bg;
1595   gboolean is_bg;
1596
1597   color_dialog = (GtkWidget *)user_data;
1598
1599 #if GTK_MAJOR_VERSION < 2
1600   gtk_color_selection_get_color(GTK_COLOR_SELECTION(
1601    GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel), new_colors);
1602
1603   new_color.red   = (guint16)(new_colors[0]*65535.0);
1604   new_color.green = (guint16)(new_colors[1]*65535.0);
1605   new_color.blue  = (guint16)(new_colors[2]*65535.0);
1606 #else
1607   gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(
1608    GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel), &new_color);
1609 #endif
1610
1611   if ( ! get_color(&new_color) ){
1612         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1613                       "Could not allocate color.  Try again.");
1614   } else {
1615         /* Find the "Edit color filter" dialog box with which this is
1616            associated. */
1617         parent = (GtkWidget *)OBJECT_GET_DATA(color_dialog, COLOR_SELECTION_PARENT);
1618
1619         /* Find that dialog box's foreground and background color selection
1620            boxes, if any. */
1621         color_selection_fg = OBJECT_GET_DATA(parent, COLOR_SELECTION_FG);
1622         color_selection_bg = OBJECT_GET_DATA(parent, COLOR_SELECTION_BG);
1623         is_bg = (color_dialog == color_selection_bg);
1624
1625         color_sel_win_destroy(color_dialog);
1626
1627         /* now apply the change to the fore/background */
1628
1629         style = gtk_style_copy(gtk_widget_get_style(filt_name_entry));
1630         if (is_bg)
1631           style->base[GTK_STATE_NORMAL] = new_color;
1632 #if GTK_MAJOR_VERSION < 2
1633         else
1634           style->fg[GTK_STATE_NORMAL] = new_color;
1635 #else
1636         else
1637           style->text[GTK_STATE_NORMAL] = new_color;
1638 #endif
1639         gtk_widget_set_style(filt_name_entry, style);
1640         gtk_widget_set_style(filt_text_entry, style);
1641         gtk_style_unref(style);
1642   }
1643 }
1644
1645 /* Don't choose the selected color as the foreground or background
1646    color for the filter. */
1647 static void
1648 color_sel_cancel_cb                    (GtkObject       *object _U_,
1649                                         gpointer         user_data)
1650 {
1651   GtkWidget *color_dialog;
1652   color_dialog = (GtkWidget *)user_data;
1653   /* nothing to change here.  Just get rid of the dialog box. */
1654
1655   color_sel_win_destroy(color_dialog);
1656 }