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