Cleanup header file define guards.
[obnox/wireshark/wip.git] / gtk / color_edit_dlg.c
1 /* color_edit_dlg.c
2  * Definitions for single color filter edit dialog boxes
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <string.h>
30
31 #include <gtk/gtk.h>
32
33 #include <epan/packet.h>
34
35 #include "../color.h"
36 #include "../color_filters.h"
37 #include "../simple_dialog.h"
38
39 #include "gtk/color_utils.h"
40 #include "gtk/dlg_utils.h"
41 #include "gtk/gui_utils.h"
42 #include "gtk/stock_icons.h"
43 #include "gtk/filter_dlg.h"
44 #include "gtk/dfilter_expr_dlg.h"
45 #include "gtk/color_edit_dlg.h"
46 #include "gtk/filter_autocomplete.h"
47
48
49 #define BUTTON_SIZE_X -1
50 #define BUTTON_SIZE_Y -1
51
52
53 static void edit_color_filter_destroy_cb(GObject *object, gpointer user_data);
54 static void edit_color_filter_fg_cb(GtkButton *button, gpointer user_data);
55 static void edit_color_filter_bg_cb(GtkButton *button, gpointer user_data);
56 /*
57 static void edit_disabled_cb_cb(GtkButton *button, gpointer user_data);
58 */
59 static void edit_color_filter_ok_cb(GtkButton *button, gpointer user_data);
60 static void edit_new_color_filter_cancel_cb(GtkButton *button, gpointer user_data);
61
62 static GtkWidget* color_sel_win_new(color_filter_t *colorf, gboolean);
63 static void color_sel_ok_cb(GtkButton *button, gpointer user_data);
64 static void color_sel_cancel_cb(GtkObject *object, gpointer user_data);
65
66
67 #define COLOR_FILTERS_CL        "color_filters_cl"
68 #define COLOR_FILTER            "color_filter"
69 #define COLOR_FILTER_NAME_TE    "color_filter_name_te"
70 #define COLOR_FILTER_TEXT_TE    "color_filter_text_te"
71 #define COLOR_SELECTION_FG      "color_selection_fg"
72 #define COLOR_SELECTION_BG      "color_selection_bg"
73 #define COLOR_SELECTION_PARENT  "color_selection_parent"
74
75 /* XXX - we don't forbid having more than one "Edit color filter" dialog
76    open, so these shouldn't be global. */
77 static GtkWidget *filt_name_entry;
78 static GtkWidget *filt_text_entry;
79 static GtkWidget *disabled_cb;
80
81
82 static void
83 filter_expr_cb(GtkWidget *w _U_, gpointer filter_te)
84 {
85
86         dfilter_expr_dlg_new(GTK_WIDGET(filter_te));
87 }
88
89
90 /* Create an "Edit Color Filter" dialog for a given color filter, and
91    associate it with that color filter. */
92 void
93 edit_color_filter_dialog(GtkWidget *color_filters,
94                          gboolean is_new_filter)
95 {
96     color_filter_t *colorf;
97     GtkWidget      *edit_dialog;
98     GtkWidget      *dialog_vbox;
99     GtkTooltips    *tooltips;
100     GdkColor       bg_color, fg_color;
101
102     GtkWidget *filter_fr;
103     GtkWidget *filter_fr_vbox;
104     GtkWidget *filter_name_hbox;
105     GtkWidget *color_filter_name;
106     GtkWidget *filter_string_hbox;
107     GtkWidget *add_expression_bt;
108     GtkWidget *color_filter_text;
109
110     GtkWidget *settings_hbox;
111
112     GtkWidget *colorize_fr;
113     GtkWidget *colorize_hbox;
114     GtkWidget *colorize_filter_fg;
115     GtkWidget *colorize_filter_bg;
116
117     GtkWidget *status_fr;
118     GtkWidget *status_vbox;
119
120     GtkWidget *bbox;
121     GtkWidget *edit_color_filter_ok;
122     GtkWidget *edit_color_filter_cancel;
123
124     GtkTreeModel     *model;
125     GtkTreeIter       iter;
126
127     model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
128
129     gtk_tree_model_iter_nth_child(model, &iter, NULL, row_selected);
130     gtk_tree_model_get(model, &iter, 5, &colorf, -1);
131
132     if (colorf->edit_dialog != NULL) {
133         /* There's already an edit box open for this filter; reactivate it. */
134         reactivate_window(colorf->edit_dialog);
135         return;
136     }
137
138     tooltips = gtk_tooltips_new ();
139
140     /* dialog window */
141     edit_dialog = dlg_conf_window_new ("Wireshark: Edit Color Filter");
142     gtk_window_set_default_size(GTK_WINDOW(edit_dialog), 500, -1);
143     g_object_set_data(G_OBJECT(edit_dialog), "edit_dialog", edit_dialog);
144     colorf->edit_dialog = edit_dialog;
145
146     dialog_vbox = gtk_vbox_new (FALSE, 0);
147     gtk_container_set_border_width  (GTK_CONTAINER (dialog_vbox), 5);
148     gtk_container_add (GTK_CONTAINER (edit_dialog), dialog_vbox);
149
150     /* Filter frame */
151     filter_fr = gtk_frame_new("Filter");
152     gtk_box_pack_start (GTK_BOX (dialog_vbox), filter_fr, FALSE, FALSE, 0);
153
154     filter_fr_vbox = gtk_vbox_new (FALSE, 0);
155     gtk_container_set_border_width  (GTK_CONTAINER (filter_fr_vbox), 5);
156     gtk_container_add(GTK_CONTAINER(filter_fr), filter_fr_vbox);
157
158     /* filter name hbox */
159     filter_name_hbox = gtk_hbox_new (FALSE, 0);
160     gtk_box_pack_start (GTK_BOX (filter_fr_vbox), filter_name_hbox, TRUE, FALSE, 3);
161
162     color_filter_name = gtk_label_new (("Name: "));
163     gtk_box_pack_start (GTK_BOX (filter_name_hbox), color_filter_name, FALSE, FALSE, 0);
164
165     filt_name_entry = gtk_entry_new ();
166     gtk_entry_set_text(GTK_ENTRY(filt_name_entry), colorf->filter_name);
167
168     color_t_to_gdkcolor(&bg_color, &colorf->bg_color);
169     color_t_to_gdkcolor(&fg_color, &colorf->fg_color);
170
171     gtk_widget_modify_base(filt_name_entry, GTK_STATE_NORMAL, &bg_color);
172     gtk_widget_modify_text(filt_name_entry, GTK_STATE_NORMAL, &fg_color);
173
174     gtk_box_pack_start (GTK_BOX (filter_name_hbox), filt_name_entry, TRUE, TRUE, 0);
175     gtk_tooltips_set_tip (tooltips, filt_name_entry, ("This is the editable name of the filter. (No @ characters allowed.)"), NULL);
176
177
178     /* filter string hbox */
179     filter_string_hbox = gtk_hbox_new (FALSE, 0);
180     gtk_box_pack_start (GTK_BOX (filter_fr_vbox), filter_string_hbox, TRUE, FALSE, 3);
181
182     color_filter_text = gtk_label_new (("String: "));
183     gtk_box_pack_start (GTK_BOX (filter_string_hbox), color_filter_text, FALSE, FALSE, 0);
184
185     filt_text_entry = gtk_entry_new ();
186     g_signal_connect(filt_text_entry, "changed", G_CALLBACK(filter_te_syntax_check_cb), NULL);
187     g_object_set_data(G_OBJECT(filter_string_hbox), E_FILT_AUTOCOMP_PTR_KEY, NULL);
188     g_signal_connect(filt_text_entry, "key-press-event", G_CALLBACK (filter_string_te_key_pressed_cb), NULL);
189     g_signal_connect(edit_dialog, "key-press-event", G_CALLBACK (filter_parent_dlg_key_pressed_cb), NULL);
190     gtk_entry_set_text(GTK_ENTRY(filt_text_entry), colorf->filter_text);
191
192     gtk_box_pack_start (GTK_BOX (filter_string_hbox), filt_text_entry, TRUE, TRUE, 0);
193     gtk_tooltips_set_tip (tooltips, filt_text_entry, ("This is the editable text of the filter"), NULL);
194
195     /* Create the "Add Expression..." button, to pop up a dialog
196        for constructing filter comparison expressions. */
197     add_expression_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_ADD_EXPRESSION);
198     g_signal_connect(add_expression_bt, "clicked", G_CALLBACK(filter_expr_cb), filt_text_entry);
199     gtk_box_pack_start (GTK_BOX(filter_string_hbox), add_expression_bt, FALSE, FALSE, 3);
200     gtk_tooltips_set_tip (tooltips, add_expression_bt, ("Add an expression to the filter string"), NULL);
201
202     /* Show the (in)validity of the default filter string */
203     filter_te_syntax_check_cb(filt_text_entry);
204
205     /* settings-hbox for "choose color frame" and "status frame" */
206     settings_hbox = gtk_hbox_new (FALSE, 0);
207     gtk_box_pack_start (GTK_BOX (dialog_vbox), settings_hbox, FALSE, FALSE, 0);
208
209     /* choose color frame */
210     colorize_fr = gtk_frame_new("Display Colors");
211     gtk_box_pack_start (GTK_BOX (settings_hbox), colorize_fr, TRUE, TRUE, 0);
212
213     colorize_hbox = gtk_hbox_new (FALSE, 0);
214     gtk_container_set_border_width  (GTK_CONTAINER (colorize_hbox), 5);
215     gtk_container_add(GTK_CONTAINER(colorize_fr), colorize_hbox);
216
217     colorize_filter_fg = gtk_button_new_with_label (("Foreground Color..."));
218     gtk_box_pack_start (GTK_BOX (colorize_hbox), colorize_filter_fg, TRUE, FALSE, 0);
219     gtk_tooltips_set_tip (tooltips, colorize_filter_fg, ("Select foreground color for data display"), NULL);
220
221     colorize_filter_bg = gtk_button_new_with_label (("Background Color..."));
222     gtk_box_pack_start (GTK_BOX (colorize_hbox), colorize_filter_bg, TRUE, FALSE, 0);
223     gtk_tooltips_set_tip (tooltips, colorize_filter_bg, ("Select background color for data display"), NULL);
224
225     /* status frame */
226     status_fr = gtk_frame_new("Status");
227     gtk_box_pack_start (GTK_BOX (settings_hbox), status_fr, TRUE, TRUE, 0);
228
229     status_vbox = gtk_vbox_new (FALSE, 0);
230     gtk_container_set_border_width  (GTK_CONTAINER (status_vbox), 5);
231     gtk_container_add(GTK_CONTAINER(status_fr), status_vbox);
232
233     disabled_cb = gtk_check_button_new_with_label("Disabled");
234     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(disabled_cb), colorf->disabled);
235     gtk_box_pack_start (GTK_BOX (status_vbox), disabled_cb, TRUE, FALSE, 0);
236     gtk_tooltips_set_tip (tooltips, disabled_cb, ("Color rule won't be checked if this box is selected"), NULL);
237     
238     /* button box */
239     bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL);
240         gtk_box_pack_start(GTK_BOX(dialog_vbox), bbox, FALSE, FALSE, 0);
241     gtk_container_set_border_width  (GTK_CONTAINER (bbox), 0);
242
243     edit_color_filter_ok = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
244     gtk_tooltips_set_tip (tooltips, edit_color_filter_ok, ("Accept filter color change"), NULL);
245
246     edit_color_filter_cancel = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
247     gtk_tooltips_set_tip (tooltips, edit_color_filter_cancel, ("Reject filter color change"), NULL);
248
249     gtk_widget_grab_default(edit_color_filter_ok);
250
251     /* signals and such */
252     g_object_set_data(G_OBJECT(edit_dialog), COLOR_FILTER, colorf);
253     g_signal_connect(edit_dialog, "destroy", G_CALLBACK(edit_color_filter_destroy_cb), NULL);
254     g_object_set_data(G_OBJECT(colorize_filter_fg), COLOR_FILTER, colorf);
255     g_signal_connect(colorize_filter_fg, "clicked", G_CALLBACK(edit_color_filter_fg_cb), NULL);
256     g_object_set_data(G_OBJECT(colorize_filter_bg), COLOR_FILTER, colorf);
257     g_signal_connect(colorize_filter_bg, "clicked", G_CALLBACK(edit_color_filter_bg_cb), NULL);
258     g_object_set_data(G_OBJECT(disabled_cb), COLOR_FILTER, colorf);
259 /*    g_signal_connect(disabled_cb, "clicked", edit_disabled_cb_cb, NULL);*/
260     g_object_set_data(G_OBJECT(edit_color_filter_ok), COLOR_FILTERS_CL, color_filters);
261     g_object_set_data(G_OBJECT(edit_color_filter_ok), COLOR_FILTER, colorf);
262     g_signal_connect(edit_color_filter_ok, "clicked", G_CALLBACK(edit_color_filter_ok_cb), edit_dialog);
263
264     /* set callback to delete new filters if cancel chosen */
265     if (is_new_filter)
266     {
267         g_object_set_data(G_OBJECT(edit_color_filter_cancel), COLOR_FILTERS_CL, color_filters);
268         g_signal_connect(edit_color_filter_cancel, "clicked",
269                        G_CALLBACK(edit_new_color_filter_cancel_cb), edit_dialog);
270     }
271     /* escape will select cancel */
272     window_set_cancel_button(edit_dialog, edit_color_filter_cancel, window_cancel_button_cb);
273
274     g_signal_connect(edit_dialog, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
275
276     gtk_widget_show_all(edit_dialog);
277     window_present(edit_dialog);
278 }
279
280 /* Called when the dialog box is being destroyed; destroy any color
281    selection dialogs opened from this dialog, and null out the pointer
282    to this dialog. */
283 static void
284 edit_color_filter_destroy_cb(GObject *object, gpointer user_data _U_)
285 {
286   color_filter_t *colorf;
287   GtkWidget *color_sel;
288
289   colorf = (color_filter_t *)g_object_get_data(G_OBJECT(object), COLOR_FILTER);
290   colorf->edit_dialog = NULL;
291
292   /* Destroy any color selection dialogs this dialog had open. */
293   color_sel = (GtkWidget *)g_object_get_data(G_OBJECT(object), COLOR_SELECTION_FG);
294   if (color_sel != NULL)
295     window_destroy(color_sel);
296   color_sel = (GtkWidget *)g_object_get_data(G_OBJECT(object), COLOR_SELECTION_BG);
297   if (color_sel != NULL)
298     window_destroy(color_sel);
299 }
300
301 /* Pop up a color selection box to choose the foreground color. */
302 static void
303 edit_color_filter_fg_cb(GtkButton *button, gpointer user_data _U_)
304 {
305   color_filter_t *colorf;
306   GtkWidget *color_selection_fg;
307
308   colorf = (color_filter_t *)g_object_get_data(G_OBJECT(button), COLOR_FILTER);
309   /* Do we already have one open for this dialog? */
310   color_selection_fg = g_object_get_data(G_OBJECT(colorf->edit_dialog), COLOR_SELECTION_FG);
311   if (color_selection_fg != NULL) {
312     /* Yes.  Just reactivate it. */
313     reactivate_window(color_selection_fg);
314   } else {
315     /* No.  Create a new color selection box, and associate it with
316        this dialog. */
317     color_selection_fg = color_sel_win_new(colorf, FALSE);
318     g_object_set_data(G_OBJECT(colorf->edit_dialog), COLOR_SELECTION_FG, color_selection_fg);
319     g_object_set_data(G_OBJECT(color_selection_fg), COLOR_SELECTION_PARENT, colorf->edit_dialog);
320   }
321 }
322
323 /* Pop up a color selection box to choose the background color. */
324 static void
325 edit_color_filter_bg_cb                (GtkButton       *button,
326                                         gpointer         user_data _U_)
327 {
328   color_filter_t *colorf;
329   GtkWidget *color_selection_bg;
330
331   colorf = (color_filter_t *)g_object_get_data(G_OBJECT(button), COLOR_FILTER);
332   /* Do we already have one open for this dialog? */
333   color_selection_bg = g_object_get_data(G_OBJECT(colorf->edit_dialog), COLOR_SELECTION_BG);
334   if (color_selection_bg != NULL) {
335     /* Yes.  Just reactivate it. */
336     reactivate_window(color_selection_bg);
337   } else {
338     /* No.  Create a new color selection box, and associate it with
339        this dialog. */
340     color_selection_bg = color_sel_win_new(colorf, TRUE);
341     g_object_set_data(G_OBJECT(colorf->edit_dialog), COLOR_SELECTION_BG, color_selection_bg);
342     g_object_set_data(G_OBJECT(color_selection_bg), COLOR_SELECTION_PARENT, colorf->edit_dialog);
343   }
344 }
345
346 /* Toggle the disabled flag */
347 /*
348 static void
349 edit_disabled_cb_cb                    (GtkButton       *button,
350                                         gpointer         user_data _U_)
351 {
352   color_filter_t *colorf;
353
354   colorf = (color_filter_t *)g_object_get_data(G_OBJECT(button), COLOR_FILTER);
355   colorf->disabled = GTK_TOGGLE_BUTTON (button)->active;
356
357   printf("Colorfilter %s is now %s\n",colorf->filter_name,colorf->disabled?"disabled":"enabled");
358 }
359 */
360
361 /* accept color (and potential content) change */
362 static void
363 edit_color_filter_ok_cb                (GtkButton       *button,
364                                         gpointer         user_data)
365 {
366     GtkWidget      *dialog;
367     GtkStyle       *style;
368     GdkColor        new_fg_color;
369     GdkColor        new_bg_color;
370     gchar          *filter_name;
371     gchar          *filter_text;
372     gboolean        filter_disabled;
373     color_filter_t *colorf;
374     dfilter_t      *compiled_filter;
375     GtkWidget      *color_filters;
376     GtkTreeModel   *model;
377     GtkTreeIter     iter;
378     gchar           fg_str[14], bg_str[14];
379
380     dialog = (GtkWidget *)user_data;
381
382     style = gtk_widget_get_style(filt_name_entry);
383     new_bg_color = style->base[GTK_STATE_NORMAL];
384     new_fg_color = style->text[GTK_STATE_NORMAL];
385
386     filter_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(filt_name_entry)));
387     filter_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(filt_text_entry)));
388     filter_disabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(disabled_cb));
389
390     if(strchr(filter_name,'@') || strchr(filter_text,'@')){
391         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
392                       "Filter names and strings must not"
393                       " use the '@' character. Filter unchanged.");
394         g_free(filter_name);
395         g_free(filter_text);
396         return;
397     }
398
399     if(!dfilter_compile(filter_text, &compiled_filter)) {
400         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
401                       "Filter \"%s\" didn't compile correctly.\n"
402                       " Please try again. Filter unchanged.\n%s\n", filter_name,
403                       dfilter_error_msg);
404     } else {
405         color_filters = (GtkWidget *)g_object_get_data(G_OBJECT(button), COLOR_FILTERS_CL);
406         colorf = (color_filter_t *)g_object_get_data(G_OBJECT(button), COLOR_FILTER);
407
408         g_free(colorf->filter_name);
409         colorf->filter_name = filter_name;
410
411         g_free(colorf->filter_text);
412         colorf->filter_text = filter_text;
413
414         colorf->disabled = filter_disabled;
415         gdkcolor_to_color_t(&colorf->fg_color, &new_fg_color);
416         gdkcolor_to_color_t(&colorf->bg_color, &new_bg_color);
417         g_snprintf(fg_str, sizeof(fg_str), "#%04X%04X%04X",
418                 new_fg_color.red, new_fg_color.green, new_fg_color.blue);
419         g_snprintf(bg_str, sizeof(bg_str), "#%04X%04X%04X",
420                 new_bg_color.red, new_bg_color.green, new_bg_color.blue);
421         model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
422         gtk_tree_model_iter_nth_child(model, &iter, NULL, row_selected);
423         gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, filter_name,
424                            1, filter_text, 2, fg_str, 3, bg_str,
425                            4, filter_disabled, -1);
426         if(colorf->c_colorfilter != NULL)
427             dfilter_free(colorf->c_colorfilter);
428         colorf->c_colorfilter = compiled_filter;
429
430         /* Destroy the dialog box. */
431         window_destroy(dialog);
432     }
433 }
434
435 /* reject new color filter addition */
436 static void
437 edit_new_color_filter_cancel_cb(GtkButton *button, gpointer user_data _U_)
438 {
439     /* Delete the entry. As a side effect this destroys the edit_dialog window. */
440     color_delete_single(num_of_filters-1, (GtkWidget*)g_object_get_data(G_OBJECT(button), COLOR_FILTERS_CL));
441 }
442
443 static GtkWidget*
444 color_sel_win_new(color_filter_t *colorf, gboolean is_bg)
445 {
446   gchar *title;
447   GtkWidget *color_sel_win;
448   color_t   *color;
449   GdkColor   gcolor;
450   GtkWidget *color_sel_ok;
451   GtkWidget *color_sel_cancel;
452   GtkWidget *color_sel_help;
453
454   if (is_bg) {
455     color = &colorf->bg_color;
456     title = g_strdup_printf("Wireshark: Choose background color for \"%s\"",
457         colorf->filter_name);
458   } else {
459     color = &colorf->fg_color;
460     title = g_strdup_printf("Wireshark: Choose foreground color for \"%s\"",
461         colorf->filter_name);
462   }
463   color_sel_win = gtk_color_selection_dialog_new(title);
464   g_free(title);
465   g_object_set_data(G_OBJECT(color_sel_win), "color_sel_win", color_sel_win);
466   gtk_container_set_border_width (GTK_CONTAINER (color_sel_win), 10);
467
468   if (color != NULL) {
469     color_t_to_gdkcolor(&gcolor, color);
470     gtk_color_selection_set_current_color(
471                     GTK_COLOR_SELECTION(
472                             GTK_COLOR_SELECTION_DIALOG(color_sel_win)->colorsel), &gcolor);
473   }
474
475   color_sel_ok = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->ok_button;
476   g_object_set_data(G_OBJECT(color_sel_win), "color_sel_ok", color_sel_ok);
477   GTK_WIDGET_SET_FLAGS (color_sel_ok, GTK_CAN_DEFAULT);
478
479   color_sel_cancel = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->cancel_button;
480   g_object_set_data(G_OBJECT(color_sel_win), "color_sel_cancel", color_sel_cancel);
481   GTK_WIDGET_SET_FLAGS (color_sel_cancel, GTK_CAN_DEFAULT);
482   window_set_cancel_button(color_sel_win, color_sel_cancel, NULL); /* ensure esc does req'd local cxl action.    */
483                                                                    /* esc as handled by the                      */
484                                                                    /* gtk_color_selection_dialog widget          */
485                                                                    /*  doesn't result in this happening.         */
486
487   color_sel_help = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->help_button;
488   g_object_set_data(G_OBJECT(color_sel_win), "color_sel_help", color_sel_help);
489
490
491   GTK_WIDGET_SET_FLAGS (color_sel_help, GTK_CAN_DEFAULT);
492
493   g_signal_connect(color_sel_ok, "clicked", G_CALLBACK(color_sel_ok_cb), color_sel_win);
494   g_signal_connect(color_sel_cancel, "clicked", G_CALLBACK(color_sel_cancel_cb), color_sel_win);
495
496   gtk_widget_show_all(color_sel_win);
497   return color_sel_win;
498 }
499
500 static void
501 color_sel_win_destroy(GtkWidget *sel_win)
502 {
503   GtkWidget *parent;
504   GtkWidget *color_selection_fg, *color_selection_bg;
505
506   /* Find the "Edit color filter" dialog box with which this is associated. */
507   parent = (GtkWidget *)g_object_get_data(G_OBJECT(sel_win), COLOR_SELECTION_PARENT);
508
509   /* Find that dialog box's foreground and background color selection
510      boxes, if any. */
511   color_selection_fg = g_object_get_data(G_OBJECT(parent), COLOR_SELECTION_FG);
512   color_selection_bg = g_object_get_data(G_OBJECT(parent), COLOR_SELECTION_BG);
513
514   if (sel_win == color_selection_fg) {
515     /* This was its foreground color selection box; it isn't, anymore. */
516     g_object_set_data(G_OBJECT(parent), COLOR_SELECTION_FG, NULL);
517   }
518   if (sel_win == color_selection_bg) {
519     /* This was its background color selection box; it isn't, anymore. */
520     g_object_set_data(G_OBJECT(parent), COLOR_SELECTION_BG, NULL);
521   }
522
523   /* Now destroy it. */
524   window_destroy(sel_win);
525 }
526
527 /* Retrieve selected color */
528 static void
529 color_sel_ok_cb                        (GtkButton       *button _U_,
530                                         gpointer         user_data)
531 {
532   GdkColor new_color; /* Color from color selection dialog */
533   GtkWidget *color_dialog;
534   GtkWidget *parent;
535   GtkWidget *color_selection_bg;
536   gboolean is_bg;
537
538   color_dialog = (GtkWidget *)user_data;
539
540   gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(
541    GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel), &new_color);
542
543   if ( ! get_color(&new_color) ){
544         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
545                       "Could not allocate color.  Try again.");
546   } else {
547         /* Find the "Edit color filter" dialog box with which this is
548            associated. */
549         parent = (GtkWidget *)g_object_get_data(G_OBJECT(color_dialog), COLOR_SELECTION_PARENT);
550
551         /* Find that dialog box's foreground and background color selection
552            boxes, if any. */
553         color_selection_bg = g_object_get_data(G_OBJECT(parent), COLOR_SELECTION_BG);
554         is_bg = (color_dialog == color_selection_bg);
555
556         color_sel_win_destroy(color_dialog);
557
558         /* now apply the change to the fore/background */
559         if (is_bg)
560           gtk_widget_modify_base(filt_name_entry, GTK_STATE_NORMAL, &new_color);
561         else
562           gtk_widget_modify_text(filt_name_entry, GTK_STATE_NORMAL, &new_color);
563   }
564 }
565
566 /* Don't choose the selected color as the foreground or background
567    color for the filter. */
568 static void
569 color_sel_cancel_cb                    (GtkObject       *object _U_,
570                                         gpointer         user_data)
571 {
572   GtkWidget *color_dialog;
573   color_dialog = (GtkWidget *)user_data;
574   /* nothing to change here.  Just get rid of the dialog box. */
575
576   color_sel_win_destroy(color_dialog);
577 }