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