Change to color filters :
[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.18 2002/09/23 19:09:49 oabad 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 "colors.h"
36 #include "color_dlg.h"
37 #include "color_utils.h"
38 #include "file.h"
39 #include <epan/dfilter/dfilter.h>
40 #include "simple_dialog.h"
41 #include "dlg_utils.h"
42 #include "ui_util.h"
43 #include "dfilter_expr_dlg.h"
44
45
46 static GtkWidget* colorize_dialog_new(void);
47 static void add_filter_to_clist(gpointer filter_arg, gpointer clist_arg);
48 static void color_filter_up_cb(GtkButton *button, gpointer user_data);
49 static void color_filter_down_cb(GtkButton *button, gpointer user_data);
50 static void remember_selected_row(GtkCList *clist, gint row, gint column,
51                                  GdkEvent *event, gpointer user_data);
52 static void unremember_selected_row(GtkCList *clist, gint row, gint column,
53                                  GdkEvent *event, gpointer user_data);
54 static void color_destroy_cb(GtkButton *button, gpointer user_data);
55 static void destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy);
56 static void color_new_cb(GtkButton *button, gpointer user_data);
57 static void color_edit_cb(GtkButton *button, gpointer user_data);
58 static void color_delete_cb(GtkWidget *widget, gpointer user_data);
59 static void color_save_cb(GtkButton *button, gpointer user_data);
60 static void color_ok_cb(GtkButton *button, gpointer user_data);
61 static void color_cancel_cb(GtkWidget *widget, gpointer user_data);
62 static void color_apply_cb(GtkButton *button, gpointer user_data);
63
64 static void edit_color_filter_dialog_new(GtkWidget *color_filters,
65                                  GtkWidget **colorize_filter_name,
66                                  GtkWidget **colorize_filter_text);
67 static void edit_color_filter_destroy_cb(GtkObject *object,
68                                  gpointer user_data);
69 static void edit_color_filter_fg_cb(GtkButton *button, gpointer user_data);
70 static void edit_color_filter_bg_cb(GtkButton *button, gpointer user_data);
71 static void edit_color_filter_ok_cb(GtkButton *button, gpointer user_data);
72 static void edit_color_filter_cancel_cb(GtkObject *object, gpointer user_data);
73
74 static GtkWidget* color_sel_win_new(color_filter_t *colorf, gboolean);
75 static void color_sel_ok_cb(GtkButton *button, gpointer user_data);
76 static void color_sel_cancel_cb(GtkObject *object, gpointer user_data);
77
78 static GtkWidget *colorize_win;
79 static gint       num_of_filters;  /* number of filters being displayed */
80 static gint       row_selected;    /* row in color_filters that is selected */
81
82 static gchar *titles[2] = { "Name", "Filter String" };
83
84 #define COLOR_UP_LB             "color_up_lb"
85 #define COLOR_DOWN_LB           "color_down_lb"
86 #define COLOR_EDIT_LB           "color_edit_lb"
87 #define COLOR_DELETE_LB         "color_delete_lb"
88 #define COLOR_FILTERS_CL        "color_filters_cl"
89 #define COLOR_FILTER            "color_filter"
90 #define COLOR_SELECTION_FG      "color_selection_fg"
91 #define COLOR_SELECTION_BG      "color_selection_bg"
92 #define COLOR_SELECTION_PARENT  "color_selection_parent"
93
94 static void
95 filter_expr_cb(GtkWidget *w _U_, gpointer filter_te)
96 {
97
98         dfilter_expr_dlg_new(GTK_WIDGET(filter_te));
99 }
100
101
102 /* Callback for the "Display:Colorize Display" menu item. */
103 void
104 color_display_cb(GtkWidget *w _U_, gpointer d _U_)
105 {
106   if (colorize_win != NULL) {
107     /* There's already a color dialog box active; reactivate it. */
108     reactivate_window(colorize_win);
109   } else {
110     /* Create a new "Colorize Display" dialog. */
111     colorize_win = colorize_dialog_new();
112   }
113 }
114
115 /* Create the "Add color to protocols" dialog. */
116 static GtkWidget*
117 colorize_dialog_new (void)
118 {
119   GtkWidget *color_win;
120   GtkWidget *vbox1;
121   GtkWidget *hbox1;
122   GtkWidget *vbox2;
123   GtkWidget *vbox4;
124   GtkWidget *color_filter_up;
125   GtkWidget *label4;
126   GtkWidget *color_filter_down;
127   GtkWidget *scrolledwindow1;
128   GtkWidget *color_filters;
129   GtkWidget *color_new;
130   GtkWidget *color_edit;
131   GtkWidget *color_delete;
132   GtkWidget *color_save;
133   GtkWidget *hbox3;
134   GtkWidget *color_ok;
135   GtkWidget *color_apply;
136   GtkWidget *color_cancel;
137   GtkTooltips *tooltips;
138
139   row_selected = -1; /* no row selected */
140   tooltips = gtk_tooltips_new ();
141
142   color_win = dlg_window_new ("Add color to protocols");
143   gtk_object_set_data (GTK_OBJECT (color_win), "color_win", color_win);
144
145   vbox1 = gtk_vbox_new (FALSE, 0);
146   gtk_widget_ref (vbox1);
147   gtk_object_set_data_full (GTK_OBJECT (color_win), "vbox1", vbox1,
148                             (GtkDestroyNotify) gtk_widget_unref);
149   gtk_widget_show (vbox1);
150   gtk_container_add (GTK_CONTAINER (color_win), vbox1);
151
152   hbox1 = gtk_hbox_new (FALSE, 0);
153   gtk_widget_ref (hbox1);
154   gtk_object_set_data_full (GTK_OBJECT (color_win), "hbox1", hbox1,
155                             (GtkDestroyNotify) gtk_widget_unref);
156   gtk_widget_show (hbox1);
157   gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
158
159   /* vbox2 holds the Up and Down Buttons and label */
160   vbox2 = gtk_vbox_new (TRUE, 0);
161   gtk_widget_ref (vbox2);
162   gtk_object_set_data_full (GTK_OBJECT (color_win), "vbox2", vbox2,
163                             (GtkDestroyNotify) gtk_widget_unref);
164   gtk_widget_show (vbox2);
165   gtk_box_pack_start (GTK_BOX (hbox1), vbox2, FALSE, TRUE, 0);
166   gtk_widget_set_usize (vbox2, 150, -2);
167
168   color_filter_up = gtk_button_new_with_label (("Up"));
169   gtk_widget_ref (color_filter_up);
170   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_filter_up", color_filter_up,
171                             (GtkDestroyNotify) gtk_widget_unref);
172   gtk_widget_show (color_filter_up);
173   gtk_box_pack_start (GTK_BOX (vbox2), color_filter_up, FALSE, FALSE, 0);
174   gtk_tooltips_set_tip (tooltips, color_filter_up, ("Move filter higher in list"), NULL);
175   gtk_widget_set_sensitive (color_filter_up, FALSE);
176
177   label4 = gtk_label_new (("Move filter\nup or down\n[List is processed \n"
178                           "in order until\nmatch is found]"));
179   gtk_widget_ref (label4);
180   gtk_object_set_data_full (GTK_OBJECT (color_win), "label4", label4,
181                             (GtkDestroyNotify) gtk_widget_unref);
182   gtk_widget_show (label4);
183   gtk_box_pack_start (GTK_BOX (vbox2), label4, FALSE, FALSE, 0);
184
185   color_filter_down = gtk_button_new_with_label (("Down"));
186   gtk_widget_ref (color_filter_down);
187   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_filter_down", color_filter_down,
188                             (GtkDestroyNotify) gtk_widget_unref);
189   gtk_widget_show (color_filter_down);
190   gtk_box_pack_start (GTK_BOX (vbox2), color_filter_down, FALSE, FALSE, 0);
191   gtk_tooltips_set_tip (tooltips, color_filter_down, ("Move filter lower in list"), NULL);
192   gtk_widget_set_sensitive (color_filter_down, FALSE);
193   /* End vbox2 */
194
195   /* create the list of filters */
196   scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
197   gtk_widget_ref (scrolledwindow1);
198   gtk_object_set_data_full (GTK_OBJECT (color_win), "scrolledwindow1", scrolledwindow1,
199                             (GtkDestroyNotify) gtk_widget_unref);
200   gtk_widget_show (scrolledwindow1);
201   gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0);
202
203   color_filters = gtk_clist_new_with_titles(2, titles);
204
205   num_of_filters = 0;
206   g_slist_foreach(filter_list, add_filter_to_clist, color_filters);
207
208   gtk_widget_show (color_filters);
209   gtk_container_add (GTK_CONTAINER (scrolledwindow1), color_filters);
210   gtk_widget_set_usize (color_filters, 300, -2);
211   gtk_clist_set_column_width (GTK_CLIST (color_filters), 0, 80);
212   gtk_clist_set_column_width (GTK_CLIST (color_filters), 1, 80);
213   gtk_clist_column_titles_show (GTK_CLIST (color_filters));
214   /* end list of filters */
215
216   /* vbox4 is first button column */
217   vbox4 = gtk_vbox_new (FALSE, 0);
218   gtk_widget_ref (vbox4);
219   gtk_object_set_data_full (GTK_OBJECT (color_win), "vbox4", vbox4,
220                             (GtkDestroyNotify) gtk_widget_unref);
221   gtk_widget_show (vbox4);
222   gtk_box_pack_start (GTK_BOX (hbox1), vbox4, TRUE, FALSE, 5);
223 #if 0
224   gtk_widget_set_usize (vbox4, -2, 30);
225 #endif
226
227   color_new = gtk_button_new_with_label (("New"));
228   gtk_widget_ref (color_new);
229   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_new", color_new,
230                             (GtkDestroyNotify) gtk_widget_unref);
231   gtk_widget_show (color_new);
232   gtk_box_pack_start (GTK_BOX (vbox4), color_new, FALSE, FALSE, 5);
233   gtk_widget_set_usize (color_new, 50, 20);
234   gtk_tooltips_set_tip (tooltips, color_new, ("Create a new colorization filter after selected filter"), NULL);
235
236   color_edit = gtk_button_new_with_label (("Edit"));
237   gtk_widget_ref (color_edit);
238   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_edit", color_edit,
239                             (GtkDestroyNotify) gtk_widget_unref);
240   gtk_widget_show (color_edit);
241   gtk_widget_set_usize(color_edit, 50, 20);
242   gtk_box_pack_start (GTK_BOX (vbox4), color_edit, FALSE, FALSE, 5);
243   gtk_tooltips_set_tip (tooltips, color_edit, ("Change color of selected filter"), NULL);
244   gtk_widget_set_sensitive (color_edit, FALSE);
245
246   color_delete = gtk_button_new_with_label (("Delete"));
247   gtk_widget_ref (color_delete);
248   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_delete", color_delete,
249                             (GtkDestroyNotify) gtk_widget_unref);
250   gtk_widget_show (color_delete);
251   gtk_box_pack_start (GTK_BOX (vbox4), color_delete, FALSE, FALSE, 5);
252   gtk_widget_set_usize (color_delete, 50, 20);
253   gtk_tooltips_set_tip (tooltips, color_delete, ("Delete selected colorization filter"), NULL);
254   gtk_widget_set_sensitive (color_delete, FALSE);
255
256   color_save = gtk_button_new_with_label (("Save"));
257   gtk_widget_ref (color_save);
258   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_save", color_save,
259                             (GtkDestroyNotify) gtk_widget_unref);
260   gtk_widget_show (color_save);
261   gtk_box_pack_start (GTK_BOX (vbox4), color_save, FALSE, FALSE, 5);
262   gtk_widget_set_usize (color_save, 50, 20);
263   gtk_tooltips_set_tip (tooltips, color_save, ("Save all filters to disk"), NULL);
264
265   /* hbox3 is bottom button row */
266   hbox3 = gtk_hbox_new (FALSE, 0);
267   gtk_widget_ref (hbox3);
268   gtk_object_set_data_full (GTK_OBJECT (color_win), "hbox3", hbox3,
269                             (GtkDestroyNotify) gtk_widget_unref);
270   gtk_widget_show (hbox3);
271   gtk_box_pack_start (GTK_BOX (vbox1), hbox3, TRUE, FALSE, 5);
272   gtk_widget_set_usize (hbox3, 177, 30);
273
274   color_ok = gtk_button_new_with_label (("OK"));
275   gtk_widget_ref (color_ok);
276   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_ok", color_ok,
277                             (GtkDestroyNotify) gtk_widget_unref);
278   gtk_widget_show (color_ok);
279   gtk_box_pack_start (GTK_BOX (hbox3), color_ok, TRUE, FALSE, 0);
280   gtk_widget_set_usize (color_ok, 50, 20);
281   gtk_tooltips_set_tip (tooltips, color_ok, ("Accept filter list; apply changes"), NULL);
282
283   color_apply = gtk_button_new_with_label (("Apply"));
284   gtk_widget_ref (color_apply);
285   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_apply", color_apply,
286                             (GtkDestroyNotify) gtk_widget_unref);
287   gtk_widget_show (color_apply);
288   gtk_box_pack_start (GTK_BOX (hbox3), color_apply, TRUE, FALSE, 0);
289   gtk_widget_set_usize (color_apply, 50, 20);
290   gtk_tooltips_set_tip (tooltips, color_apply, ("Apply filters in list"), NULL);
291
292   color_cancel = gtk_button_new_with_label (("Cancel"));
293   gtk_widget_ref (color_cancel);
294   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_cancel", color_cancel,
295                             (GtkDestroyNotify) gtk_widget_unref);
296   gtk_widget_show (color_cancel);
297   gtk_box_pack_start (GTK_BOX (hbox3), color_cancel, TRUE, FALSE, 0);
298   gtk_widget_set_usize (color_cancel, 50, 20);
299   gtk_tooltips_set_tip (tooltips, color_cancel, ("No more filter changes; don't apply"), NULL);
300
301   gtk_signal_connect (GTK_OBJECT (color_win), "destroy",
302                       GTK_SIGNAL_FUNC (color_destroy_cb),
303                       NULL);
304   gtk_object_set_data(GTK_OBJECT (color_filter_up), COLOR_FILTERS_CL,
305                       color_filters);
306   gtk_signal_connect (GTK_OBJECT (color_filter_up), "clicked",
307                       GTK_SIGNAL_FUNC (color_filter_up_cb),
308                       NULL);
309   gtk_object_set_data(GTK_OBJECT (color_filter_down), COLOR_FILTERS_CL,
310                       color_filters);
311   gtk_signal_connect (GTK_OBJECT (color_filter_down), "clicked",
312                       GTK_SIGNAL_FUNC (color_filter_down_cb),
313                       NULL);
314   gtk_signal_connect (GTK_OBJECT (color_filters), "select_row",
315                       GTK_SIGNAL_FUNC (remember_selected_row),
316                       NULL);
317   gtk_signal_connect (GTK_OBJECT (color_filters), "unselect_row",
318                       GTK_SIGNAL_FUNC (unremember_selected_row),
319                       NULL);
320   gtk_object_set_data(GTK_OBJECT (color_filters), COLOR_UP_LB,
321                       color_filter_up);
322   gtk_object_set_data(GTK_OBJECT (color_filters), COLOR_DOWN_LB,
323                       color_filter_down);
324   gtk_object_set_data(GTK_OBJECT (color_filters), COLOR_EDIT_LB,
325                       color_edit);
326   gtk_object_set_data(GTK_OBJECT (color_filters), COLOR_DELETE_LB,
327                       color_delete);
328   gtk_object_set_data(GTK_OBJECT (color_new), COLOR_FILTERS_CL,
329                       color_filters);
330   gtk_signal_connect (GTK_OBJECT (color_new), "clicked",
331                       GTK_SIGNAL_FUNC (color_new_cb),
332                       NULL);
333   gtk_object_set_data(GTK_OBJECT (color_edit), COLOR_FILTERS_CL,
334                       color_filters);
335   gtk_signal_connect (GTK_OBJECT (color_edit), "clicked",
336                       GTK_SIGNAL_FUNC (color_edit_cb),
337                       NULL);
338   gtk_object_set_data(GTK_OBJECT (color_delete), COLOR_EDIT_LB,
339                       color_edit);
340   gtk_object_set_data(GTK_OBJECT (color_delete), COLOR_FILTERS_CL,
341                       color_filters);
342   gtk_signal_connect (GTK_OBJECT (color_delete), "clicked",
343                       GTK_SIGNAL_FUNC (color_delete_cb),
344                       NULL);
345   gtk_signal_connect (GTK_OBJECT (color_save), "clicked",
346                       GTK_SIGNAL_FUNC (color_save_cb),
347                       NULL);
348   gtk_signal_connect (GTK_OBJECT (color_ok), "clicked",
349                       GTK_SIGNAL_FUNC (color_ok_cb),
350                       NULL);
351   gtk_signal_connect (GTK_OBJECT (color_apply), "clicked",
352                       GTK_SIGNAL_FUNC (color_apply_cb),
353                       NULL);
354   gtk_signal_connect (GTK_OBJECT (color_cancel), "clicked",
355                       GTK_SIGNAL_FUNC (color_cancel_cb),
356                       NULL);
357
358   gtk_widget_grab_focus (color_filters);
359   gtk_object_set_data (GTK_OBJECT (color_win), "tooltips", tooltips);
360   gtk_widget_show (color_win);
361
362   dlg_set_cancel(color_win, color_cancel);
363
364   return color_win;
365 }
366
367 static void
368 add_filter_to_clist(gpointer filter_arg, gpointer clist_arg)
369 {
370   color_filter_t *colorf = filter_arg;
371   GtkWidget      *color_filters = clist_arg;
372   gchar          *data[2];
373   gint            row;
374   GdkColor        bg, fg;
375
376   data[0] = colorf->filter_name;
377   data[1] = colorf->filter_text;
378   row = gtk_clist_append(GTK_CLIST(color_filters), data);
379   color_t_to_gdkcolor(&fg, &colorf->fg_color);
380   color_t_to_gdkcolor(&bg, &colorf->bg_color);
381   gtk_clist_set_row_data(GTK_CLIST(color_filters), row, colorf);
382   gtk_clist_set_foreground(GTK_CLIST(color_filters), row, &fg);
383   gtk_clist_set_background(GTK_CLIST(color_filters), row, &bg);
384   num_of_filters++;
385 }
386
387 /* Move the selected filter up in the list */
388 static void
389 color_filter_up_cb                     (GtkButton       *button,
390                                         gpointer         user_data _U_)
391 {
392   gint filter_number;
393   GtkWidget *color_filters;
394   color_filter_t *colorf;
395
396   filter_number = row_selected;
397   g_assert(filter_number > 0);
398
399   color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
400                       COLOR_FILTERS_CL);
401   colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
402   gtk_clist_swap_rows(GTK_CLIST(color_filters), filter_number, filter_number-1);
403
404   /*
405    * That row is still selected, but it's now row N-1.
406    */
407   remember_selected_row(GTK_CLIST(color_filters), filter_number-1, 0, NULL,
408       NULL);
409
410   filter_list = g_slist_remove(filter_list, colorf);
411   filter_list = g_slist_insert(filter_list, colorf, filter_number-1);
412 }
413
414 /* Move the selected filter down in the list */
415 static void
416 color_filter_down_cb                   (GtkButton       *button,
417                                         gpointer         user_data _U_)
418 {
419   gint filter_number;
420   GtkWidget *color_filters;
421   color_filter_t *colorf;
422
423   filter_number = row_selected;
424   g_assert(filter_number < num_of_filters - 1);
425
426   color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
427                       COLOR_FILTERS_CL);
428   colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
429   gtk_clist_swap_rows(GTK_CLIST(color_filters), filter_number+1, filter_number);
430
431   /*
432    * That row is still selected, but it's now row N+1.
433    */
434   remember_selected_row(GTK_CLIST(color_filters), filter_number+1, 0, NULL,
435       NULL);
436
437   filter_list = g_slist_remove(filter_list, colorf);
438   filter_list = g_slist_insert(filter_list, colorf, filter_number+1);
439 }
440
441 /* A row was selected; remember its row number */
442 static void
443 remember_selected_row                 (GtkCList        *clist,
444                                         gint             row,
445                                         gint             column _U_,
446                                         GdkEvent        *event _U_,
447                                         gpointer         user_data _U_)
448 {
449   GtkWidget *button;
450
451   row_selected = row;
452
453   /*
454    * A row is selected, so we can move it up *if* it's not at the top
455    * and move it down *if* it's not at the bottom.
456    */
457   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(clist),
458                                             COLOR_UP_LB);
459   gtk_widget_set_sensitive (button, row > 0);
460   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(clist),
461                                             COLOR_DOWN_LB);
462   gtk_widget_set_sensitive (button, row < num_of_filters - 1);
463
464   /*
465    * A row is selected, so we can operate on it.
466    */
467   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(clist),
468                                             COLOR_EDIT_LB);
469   gtk_widget_set_sensitive (button, TRUE);
470   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(clist),
471                                             COLOR_DELETE_LB);
472   gtk_widget_set_sensitive (button, TRUE);
473 }
474
475 /* A row was unselected; un-remember its row number */
476 static void
477 unremember_selected_row                 (GtkCList        *clist,
478                                          gint             row _U_,
479                                          gint             column _U_,
480                                          GdkEvent        *event _U_,
481                                          gpointer         user_data _U_)
482 {
483   GtkWidget *button;
484
485   row_selected = -1;
486
487   /*
488    * No row is selected, so we can't do operations that affect the
489    * selected row.
490    */
491   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(clist),
492                                             COLOR_UP_LB);
493   gtk_widget_set_sensitive (button, FALSE);
494   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(clist),
495                                             COLOR_DOWN_LB);
496   gtk_widget_set_sensitive (button, FALSE);
497   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(clist),
498                                             COLOR_EDIT_LB);
499   gtk_widget_set_sensitive (button, FALSE);
500   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(clist),
501                                             COLOR_DELETE_LB);
502   gtk_widget_set_sensitive (button, FALSE);
503 }
504
505 /* Called when the dialog box is being destroyed; destroy any edit
506  * dialogs opened from this dialog, and null out the pointer to this
507  * dialog.
508  jjj*/
509 static void
510 color_destroy_cb                       (GtkButton       *button _U_,
511                                         gpointer         user_data _U_)
512 {
513   /* Destroy any edit dialogs we have open. */
514   g_slist_foreach(filter_list, destroy_edit_dialog_cb, NULL);
515
516   colorize_win = NULL;
517 }
518
519 static void
520 destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy _U_)
521 {
522   color_filter_t *colorf = (color_filter_t *)filter_arg;
523
524   if (colorf->edit_dialog != NULL)
525     gtk_widget_destroy(colorf->edit_dialog);
526 }
527
528 /* XXX - we don't forbid having more than one "Edit color filter" dialog
529    open, so these shouldn't be static. */
530 static GtkWidget *filt_name_entry;
531 static GtkWidget *filt_text_entry;
532
533 /* Create a new filter in the list, and pop up an "Edit color filter"
534    dialog box to edit it. */
535 static void
536 color_new_cb                          (GtkButton       *button,
537                                        gpointer         user_data _U_)
538 {
539   color_filter_t *colorf;
540   GtkWidget *color_filters;
541   gchar *data[2];
542   gint row;
543
544   colorf = new_color_filter("name", "filter"); /* Adds at end! */
545
546   color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
547                       COLOR_FILTERS_CL);
548   data[0] = colorf->filter_name;
549   data[1] = colorf->filter_text;
550   row = gtk_clist_append(GTK_CLIST(color_filters), data);
551   gtk_clist_set_row_data(GTK_CLIST(color_filters), row, colorf);
552   num_of_filters++;
553
554   /* select the new row */
555   gtk_clist_select_row(GTK_CLIST(color_filters), row, -1);
556   edit_color_filter_dialog_new(color_filters, &filt_name_entry,
557                                 &filt_text_entry);
558 }
559
560 /* Pop up an "Edit color filter" dialog box to edit an existing filter. */
561 static void
562 color_edit_cb                        (GtkButton       *button,
563                                       gpointer         user_data _U_)
564 {
565   GtkWidget *color_filters;
566
567   color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
568                       COLOR_FILTERS_CL);
569   g_assert(row_selected != -1);
570   edit_color_filter_dialog_new(color_filters, &filt_name_entry,
571                                 &filt_text_entry);
572 }
573
574 /* Delete a color from the list. */
575 static void
576 color_delete_cb(GtkWidget *widget, gpointer user_data _U_)
577 {
578   GtkWidget *color_filters;
579   color_filter_t *colorf;
580
581   if(row_selected != -1){
582         color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
583                       COLOR_FILTERS_CL);
584         colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row_selected);
585
586         /* Remove this color filter from the CList displaying the
587            color filters. */
588         gtk_clist_remove(GTK_CLIST(color_filters), row_selected);
589         num_of_filters--;
590
591         /* Destroy any "Edit color filter" dialog boxes editing it. */
592         if (colorf->edit_dialog != NULL)
593                 gtk_widget_destroy(colorf->edit_dialog);
594
595         /* Remove the color filter from the list of color filters. */
596         delete_color_filter(colorf);
597
598         /* Select the previous row, if there is one. */
599         if (row_selected > 0) {
600                 row_selected--;
601                 gtk_clist_select_row(GTK_CLIST(color_filters), row_selected, 0);
602         }
603   }
604 }
605
606 /* Save color filters to the color filter file. */
607 static void
608 color_save_cb                          (GtkButton       *button _U_,
609                                         gpointer         user_data _U_)
610 {
611   if (!write_filters())
612         simple_dialog(ESD_TYPE_CRIT, NULL, "Could not open filter file: %s",
613             strerror(errno));
614
615 }
616
617 /* Exit dialog and apply new list of color filters to the capture. */
618 static void
619 color_ok_cb                            (GtkButton       *button _U_,
620                                         gpointer         user_data _U_)
621 {
622   /* colorize list */
623   colorize_packets(&cfile);
624
625   /* Destroy the dialog box. */
626   gtk_widget_destroy(colorize_win);
627 }
628
629 /* Exit dialog without colorizing packets with the new list.
630    XXX - should really undo any changes to the list.... */
631 static void
632 color_cancel_cb                        (GtkWidget       *widget _U_,
633                                         gpointer         user_data _U_)
634 {
635   /* Destroy the dialog box. */
636   gtk_widget_destroy(colorize_win);
637 }
638
639 /* Apply new list of color filters to the capture. */
640 static void
641 color_apply_cb                         (GtkButton       *button _U_,
642                                         gpointer         user_data _U_)
643 {
644   colorize_packets(&cfile);
645 }
646
647 /* Create an "Edit color filter" dialog for a given color filter, and
648    associate it with that color filter. */
649 static void
650 edit_color_filter_dialog_new (GtkWidget *color_filters,
651         GtkWidget **colorize_filter_name,
652         GtkWidget **colorize_filter_text)
653 {
654   color_filter_t *colorf;
655   GtkWidget *edit_dialog;
656   GtkWidget *vbox3;
657   GtkWidget *hbox6;
658   GtkWidget *color_filter_name;
659   GtkWidget *hbox7;
660   GtkWidget *add_expression_bt;
661   GtkWidget *color_filter_text;
662   GtkWidget *hbox5;
663   GtkWidget *colorize_filter_fg;
664   GtkWidget *colorize_filter_bg;
665   GtkWidget *hbox4;
666   GtkWidget *edit_color_filter_ok;
667   GtkWidget *edit_color_filter_cancel;
668   GtkTooltips *tooltips;
669   GtkStyle  *style;
670
671   colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row_selected);
672   if (colorf->edit_dialog != NULL) {
673     /* There's already an edit box open for this filter; reactivate it. */
674     reactivate_window(colorf->edit_dialog);
675     return;
676   }
677
678   tooltips = gtk_tooltips_new ();
679
680   edit_dialog = dlg_window_new ("Edit color filter");
681   gtk_object_set_data (GTK_OBJECT (edit_dialog), "edit_dialog", edit_dialog);
682   colorf->edit_dialog = edit_dialog;
683
684   vbox3 = gtk_vbox_new (FALSE, 0);
685   gtk_widget_ref (vbox3);
686   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "vbox3", vbox3,
687                             (GtkDestroyNotify) gtk_widget_unref);
688   gtk_widget_show (vbox3);
689   gtk_container_add (GTK_CONTAINER (edit_dialog), vbox3);
690
691   hbox6 = gtk_hbox_new (FALSE, 0);
692   gtk_widget_ref (hbox6);
693   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "hbox6", hbox6,
694                             (GtkDestroyNotify) gtk_widget_unref);
695   gtk_widget_show (hbox6);
696   gtk_box_pack_start (GTK_BOX (vbox3), hbox6, TRUE, FALSE, 5);
697
698   color_filter_name = gtk_label_new (("Name: "));
699   gtk_widget_ref (color_filter_name);
700   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "color_filter_name", color_filter_name,
701                             (GtkDestroyNotify) gtk_widget_unref);
702   gtk_widget_show (color_filter_name);
703   gtk_box_pack_start (GTK_BOX (hbox6), color_filter_name, FALSE, FALSE, 0);
704
705   *colorize_filter_name = gtk_entry_new ();
706   gtk_widget_ref (*colorize_filter_name);
707   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "*colorize_filter_name", *colorize_filter_name,
708                             (GtkDestroyNotify) gtk_widget_unref);
709   gtk_entry_set_text(GTK_ENTRY(*colorize_filter_name), colorf->filter_name);
710
711   style = gtk_style_copy(gtk_widget_get_style(*colorize_filter_name));
712   color_t_to_gdkcolor(&style->base[GTK_STATE_NORMAL], &colorf->bg_color);
713   color_t_to_gdkcolor(&style->fg[GTK_STATE_NORMAL], &colorf->fg_color);
714   gtk_widget_set_style(*colorize_filter_name, style);
715
716   gtk_widget_show (*colorize_filter_name);
717   gtk_box_pack_start (GTK_BOX (hbox6), *colorize_filter_name, TRUE, TRUE, 0);
718   gtk_tooltips_set_tip (tooltips, *colorize_filter_name, ("This is the editable name of the filter. (No @ characters allowed.)"), NULL);
719
720   hbox7 = gtk_hbox_new (FALSE, 0);
721   gtk_widget_ref (hbox7);
722   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "hbox7", hbox7,
723                             (GtkDestroyNotify) gtk_widget_unref);
724   gtk_widget_show (hbox7);
725   gtk_box_pack_start (GTK_BOX (vbox3), hbox7, TRUE, FALSE, 5);
726
727   color_filter_text = gtk_label_new (("Filter text:"));
728   gtk_widget_ref (color_filter_text);
729   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "color_filter_text", color_filter_text,
730                             (GtkDestroyNotify) gtk_widget_unref);
731   gtk_widget_show (color_filter_text);
732   gtk_box_pack_start (GTK_BOX (hbox7), color_filter_text, FALSE, FALSE, 0);
733
734   *colorize_filter_text = gtk_entry_new ();
735   gtk_widget_ref (*colorize_filter_text);
736   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "*colorize_filter_text", *colorize_filter_text,
737                             (GtkDestroyNotify) gtk_widget_unref);
738   gtk_entry_set_text(GTK_ENTRY(*colorize_filter_text), colorf->filter_text);
739
740
741 #if 0
742   style = gtk_style_copy(gtk_widget_get_style(*colorize_filter_text));
743   style->base[GTK_STATE_NORMAL] = colorf->bg_color;
744   style->fg[GTK_STATE_NORMAL]   = colorf->fg_color;
745 #endif
746   gtk_widget_set_style(*colorize_filter_text, style);
747   gtk_widget_show (*colorize_filter_text);
748   gtk_box_pack_start (GTK_BOX (hbox7), *colorize_filter_text, TRUE, TRUE, 0);
749   gtk_tooltips_set_tip (tooltips, *colorize_filter_text, ("This is the editable text of the filter"), NULL);
750
751   /* Create the "Add Expression..." button, to pop up a dialog
752   for constructing filter comparison expressions. */
753   add_expression_bt = gtk_button_new_with_label("Add Expression...");
754   gtk_signal_connect(GTK_OBJECT(add_expression_bt), "clicked",
755       GTK_SIGNAL_FUNC(filter_expr_cb), *colorize_filter_text);
756   gtk_box_pack_start (GTK_BOX(hbox7), add_expression_bt, FALSE, FALSE, 3);
757   gtk_widget_show(add_expression_bt);
758
759   hbox5 = gtk_hbox_new (FALSE, 0);
760   gtk_widget_ref (hbox5);
761   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "hbox5", hbox5,
762                             (GtkDestroyNotify) gtk_widget_unref);
763   gtk_widget_show (hbox5);
764   gtk_box_pack_start (GTK_BOX (vbox3), hbox5, FALSE, FALSE, 5);
765   gtk_widget_set_usize (hbox5, -2, 60);
766
767   colorize_filter_fg = gtk_button_new_with_label (("Choose \nforeground\ncolor"));
768   gtk_widget_ref (colorize_filter_fg);
769   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "colorize_filter_fg", colorize_filter_fg,
770                             (GtkDestroyNotify) gtk_widget_unref);
771   gtk_widget_show (colorize_filter_fg);
772   gtk_box_pack_start (GTK_BOX (hbox5), colorize_filter_fg, TRUE, FALSE, 0);
773   gtk_tooltips_set_tip (tooltips, colorize_filter_fg, ("Select color for data display"), NULL);
774
775   colorize_filter_bg = gtk_button_new_with_label (("Choose\nbackground\ncolor"));
776   gtk_widget_ref (colorize_filter_bg);
777   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "colorize_filter_bg", colorize_filter_bg,
778                             (GtkDestroyNotify) gtk_widget_unref);
779   gtk_widget_show (colorize_filter_bg);
780   gtk_box_pack_start (GTK_BOX (hbox5), colorize_filter_bg, TRUE, FALSE, 0);
781   gtk_tooltips_set_tip (tooltips, colorize_filter_bg, ("Select color for data display"), NULL);
782
783   hbox4 = gtk_hbox_new (FALSE, 0);
784   gtk_widget_ref (hbox4);
785   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "hbox4", hbox4,
786                             (GtkDestroyNotify) gtk_widget_unref);
787   gtk_widget_show (hbox4);
788   gtk_box_pack_start (GTK_BOX (vbox3), hbox4, TRUE, FALSE, 5);
789   gtk_widget_set_usize (hbox4, -2, 30);
790
791   edit_color_filter_ok = gtk_button_new_with_label (("OK"));
792   gtk_widget_ref (edit_color_filter_ok);
793   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "edit_color_filter_ok", edit_color_filter_ok,
794                             (GtkDestroyNotify) gtk_widget_unref);
795   gtk_widget_set_usize (edit_color_filter_ok, 50, 20);
796   gtk_widget_show (edit_color_filter_ok);
797   gtk_box_pack_start (GTK_BOX (hbox4), edit_color_filter_ok, TRUE, FALSE, 0);
798   gtk_tooltips_set_tip (tooltips, edit_color_filter_ok, ("Accept filter color change"), NULL);
799
800   edit_color_filter_cancel = gtk_button_new_with_label (("Cancel"));
801   gtk_widget_ref (edit_color_filter_cancel);
802   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "edit_color_filter_cancel", edit_color_filter_cancel,
803                             (GtkDestroyNotify) gtk_widget_unref);
804   gtk_widget_set_usize (edit_color_filter_cancel, 50, 20);
805   gtk_widget_show (edit_color_filter_cancel);
806   gtk_box_pack_start (GTK_BOX (hbox4), edit_color_filter_cancel, TRUE, FALSE, 0);
807   gtk_tooltips_set_tip (tooltips, edit_color_filter_cancel, ("Reject filter color change"), NULL);
808   gtk_object_set_data(GTK_OBJECT (edit_dialog), COLOR_FILTER,
809                       colorf);
810   gtk_signal_connect (GTK_OBJECT (edit_dialog), "destroy",
811                       GTK_SIGNAL_FUNC (edit_color_filter_destroy_cb),
812                       NULL);
813   gtk_object_set_data(GTK_OBJECT (colorize_filter_fg), COLOR_FILTER,
814                       colorf);
815   gtk_signal_connect (GTK_OBJECT (colorize_filter_fg), "clicked",
816                       GTK_SIGNAL_FUNC (edit_color_filter_fg_cb),
817                       NULL);
818   gtk_object_set_data(GTK_OBJECT (colorize_filter_bg), COLOR_FILTER,
819                       colorf);
820   gtk_signal_connect (GTK_OBJECT (colorize_filter_bg), "clicked",
821                       GTK_SIGNAL_FUNC (edit_color_filter_bg_cb),
822                       NULL);
823   gtk_object_set_data(GTK_OBJECT (edit_color_filter_ok), COLOR_FILTERS_CL,
824                       color_filters);
825   gtk_object_set_data(GTK_OBJECT (edit_color_filter_ok), COLOR_FILTER,
826                       colorf);
827   gtk_signal_connect (GTK_OBJECT (edit_color_filter_ok), "clicked",
828                       GTK_SIGNAL_FUNC (edit_color_filter_ok_cb),
829                       edit_dialog);
830   gtk_signal_connect (GTK_OBJECT (edit_color_filter_cancel), "clicked",
831                       GTK_SIGNAL_FUNC (edit_color_filter_cancel_cb),
832                       edit_dialog);
833
834   gtk_object_set_data (GTK_OBJECT (edit_dialog), "tooltips", tooltips);
835
836   dlg_set_cancel(edit_dialog, edit_color_filter_cancel);
837
838   gtk_widget_show (edit_dialog);
839 }
840
841 /* Called when the dialog box is being destroyed; destroy any color
842    selection dialogs opened from this dialog, and null out the pointer
843    to this dialog. */
844 static void
845 edit_color_filter_destroy_cb           (GtkObject       *object,
846                                         gpointer         user_data _U_)
847 {
848   color_filter_t *colorf;
849   GtkWidget *color_sel;
850
851   colorf = (color_filter_t *) gtk_object_get_data(GTK_OBJECT(object),
852                       COLOR_FILTER);
853
854   colorf->edit_dialog = NULL;
855
856   /* Destroy any color selection dialogs this dialog had open. */
857   color_sel = (GtkWidget *) gtk_object_get_data(object, COLOR_SELECTION_FG);
858   if (color_sel != NULL)
859     gtk_widget_destroy(color_sel);
860   color_sel = (GtkWidget *) gtk_object_get_data(object, COLOR_SELECTION_BG);
861   if (color_sel != NULL)
862     gtk_widget_destroy(color_sel);
863 }
864
865 /* Pop up a color selection box to choose the foreground color. */
866 static void
867 edit_color_filter_fg_cb                (GtkButton       *button,
868                                         gpointer         user_data _U_)
869 {
870   color_filter_t *colorf;
871   GtkWidget *color_selection_fg;
872
873   colorf = (color_filter_t *) gtk_object_get_data(GTK_OBJECT(button),
874                       COLOR_FILTER);
875   /* Do we already have one open for this dialog? */
876   color_selection_fg = gtk_object_get_data(GTK_OBJECT (colorf->edit_dialog),
877       COLOR_SELECTION_FG);
878   if (color_selection_fg != NULL) {
879     /* Yes.  Just reactivate it. */
880     reactivate_window(color_selection_fg);
881   } else {
882     /* No.  Create a new color selection box, and associate it with
883        this dialog. */
884     color_selection_fg = color_sel_win_new(colorf, FALSE);
885     gtk_object_set_data(GTK_OBJECT (colorf->edit_dialog), COLOR_SELECTION_FG,
886                       color_selection_fg);
887     gtk_object_set_data(GTK_OBJECT (color_selection_fg),
888                 COLOR_SELECTION_PARENT, colorf->edit_dialog);
889   }
890 }
891
892 /* Pop up a color selection box to choose the background color. */
893 static void
894 edit_color_filter_bg_cb                (GtkButton       *button,
895                                         gpointer         user_data _U_)
896 {
897   color_filter_t *colorf;
898   GtkWidget *color_selection_bg;
899
900   colorf = (color_filter_t *) gtk_object_get_data(GTK_OBJECT(button),
901                       COLOR_FILTER);
902
903   /* Do we already have one open for this dialog? */
904   color_selection_bg = gtk_object_get_data(GTK_OBJECT (colorf->edit_dialog),
905       COLOR_SELECTION_BG);
906   if (color_selection_bg != NULL) {
907     /* Yes.  Just reactivate it. */
908     reactivate_window(color_selection_bg);
909   } else {
910     /* No.  Create a new color selection box, and associate it with
911        this dialog. */
912     color_selection_bg = color_sel_win_new(colorf, TRUE);
913     gtk_object_set_data(GTK_OBJECT (colorf->edit_dialog), COLOR_SELECTION_BG,
914                       color_selection_bg);
915     gtk_object_set_data(GTK_OBJECT (color_selection_bg),
916                 COLOR_SELECTION_PARENT, colorf->edit_dialog);
917   }
918 }
919
920 /* accept color (and potential content) change */
921 static void
922 edit_color_filter_ok_cb                (GtkButton       *button,
923                                         gpointer         user_data)
924 {
925   GtkWidget *dialog;
926   GtkStyle *style;
927   GdkColor new_fg_color;
928   GdkColor new_bg_color;
929   gchar *filter_name;
930   gchar *filter_text;
931   color_filter_t *colorf;
932   dfilter_t *compiled_filter;
933   GtkWidget *color_filters;
934
935   dialog = (GtkWidget *)user_data;
936
937   style = gtk_widget_get_style(filt_name_entry);
938   new_bg_color = style->base[GTK_STATE_NORMAL];
939   new_fg_color = style->fg[GTK_STATE_NORMAL];
940
941   filter_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(filt_name_entry)));
942   filter_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(filt_text_entry)));
943
944   if(strchr(filter_name,'@') || strchr(filter_text,'@')){
945         simple_dialog(ESD_TYPE_CRIT, NULL, "Filter names and strings must not"
946           " use the '@' character. Filter unchanged.");
947         g_free(filter_name);
948         g_free(filter_text);
949         return;
950   }
951
952   if(!dfilter_compile(filter_text, &compiled_filter)) {
953         simple_dialog(ESD_TYPE_CRIT, NULL, "Filter \"%s\" did not compile correctly.\n"
954                 " Please try again. Filter unchanged.\n%s\n", filter_name,
955                 dfilter_error_msg);
956   } else {
957         color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
958                       COLOR_FILTERS_CL);
959         colorf = (color_filter_t *) gtk_object_get_data(GTK_OBJECT(button),
960                       COLOR_FILTER);
961
962         if (colorf->filter_name != NULL)
963             g_free(colorf->filter_name);
964         colorf->filter_name = filter_name;
965         if (colorf->filter_text != NULL)
966             g_free(colorf->filter_text);
967         colorf->filter_text = filter_text;
968         gdkcolor_to_color_t(&colorf->fg_color, &new_fg_color);
969         gdkcolor_to_color_t(&colorf->bg_color, &new_bg_color);
970         gtk_clist_set_foreground(GTK_CLIST(color_filters), row_selected,
971             &new_fg_color);
972         gtk_clist_set_background(GTK_CLIST(color_filters), row_selected,
973             &new_bg_color);
974         if(colorf->c_colorfilter != NULL)
975             dfilter_free(colorf->c_colorfilter);
976         colorf->c_colorfilter = compiled_filter;
977         /* gtk_clist_set_text frees old text (if any) and allocates new space */
978         gtk_clist_set_text(GTK_CLIST(color_filters), row_selected, 0,
979             filter_name);
980         gtk_clist_set_text(GTK_CLIST(color_filters), row_selected, 1,
981             filter_text);
982
983         /* Destroy the dialog box. */
984         gtk_widget_destroy(dialog);
985   }
986 }
987
988 /* Exit dialog and do not process list */
989 static void
990 edit_color_filter_cancel_cb            (GtkObject       *object _U_,
991                                         gpointer         user_data)
992 {
993   GtkWidget *dialog;
994
995   dialog = (GtkWidget *)user_data;
996
997   /* Destroy the dialog box. */
998   gtk_widget_destroy(dialog);
999 }
1000
1001 static GtkWidget*
1002 color_sel_win_new(color_filter_t *colorf, gboolean is_bg)
1003 {
1004   gint title_len;
1005   gchar *title;
1006   static const gchar fg_title_format[] = "Choose foreground color for \"%s\"";
1007   static const gchar bg_title_format[] = "Choose background color for \"%s\"";
1008   GtkWidget *color_sel_win;
1009   color_t   *color;
1010   GtkWidget *color_sel_ok;
1011   GtkWidget *color_sel_cancel;
1012   GtkWidget *color_sel_help;
1013
1014   if (is_bg) {
1015     color = &colorf->bg_color;
1016     title_len = strlen(bg_title_format) + strlen(colorf->filter_name);
1017     title = g_malloc(title_len + 1);
1018     sprintf(title, bg_title_format, colorf->filter_name);
1019   } else {
1020     color = &colorf->fg_color;
1021     title_len = strlen(fg_title_format) + strlen(colorf->filter_name);
1022     title = g_malloc(title_len + 1);
1023     sprintf(title, fg_title_format, colorf->filter_name);
1024   }
1025   color_sel_win = gtk_color_selection_dialog_new(title);
1026   g_free(title);
1027   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_win", color_sel_win);
1028   gtk_container_set_border_width (GTK_CONTAINER (color_sel_win), 10);
1029
1030   if (color != NULL) {
1031     gdouble cols[3];
1032
1033     cols[0] = (gdouble)color->red / 65536.0;
1034     cols[1] = (gdouble)color->green / 65536.0;
1035     cols[2] = (gdouble)color->blue / 65536.0;
1036
1037     gtk_color_selection_set_color(
1038                     GTK_COLOR_SELECTION(
1039                             GTK_COLOR_SELECTION_DIALOG(color_sel_win)->colorsel), cols);
1040   }
1041
1042   color_sel_ok = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->ok_button;
1043   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_ok", color_sel_ok);
1044   gtk_widget_show (color_sel_ok);
1045   GTK_WIDGET_SET_FLAGS (color_sel_ok, GTK_CAN_DEFAULT);
1046
1047   color_sel_cancel = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->cancel_button;
1048   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_cancel", color_sel_cancel);
1049   gtk_widget_show (color_sel_cancel);
1050   GTK_WIDGET_SET_FLAGS (color_sel_cancel, GTK_CAN_DEFAULT);
1051
1052
1053   color_sel_help = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->help_button;
1054   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_help", color_sel_help);
1055   gtk_widget_show (color_sel_help);
1056
1057
1058   GTK_WIDGET_SET_FLAGS (color_sel_help, GTK_CAN_DEFAULT);
1059   gtk_signal_connect (GTK_OBJECT (color_sel_win), "destroy",
1060                       GTK_SIGNAL_FUNC (color_sel_cancel_cb),
1061                       color_sel_win);
1062
1063   gtk_signal_connect (GTK_OBJECT (color_sel_ok), "clicked",
1064                       GTK_SIGNAL_FUNC (color_sel_ok_cb),
1065                       color_sel_win);
1066   gtk_signal_connect (GTK_OBJECT (color_sel_cancel), "clicked",
1067                       GTK_SIGNAL_FUNC (color_sel_cancel_cb),
1068                       color_sel_win);
1069
1070   gtk_widget_show(color_sel_win);
1071   return color_sel_win;
1072 }
1073
1074 static void
1075 color_sel_win_destroy(GtkWidget *sel_win)
1076 {
1077   GtkWidget *parent;
1078   GtkWidget *color_selection_fg, *color_selection_bg;
1079
1080   /* Find the "Edit color filter" dialog box with which this is associated. */
1081   parent = (GtkWidget *)gtk_object_get_data(GTK_OBJECT (sel_win),
1082       COLOR_SELECTION_PARENT);
1083
1084   /* Find that dialog box's foreground and background color selection
1085      boxes, if any. */
1086   color_selection_fg = gtk_object_get_data(GTK_OBJECT (parent),
1087       COLOR_SELECTION_FG);
1088   color_selection_bg = gtk_object_get_data(GTK_OBJECT (parent),
1089       COLOR_SELECTION_BG);
1090
1091   if (sel_win == color_selection_fg) {
1092     /* This was its foreground color selection box; it isn't, anymore. */
1093     gtk_object_set_data(GTK_OBJECT (parent), COLOR_SELECTION_FG, NULL);
1094   }
1095   if (sel_win == color_selection_bg) {
1096     /* This was its background color selection box; it isn't, anymore. */
1097     gtk_object_set_data(GTK_OBJECT (parent), COLOR_SELECTION_BG, NULL);
1098   }
1099
1100   /* Now destroy it. */
1101   gtk_widget_destroy(sel_win);
1102 }
1103
1104 /* Retrieve selected color */
1105 static void
1106 color_sel_ok_cb                        (GtkButton       *button _U_,
1107                                         gpointer         user_data)
1108 {
1109   GdkColor new_color; /* Color from color selection dialog */
1110   gdouble new_colors[3];
1111   GtkWidget *color_dialog;
1112   GtkStyle  *style;
1113   GtkWidget *parent;
1114   GtkWidget *color_selection_fg, *color_selection_bg;
1115   gboolean is_bg;
1116
1117   color_dialog = (GtkWidget *)user_data;
1118
1119   gtk_color_selection_get_color(GTK_COLOR_SELECTION(
1120    GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel), new_colors);
1121
1122   new_color.red   = (guint16)(new_colors[0]*65535.0);
1123   new_color.green = (guint16)(new_colors[1]*65535.0);
1124   new_color.blue  = (guint16)(new_colors[2]*65535.0);
1125
1126   if ( ! get_color(&new_color) ){
1127         simple_dialog(ESD_TYPE_CRIT, NULL, "Could not allocate color.  Try again.");
1128   } else {
1129         /* Find the "Edit color filter" dialog box with which this is
1130            associated. */
1131         parent = (GtkWidget *)gtk_object_get_data(GTK_OBJECT (color_dialog),
1132               COLOR_SELECTION_PARENT);
1133
1134         /* Find that dialog box's foreground and background color selection
1135            boxes, if any. */
1136         color_selection_fg = gtk_object_get_data(GTK_OBJECT (parent),
1137               COLOR_SELECTION_FG);
1138         color_selection_bg = gtk_object_get_data(GTK_OBJECT (parent),
1139               COLOR_SELECTION_BG);
1140         is_bg = (color_dialog == color_selection_bg);
1141
1142         color_sel_win_destroy(color_dialog);
1143
1144         /* now apply the change to the fore/background */
1145
1146         style = gtk_style_copy(gtk_widget_get_style(filt_name_entry));
1147         if (is_bg)
1148           style->base[GTK_STATE_NORMAL] = new_color;
1149         else
1150           style->fg[GTK_STATE_NORMAL] = new_color;
1151         gtk_widget_set_style(filt_name_entry, style);
1152         gtk_widget_set_style(filt_text_entry, style);
1153   }
1154 }
1155
1156 /* Don't choose the selected color as the foreground or background
1157    color for the filter. */
1158 static void
1159 color_sel_cancel_cb                    (GtkObject       *object _U_,
1160                                         gpointer         user_data)
1161 {
1162   GtkWidget *color_dialog;
1163   color_dialog = (GtkWidget *)user_data;
1164   /* nothing to change here.  Just get rid of the dialog box. */
1165
1166   color_sel_win_destroy(color_dialog);
1167 }