2 * Definitions for dialog boxes for color filters
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
31 #include <epan/packet.h>
32 #include <epan/dfilter/dfilter.h>
33 #include <epan/prefs.h>
36 #include "../color_filters.h"
39 #include "ui/simple_dialog.h"
41 #include "ui/gtk/main.h"
42 #include "ui/gtk/color_utils.h"
43 #include "ui/gtk/color_dlg.h"
44 #include "ui/gtk/dlg_utils.h"
45 #include "ui/gtk/gui_utils.h"
46 #include "ui/gtk/dfilter_expr_dlg.h"
47 #include "ui/gtk/stock_icons.h"
48 #include "ui/gtk/filter_dlg.h"
49 #include "ui/gtk/capture_file_dlg.h"
50 #include "ui/gtk/gtkglobals.h"
51 #include "ui/gtk/help_dlg.h"
52 #include "ui/gtk/color_edit_dlg.h"
53 #include "ui/gtk/packet_list.h"
56 #define BUTTON_SIZE_X -1
57 #define BUTTON_SIZE_Y -1
60 static GtkWidget
* colorize_dialog_new(char *filter
);
61 static void add_filter_to_list(gpointer filter_arg
, gpointer list_arg
, gboolean prepend
);
62 static void color_filter_up_cb(GtkButton
*button
, gpointer user_data
);
63 static void color_filter_down_cb(GtkButton
*button
, gpointer user_data
);
64 static void remember_selected_row(GtkTreeSelection
*sel
, gpointer list
);
65 static void color_destroy_cb(GtkButton
*button
, gpointer user_data
);
66 static void destroy_edit_dialog_cb(gpointer filter_arg
, gpointer dummy
);
67 static void create_new_color_filter(GtkButton
*button
, const char *filter
);
68 static void color_new_cb(GtkButton
*button
, gpointer user_data
);
69 static void color_edit_cb(GtkButton
*button
, gpointer user_data
);
70 static gboolean
color_filters_button_cb(GtkWidget
*, GdkEventButton
*, gpointer
);
71 static void color_disable_cb(GtkWidget
*widget
, gboolean user_data
);
72 static void color_delete_cb(GtkWidget
*widget
, gpointer user_data
);
73 static void color_save_cb(GtkButton
*button
, gpointer user_data
);
74 static void color_ok_cb(GtkButton
*button
, gpointer user_data
);
75 static void color_cancel_cb(GtkWidget
*widget
, gpointer user_data
);
76 static void color_apply_cb(GtkButton
*button
, gpointer user_data
);
77 static void color_clear_cb(GtkWidget
*button
, gpointer user_data
);
78 static void color_import_cb(GtkButton
*button
, gpointer user_data
);
79 static void color_export_cb(GtkButton
*button
, gpointer user_data
);
82 static GtkWidget
*colorize_win
;
83 gint color_dlg_num_of_filters
; /* number of filters being displayed */
84 gint color_dlg_row_selected
; /* row in color_filters that is selected */
86 static gboolean row_is_moving
= FALSE
;
88 /* This is a list of all current color filters in the dialog
89 * (copied from color_filters.c and edited with the dialog).
90 * The color filter items are not identical to the ones used for the
91 * packet list display, so they can be safely edited.
93 * Keep the temporary filters in a separate list so that they are
94 * not shown in the edit-dialog
96 * XXX - use the existing GTK list for this purpose and build temporary copies
97 * e.g. for the save/export functions.
98 * Problem: Don't know when able to safely throw away, e.g. while exporting.
100 static GSList
*color_filter_edit_list
= NULL
;
101 static GSList
*color_filter_tmp_list
= NULL
;
104 #define COLOR_UP_LB "color_up_lb"
105 #define COLOR_DOWN_LB "color_down_lb"
106 #define COLOR_EDIT_LB "color_edit_lb"
107 #define COLOR_ENABLE_LB "color_enable_lb"
108 #define COLOR_DISABLE_LB "color_disable_lb"
109 #define COLOR_DELETE_LB "color_delete_lb"
110 #define COLOR_FILTERS_CL "color_filters_cl"
111 #define COLOR_FILTER_LIST "color_filter_list"
114 /* Callback for the "Display:Coloring Rules" menu item. */
116 color_display_cb(GtkWidget
*w _U_
, gpointer d _U_
)
118 if (colorize_win
!= NULL
) {
119 /* There's already a color dialog box active; reactivate it. */
120 reactivate_window(colorize_win
);
122 /* Create a new "Colorize Display" dialog. */
123 colorize_win
= colorize_dialog_new(NULL
);
127 /* this opens the color dialog and presets the filter string */
129 color_display_with_filter(char *filter
)
131 if (colorize_win
!= NULL
) {
132 /* There's already a color dialog box active; reactivate it. */
133 reactivate_window(colorize_win
);
135 /* Create a new "Colorize Display" dialog. */
136 colorize_win
= colorize_dialog_new(filter
);
140 /* if this filter is selected - count it in the given int* */
142 count_this_select(gpointer filter_arg
, gpointer counter_arg
)
144 color_filter_t
*colorf
= (color_filter_t
*)filter_arg
;
145 int * cnt
= (int *)counter_arg
;
147 if (colorf
->selected
)
151 /* TODO: implement count of selected filters. Plug in to file_dlg update of "export selected" checkbox. */
152 int color_selected_count(void)
156 g_slist_foreach(color_filter_edit_list
, count_this_select
, &count
);
161 /* Create the "Coloring Rules" dialog. */
163 colorize_dialog_new (char *filter
)
165 GtkWidget
*color_win
;
167 GtkWidget
*main_hbox
;
168 GtkWidget
*ctrl_vbox
;
170 GtkWidget
*order_vbox
;
171 GtkWidget
*color_filter_up
;
172 GtkWidget
*order_move_label
;
173 GtkWidget
*color_filter_down
;
176 GtkWidget
*list_vbox
;
177 GtkWidget
*scrolledwindow1
;
178 GtkWidget
*color_filters
;
179 GtkWidget
*list_label
;
182 GtkWidget
*edit_vbox
;
183 GtkWidget
*color_new
;
184 GtkWidget
*color_edit
;
185 GtkWidget
*color_enable
;
186 GtkWidget
*color_disable
;
187 GtkWidget
*color_delete
;
189 GtkWidget
*manage_fr
;
190 GtkWidget
*manage_vbox
;
191 GtkWidget
*color_import
;
192 GtkWidget
*color_export
;
193 GtkWidget
*color_clear
;
195 GtkWidget
*button_ok_hbox
;
197 GtkWidget
*color_apply
;
198 GtkWidget
*color_save
;
199 GtkWidget
*color_cancel
;
200 GtkWidget
*color_help
;
203 GtkCellRenderer
*renderer
;
204 GtkTreeViewColumn
*column
;
205 GtkTreeSelection
*selection
;
206 static const gchar
*titles
[] = { "Name", "String" };
210 color_dlg_num_of_filters
= 0;
211 color_dlg_row_selected
= -1; /* no row selected */
212 /* Resizing of the dialog window is now reasonably done.
213 * Default size is set so that it should fit into every usual screen resolution.
214 * All other widgets are always packed depending on the current window size. */
215 color_win
= dlg_conf_window_new ("Wireshark: Coloring Rules");
216 g_object_set_data(G_OBJECT(color_win
), "color_win", color_win
);
217 gtk_window_set_default_size(GTK_WINDOW(color_win
), DEF_WIDTH
, DEF_HEIGHT
* 2/3);
218 dlg_vbox
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0, FALSE
);
219 gtk_container_set_border_width (GTK_CONTAINER (dlg_vbox
), 5);
220 gtk_container_add (GTK_CONTAINER (color_win
), dlg_vbox
);
222 main_hbox
= ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0, FALSE
);
223 gtk_box_pack_start (GTK_BOX (dlg_vbox
), main_hbox
, TRUE
, TRUE
, 0);
225 ctrl_vbox
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0, FALSE
);
226 gtk_box_pack_start (GTK_BOX (main_hbox
), ctrl_vbox
, FALSE
, FALSE
, 0);
228 /* edit buttons frame */
229 edit_fr
= gtk_frame_new("Edit");
230 gtk_box_pack_start (GTK_BOX (ctrl_vbox
), edit_fr
, TRUE
, TRUE
, 0);
232 /* edit_vbox is first button column (containing: new, edit and such) */
233 edit_vbox
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0, TRUE
);
234 gtk_container_set_border_width (GTK_CONTAINER (edit_vbox
), 5);
235 gtk_container_add(GTK_CONTAINER(edit_fr
), edit_vbox
);
237 color_new
= gtk_button_new_from_stock(GTK_STOCK_NEW
);
238 gtk_box_pack_start (GTK_BOX (edit_vbox
), color_new
, FALSE
, FALSE
, 5);
239 gtk_widget_set_tooltip_text(color_new
, "Create a new filter at the top of the list");
241 color_edit
= gtk_button_new_from_stock(WIRESHARK_STOCK_EDIT
);
242 gtk_box_pack_start (GTK_BOX (edit_vbox
), color_edit
, FALSE
, FALSE
, 5);
243 gtk_widget_set_tooltip_text(color_edit
, " If more than one filter is selected, edit the first selected one");
244 gtk_widget_set_sensitive (color_edit
, FALSE
);
246 color_enable
= gtk_button_new_from_stock(WIRESHARK_STOCK_ENABLE
);
247 gtk_box_pack_start (GTK_BOX (edit_vbox
), color_enable
, FALSE
, FALSE
, 5);
248 gtk_widget_set_tooltip_text(color_enable
, "Enable the selected filter(s)");
249 gtk_widget_set_sensitive (color_enable
, FALSE
);
251 color_disable
= gtk_button_new_from_stock(WIRESHARK_STOCK_DISABLE
);
252 gtk_box_pack_start (GTK_BOX (edit_vbox
), color_disable
, FALSE
, FALSE
, 5);
253 gtk_widget_set_tooltip_text(color_disable
, "Disable the selected filter(s)");
254 gtk_widget_set_sensitive (color_disable
, FALSE
);
256 color_delete
= gtk_button_new_from_stock(GTK_STOCK_DELETE
);
257 gtk_box_pack_start (GTK_BOX (edit_vbox
), color_delete
, FALSE
, FALSE
, 5);
258 gtk_widget_set_tooltip_text(color_delete
, "Delete the selected filter(s)");
259 gtk_widget_set_sensitive (color_delete
, FALSE
);
260 /* End edit buttons frame */
263 /* manage buttons frame */
264 manage_fr
= gtk_frame_new("Manage");
265 gtk_box_pack_start (GTK_BOX (ctrl_vbox
), manage_fr
, TRUE
, TRUE
, 0);
267 manage_vbox
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0, TRUE
);
268 gtk_container_set_border_width (GTK_CONTAINER (manage_vbox
), 5);
269 gtk_container_add(GTK_CONTAINER(manage_fr
), manage_vbox
);
271 color_import
= gtk_button_new_from_stock(WIRESHARK_STOCK_IMPORT
);
272 gtk_box_pack_start (GTK_BOX (manage_vbox
), color_import
, FALSE
, FALSE
, 5);
273 gtk_widget_set_tooltip_text(color_import
, "Load filters from a file and append them to the list");
274 color_export
= gtk_button_new_from_stock(WIRESHARK_STOCK_EXPORT
);
275 gtk_box_pack_start (GTK_BOX (manage_vbox
), color_export
, FALSE
, FALSE
, 5);
276 gtk_widget_set_tooltip_text(color_export
, "Save all/selected filters to a file");
277 color_clear
= gtk_button_new_from_stock(GTK_STOCK_CLEAR
);
278 gtk_box_pack_start(GTK_BOX (manage_vbox
), color_clear
, FALSE
, FALSE
, 5);
279 gtk_widget_set_tooltip_text(color_clear
, "Clear the filter list and revert to system-wide default filter set");
281 /* filter list frame */
282 list_fr
= gtk_frame_new("Filter");
283 gtk_box_pack_start (GTK_BOX (main_hbox
), list_fr
, TRUE
, TRUE
, 0);
285 list_vbox
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0, FALSE
);
286 gtk_container_set_border_width (GTK_CONTAINER (list_vbox
), 5);
287 gtk_container_add(GTK_CONTAINER(list_fr
), list_vbox
);
289 list_label
= gtk_label_new (("List is processed in order until match is found"));
290 gtk_box_pack_start (GTK_BOX (list_vbox
), list_label
, FALSE
, FALSE
, 0);
292 /* create the list of filters */
293 scrolledwindow1
= scrolled_window_new(NULL
, NULL
);
294 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow1
),
296 gtk_box_pack_start (GTK_BOX (list_vbox
), scrolledwindow1
, TRUE
, TRUE
, 0);
298 /* the list store contains : filter name, filter string, foreground
299 * color, background color, pointer to color filter */
300 store
= gtk_list_store_new(6,
307 color_filters
= tree_view_new(GTK_TREE_MODEL(store
));
308 g_object_unref(store
);
309 renderer
= gtk_cell_renderer_text_new();
310 column
= gtk_tree_view_column_new_with_attributes(titles
[0], renderer
,
316 gtk_tree_view_column_set_fixed_width(column
, 80);
317 gtk_tree_view_append_column(GTK_TREE_VIEW(color_filters
), column
);
318 renderer
= gtk_cell_renderer_text_new();
319 column
= gtk_tree_view_column_new_with_attributes(titles
[1], renderer
,
325 gtk_tree_view_column_set_fixed_width(column
, 300);
326 gtk_tree_view_append_column(GTK_TREE_VIEW(color_filters
), column
);
327 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(color_filters
), TRUE
);
328 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(color_filters
), FALSE
);
330 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters
));
331 gtk_tree_selection_set_mode(selection
, GTK_SELECTION_MULTIPLE
);
333 gtk_container_add (GTK_CONTAINER (scrolledwindow1
), color_filters
);
337 order_fr
= gtk_frame_new("Order");
338 gtk_box_pack_start (GTK_BOX (main_hbox
), order_fr
, FALSE
, FALSE
, 0);
340 order_vbox
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0, TRUE
);
341 gtk_container_set_border_width (GTK_CONTAINER (order_vbox
), 5);
342 gtk_container_add(GTK_CONTAINER(order_fr
), order_vbox
);
344 color_filter_up
= gtk_button_new_from_stock(GTK_STOCK_GO_UP
);
345 gtk_box_pack_start (GTK_BOX (order_vbox
), color_filter_up
, FALSE
, FALSE
, 0);
346 gtk_widget_set_tooltip_text(color_filter_up
, "Move filter higher in list");
347 gtk_widget_set_sensitive (color_filter_up
, FALSE
);
349 order_move_label
= gtk_label_new (("Move\nselected filter\nup or down"));
350 gtk_box_pack_start (GTK_BOX (order_vbox
), order_move_label
, FALSE
, FALSE
, 0);
352 color_filter_down
= gtk_button_new_from_stock(GTK_STOCK_GO_DOWN
);
353 gtk_box_pack_start (GTK_BOX (order_vbox
), color_filter_down
, FALSE
, FALSE
, 0);
354 gtk_widget_set_tooltip_text(color_filter_down
, "Move filter lower in list");
355 gtk_widget_set_sensitive (color_filter_down
, FALSE
);
358 /* Button row: OK, cancel and help buttons */
359 button_ok_hbox
= dlg_button_row_new(GTK_STOCK_OK
, GTK_STOCK_APPLY
, GTK_STOCK_SAVE
, GTK_STOCK_CANCEL
, GTK_STOCK_HELP
, NULL
);
360 gtk_box_pack_start (GTK_BOX (dlg_vbox
), button_ok_hbox
, FALSE
, FALSE
, 5);
362 color_ok
= (GtkWidget
*)g_object_get_data(G_OBJECT(button_ok_hbox
), GTK_STOCK_OK
);
363 gtk_widget_set_tooltip_text(color_ok
, "Apply the color filters to the display and close this dialog");
364 color_apply
= (GtkWidget
*)g_object_get_data(G_OBJECT(button_ok_hbox
), GTK_STOCK_APPLY
);
365 gtk_widget_set_tooltip_text(color_apply
, "Apply the color filters to the display and keep this dialog open");
367 color_save
= (GtkWidget
*)g_object_get_data(G_OBJECT(button_ok_hbox
), GTK_STOCK_SAVE
);
368 gtk_widget_set_tooltip_text(color_save
, "Save the color filters permanently and keep this dialog open");
369 color_cancel
= (GtkWidget
*)g_object_get_data(G_OBJECT(button_ok_hbox
), GTK_STOCK_CANCEL
);
370 window_set_cancel_button(color_win
, color_cancel
, color_cancel_cb
);
371 gtk_widget_set_tooltip_text(color_cancel
, "Cancel changes done (since last \"Apply\") and close this dialog");
373 color_help
= (GtkWidget
*)g_object_get_data(G_OBJECT(button_ok_hbox
), GTK_STOCK_HELP
);
374 gtk_widget_set_tooltip_text(color_help
, "Get help about this dialog");
375 g_signal_connect(color_help
, "clicked", G_CALLBACK(topic_cb
), (gpointer
)HELP_COLORING_RULES_DIALOG
);
377 gtk_widget_grab_default(color_ok
);
379 /* signals and such */
380 g_signal_connect(color_win
, "destroy", G_CALLBACK(color_destroy_cb
), NULL
);
381 g_object_set_data(G_OBJECT(color_filter_up
), COLOR_FILTERS_CL
, color_filters
);
382 g_signal_connect(color_filter_up
, "clicked", G_CALLBACK(color_filter_up_cb
), NULL
);
383 g_object_set_data(G_OBJECT(color_filter_down
), COLOR_FILTERS_CL
, color_filters
);
384 g_signal_connect(color_filter_down
, "clicked", G_CALLBACK(color_filter_down_cb
), NULL
);
385 g_signal_connect(selection
, "changed", G_CALLBACK(remember_selected_row
), color_filters
);
386 g_signal_connect(color_filters
, "button_press_event", G_CALLBACK(color_filters_button_cb
), NULL
);
387 g_object_set_data(G_OBJECT(color_filters
), COLOR_UP_LB
, color_filter_up
);
388 g_object_set_data(G_OBJECT(color_filters
), COLOR_DOWN_LB
, color_filter_down
);
389 g_object_set_data(G_OBJECT(color_filters
), COLOR_EDIT_LB
, color_edit
);
390 g_object_set_data(G_OBJECT(color_filters
), COLOR_ENABLE_LB
, color_enable
);
391 g_object_set_data(G_OBJECT(color_filters
), COLOR_DISABLE_LB
, color_disable
);
392 g_object_set_data(G_OBJECT(color_filters
), COLOR_DELETE_LB
, color_delete
);
393 g_object_set_data(G_OBJECT(color_new
), COLOR_FILTERS_CL
, color_filters
);
394 g_signal_connect(color_new
, "clicked", G_CALLBACK(color_new_cb
), NULL
);
395 g_object_set_data(G_OBJECT(color_edit
), COLOR_FILTERS_CL
, color_filters
);
396 g_signal_connect(color_edit
, "clicked", G_CALLBACK(color_edit_cb
), NULL
);
397 g_object_set_data(G_OBJECT(color_enable
), COLOR_FILTERS_CL
, color_filters
);
398 g_signal_connect(color_enable
, "clicked", G_CALLBACK(color_disable_cb
), FALSE
);
399 g_object_set_data(G_OBJECT(color_disable
), COLOR_FILTERS_CL
, color_filters
);
400 g_signal_connect(color_disable
, "clicked", G_CALLBACK(color_disable_cb
), (gpointer
)TRUE
);
401 g_object_set_data(G_OBJECT(color_delete
), COLOR_EDIT_LB
, color_edit
);
402 g_object_set_data(G_OBJECT(color_delete
), COLOR_FILTERS_CL
, color_filters
);
403 g_signal_connect(color_delete
, "clicked", G_CALLBACK(color_delete_cb
), NULL
);
404 g_object_set_data(G_OBJECT(color_import
), COLOR_FILTERS_CL
, color_filters
);
405 g_signal_connect(color_import
, "clicked", G_CALLBACK(color_import_cb
), NULL
);
406 g_signal_connect(color_export
, "clicked", G_CALLBACK(color_export_cb
), NULL
);
407 g_object_set_data(G_OBJECT(color_clear
), COLOR_FILTERS_CL
, color_filters
);
408 g_signal_connect(color_clear
, "clicked", G_CALLBACK(color_clear_cb
), NULL
);
409 g_signal_connect(color_ok
, "clicked", G_CALLBACK(color_ok_cb
), NULL
);
410 g_signal_connect(color_apply
, "clicked", G_CALLBACK(color_apply_cb
), NULL
);
411 g_signal_connect(color_save
, "clicked", G_CALLBACK(color_save_cb
), NULL
);
413 g_signal_connect(color_win
, "delete_event", G_CALLBACK(window_delete_event_cb
), NULL
);
415 gtk_widget_grab_focus(color_filters
);
417 /* prepare filter list content */
418 color_filters_clone(color_filters
);
419 g_object_set_data(G_OBJECT(color_win
), COLOR_FILTER_LIST
, &color_filter_edit_list
);
421 gtk_widget_show_all(color_win
);
423 /* hide the Save button if the user uses implicit save */
424 if(!prefs
.gui_use_pref_save
) {
425 gtk_widget_hide(color_save
);
428 window_present(color_win
);
431 /* if we specified a preset filter string, open the new dialog and
433 create_new_color_filter(GTK_BUTTON(color_new
), filter
);
439 /* move a row in the list +/- one position up/down */
440 static void move_this_row (GtkWidget
*color_filters
,
442 gint amount
) /* only tested with +1(down) and -1(up) */
444 color_filter_t
*colorf
;
446 GtkTreeIter iter1
, iter2
;
447 gchar
*name
, *string
, *fg_str
, *bg_str
;
450 g_assert(amount
== +1 || amount
== -1);
451 g_assert(amount
== +1 || filter_number
> 0);
452 g_assert(amount
== -1 || filter_number
< color_dlg_num_of_filters
- 1);
454 row_is_moving
= TRUE
;
455 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters
));
456 gtk_tree_model_iter_nth_child(model
, &iter1
, NULL
, filter_number
);
457 gtk_tree_model_iter_nth_child(model
, &iter2
, NULL
, filter_number
+ amount
);
459 gtk_tree_model_get(model
, &iter1
, 0, &name
, 1, &string
,
460 2, &fg_str
, 3, &bg_str
, 4, &disabled
, 5, &colorf
, -1);
461 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter1
);
463 gtk_list_store_insert_before(GTK_LIST_STORE(model
), &iter1
, &iter2
);
465 gtk_list_store_insert_after(GTK_LIST_STORE(model
), &iter1
, &iter2
);
467 gtk_list_store_set(GTK_LIST_STORE(model
), &iter1
,
479 row_is_moving
= FALSE
;
482 * re-select the initial row
484 gtk_widget_grab_focus(color_filters
);
485 gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters
)), &iter1
);
487 color_filter_edit_list
= g_slist_remove(color_filter_edit_list
, colorf
);
488 color_filter_edit_list
= g_slist_insert(color_filter_edit_list
, colorf
, filter_number
+ amount
);
491 /* User pressed the "Up" button: Move the selected filters up in the list */
493 color_filter_up_cb(GtkButton
*button
, gpointer user_data _U_
)
497 GtkWidget
* color_filters
;
498 color_filter_t
*colorf
;
501 GtkTreeSelection
*sel
;
504 color_filters
= (GtkWidget
*)g_object_get_data(G_OBJECT(button
), COLOR_FILTERS_CL
);
506 for (filter_number
= 0; filter_number
< color_dlg_num_of_filters
; filter_number
++)
508 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters
));
509 gtk_tree_model_iter_nth_child(model
, &iter
, NULL
, filter_number
);
510 gtk_tree_model_get(model
, &iter
, 5, &colorf
, -1);
511 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters
));
512 if (gtk_tree_selection_iter_is_selected(sel
, &iter
))
513 move_this_row (color_filters
, filter_number
, amount
);
517 /* User pressed the "Down" button: Move the selected filters down in the list */
519 color_filter_down_cb(GtkButton
*button
, gpointer user_data _U_
)
523 GtkWidget
* color_filters
;
524 color_filter_t
*colorf
;
529 color_filters
= (GtkWidget
*)g_object_get_data(G_OBJECT(button
), COLOR_FILTERS_CL
);
531 for (filter_number
= color_dlg_num_of_filters
- 1; filter_number
>= 0; filter_number
--)
533 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters
));
534 gtk_tree_model_iter_nth_child(model
, &iter
, NULL
, filter_number
);
535 gtk_tree_model_get(model
, &iter
, 5, &colorf
, -1);
536 if (colorf
->selected
)
537 move_this_row (color_filters
, filter_number
, amount
);
544 gint count
; /* count of selected filters */
545 gboolean first_selected
; /* true if the first filter in the list is selected */
546 gboolean last_selected
; /* true if the last filter in the list is selected */
547 gboolean all_enabled
; /* true if all selected coloring rules are enabled */
548 gboolean all_disabled
; /* true if all selected coloring rules are disabled */
549 gpointer color_filters
;
551 /* called for each selected row in the tree.
553 static void remember_this_row (GtkTreeModel
*model
, GtkTreePath
*path
, GtkTreeIter
*iter
, gpointer arg
)
556 color_filter_t
*colorf
;
557 struct remember_data
*data
= (struct remember_data
*)arg
;
559 gtk_tree_model_get(model
, iter
, 5, &colorf
, -1);
560 colorf
->selected
= TRUE
;
562 data
->all_enabled
&= (!colorf
->disabled
);
563 data
->all_disabled
&= colorf
->disabled
;
565 path_index
= gtk_tree_path_get_indices(path
); /* not to be freed */
566 if (path_index
== NULL
) /* can return NULL according to API doc.*/
570 color_dlg_row_selected
= path_index
[0];
572 if (color_dlg_row_selected
== 0)
573 data
->first_selected
= TRUE
;
574 if (color_dlg_row_selected
== color_dlg_num_of_filters
- 1)
575 data
->last_selected
= TRUE
;
579 gtk_tree_view_scroll_to_cell((GtkTreeView
*)data
->color_filters
, path
, NULL
, FALSE
, 0.0f
, 0.0f
);
582 /* clear the selection flag of this filter */
584 clear_select_flag(gpointer filter_arg
, gpointer arg _U_
)
586 color_filter_t
*colorf
= (color_filter_t
*)filter_arg
;
588 colorf
->selected
= FALSE
;
591 /* The gtk+2.0 version gets called for, (maybe multiple,) changes in the selection. */
593 remember_selected_row(GtkTreeSelection
*sel
, gpointer color_filters
)
596 struct remember_data data
;
598 data
.first_selected
= data
.last_selected
= FALSE
;
599 data
.all_enabled
= data
.all_disabled
= TRUE
;
601 data
.color_filters
= color_filters
;
603 g_slist_foreach(color_filter_edit_list
, clear_select_flag
, NULL
);
604 gtk_tree_selection_selected_foreach(sel
,remember_this_row
, &data
);
609 * One or more rows are selected, so we can operate on them.
612 /* We can only edit if there is exactly one filter selected */
613 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_EDIT_LB
);
614 gtk_widget_set_sensitive (button
, data
.count
== 1);
616 /* We can enable any number of filters */
617 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_ENABLE_LB
);
618 gtk_widget_set_sensitive (button
, !data
.all_enabled
);
620 /* We can disable any number of filters */
621 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_DISABLE_LB
);
622 gtk_widget_set_sensitive (button
, !data
.all_disabled
);
624 /* We can delete any number of filters */
625 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_DELETE_LB
);
626 gtk_widget_set_sensitive (button
, TRUE
);
629 * We can move them up *if* one of them isn't the top row,
630 * and move them down *if* one of them isn't the bottom row.
632 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_UP_LB
);
633 gtk_widget_set_sensitive(button
, !data
.first_selected
);
634 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_DOWN_LB
);
635 gtk_widget_set_sensitive(button
, !data
.last_selected
);
639 color_dlg_row_selected
= -1;
642 * No row is selected, so we can't do operations that affect the
645 if (!row_is_moving
) {
646 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_UP_LB
);
647 gtk_widget_set_sensitive (button
, FALSE
);
648 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_DOWN_LB
);
649 gtk_widget_set_sensitive (button
, FALSE
);
651 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_EDIT_LB
);
652 gtk_widget_set_sensitive (button
, FALSE
);
653 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_ENABLE_LB
);
654 gtk_widget_set_sensitive (button
, FALSE
);
655 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_DISABLE_LB
);
656 gtk_widget_set_sensitive (button
, FALSE
);
657 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_DELETE_LB
);
658 gtk_widget_set_sensitive (button
, FALSE
);
664 /* destroy a single color edit dialog */
666 destroy_edit_dialog_cb(gpointer filter_arg
, gpointer dummy _U_
)
668 color_filter_t
*colorf
= (color_filter_t
*)filter_arg
;
670 color_edit_dlg_destroy((color_edit_dlg_info_t
*)colorf
->color_edit_dlg_info
);
673 /* Called when the dialog box is being destroyed; destroy any edit
674 * dialogs opened from this dialog.
677 color_destroy_cb (GtkButton
*button _U_
,
678 gpointer user_data _U_
)
680 /* Destroy any edit dialogs we have open. */
681 g_slist_foreach(color_filter_edit_list
, destroy_edit_dialog_cb
, NULL
);
683 /* destroy the filter list itself */
684 color_filter_list_delete(&color_filter_edit_list
);
685 color_filter_list_delete(&color_filter_tmp_list
);
692 select_row(GtkWidget
*color_filters
, int row
)
696 GtkTreeSelection
*sel
;
698 /* select the new row */
699 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters
));
700 gtk_tree_model_iter_nth_child(model
, &iter
, NULL
, row
);
701 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters
));
702 gtk_tree_selection_select_iter(sel
, &iter
);
706 /* add a single color filter to the list */
708 add_filter_to_list(gpointer filter_arg
, gpointer list_arg
, gboolean prepend
)
710 color_filter_t
*colorf
= (color_filter_t
*)filter_arg
;
711 gchar fg_str
[14], bg_str
[14];
715 if( strstr(colorf
->filter_name
,CONVERSATION_COLOR_PREFIX
)==NULL
) {
716 store
= GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list_arg
)));
718 gtk_list_store_prepend(store
, &iter
);
720 gtk_list_store_append(store
, &iter
);
722 g_snprintf(fg_str
, sizeof(fg_str
), "#%04X%04X%04X",
723 colorf
->fg_color
.red
, colorf
->fg_color
.green
, colorf
->fg_color
.blue
);
724 g_snprintf(bg_str
, sizeof(bg_str
), "#%04X%04X%04X",
725 colorf
->bg_color
.red
, colorf
->bg_color
.green
, colorf
->bg_color
.blue
);
726 gtk_list_store_set(store
, &iter
,
727 0, colorf
->filter_name
,
728 1, colorf
->filter_text
,
734 color_filter_edit_list
= g_slist_prepend(color_filter_edit_list
, colorf
);
736 color_filter_edit_list
= g_slist_append(color_filter_edit_list
, colorf
);
738 color_dlg_num_of_filters
++;
740 /* But keep the temporary ones too, so they can be added again
741 * when the user is done editing */
742 color_filter_tmp_list
= g_slist_append(color_filter_tmp_list
, colorf
);
747 /* a new color filter was read in from a filter file */
749 color_filter_add_cb(color_filter_t
*colorf
, gpointer user_data
)
751 GtkWidget
*color_filters
= (GtkWidget
*)user_data
;
753 add_filter_to_list(colorf
, color_filters
, FALSE
);
755 gtk_widget_grab_focus(color_filters
);
758 /* Create a new filter, add it to the list, and pop up an
759 "Edit color filter" dialog box to edit it. */
761 create_new_color_filter(GtkButton
*button
, const char *filter
)
763 #if GTK_CHECK_VERSION(3,0,0)
764 GtkStyleContext
*context
;
765 GdkRGBA
*rgba_bg_color
;
766 GdkRGBA
*rgba_fg_color
;
770 color_filter_t
*colorf
;
771 color_t bg_color
, fg_color
;
772 GtkWidget
*color_filters
;
773 GtkTreeSelection
*sel
;
775 color_filters
= (GtkWidget
*)g_object_get_data(G_OBJECT(button
), COLOR_FILTERS_CL
);
777 /* unselect all filters */
778 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters
));
779 gtk_tree_selection_unselect_all (sel
);
781 /* Use the default background and foreground colors as the colors. */
782 #if GTK_CHECK_VERSION(3,0,0)
783 context
= gtk_widget_get_style_context (packet_list_get_widget());
784 gtk_style_context_get (context
, GTK_STATE_FLAG_NORMAL
,
785 "background-color", &rgba_bg_color
,
787 gtk_style_context_get (context
, GTK_STATE_FLAG_NORMAL
,
788 "color", &rgba_fg_color
,
790 gdkRGBAcolor_to_color_t(&bg_color
, rgba_bg_color
);
791 gdkRGBAcolor_to_color_t(&fg_color
, rgba_fg_color
);
792 gdk_rgba_free (rgba_bg_color
);
793 gdk_rgba_free (rgba_fg_color
);
796 style
= gtk_widget_get_style(packet_list_get_widget());
797 gdkcolor_to_color_t(&bg_color
, &style
->base
[GTK_STATE_NORMAL
]);
798 gdkcolor_to_color_t(&fg_color
, &style
->text
[GTK_STATE_NORMAL
]);
800 colorf
= color_filter_new("name", filter
, &bg_color
, &fg_color
, FALSE
);
801 add_filter_to_list(colorf
, color_filters
, TRUE
);
802 select_row(color_filters
, 0);
804 /* open the edit dialog */
805 color_edit_dlg_new(color_filters
, TRUE
/* is a new filter */);
807 gtk_widget_grab_focus(color_filters
);
810 /* User pressed the "New" button: Create a new filter in the list,
811 and pop up an "Edit color filter" dialog box to edit it. */
813 color_new_cb(GtkButton
*button
, gpointer user_data _U_
)
815 create_new_color_filter(button
, "filter");
818 /* User pressed the "Edit" button: Pop up an "Edit color filter" dialog box
819 * to edit an existing filter. */
821 color_edit_cb(GtkButton
*button
, gpointer user_data _U_
)
823 GtkWidget
*color_filters
;
825 color_filters
= (GtkWidget
*)g_object_get_data(G_OBJECT(button
), COLOR_FILTERS_CL
);
826 g_assert(color_dlg_row_selected
!= -1);
827 color_edit_dlg_new(color_filters
, FALSE
/* is not a new filter */);
830 /* User double-clicked on the coloring rule */
832 color_filters_button_cb(GtkWidget
*list
, GdkEventButton
*event
,
835 if (event
->type
== GDK_2BUTTON_PRESS
) {
836 color_edit_dlg_new(list
, FALSE
);
842 /* action_disable==TRUE ==> User pressed the "Disable" button:
843 * Disable the selected filters in the list.
844 * action_disable==FALSE ==> User pressed the "Enable" button:
845 * Enable the selected filters in the list.
848 color_disable_cb(GtkWidget
*widget
, gboolean action_disable
)
852 GtkWidget
* color_filters
;
853 color_filter_t
*colorf
;
856 GtkTreeSelection
*sel
;
858 color_filters
= (GtkWidget
*)g_object_get_data(G_OBJECT(widget
), COLOR_FILTERS_CL
);
860 for (filter_number
= 0; filter_number
< color_dlg_num_of_filters
; filter_number
++)
862 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters
));
863 gtk_tree_model_iter_nth_child(model
, &iter
, NULL
, filter_number
);
864 gtk_tree_model_get(model
, &iter
, 5, &colorf
, -1);
865 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters
));
866 if (gtk_tree_selection_iter_is_selected(sel
, &iter
)) {
867 colorf
->disabled
= action_disable
;
868 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
,
869 4, action_disable
, -1);
872 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_ENABLE_LB
);
873 gtk_widget_set_sensitive(button
, action_disable
);
874 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(color_filters
), COLOR_DISABLE_LB
);
875 gtk_widget_set_sensitive(button
, !action_disable
);
878 /* Delete a single color filter from the list and elsewhere. */
880 color_delete_single(gint row
, GtkWidget
*color_filters
)
882 color_filter_t
*colorf
;
888 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters
));
889 gtk_tree_model_iter_nth_child(model
, &iter
, NULL
, row
);
890 gtk_tree_model_get(model
, &iter
, 5, &colorf
, -1);
892 /* Remove this color filter from the CList displaying the
894 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
895 color_dlg_num_of_filters
--;
897 /* Destroy any "Edit color filter" dialog boxes editing it. */
898 color_edit_dlg_destroy((color_edit_dlg_info_t
*)colorf
->color_edit_dlg_info
);
900 /* Delete the color filter from the list of color filters. */
901 color_filter_edit_list
= g_slist_remove(color_filter_edit_list
, colorf
);
902 color_filter_delete(colorf
);
904 /* If we grab the focus after updating the selection, the first
905 * row is always selected, so we do it before */
906 gtk_widget_grab_focus(color_filters
);
909 /* User pressed the "Delete" button: Delete the selected filters from the list.*/
911 color_delete_cb(GtkWidget
*widget
, gpointer user_data _U_
)
913 GtkWidget
*color_filters
;
914 gint row
, num_filters
;
917 GtkTreeSelection
*sel
;
919 color_filters
= (GtkWidget
*)g_object_get_data(G_OBJECT(widget
), COLOR_FILTERS_CL
);
921 /* get the number of filters in the list */
922 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters
));
923 num_filters
= gtk_tree_model_iter_n_children(model
, NULL
);
924 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters
));
926 /* iterate through the list and delete the selected ones */
927 for (row
= num_filters
- 1; row
>= 0; row
--)
929 gtk_tree_model_iter_nth_child(model
, &iter
, NULL
, row
);
930 if (gtk_tree_selection_iter_is_selected(sel
, &iter
))
931 color_delete_single (row
, color_filters
);
935 /* User pressed "Import": Pop up an "Import color filter" dialog box. */
937 color_import_cb(GtkButton
*button
, gpointer data _U_
)
939 GtkWidget
*color_filters
;
940 GtkTreeSelection
*sel
;
942 color_filters
= (GtkWidget
*)g_object_get_data(G_OBJECT(button
), COLOR_FILTERS_CL
);
944 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters
));
945 gtk_tree_selection_unselect_all (sel
);
947 file_color_import_cmd_cb(color_filters
, &color_filter_edit_list
);
950 /* User pressed "Export": Pop up an "Export color filter" dialog box. */
952 color_export_cb(GtkButton
*button
, gpointer data _U_
)
954 GtkWidget
*color_filters
;
956 color_filters
= (GtkWidget
*)g_object_get_data(G_OBJECT(button
), COLOR_FILTERS_CL
);
958 file_color_export_cmd_cb(color_filters
, color_filter_edit_list
);
961 /* User confirmed the clear operation: Remove all user defined color filters and
962 revert to the global file. */
964 color_clear_cmd(GtkWidget
*widget
)
966 GtkWidget
* color_filters
;
968 color_filters
= (GtkWidget
*)g_object_get_data(G_OBJECT(widget
), COLOR_FILTERS_CL
);
970 while (color_dlg_num_of_filters
> 0)
972 color_delete_single (color_dlg_num_of_filters
-1, color_filters
);
975 /* try to read the global filters */
976 color_filters_read_globals(color_filters
);
979 /* User pressed "clear" button: ask user before really doing it */
981 color_clear_cb(GtkWidget
*widget
, gpointer data _U_
) {
982 GtkWidget
*msg_dialog
;
985 /* ask user, if he/she is really sure */
986 msg_dialog
= gtk_message_dialog_new(GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
987 (GtkDialogFlags
)(GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
),
988 GTK_MESSAGE_QUESTION
,
990 "Do you want to remove all your personal color settings?");
991 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(msg_dialog
),
992 "This will revert the color settings to global defaults.\n\n"
993 "Are you really sure?");
994 gtk_dialog_add_button(GTK_DIALOG(msg_dialog
),
995 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
);
996 gtk_dialog_add_button(GTK_DIALOG(msg_dialog
),
997 GTK_STOCK_CLEAR
, GTK_RESPONSE_ACCEPT
);
998 gtk_dialog_set_alternative_button_order(GTK_DIALOG(msg_dialog
),
1000 GTK_RESPONSE_CANCEL
,
1002 gtk_dialog_set_default_response(GTK_DIALOG(msg_dialog
), GTK_RESPONSE_CANCEL
);
1004 response
= gtk_dialog_run(GTK_DIALOG(msg_dialog
));
1005 gtk_widget_destroy(msg_dialog
);
1009 case GTK_RESPONSE_ACCEPT
:
1010 color_clear_cmd(widget
);
1013 case GTK_RESPONSE_CANCEL
:
1014 case GTK_RESPONSE_NONE
:
1015 case GTK_RESPONSE_DELETE_EVENT
:
1023 overwrite_existing_colorfilters_cb(gpointer dialog _U_
, gint btn
, gpointer data _U_
)
1027 /* overwrite the file*/
1028 if (!color_filters_write(color_filter_edit_list
))
1029 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
,
1030 "Could not open colorfilter file: %s", g_strerror(errno
));
1032 prefs
.unknown_colorfilters
= FALSE
;
1034 case(ESD_BTN_DONT_SAVE
):
1037 g_assert_not_reached();
1042 colorfilters_main_save(void)
1044 if (prefs
.unknown_colorfilters
) {
1045 gpointer dialog
= simple_dialog(ESD_TYPE_CONFIRMATION
, ESD_BTNS_SAVE_DONTSAVE
,
1046 "Obsolete or unrecognized color filters have been detected. "
1047 "If this profile will be used with an older or nonstandard Wireshark version "
1048 "or one that includes a proprietary dissector plugin, click 'Continue "
1049 "without Saving' and save this profile under a different name.\n\n");
1051 simple_dialog_set_cb(dialog
, overwrite_existing_colorfilters_cb
, NULL
);
1053 if (!color_filters_write(color_filter_edit_list
))
1054 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "Could not open filter file: %s", g_strerror(errno
));
1059 /* User pressed "Ok" button: Exit dialog and apply new list of
1060 color filters to the capture. */
1062 color_ok_cb(GtkButton
*button _U_
, gpointer user_data _U_
)
1064 /* Apply the new coloring rules... */
1065 color_apply_cb(button
,user_data
);
1067 /* ... and destroy the dialog box. */
1068 window_destroy(colorize_win
);
1071 /* User pressed "Apply" button: apply the new list of color filters
1074 color_apply_cb(GtkButton
*button _U_
, gpointer user_data _U_
)
1076 /* if we don't have a Save button, just save the settings now */
1077 if (!prefs
.gui_use_pref_save
)
1078 colorfilters_main_save();
1080 /* Apply the coloring rules, both the temporary ones in
1081 * color_filter_tmp_list as the permanent ones in color_filter_edit_list
1083 color_filters_apply(color_filter_tmp_list
, color_filter_edit_list
);
1086 packet_list_colorize_packets();
1089 /* User pressed the "Save" button: save the color filters to the
1090 color filter file. */
1092 color_save_cb(GtkButton
*button _U_
, gpointer user_data _U_
)
1094 colorfilters_main_save();
1097 /* User pressed "Cancel" button (or "ESC" or the 'X'):
1098 Exit dialog without colorizing packets with the new list. */
1100 color_cancel_cb(GtkWidget
*widget _U_
, gpointer user_data _U_
)
1102 /* Destroy the dialog box. */
1103 window_destroy(colorize_win
);
1107 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1112 * indent-tabs-mode: nil
1115 * vi: set shiftwidth=2 tabstop=8 expandtab:
1116 * :indentSize=2:tabSize=8:noTabs=true: