In newer versions of GTK+ 2.x, if you have the mouse positioned above a
[obnox/wireshark/wip.git] / gtk / color_dlg.c
1 /* color_dlg.c
2  * Definitions for dialog boxes for color filters
3  *
4  * $Id$
5  *
6  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <gtk/gtk.h>
30
31 #include <string.h>
32
33 #include "gtk/main.h"
34 #include <epan/packet.h>
35 #include "color.h"
36 #include "colors.h"
37 #include "color_filters.h"
38 #include "color_dlg.h"
39 #include "file.h"
40 #include <epan/dfilter/dfilter.h>
41 #include "simple_dialog.h"
42 #include "dlg_utils.h"
43 #include "gui_utils.h"
44 #include "dfilter_expr_dlg.h"
45 #include "compat_macros.h"
46 #include "filter_dlg.h"
47 #include "capture_file_dlg.h"
48 #include "gtkglobals.h"
49 #include <epan/prefs.h>
50 #include "help_dlg.h"
51
52 #include "color_edit_dlg.h"
53
54 #if GTK_MAJOR_VERSION >= 2
55 #define BUTTON_SIZE_X -1
56 #define BUTTON_SIZE_Y -1
57 #else
58 #define BUTTON_SIZE_X 50
59 #define BUTTON_SIZE_Y 20
60 #endif
61
62
63 static GtkWidget* colorize_dialog_new(char *filter);
64 static void add_filter_to_list(gpointer filter_arg, gpointer list_arg);
65 static void color_filter_up_cb(GtkButton *button, gpointer user_data);
66 static void color_filter_down_cb(GtkButton *button, gpointer user_data);
67 #if GTK_MAJOR_VERSION < 2
68 static void remember_selected_row(GtkCList *clist, gint row, gint column,
69                                   GdkEvent *event, gpointer user_data);
70 static void unremember_selected_row(GtkCList *clist, gint row, gint column,
71                                     GdkEvent *event, gpointer user_data);
72 #else
73 static void remember_selected_row(GtkTreeSelection *sel, gpointer list);
74 #endif
75 static void color_destroy_cb(GtkButton *button, gpointer user_data);
76 static void destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy);
77 static void create_new_color_filter(GtkButton *button, const char *filter);
78 static void color_new_cb(GtkButton *button, gpointer user_data);
79 static void color_edit_cb(GtkButton *button, gpointer user_data);
80 static void color_delete_cb(GtkWidget *widget, gpointer user_data);
81 static void color_save_cb(GtkButton *button, gpointer user_data);
82 static void color_ok_cb(GtkButton *button, gpointer user_data);
83 static void color_cancel_cb(GtkWidget *widget, gpointer user_data);
84 static void color_apply_cb(GtkButton *button, gpointer user_data);
85 static void color_clear_cb(GtkWidget *button, gpointer user_data);
86 static void color_export_cb(GtkButton *button, gpointer user_data );
87 static void color_import_cb(GtkButton *button, gpointer user_data );
88
89
90 static GtkWidget *colorize_win;
91 gint      num_of_filters;  /* number of filters being displayed */
92 gint      row_selected;    /* row in color_filters that is selected */
93 #if GTK_MAJOR_VERSION >= 2
94 gboolean  row_is_moving = FALSE;
95 #endif
96
97 /* This is a list of all current color filters in the dialog
98  * (copied from color_filters.c and edited with the dialog).
99  * The color filter items are not identical to the ones used for the
100  * packet list display, so they can be safely edited.
101  *
102  * XXX - use the existing GTK list for this purpose and build temporary copies
103  * e.g. for the save/export functions.
104  * Problem: Don't know when able to safely throw away, e.g. while exporting.
105  */
106 static GSList *color_filter_edit_list = NULL;
107
108
109 #define COLOR_UP_LB             "color_up_lb"
110 #define COLOR_DOWN_LB           "color_down_lb"
111 #define COLOR_EDIT_LB           "color_edit_lb"
112 #define COLOR_DELETE_LB         "color_delete_lb"
113 #define COLOR_FILTERS_CL        "color_filters_cl"
114 #define COLOR_FILTER_LIST       "color_filter_list"
115
116
117 /* Callback for the "Display:Coloring Rules" menu item. */
118 void
119 color_display_cb(GtkWidget *w _U_, gpointer d _U_)
120 {
121   if (colorize_win != NULL) {
122     /* There's already a color dialog box active; reactivate it. */
123     reactivate_window(colorize_win);
124   } else {
125     /* Create a new "Colorize Display" dialog. */
126     colorize_win = colorize_dialog_new(NULL);
127   }
128 }
129
130 /* this opens the color dialog and presets the filter string */
131 void
132 color_display_with_filter(char *filter)
133 {
134   if (colorize_win != NULL) {
135     /* There's already a color dialog box active; reactivate it. */
136     reactivate_window(colorize_win);
137   } else {
138     /* Create a new "Colorize Display" dialog. */
139     colorize_win = colorize_dialog_new(filter);
140   }
141 }
142
143 /* if this filter is selected - count it in the given int* */
144 static void
145 count_this_select(gpointer filter_arg, gpointer counter_arg)
146 {
147   color_filter_t *colorf = filter_arg;
148   int * cnt = counter_arg;
149
150   if (colorf->selected)
151     (*cnt)++;
152 }
153
154 /* TODO: implement count of selected filters. Plug in to file_dlg update of "export selected" checkbox. */
155 int color_selected_count(void)
156 {
157   int count = 0;
158
159   g_slist_foreach(color_filter_edit_list, count_this_select, &count);
160
161   return count;
162 }
163
164 /* Create the "Coloring Rules" dialog. */
165 static GtkWidget*
166 colorize_dialog_new (char *filter)
167 {
168   GtkWidget *color_win;
169   GtkWidget *dlg_vbox;
170   GtkWidget *main_hbox;
171   GtkWidget *ctrl_vbox;
172   GtkTooltips *tooltips;
173
174   GtkWidget *order_fr;
175   GtkWidget *order_vbox;
176   GtkWidget *color_filter_up;
177   GtkWidget *order_move_label;
178   GtkWidget *color_filter_down;
179
180   GtkWidget *list_fr;
181   GtkWidget *list_vbox;
182   GtkWidget *scrolledwindow1;
183   GtkWidget *color_filters;
184   GtkWidget *list_label;
185
186   GtkWidget *edit_fr;
187   GtkWidget *edit_vbox;
188   GtkWidget *color_new;
189   GtkWidget *color_edit;
190   GtkWidget *color_delete;
191
192   GtkWidget *manage_fr;
193   GtkWidget *manage_vbox;
194   GtkWidget *color_export;
195   GtkWidget *color_import;
196   GtkWidget *color_clear;
197
198   GtkWidget *button_ok_hbox;
199   GtkWidget *color_ok;
200   GtkWidget *color_apply;
201   GtkWidget *color_save;
202   GtkWidget *color_cancel;
203   GtkWidget *color_help;
204
205 #if GTK_MAJOR_VERSION >= 2
206   GtkListStore      *store;
207   GtkCellRenderer   *renderer;
208   GtkTreeViewColumn *column;
209   GtkTreeSelection  *selection;
210 #endif
211   const gchar *titles[] = { "Name", "String" };
212
213
214
215   num_of_filters = 0;
216   row_selected = -1; /* no row selected */
217   tooltips = gtk_tooltips_new ();
218
219   /* Resizing of the dialog window is now reasonably done.
220    * Default size is set so that it should fit into every usual screen resolution.
221    * All other widgets are always packed depending on the current window size. */
222   color_win = dlg_window_new ("Wireshark: Coloring Rules");
223   OBJECT_SET_DATA(color_win, "color_win", color_win);
224   gtk_window_set_default_size(GTK_WINDOW(color_win), DEF_WIDTH, DEF_HEIGHT * 2/3);
225   dlg_vbox = gtk_vbox_new (FALSE, 0);
226   gtk_container_set_border_width  (GTK_CONTAINER (dlg_vbox), 5);
227   gtk_container_add (GTK_CONTAINER (color_win), dlg_vbox);
228
229   main_hbox = gtk_hbox_new (FALSE, 0);
230   gtk_box_pack_start (GTK_BOX (dlg_vbox), main_hbox, TRUE, TRUE, 0);
231
232   ctrl_vbox = gtk_vbox_new (FALSE, 0);
233   gtk_box_pack_start (GTK_BOX (main_hbox), ctrl_vbox, FALSE, FALSE, 0);
234
235   /* edit buttons frame */
236   edit_fr = gtk_frame_new("Edit");
237   gtk_box_pack_start (GTK_BOX (ctrl_vbox), edit_fr, TRUE, TRUE, 0);
238
239   /* edit_vbox is first button column (containing: new, edit and such) */
240   edit_vbox = gtk_vbutton_box_new();
241   gtk_button_box_set_child_size(GTK_BUTTON_BOX(edit_vbox), BUTTON_SIZE_X, BUTTON_SIZE_Y);
242   gtk_container_set_border_width  (GTK_CONTAINER (edit_vbox), 5);
243   gtk_container_add(GTK_CONTAINER(edit_fr), edit_vbox);
244
245   color_new = BUTTON_NEW_FROM_STOCK(GTK_STOCK_NEW);
246 #if GTK_MAJOR_VERSION < 2
247   WIDGET_SET_SIZE(color_new, BUTTON_SIZE_X, BUTTON_SIZE_Y);
248 #endif
249   gtk_box_pack_start (GTK_BOX (edit_vbox), color_new, FALSE, FALSE, 5);
250   gtk_tooltips_set_tip (tooltips, color_new, ("Create a new filter at the end of the list"), NULL);
251
252   color_edit = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_EDIT);
253 #if GTK_MAJOR_VERSION < 2
254   WIDGET_SET_SIZE(color_edit, BUTTON_SIZE_X, BUTTON_SIZE_Y);
255 #endif
256   gtk_box_pack_start (GTK_BOX (edit_vbox), color_edit, FALSE, FALSE, 5);
257   gtk_tooltips_set_tip (tooltips, color_edit, ("Edit the properties of the selected filter."
258       " If more than one filter is selected, edit the first selected one"), NULL);
259   gtk_widget_set_sensitive (color_edit, FALSE);
260
261   color_delete = BUTTON_NEW_FROM_STOCK(GTK_STOCK_DELETE);
262   gtk_box_pack_start (GTK_BOX (edit_vbox), color_delete, FALSE, FALSE, 5);
263 #if GTK_MAJOR_VERSION < 2
264   WIDGET_SET_SIZE(color_delete, BUTTON_SIZE_X, BUTTON_SIZE_Y);
265 #endif
266   gtk_tooltips_set_tip (tooltips, color_delete, ("Delete the selected filter(s)"), NULL);
267   gtk_widget_set_sensitive (color_delete, FALSE);
268   /* End edit buttons frame */
269
270
271   /* manage buttons frame */
272   manage_fr = gtk_frame_new("Manage");
273   gtk_box_pack_start (GTK_BOX (ctrl_vbox), manage_fr, FALSE, FALSE, 0);
274
275   manage_vbox = gtk_vbox_new (FALSE, 0);
276   gtk_container_set_border_width  (GTK_CONTAINER (manage_vbox), 5);
277   gtk_container_add(GTK_CONTAINER(manage_fr), manage_vbox);
278
279   color_export = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_EXPORT);
280   gtk_box_pack_start (GTK_BOX (manage_vbox), color_export, FALSE, FALSE, 5);
281 #if GTK_MAJOR_VERSION < 2
282   WIDGET_SET_SIZE(color_export, BUTTON_SIZE_X, BUTTON_SIZE_Y);
283 #endif
284   gtk_tooltips_set_tip(tooltips, color_export, ("Save all/selected filters to a file"), NULL);
285
286   color_import = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_IMPORT);
287   gtk_box_pack_start (GTK_BOX (manage_vbox), color_import, FALSE, FALSE, 5);
288 #if GTK_MAJOR_VERSION < 2
289   WIDGET_SET_SIZE(color_import, BUTTON_SIZE_X, BUTTON_SIZE_Y);
290 #endif
291   gtk_tooltips_set_tip(tooltips, color_import, ("Load filters from a file and append them to the list"), NULL);
292
293   color_clear = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLEAR);
294   gtk_box_pack_start(GTK_BOX (manage_vbox), color_clear, FALSE, FALSE, 5);
295 #if GTK_MAJOR_VERSION < 2
296   WIDGET_SET_SIZE(color_clear, BUTTON_SIZE_X, BUTTON_SIZE_Y);
297 #endif
298   gtk_tooltips_set_tip(tooltips, color_clear, ("Clear the filter list and revert to system-wide default filter set"), NULL);
299
300
301   /* filter list frame */
302   list_fr = gtk_frame_new("Filter");
303   gtk_box_pack_start (GTK_BOX (main_hbox), list_fr, TRUE, TRUE, 0);
304
305   list_vbox = gtk_vbox_new (FALSE, 0);
306   gtk_container_set_border_width  (GTK_CONTAINER (list_vbox), 5);
307   gtk_container_add(GTK_CONTAINER(list_fr), list_vbox);
308
309   list_label = gtk_label_new (("List is processed in order until match is found"));
310   gtk_box_pack_start (GTK_BOX (list_vbox), list_label, FALSE, FALSE, 0);
311
312   /* create the list of filters */
313   scrolledwindow1 = scrolled_window_new(NULL, NULL);
314 #if GTK_MAJOR_VERSION >= 2
315   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow1),
316                                    GTK_SHADOW_IN);
317 #endif
318   gtk_box_pack_start (GTK_BOX (list_vbox), scrolledwindow1, TRUE, TRUE, 0);
319
320 #if GTK_MAJOR_VERSION < 2
321   color_filters = gtk_clist_new_with_titles(2, (gchar **) titles);
322 #else
323   /* the list store contains : filter name, filter string, foreground
324    * color, background color, pointer to color filter */
325   store = gtk_list_store_new(5, G_TYPE_STRING, G_TYPE_STRING,
326                              G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
327   color_filters = tree_view_new(GTK_TREE_MODEL(store));
328   g_object_unref(store);
329   renderer = gtk_cell_renderer_text_new();
330   column = gtk_tree_view_column_new_with_attributes(titles[0], renderer, "text",
331                                                     0, "foreground", 2,
332                                                     "background", 3, NULL);
333   gtk_tree_view_column_set_fixed_width(column, 80);
334   gtk_tree_view_append_column(GTK_TREE_VIEW(color_filters), column);
335   renderer = gtk_cell_renderer_text_new();
336   column = gtk_tree_view_column_new_with_attributes(titles[1], renderer, "text",
337                                                     1, "foreground", 2,
338                                                     "background", 3, NULL);
339   gtk_tree_view_column_set_fixed_width(column, 300);
340   gtk_tree_view_append_column(GTK_TREE_VIEW(color_filters), column);
341   gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(color_filters), TRUE);
342   gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(color_filters), FALSE);
343 #endif
344
345 #if GTK_MAJOR_VERSION < 2
346   gtk_clist_set_selection_mode    (GTK_CLIST (color_filters),GTK_SELECTION_EXTENDED);
347 #else
348   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
349   gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
350 #endif
351
352   gtk_container_add (GTK_CONTAINER (scrolledwindow1), color_filters);
353 #if GTK_MAJOR_VERSION < 2
354   gtk_clist_set_column_width (GTK_CLIST (color_filters), 0, 80);
355   gtk_clist_set_column_width (GTK_CLIST (color_filters), 1, 300);
356   gtk_clist_column_titles_show (GTK_CLIST (color_filters));
357 #endif
358
359
360   /* order frame */
361   order_fr = gtk_frame_new("Order");
362   gtk_box_pack_start (GTK_BOX (main_hbox), order_fr, FALSE, FALSE, 0);
363
364   order_vbox = gtk_vbox_new (TRUE, 0);
365   gtk_container_set_border_width  (GTK_CONTAINER (order_vbox), 5);
366   gtk_container_add(GTK_CONTAINER(order_fr), order_vbox);
367
368   color_filter_up = BUTTON_NEW_FROM_STOCK(GTK_STOCK_GO_UP);
369 #if GTK_MAJOR_VERSION < 2
370   WIDGET_SET_SIZE(color_filter_up, BUTTON_SIZE_X, BUTTON_SIZE_Y);
371 #endif
372   gtk_box_pack_start (GTK_BOX (order_vbox), color_filter_up, FALSE, FALSE, 0);
373   gtk_tooltips_set_tip (tooltips, color_filter_up, ("Move filter higher in list"), NULL);
374   gtk_widget_set_sensitive (color_filter_up, FALSE);
375
376   order_move_label = gtk_label_new (("Move\nselected filter\nup or down"));
377   gtk_box_pack_start (GTK_BOX (order_vbox), order_move_label, FALSE, FALSE, 0);
378
379   color_filter_down = BUTTON_NEW_FROM_STOCK(GTK_STOCK_GO_DOWN);
380 #if GTK_MAJOR_VERSION < 2
381   WIDGET_SET_SIZE(color_filter_down, BUTTON_SIZE_X, BUTTON_SIZE_Y);
382 #endif
383   gtk_box_pack_start (GTK_BOX (order_vbox), color_filter_down, FALSE, FALSE, 0);
384   gtk_tooltips_set_tip (tooltips, color_filter_down, ("Move filter lower in list"), NULL);
385   gtk_widget_set_sensitive (color_filter_down, FALSE);
386
387
388   /* Button row: OK and cancel buttons */
389   if(topic_available(HELP_COLORING_RULES_DIALOG)) {
390     button_ok_hbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
391   } else {
392     button_ok_hbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CANCEL, NULL);
393   }
394   gtk_box_pack_start (GTK_BOX (dlg_vbox), button_ok_hbox, FALSE, FALSE, 5);
395
396   color_ok = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_OK);
397   gtk_tooltips_set_tip (tooltips, color_ok, ("Apply the color filters to the display and close this dialog"), NULL);
398
399   color_apply = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_APPLY);
400   gtk_tooltips_set_tip (tooltips, color_apply, ("Apply the color filters to the display and keep this dialog open"), NULL);
401
402   color_save = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_SAVE);
403   gtk_tooltips_set_tip (tooltips, color_save, ("Save the color filters permanently and keep this dialog open"), NULL);
404
405   color_cancel = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_CANCEL);
406   window_set_cancel_button(color_win, color_cancel, color_cancel_cb);
407   gtk_tooltips_set_tip (tooltips, color_cancel, ("Cancel changes done (since last \"Apply\") and close this dialog"), NULL);
408
409   if(topic_available(HELP_COLORING_RULES_DIALOG)) {
410       color_help = OBJECT_GET_DATA(button_ok_hbox, GTK_STOCK_HELP);
411       gtk_tooltips_set_tip (tooltips, color_help, ("Get help about this dialog"), NULL);
412       SIGNAL_CONNECT(color_help, "clicked", topic_cb, HELP_COLORING_RULES_DIALOG);
413   }
414
415   gtk_widget_grab_default(color_ok);
416
417   /* signals and such */
418   SIGNAL_CONNECT(color_win, "destroy", color_destroy_cb, NULL);
419   OBJECT_SET_DATA(color_filter_up, COLOR_FILTERS_CL, color_filters);
420   SIGNAL_CONNECT(color_filter_up, "clicked", color_filter_up_cb, NULL);
421   OBJECT_SET_DATA(color_filter_down, COLOR_FILTERS_CL, color_filters);
422   SIGNAL_CONNECT(color_filter_down, "clicked", color_filter_down_cb, NULL);
423 #if GTK_MAJOR_VERSION < 2
424   SIGNAL_CONNECT(color_filters, "select_row", remember_selected_row, NULL);
425   SIGNAL_CONNECT(color_filters, "unselect_row", unremember_selected_row, NULL);
426 #else
427   SIGNAL_CONNECT(selection, "changed", remember_selected_row, color_filters);
428 #endif
429   OBJECT_SET_DATA(color_filters, COLOR_UP_LB, color_filter_up);
430   OBJECT_SET_DATA(color_filters, COLOR_DOWN_LB, color_filter_down);
431   OBJECT_SET_DATA(color_filters, COLOR_EDIT_LB, color_edit);
432   OBJECT_SET_DATA(color_filters, COLOR_DELETE_LB, color_delete);
433   OBJECT_SET_DATA(color_new, COLOR_FILTERS_CL, color_filters);
434   SIGNAL_CONNECT(color_new, "clicked", color_new_cb, NULL);
435   OBJECT_SET_DATA(color_edit, COLOR_FILTERS_CL, color_filters);
436   SIGNAL_CONNECT(color_edit, "clicked", color_edit_cb, NULL);
437   OBJECT_SET_DATA(color_delete, COLOR_EDIT_LB, color_edit);
438   OBJECT_SET_DATA(color_delete, COLOR_FILTERS_CL, color_filters);
439   SIGNAL_CONNECT(color_delete, "clicked", color_delete_cb, NULL);
440   SIGNAL_CONNECT(color_export, "clicked", color_export_cb, NULL);
441   OBJECT_SET_DATA(color_import, COLOR_FILTERS_CL, color_filters);
442   SIGNAL_CONNECT(color_import, "clicked", color_import_cb, NULL);
443   OBJECT_SET_DATA(color_clear, COLOR_FILTERS_CL, color_filters);
444   SIGNAL_CONNECT(color_clear, "clicked", color_clear_cb, NULL);
445   SIGNAL_CONNECT(color_ok, "clicked", color_ok_cb, NULL);
446   SIGNAL_CONNECT(color_apply, "clicked", color_apply_cb, NULL);
447   SIGNAL_CONNECT(color_save, "clicked", color_save_cb, NULL);
448
449   SIGNAL_CONNECT(color_win, "delete_event", window_delete_event_cb, NULL);
450
451   gtk_widget_grab_focus(color_filters);
452
453   /* prepare filter list content */
454   color_filters_clone(color_filters);
455   OBJECT_SET_DATA(color_win, COLOR_FILTER_LIST, &color_filter_edit_list);
456
457   gtk_widget_show_all(color_win);
458
459   /* hide the Save button if the user uses implicit save */
460   if(!prefs.gui_use_pref_save) {
461     gtk_widget_hide(color_save);
462   }
463
464   window_present(color_win);
465
466   if(filter){
467     /* if we specified a preset filter string, open the new dialog and
468        set the filter */
469     create_new_color_filter(GTK_BUTTON(color_new), filter);
470   }
471
472   return color_win;
473 }
474
475 /* move a row in the list +/- one position up/down */
476 static void move_this_row (GtkWidget   *color_filters,
477                      gint         filter_number,
478                      gint         amount)            /* only tested with +1(down) and -1(up) */
479 {
480   color_filter_t *colorf;
481 #if GTK_MAJOR_VERSION < 2
482   gint            lower, higher;
483 #else
484   GtkTreeModel   *model;
485   GtkTreeIter     iter1, iter2;
486   gchar          *name, *string, *fg_str, *bg_str;
487 #endif
488
489   g_assert(amount == +1 || amount == -1);
490   g_assert(amount == +1 || filter_number > 0);
491   g_assert(amount == -1 || filter_number < num_of_filters - 1);
492
493 #if GTK_MAJOR_VERSION < 2
494   if (amount > 0)
495   {
496     lower = filter_number;
497     higher = filter_number + amount;
498   }
499   else
500   {
501     higher = filter_number;
502     lower = filter_number + amount;
503   }
504
505   colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
506   gtk_clist_swap_rows(GTK_CLIST(color_filters), higher, lower);
507
508   /*
509    * That row is still selected, but it's now moved.
510    */
511   remember_selected_row(GTK_CLIST(color_filters), filter_number + amount, 0, NULL, NULL);
512 #else
513
514   row_is_moving = TRUE;
515   model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
516   gtk_tree_model_iter_nth_child(model, &iter1, NULL, filter_number);
517   gtk_tree_model_iter_nth_child(model, &iter2, NULL, filter_number + amount);
518
519   gtk_tree_model_get(model, &iter1, 0, &name, 1, &string,
520                      2, &fg_str, 3, &bg_str, 4, &colorf, -1);
521   gtk_list_store_remove(GTK_LIST_STORE(model), &iter1);
522   if (amount < 0)
523     gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter1, &iter2);
524   else
525     gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter1, &iter2);
526   gtk_list_store_set(GTK_LIST_STORE(model), &iter1, 0, name, 1, string,
527                      2, fg_str, 3, bg_str, 4, colorf, -1);
528   g_free(name);
529   g_free(string);
530   g_free(fg_str);
531   g_free(bg_str);
532   row_is_moving = FALSE;
533
534   /*
535    * re-select the initial row
536    */
537   gtk_widget_grab_focus(color_filters);
538   gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters)), &iter1);
539
540 #endif
541
542   color_filter_edit_list = g_slist_remove(color_filter_edit_list, colorf);
543   color_filter_edit_list = g_slist_insert(color_filter_edit_list, colorf, filter_number + amount);
544 }
545
546 /* User pressed the "Up" button: Move the selected filters up in the list */
547 static void
548 color_filter_up_cb(GtkButton *button, gpointer user_data _U_)
549 {
550   gint amount;
551   gint filter_number;
552   GtkWidget * color_filters;
553   color_filter_t *colorf;
554 #if GTK_MAJOR_VERSION < 2
555 #else
556   GtkTreeIter       iter;
557   GtkTreeModel     *model;
558   GtkTreeSelection *sel;
559 #endif
560
561   amount = -1;
562   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
563
564 #if GTK_MAJOR_VERSION < 2
565   colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), 0);
566   if (colorf->selected)
567     return;
568 #endif
569
570   for (filter_number = 0; filter_number < num_of_filters; filter_number++)
571   {
572 #if GTK_MAJOR_VERSION < 2
573     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
574     if (colorf->selected)
575       move_this_row (color_filters, filter_number, amount);
576 #else
577     model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
578     gtk_tree_model_iter_nth_child(model, &iter, NULL, filter_number);
579     gtk_tree_model_get(model, &iter, 4, &colorf, -1);
580     sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
581     if (gtk_tree_selection_iter_is_selected(sel, &iter))
582       move_this_row (color_filters, filter_number, amount);
583 #endif
584   }
585 }
586
587 /* User pressed the "Down" button: Move the selected filters down in the list */
588 static void
589 color_filter_down_cb(GtkButton *button, gpointer user_data _U_)
590 {
591   gint amount;
592   gint filter_number;
593   GtkWidget * color_filters;
594   color_filter_t *colorf;
595 #if GTK_MAJOR_VERSION < 2
596 #else
597   GtkTreeIter     iter;
598   GtkTreeModel   *model;
599 #endif
600
601   amount = +1;
602   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
603
604 #if GTK_MAJOR_VERSION < 2
605     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), num_of_filters - 1);
606     if (colorf->selected)
607       return;
608 #endif
609
610   for (filter_number = num_of_filters - 1; filter_number >= 0; filter_number--)
611   {
612 #if GTK_MAJOR_VERSION < 2
613     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), filter_number);
614 #else
615     model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
616     gtk_tree_model_iter_nth_child(model, &iter, NULL, filter_number);
617     gtk_tree_model_get(model, &iter, 4, &colorf, -1);
618 #endif
619     if (colorf->selected)
620       move_this_row (color_filters, filter_number, amount);
621   }
622 }
623
624 /* A row was selected; remember its row number */
625 #if GTK_MAJOR_VERSION < 2
626 static void
627 remember_selected_row(GtkCList *clist, gint row, gint column _U_,
628                       GdkEvent *event _U_, gpointer user_data _U_)
629 {
630     GtkWidget    *button;
631     color_filter_t *colorf;
632
633     row_selected = row;
634
635     colorf = gtk_clist_get_row_data(clist, row);
636     colorf->selected = TRUE;
637
638     /*
639      * A row is selected, so we can move it up *if* it's not at the top
640      * and move it down *if* it's not at the bottom.
641      */
642     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_UP_LB);
643     gtk_widget_set_sensitive (button, row > 0);
644     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DOWN_LB);
645     gtk_widget_set_sensitive(button, row < num_of_filters - 1);
646
647     /*
648      * A row is selected, so we can operate on it.
649      */
650     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_EDIT_LB);
651     gtk_widget_set_sensitive (button, TRUE);
652     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DELETE_LB);
653     gtk_widget_set_sensitive(button, TRUE);
654
655 }
656 #else
657
658 struct remember_data
659 {
660     gint count;               /* count of selected filters */
661     gboolean first_selected;  /* true if the first filter in the list is selected */
662     gboolean last_selected;   /* true if the last filter in the list is selected */
663     gpointer color_filters;
664 };
665 /* called for each selected row in the tree.
666 */
667 static void remember_this_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer arg)
668 {
669     gint         *path_index;
670     color_filter_t *colorf;
671     struct remember_data *data = arg;
672
673     gtk_tree_model_get(model, iter, 4, &colorf, -1);
674     colorf->selected = TRUE;
675
676     path_index = gtk_tree_path_get_indices(path);   /* not to be freed */
677     if (path_index == NULL)       /* can return NULL according to API doc.*/
678     {
679       return;
680     }
681     row_selected = path_index[0];
682
683     if (row_selected == 0)
684       data->first_selected = TRUE;
685     if (row_selected == num_of_filters - 1)
686       data->last_selected = TRUE;
687
688     data->count++;
689
690     gtk_tree_view_scroll_to_cell(data->color_filters, path, NULL, FALSE, 0.0, 0.0);
691 }
692
693 /* clear the selection flag of this filter */
694 static void
695 clear_select_flag(gpointer filter_arg, gpointer arg _U_)
696 {
697   color_filter_t *colorf = filter_arg;
698
699   colorf->selected = FALSE;
700 }
701
702 /* The gtk+2.0 version gets called for, (maybe multiple,) changes in the selection. */
703 static void
704 remember_selected_row(GtkTreeSelection *sel, gpointer color_filters)
705 {
706     GtkWidget    *button;
707     struct remember_data data;
708
709     data.first_selected = data.last_selected = FALSE;
710     data.count = 0;
711     data.color_filters = color_filters;
712
713     g_slist_foreach(color_filter_edit_list, clear_select_flag, NULL);
714     gtk_tree_selection_selected_foreach(sel,remember_this_row, &data);
715
716     if (data.count > 0)
717     {
718       /*
719        * One or more rows are selected, so we can operate on them.
720       */
721
722       /* We can only edit if there is exactly one filter selected */
723       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_EDIT_LB);
724       gtk_widget_set_sensitive (button, data.count == 1);
725
726       /* We can delete any number of filters */
727       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DELETE_LB);
728       gtk_widget_set_sensitive (button, TRUE);
729       /*
730        * We can move them up *if* one of them isn't the top row,
731        * and move them down *if* one of them isn't the bottom row.
732       */
733       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_UP_LB);
734       gtk_widget_set_sensitive(button, !data.first_selected);
735       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DOWN_LB);
736       gtk_widget_set_sensitive(button, !data.last_selected);
737     }
738     else
739     {
740       row_selected = -1;
741
742       /*
743        * No row is selected, so we can't do operations that affect the
744        * selected row.
745        */
746       if (!row_is_moving) {
747         button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_UP_LB);
748         gtk_widget_set_sensitive (button, FALSE);
749         button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DOWN_LB);
750         gtk_widget_set_sensitive (button, FALSE);
751       }
752       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_EDIT_LB);
753       gtk_widget_set_sensitive (button, FALSE);
754       button = (GtkWidget *)OBJECT_GET_DATA(color_filters, COLOR_DELETE_LB);
755       gtk_widget_set_sensitive (button, FALSE);
756     }
757 }
758 #endif
759
760 #if GTK_MAJOR_VERSION < 2
761 /* A row was unselected; un-remember its row number */
762 static void
763 unremember_selected_row                 (GtkCList        *clist,
764                                          gint             row _U_,
765                                          gint             column _U_,
766                                          GdkEvent        *event _U_,
767                                          gpointer         user_data _U_)
768 {
769   GtkWidget *button;
770   color_filter_t *colorf;
771
772   row_selected = -1;
773
774   colorf = gtk_clist_get_row_data(clist, row);
775   colorf->selected = FALSE;
776
777   if (color_selected_count() == 0)
778   {
779     /*
780      * No row is selected, so we can't do operations that affect the
781      * selected row.
782      */
783     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_UP_LB);
784     gtk_widget_set_sensitive (button, FALSE);
785     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DOWN_LB);
786     gtk_widget_set_sensitive (button, FALSE);
787     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_EDIT_LB);
788     gtk_widget_set_sensitive (button, FALSE);
789     button = (GtkWidget *)OBJECT_GET_DATA(clist, COLOR_DELETE_LB);
790     gtk_widget_set_sensitive(button, FALSE);
791   }
792 }
793 #endif
794
795
796
797 /* destroy a single color edit dialog */
798 static void
799 destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy _U_)
800 {
801   color_filter_t *colorf = (color_filter_t *)filter_arg;
802
803   if (colorf->edit_dialog != NULL)
804     window_destroy(colorf->edit_dialog);
805 }
806
807 /* Called when the dialog box is being destroyed; destroy any edit
808  * dialogs opened from this dialog.
809  */
810 static void
811 color_destroy_cb                       (GtkButton       *button _U_,
812                                         gpointer         user_data _U_)
813 {
814   /* Destroy any edit dialogs we have open. */
815   g_slist_foreach(color_filter_edit_list, destroy_edit_dialog_cb, NULL);
816
817   /* destroy the filter list itself */
818   color_filter_list_delete(&color_filter_edit_list);
819
820   colorize_win = NULL;
821 }
822
823
824 static void
825 select_row(GtkWidget *color_filters, int row)
826 {
827 #if GTK_MAJOR_VERSION < 2
828 #else
829   GtkTreeModel     *model;
830   gint              num_filters;
831   GtkTreeIter       iter;
832   GtkTreeSelection *sel;
833 #endif
834
835 #if GTK_MAJOR_VERSION < 2
836   /* select the new row */
837   gtk_clist_select_row(GTK_CLIST(color_filters), row, -1);
838 #else
839   /* select the new row */
840   model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
841   num_filters = gtk_tree_model_iter_n_children(model, NULL);
842   gtk_tree_model_iter_nth_child(model, &iter, NULL, row);
843   sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
844   gtk_tree_selection_select_iter(sel, &iter);
845 #endif
846 }
847
848
849
850 /* add a single color filter to the list */
851 static void
852 add_filter_to_list(gpointer filter_arg, gpointer list_arg)
853 {
854   color_filter_t *colorf = filter_arg;
855 #if GTK_MAJOR_VERSION < 2
856   GtkWidget      *color_filters = list_arg;
857   gchar          *data[2];
858   gint            row;
859   GdkColor        bg, fg;
860
861   data[0] = colorf->filter_name;
862   data[1] = colorf->filter_text;
863   row = gtk_clist_append(GTK_CLIST(color_filters), data);
864   color_t_to_gdkcolor(&fg, &colorf->fg_color);
865   color_t_to_gdkcolor(&bg, &colorf->bg_color);
866   gtk_clist_set_row_data(GTK_CLIST(color_filters), row, colorf);
867   gtk_clist_set_foreground(GTK_CLIST(color_filters), row, &fg);
868   gtk_clist_set_background(GTK_CLIST(color_filters), row, &bg);
869 #else
870   gchar           fg_str[14], bg_str[14];
871   GtkListStore   *store;
872   GtkTreeIter     iter;
873
874   store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list_arg)));
875   gtk_list_store_append(store, &iter);
876   g_snprintf(fg_str, 14, "#%04X%04X%04X",
877           colorf->fg_color.red, colorf->fg_color.green, colorf->fg_color.blue);
878   g_snprintf(bg_str, 14, "#%04X%04X%04X",
879           colorf->bg_color.red, colorf->bg_color.green, colorf->bg_color.blue);
880   gtk_list_store_set(store, &iter, 0, colorf->filter_name,
881                      1, colorf->filter_text, 2, fg_str, 3, bg_str,
882                      4, colorf, -1);
883 #endif
884   color_filter_edit_list = g_slist_append(color_filter_edit_list, colorf);
885
886   num_of_filters++;
887 }
888
889
890 /* a new color filter was read in from a filter file */
891 void
892 color_filter_add_cb(color_filter_t *colorf, gpointer user_data)
893 {
894   GtkWidget        *color_filters = user_data;
895
896   add_filter_to_list(colorf, color_filters);
897
898 #if GTK_MAJOR_VERSION >= 2
899   gtk_widget_grab_focus(color_filters);
900 #endif
901 }
902
903 /* Create a new filter, add it to the list, and pop up an
904    "Edit color filter" dialog box to edit it. */
905 static void
906 create_new_color_filter(GtkButton *button, const char *filter)
907 {
908   color_filter_t   *colorf;
909   GtkStyle         *style;
910   color_t          bg_color, fg_color;
911   GtkWidget        *color_filters;
912 #if GTK_MAJOR_VERSION >= 2
913   GtkTreeSelection *sel;
914 #endif
915
916   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
917
918   /* unselect all filters */
919 #if GTK_MAJOR_VERSION >= 2
920   sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
921   gtk_tree_selection_unselect_all (sel);
922 #else
923   gtk_clist_unselect_all (GTK_CLIST(color_filters));
924 #endif
925
926   /* Use the default background and foreground colors as the colors. */
927   style = gtk_widget_get_style(packet_list);
928   gdkcolor_to_color_t(&bg_color, &style->base[GTK_STATE_NORMAL]);
929   gdkcolor_to_color_t(&fg_color, &style->text[GTK_STATE_NORMAL]);
930
931   colorf = color_filter_new("name", filter, &bg_color, &fg_color);
932
933   add_filter_to_list(colorf, color_filters);
934
935   select_row(color_filters, num_of_filters-1);
936
937   /* open the edit dialog */
938   edit_color_filter_dialog(color_filters, TRUE /* is a new filter */);
939
940 #if GTK_MAJOR_VERSION >= 2
941   gtk_widget_grab_focus(color_filters);
942 #endif
943 }
944
945 /* User pressed the "New" button: Create a new filter in the list,
946    and pop up an "Edit color filter" dialog box to edit it. */
947 static void
948 color_new_cb(GtkButton *button, gpointer user_data _U_)
949 {
950   create_new_color_filter(button, "filter");
951 }
952
953 /* User pressed the "Edit" button: Pop up an "Edit color filter" dialog box
954    to edit an existing filter. */
955 static void
956 color_edit_cb(GtkButton *button, gpointer user_data _U_)
957 {
958   GtkWidget *color_filters;
959
960   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
961   g_assert(row_selected != -1);
962   edit_color_filter_dialog(color_filters, FALSE /* is not a new filter */);
963 }
964
965 /* Delete a single color filter from the list and elsewhere. */
966 void
967 color_delete(gint row, GtkWidget *color_filters)
968 {
969     color_filter_t *colorf;
970
971 #if GTK_MAJOR_VERSION >= 2
972     GtkTreeModel     *model;
973     GtkTreeIter       iter;
974
975
976     model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
977     gtk_tree_model_iter_nth_child(model, &iter, NULL, row);
978     gtk_tree_model_get(model, &iter, 4, &colorf, -1);
979
980     /* Remove this color filter from the CList displaying the
981     color filters. */
982     gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
983     num_of_filters--;
984
985     /* Destroy any "Edit color filter" dialog boxes editing it. */
986     if (colorf->edit_dialog != NULL)
987     window_destroy(colorf->edit_dialog);
988
989     /* Delete the color filter from the list of color filters. */
990     color_filter_edit_list = g_slist_remove(color_filter_edit_list, colorf);
991     color_filter_delete(colorf);
992
993     /* If we grab the focus after updating the selection, the first
994     * row is always selected, so we do it before */
995     gtk_widget_grab_focus(color_filters);
996 #else
997     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row);
998
999     /* Remove this color filter from the CList displaying the
1000        color filters. */
1001     gtk_clist_remove(GTK_CLIST(color_filters), row);
1002     num_of_filters--;
1003
1004     /* Destroy any "Edit color filter" dialog boxes editing it. */
1005     if (colorf->edit_dialog != NULL)
1006         window_destroy(colorf->edit_dialog);
1007
1008     /* Delete the color filter from the list of color filters. */
1009     color_filter_edit_list = g_slist_remove(color_filter_edit_list, colorf);
1010     color_filter_delete(colorf);
1011 #endif
1012 }
1013
1014 /* User pressed the "Delete" button: Delete the selected filters from the list.*/
1015 static void
1016 color_delete_cb(GtkWidget *widget, gpointer user_data _U_)
1017 {
1018   GtkWidget  *color_filters;
1019   gint row, num_filters;
1020 #if GTK_MAJOR_VERSION < 2
1021   color_filter_t *colorf;
1022 #else
1023     GtkTreeModel     *model;
1024     GtkTreeIter       iter;
1025     GtkTreeSelection *sel;
1026 #endif
1027
1028   color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL);
1029
1030   /* get the number of filters in the list */
1031 #if GTK_MAJOR_VERSION < 2
1032   num_filters = num_of_filters;
1033 #else
1034   model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
1035   num_filters = gtk_tree_model_iter_n_children(model, NULL);
1036   sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
1037 #endif
1038
1039   /* iterate through the list and delete the selected ones */
1040   for (row = num_filters - 1; row >= 0; row--)
1041   {
1042 #if GTK_MAJOR_VERSION < 2
1043     colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row);
1044     if (colorf->selected)
1045       color_delete (row, color_filters);
1046 #else
1047     gtk_tree_model_iter_nth_child(model, &iter, NULL, row);
1048     if (gtk_tree_selection_iter_is_selected(sel, &iter))
1049       color_delete (row, color_filters);
1050 #endif
1051   }
1052 }
1053
1054 /* User pressed "Export": Pop up an "Export color filter" dialog box. */
1055 static void
1056 color_export_cb(GtkButton *button, gpointer data _U_)
1057 {
1058   GtkWidget        *color_filters;
1059
1060   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
1061
1062   file_color_export_cmd_cb(color_filters, color_filter_edit_list);
1063 }
1064
1065 /* User pressed "Import": Pop up an "Import color filter" dialog box. */
1066 static void
1067 color_import_cb(GtkButton *button, gpointer data _U_)
1068 {
1069   GtkWidget        *color_filters;
1070 #if GTK_MAJOR_VERSION >= 2
1071   GtkTreeSelection *sel;
1072 #endif
1073
1074   color_filters = (GtkWidget *)OBJECT_GET_DATA(button, COLOR_FILTERS_CL);
1075
1076 #if GTK_MAJOR_VERSION >= 2
1077   sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
1078   gtk_tree_selection_unselect_all (sel);
1079 #else
1080   gtk_clist_unselect_all (GTK_CLIST(color_filters));
1081 #endif
1082
1083   file_color_import_cmd_cb(color_filters, &color_filter_edit_list);
1084 }
1085
1086 /* User confirmed the clear operation: Remove all user defined color filters and
1087    revert to the global file. */
1088 static void
1089 color_clear_cmd(GtkWidget *widget)
1090 {
1091     GtkWidget * color_filters;
1092
1093     color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL);
1094
1095     while (num_of_filters > 0)
1096     {
1097         color_delete (num_of_filters-1, color_filters);
1098     }
1099
1100     /* try to read the global filters */
1101     color_filters_read_globals(color_filters);
1102 }
1103
1104 /* Clear button: user responded to question */
1105 static void color_clear_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
1106 {
1107     switch(btn) {
1108     case(ESD_BTN_CLEAR):
1109         color_clear_cmd(data);
1110         break;
1111     case(ESD_BTN_CANCEL):
1112         break;
1113     default:
1114         g_assert_not_reached();
1115     }
1116 }
1117
1118 /* User pressed "clear" button: ask user before really doing it */
1119 void
1120 color_clear_cb(GtkWidget *widget, gpointer data _U_) {
1121     gpointer  dialog;
1122
1123     /* ask user, if he/she is really sure */
1124     dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTN_CLEAR | ESD_BTN_CANCEL,
1125                 PRIMARY_TEXT_START "Remove all your personal color settings?" PRIMARY_TEXT_END "\n\n"
1126                 "This will revert the color settings to global defaults.\n\n"
1127                 "Are you really sure?");
1128
1129     simple_dialog_set_cb(dialog, color_clear_answered_cb, widget);
1130 }
1131
1132
1133
1134 /* User pressed "Ok" button: Exit dialog and apply new list of
1135    color filters to the capture. */
1136 static void
1137 color_ok_cb(GtkButton *button _U_, gpointer user_data _U_)
1138 {
1139   color_filters_apply(color_filter_edit_list);
1140
1141   /* if we don't have a Save button, just save the settings now */
1142   if (!prefs.gui_use_pref_save) {
1143       if (!color_filters_write(color_filter_edit_list))
1144             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1145                 "Could not open filter file: %s", strerror(errno));
1146   }
1147
1148   /* colorize list */
1149   cf_colorize_packets(&cfile);
1150
1151   /* Destroy the dialog box. */
1152   window_destroy(colorize_win);
1153 }
1154
1155 /* User pressed "Apply" button: apply the new list of color filters
1156    to the capture. */
1157 static void
1158 color_apply_cb(GtkButton *button _U_, gpointer user_data _U_)
1159 {
1160   color_filters_apply(color_filter_edit_list);
1161
1162   /* if we don't have a Save button, just save the settings now */
1163   if (!prefs.gui_use_pref_save) {
1164       if (!color_filters_write(color_filter_edit_list))
1165             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1166                 "Could not open filter file: %s", strerror(errno));
1167   }
1168
1169   cf_colorize_packets(&cfile);
1170 }
1171
1172 /* User pressed the "Save" button: save the color filters to the
1173    color filter file. */
1174 static void
1175 color_save_cb(GtkButton *button _U_, gpointer user_data _U_)
1176 {
1177
1178   if (!color_filters_write(color_filter_edit_list))
1179         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1180             "Could not open filter file: %s", strerror(errno));
1181 }
1182
1183 /* User pressed "Cancel" button (or "ESC" or the 'X'):
1184    Exit dialog without colorizing packets with the new list. */
1185 static void
1186 color_cancel_cb(GtkWidget *widget _U_, gpointer user_data _U_)
1187 {
1188   /* Destroy the dialog box. */
1189   window_destroy(colorize_win);
1190 }
1191