Make the columns of the capture options dialog selectable. Changes are stored in the preferences file.

The ordering can be changed by dragging the column. The order is not stored.

svn path=/trunk/; revision=44239
This commit is contained in:
Irene Rüngeler 2012-08-03 11:15:40 +00:00
parent 285e322329
commit 2e1952678f
9 changed files with 761 additions and 14 deletions

View File

@ -722,6 +722,7 @@ prefs DATA
prefs_apply
prefs_apply_all
prefs_capture_device_monitor_mode
prefs_capture_options_dialog_column_is_visible
prefs_clear_string_list
prefs_is_capture_device_hidden
prefs_find_module

View File

@ -1382,11 +1382,40 @@ init_prefs(void)
{
int i;
fmt_data *cfmt;
gchar *col_name;
static const gchar *col_fmt[DEF_NUM_COLS*2] = {
"No.", "%m", "Time", "%t",
"Source", "%s", "Destination", "%d",
"Protocol", "%p", "Length", "%L",
"Info", "%i"};
#if defined(HAVE_PCAP_CREATE)
static gint num_capture_cols = 7;
static const gchar *capture_cols[7] = {
"INTERFACE",
"LINK",
"PMODE",
"SNAPLEN",
"MONITOR",
"BUFFER",
"FILTER"};
#elif defined(_WIN32) && !defined (HAVE_PCAP_CREATE)
static gint num_capture_cols = 6;
static const gchar *capture_cols[6] = {
"INTERFACE",
"LINK",
"PMODE",
"SNAPLEN",
"BUFFER",
"FILTER"};
#else
static gint num_capture_cols = 5;
static const gchar *capture_cols[5] = {
"INTERFACE",
"LINK",
"PMODE",
"SNAPLEN",
"FILTER"};
#endif
if (prefs_initialized)
return;
@ -1547,6 +1576,12 @@ init_prefs(void)
prefs.capture_real_time = TRUE;
prefs.capture_auto_scroll = TRUE;
prefs.capture_show_info = FALSE;
prefs.capture_columns = NULL;
for (i = 0; i < num_capture_cols; i++) {
col_name = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
col_name = g_strdup(capture_cols[i]);
prefs.capture_columns = g_list_append(prefs.capture_columns, col_name);
}
/* set the default values for the tap/statistics dialog box */
prefs.tap_update_interval = TAP_UPDATE_DEFAULT_INTERVAL;
@ -1659,6 +1694,7 @@ prefs_reset(void)
g_free(prefs.capture_devices_descr);
g_free(prefs.capture_devices_hide);
g_free(prefs.capture_devices_monitor_mode);
g_list_free(prefs.capture_columns);
/*
* Unload all UAT preferences.
@ -2162,6 +2198,25 @@ prefs_capture_device_monitor_mode(const char *name)
return FALSE;
}
/*
* Returns TRUE if the user has marked this column as visible
*/
gboolean
prefs_capture_options_dialog_column_is_visible(const gchar *column)
{
GList *curr;
gchar *col;
for (curr = g_list_first(prefs.capture_columns); curr; curr = g_list_next(curr)) {
col = (gchar *)curr->data;
if (col && (g_ascii_strcasecmp(col, column) == 0)) {
return TRUE;
}
}
return FALSE;
}
#define PRS_COL_HIDDEN "column.hidden"
#define PRS_COL_FMT "column.format"
#define PRS_STREAM_CL_FG "stream.client.fg"
@ -2240,6 +2295,7 @@ prefs_capture_device_monitor_mode(const char *name)
#define PRS_CAP_REAL_TIME "capture.real_time_update"
#define PRS_CAP_AUTO_SCROLL "capture.auto_scroll"
#define PRS_CAP_SHOW_INFO "capture.show_info"
#define PRS_CAP_COLUMNS "capture.columns"
/* obsolete preference */
#define PRS_CAP_SYNTAX_CHECK_FILTER "capture.syntax_check_filter"
@ -2699,6 +2755,24 @@ set_pref(gchar *pref_name, gchar *value, void *private_data _U_,
prefs.capture_auto_scroll = ((g_ascii_strcasecmp(value, "true") == 0)?TRUE:FALSE);
} else if (strcmp(pref_name, PRS_CAP_SHOW_INFO) == 0) {
prefs.capture_show_info = ((g_ascii_strcasecmp(value, "true") == 0)?TRUE:FALSE);
} else if (strcmp(pref_name, PRS_CAP_COLUMNS) == 0) {
gchar *col_name;
col_l = prefs_get_string_list(value);
if (col_l == NULL)
return PREFS_SET_SYNTAX_ERR;
/* They're all valid; process them. */
g_list_free(prefs.capture_columns);
prefs.capture_columns = NULL;
col_l_elt = g_list_first(col_l);
col_name = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
col_name = (gchar *)col_l_elt->data;
while(col_l_elt) {
prefs.capture_columns = g_list_append(prefs.capture_columns, col_name);
col_l_elt = col_l_elt->next;
col_name = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
col_name = (gchar *)col_l_elt->data;
}
} else if (strcmp(pref_name, PRS_CAP_SYNTAX_CHECK_FILTER) == 0) {
/* Obsolete preference. */
;
@ -3263,6 +3337,7 @@ write_prefs(char **pf_path_return)
GList *clp, *col_l;
fmt_data *cfmt;
GString *cols_hidden = g_string_new ("");
gchar *col;
/* Needed for "-G defaultprefs" */
init_prefs();
@ -3739,6 +3814,21 @@ write_prefs(char **pf_path_return)
fprintf(pf, "#");
fprintf(pf, PRS_CAP_SHOW_INFO ": %s\n",
prefs.capture_show_info == TRUE ? "TRUE" : "FALSE");
clp = prefs.capture_columns;
col_l = NULL;
while (clp) {
col = (gchar *) clp->data;
col_l = g_list_append(col_l, g_strdup(col));
clp = clp->next;
}
fprintf(pf, "\n# Capture options dialog column list.\n");
fprintf(pf, "# List of columns to be displayed.\n");
fprintf(pf, "# Possible values: INTERFACE,LINK,PMODE,SNAPLEN,MONITOR,BUFFER,FILTER\n");
fprintf (pf, "%s: %s\n", PRS_CAP_COLUMNS, put_string_list(col_l));
/* This frees the list of strings, but not the strings to which it
refers; they are free'ed in put_string_list(). */
g_list_free(col_l);
/*
* XXX - The following members are intentionally not written here because

View File

@ -174,6 +174,7 @@ typedef struct _e_prefs {
gboolean capture_real_time;
gboolean capture_auto_scroll;
gboolean capture_show_info;
GList *capture_columns;
guint rtp_player_max_visible;
guint tap_update_interval;
gboolean display_hidden_proto_items;
@ -496,6 +497,8 @@ extern gboolean prefs_is_capture_device_hidden(const char *name);
*/
extern gboolean prefs_capture_device_monitor_mode(const char *name);
extern gboolean prefs_capture_options_dialog_column_is_visible(const gchar *column);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -66,6 +66,8 @@
#include "ui/gtk/capture_if_dlg.h"
#include "ui/gtk/main_welcome.h"
#include "ui/gtk/network_icons.h"
#include "ui/gtk/menus.h"
#include "ui/gtk/prefs_dlg.h"
#include "ui/gtk/main_80211_toolbar.h"
#include "ui/gtk/keys.h"
@ -207,6 +209,9 @@ static GtkWidget *cap_open_w = NULL, *opt_edit_w = NULL, *ok_bt, *new_interfaces
static gboolean cap_open_complete; /* valid only if cap_open_w != NULL */
static const gchar *pipe_name;
static const gchar *selected_name;
static GtkWidget *columns_menu_object;
static GtkUIManager *ui_manager_columns = NULL;
static GSList *popup_menu_list = NULL;
static gint marked_interface;
static gint marked_row;
@ -254,6 +259,9 @@ capture_dlg_prep(gpointer parent_w);
static GtkTreeModel*
create_and_fill_model(GtkTreeView *view);
void
update_visible_columns_menu (void);
static gboolean
query_tooltip_tree_view_cb (GtkWidget *widget,
gint x,
@ -262,12 +270,242 @@ query_tooltip_tree_view_cb (GtkWidget *widget,
GtkTooltip *tooltip,
gpointer data);
static
gchar *col_index_to_name(gint index)
{
gchar *col_name;
switch (index)
{
case INTERFACE: col_name = g_strdup("INTERFACE");
break;
case LINK: col_name = g_strdup("LINK");
break;
case PMODE: col_name = g_strdup("PMODE");
break;
case SNAPLEN: col_name = g_strdup("SNAPLEN");
break;
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
case BUFFER: col_name = g_strdup("BUFFER");
break;
#endif
#if defined (HAVE_PCAP_CREATE)
case MONITOR: col_name = g_strdup("MONITOR");
break;
#endif
case FILTER: col_name = g_strdup("FILTER");
break;
default: return NULL;
}
return col_name;
}
static void
set_capture_column_visible(gchar *col, gboolean visible _U_)
{
GList *curr;
gchar *col_name;
if (visible && !prefs_capture_options_dialog_column_is_visible(col)) {
prefs.capture_columns = g_list_append(prefs.capture_columns, col);
} else if (!visible && prefs_capture_options_dialog_column_is_visible(col)) {
for (curr = g_list_first(prefs.capture_columns); curr; curr = g_list_next(curr)) {
col_name = (gchar *)curr->data;
if (col_name && (g_ascii_strcasecmp(col_name, col) == 0)) {
prefs.capture_columns = g_list_remove(prefs.capture_columns, curr->data);
break;
}
}
}
}
static void
toggle_visible_column_cb (GtkWidget *w _U_, gpointer data)
{
GtkTreeView *view;
GtkTreeViewColumn *col;
gchar *col_name;
gint col_id;
col_id = GPOINTER_TO_INT(data);
view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
col = gtk_tree_view_get_column(GTK_TREE_VIEW(view), col_id);
col_name = col_index_to_name(col_id);
gtk_tree_view_column_set_visible(col, prefs_capture_options_dialog_column_is_visible(col_name)?FALSE:TRUE);
set_capture_column_visible(col_name, prefs_capture_options_dialog_column_is_visible(col_name)?FALSE:TRUE);
}
static void
set_all_columns_visible (void)
{
GtkTreeViewColumn *col;
int col_id;
GtkTreeView *view;
gchar *name;
view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
for (col_id = 2; col_id < NUM_COLUMNS; col_id++) {
col = gtk_tree_view_get_column(GTK_TREE_VIEW(view), col_id);
gtk_tree_view_column_set_visible(col, TRUE);
if ((name = col_index_to_name(col_id)) != NULL) {
set_capture_column_visible(name, TRUE);
}
}
if (!prefs.gui_use_pref_save) {
prefs_main_write();
}
update_visible_columns_menu ();
}
static void
columns_activate_all_columns_cb(GtkAction *action _U_, gpointer user_data _U_)
{
set_all_columns_visible ();
}
void
update_visible_tree_view_columns(void)
{
GtkTreeView *view;
gint col_id;
GtkTreeViewColumn *col;
view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
for (col_id = 2; col_id < NUM_COLUMNS; col_id++) {
col = gtk_tree_view_get_column(GTK_TREE_VIEW(view), col_id);
gtk_tree_view_column_set_visible(col, prefs_capture_options_dialog_column_is_visible(col_index_to_name(col_id))?TRUE:FALSE);
}
}
void
update_visible_columns_menu (void)
{
GtkWidget *menu_columns, *menu_item;
GtkTreeViewColumn *col;
GtkWidget *sub_menu;
gchar *title;
GtkTreeView *view;
gint col_id;
menu_columns = gtk_ui_manager_get_widget(ui_manager_columns, "/ColumnsPopup/DisplayedColumns");
/* Debug */
if(! menu_columns){
fprintf (stderr, "Warning: couldn't find menu_columns path=/ColumnsPopup/DisplayedColumns");
}
sub_menu = gtk_menu_new();
gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_columns), sub_menu);
view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
for (col_id = 2; col_id < NUM_COLUMNS; col_id++) {
col = gtk_tree_view_get_column(GTK_TREE_VIEW(view), col_id);
title = col_index_to_name(col_id);
menu_item = gtk_check_menu_item_new_with_label(title);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), prefs_capture_options_dialog_column_is_visible(title));
g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(toggle_visible_column_cb), GINT_TO_POINTER(col_id));
gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
gtk_widget_show (menu_item);
}
menu_item = gtk_menu_item_new();
gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
gtk_widget_show (menu_item);
menu_item = gtk_menu_item_new_with_label ("Display All");
gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
g_signal_connect(menu_item, "activate", G_CALLBACK(columns_activate_all_columns_cb), NULL);
gtk_widget_show (menu_item);
}
static void
columns_pref_cb(GtkAction *action _U_, gpointer user_data)
{
GtkWidget *widget = gtk_ui_manager_get_widget(ui_manager_columns, "/ColumnsPopup/ColumnPreferences");
prefs_page_cb( widget , user_data, PREFS_PAGE_CAPTURE);
}
static void
columns_hide_col_cb(GtkAction *action _U_, gpointer user_data _U_)
{
GtkTreeView *view;
GtkTreeViewColumn *col;
gint num;
gchar *name;
view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
col = (GtkTreeViewColumn *)g_object_get_data(G_OBJECT(view), E_MCAPTURE_COLUMNS_COLUMN_KEY);
gtk_tree_view_column_set_visible(col, FALSE);
num = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(col), E_MCAPTURE_COLUMNS_COL_KEY));
if ((name = col_index_to_name(num)) != NULL) {
set_capture_column_visible(name, FALSE);
if (!prefs.gui_use_pref_save) {
prefs_main_write();
}
update_visible_columns_menu ();
}
}
static const char *ui_desc_columns_menu_popup =
"<ui>\n"
" <popup name='ColumnsPopup' action='PopupAction'>\n"
" <menuitem name='ColumnPreferences' action='/Column Preferences'/>\n"
" <menu name='DisplayedColumns' action='/Displayed Columns'>\n"
" <menuitem name='Display All' action='/Displayed Columns/Display All'/>\n"
" </menu>\n"
" <menuitem name='HideColumn' action='/Hide Column'/>\n"
" </popup>\n"
"</ui>\n";
static const GtkActionEntry columns_menu_popup_action_entries[] = {
{ "/Column Preferences", GTK_STOCK_PREFERENCES, "Column Preferences...", NULL, NULL, G_CALLBACK(columns_pref_cb) },
{ "/Displayed Columns", NULL, "Displayed Columns", NULL, NULL, NULL },
{ "/Displayed Columns/Display All", NULL, "Display All", NULL, NULL, G_CALLBACK(columns_activate_all_columns_cb) },
{ "/Hide Column", NULL, "Hide Column", NULL, NULL, G_CALLBACK(columns_hide_col_cb) },
};
#ifdef HAVE_PCAP_CREATE
static void
activate_monitor(GtkTreeViewColumn *tree_column, GtkCellRenderer *renderer,
GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data);
#endif
void
init_columns_menu(void)
{
GtkActionGroup *columns_action_group;
GError *error = NULL;
columns_menu_object = gtk_menu_new();
/* columns pop-up menu */
columns_action_group = gtk_action_group_new ("ColumnsPopUpMenuActionGroup");
gtk_action_group_add_actions (columns_action_group, /* the action group */
(gpointer)columns_menu_popup_action_entries, /* an array of action descriptions */
G_N_ELEMENTS(columns_menu_popup_action_entries), /* the number of entries */
columns_menu_object); /* data to pass to the action callbacks */
ui_manager_columns = gtk_ui_manager_new ();
gtk_ui_manager_insert_action_group (ui_manager_columns,
columns_action_group,
0); /* the position at which the group will be inserted. */
gtk_ui_manager_add_ui_from_string (ui_manager_columns, ui_desc_columns_menu_popup, -1, &error);
if (error != NULL)
{
fprintf (stderr, "Warning: building Packet List Heading Pop-Up failed: %s\n", error->message);
g_error_free (error);
error = NULL;
}
g_object_set_data(G_OBJECT(columns_menu_object), PM_COLUMNS_KEY,
gtk_ui_manager_get_widget(ui_manager_columns, "/ColumnsPopup"));
popup_menu_list = g_slist_append((GSList *)popup_menu_list, ui_manager_columns);
}
/* stop the currently running capture */
void
capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
@ -3561,6 +3799,41 @@ show_add_interfaces_dialog(void)
? Other ??
*/
static gboolean
columns_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
{
GtkWidget *menu = (GtkWidget *)data;
GdkEventButton *event_button = NULL;
/* context menu handler */
if(event->type == GDK_BUTTON_PRESS) {
event_button = (GdkEventButton *) event;
/* To quote the "Gdk Event Structures" doc:
* "Normally button 1 is the left mouse button, 2 is the middle button, and 3 is the right button" */
if(event_button->button == 3) {
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, widget,
event_button->button,
event_button->time);
g_signal_stop_emission_by_name(widget, "button_press_event");
return TRUE;
}
}
return FALSE;
}
static gboolean
column_button_pressed_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
{
GtkWidget *col = (GtkWidget *) data;
GtkTreeView *view;
GtkWidget *menu = g_object_get_data(G_OBJECT(columns_menu_object), PM_COLUMNS_KEY);
view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
g_object_set_data(G_OBJECT(view), E_MCAPTURE_COLUMNS_COLUMN_KEY, col);
return columns_menu_handler (widget, event, menu);
}
void
capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
{
@ -3615,6 +3888,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
reactivate_window(cap_open_w);
return;
}
init_columns_menu();
/* use user-defined title if preference is set */
@ -3689,29 +3963,74 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
gtk_tree_view_column_set_min_width(column, 200);
gtk_tree_view_column_set_resizable(column, TRUE );
gtk_tree_view_column_set_alignment(column, 0.5);
g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(INTERFACE));
gtk_tree_view_column_set_clickable(column, TRUE);
gtk_tree_view_column_set_reorderable(column, TRUE);
g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
G_CALLBACK(column_button_pressed_cb), column);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("INTERFACE"))
gtk_tree_view_column_set_visible(column, TRUE);
else
gtk_tree_view_column_set_visible(column, FALSE);
g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes ("Link-layer header", renderer, "text", LINK, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
gtk_tree_view_column_set_clickable(column, TRUE);
gtk_tree_view_column_set_reorderable(column, TRUE);
gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW (view),LINK), TRUE );
g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(LINK));
g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
G_CALLBACK(column_button_pressed_cb), column);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("LINK"))
gtk_tree_view_column_set_visible(column, TRUE);
else
gtk_tree_view_column_set_visible(column, FALSE);
gtk_tree_view_column_set_alignment(column, 0.5);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Prom. Mode", renderer, "text", PMODE, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
g_object_set(renderer, "xalign", 0.5, NULL);
gtk_tree_view_column_set_clickable(column, TRUE);
gtk_tree_view_column_set_reorderable(column, TRUE);
g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(PMODE));
g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
G_CALLBACK(column_button_pressed_cb), column);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("PMODE"))
gtk_tree_view_column_set_visible(column, TRUE);
else
gtk_tree_view_column_set_visible(column, FALSE);
gtk_tree_view_column_set_alignment(column, 0.5);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Snaplen [B]", renderer, "text", SNAPLEN, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
gtk_tree_view_column_set_clickable(column, TRUE);
gtk_tree_view_column_set_reorderable(column, TRUE);
g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(SNAPLEN));
g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
G_CALLBACK(column_button_pressed_cb), column);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("SNAPLEN"))
gtk_tree_view_column_set_visible(column, TRUE);
else
gtk_tree_view_column_set_visible(column, FALSE);
g_object_set(renderer, "xalign", 0.5, NULL);
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Buffer [MB]", renderer, "text", BUFFER, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
gtk_tree_view_column_set_reorderable(column, TRUE);
g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(BUFFER));
gtk_tree_view_column_set_clickable(column, TRUE);
g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
G_CALLBACK(column_button_pressed_cb), column);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("BUFFER"))
gtk_tree_view_column_set_visible(column, TRUE);
else
gtk_tree_view_column_set_visible(column, FALSE);
g_object_set(renderer, "xalign", 0.5, NULL);
#endif
@ -3720,6 +4039,15 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
column = gtk_tree_view_column_new_with_attributes ("Mon. Mode", renderer, "text", MONITOR, NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer, activate_monitor, NULL, FALSE);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
gtk_tree_view_column_set_reorderable(column, TRUE);
g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(MONITOR));
gtk_tree_view_column_set_clickable(column, TRUE);
g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
G_CALLBACK(column_button_pressed_cb), column);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("MONITOR"))
gtk_tree_view_column_set_visible(column, TRUE);
else
gtk_tree_view_column_set_visible(column, FALSE);
g_object_set(renderer, "xalign", 0.5, NULL);
#endif
@ -3730,6 +4058,15 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
create_and_fill_model(GTK_TREE_VIEW(view));
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
gtk_tree_view_column_set_clickable(column, TRUE);
gtk_tree_view_column_set_reorderable(column, TRUE);
g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(FILTER));
g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
G_CALLBACK(column_button_pressed_cb), column);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("FILTER"))
gtk_tree_view_column_set_visible(column, TRUE);
else
gtk_tree_view_column_set_visible(column, FALSE);
gtk_container_add (GTK_CONTAINER (swindow), view);
gtk_box_pack_start(GTK_BOX(capture_vb), swindow, TRUE, TRUE, 0);
@ -4163,6 +4500,8 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
widgets. */
capture_prep_adjust_sensitivity(NULL, cap_open_w);
update_visible_columns_menu ();
/* Catch the "activate" signal on the text
entries, so that if the user types Return there, we act as if the
"OK" button had been selected, as happens if Return is typed if some

View File

@ -114,6 +114,12 @@ options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *co
void
capture_dlg_refresh_if(void);
void
update_visible_columns_menu (void);
void
update_visible_tree_view_columns(void);
/*
* Refresh everything visible that shows an interface list that
* includes local interfaces.

View File

@ -30,13 +30,15 @@
*/
#define E_DFILTER_CM_KEY "display_filter_combo"
#define E_DFILTER_TE_KEY "display_filter_entry"
#define E_RFILTER_TE_KEY "read_filter_te"
#define E_MPACKET_LIST_KEY "menu_packet_list"
#define E_MPACKET_LIST_ROW_KEY "menu_packet_list_row"
#define E_MPACKET_LIST_COL_KEY "menu_packet_list_col"
#define E_MPACKET_LIST_COLUMN_KEY "menu_packet_list_column"
#define E_MPACKET_LIST_PREV_COLUMN_KEY "menu_packet_list_prev_column"
#define E_DFILTER_TE_KEY "display_filter_entry"
#define E_RFILTER_TE_KEY "read_filter_te"
#define E_MPACKET_LIST_KEY "menu_packet_list"
#define E_MPACKET_LIST_ROW_KEY "menu_packet_list_row"
#define E_MPACKET_LIST_COL_KEY "menu_packet_list_col"
#define E_MPACKET_LIST_COLUMN_KEY "menu_packet_list_column"
#define E_MPACKET_LIST_PREV_COLUMN_KEY "menu_packet_list_prev_column"
#define E_MCAPTURE_COLUMNS_COL_KEY "menu_capture_columns_col"
#define E_MCAPTURE_COLUMNS_COLUMN_KEY "menu_capture_columns_column"
#define PRINT_CMD_LB_KEY "printer_command_label"
#define PRINT_CMD_TE_KEY "printer_command_entry"
@ -51,6 +53,7 @@
#define PM_TREE_VIEW_KEY "popup_menu_tree_view"
#define PM_BYTES_VIEW_KEY "popup_menu_bytes_view"
#define PM_STATUSBAR_PROFILES_KEY "popup_menu_statusbar_profiles"
#define PM_COLUMNS_KEY "popup_menu_capture_options"
#define E_TB_MAIN_KEY "toolbar_main"
#define E_TB_FILTER_KEY "toolbar_filter"

View File

@ -65,6 +65,8 @@
#define IFOPTS_LIST_TEXT_COLS 4
#define IFOPTS_MAX_DESCR_LEN 128
#define IFOPTS_IF_NOSEL -1
#define COLOPTS_CALLER_PTR_KEY "colopts_caller_ptr"
#define COLOPTS_DIALOG_PTR_KEY "colopts_dialog_ptr"
/* interface options dialog */
static GtkWidget *cur_list, *if_dev_lb, *if_name_lb, *if_linktype_lb, *if_linktype_cb, *if_descr_te, *if_hide_cb, *if_default_if_lb;
@ -96,12 +98,25 @@ static void ifopts_write_new_linklayer(void);
static void ifopts_write_new_descr(void);
static void ifopts_write_new_hide(void);
/* Columns options dialog */
#ifdef HAVE_PCAP_CREATE
static GtkWidget *col_monitor_cb;
#endif
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
static GtkWidget *col_buf_cb;
#endif
static GtkWidget *col_interface_cb, *col_snap_cb;
static GtkWidget *col_link_cb, *col_filter_cb, *col_pmode_cb;
static void colopts_edit_destroy_cb(GtkWidget *win, gpointer data);
static void colopts_edit_cb(GtkWidget *w, gpointer data);
static void colopts_edit_ok_cb(GtkWidget *w, gpointer parent_w);
GtkWidget*
capture_prefs_show(void)
{
GtkWidget *main_tb, *main_vb;
GtkWidget *if_cbxe, *if_lb, *promisc_cb, *pcap_ng_cb, *sync_cb, *auto_scroll_cb, *show_info_cb;
GtkWidget *ifopts_lb, *ifopts_bt;
GtkWidget *ifopts_lb, *ifopts_bt, *colopts_lb, *colopts_bt;
GList *if_list, *combo_list;
int err;
int row = 0;
@ -206,6 +221,20 @@ capture_prefs_show(void)
!prefs.capture_show_info);
g_object_set_data(G_OBJECT(main_vb), SHOW_INFO_KEY, show_info_cb);
/* Column properties */
colopts_lb = gtk_label_new("Columns:");
gtk_table_attach_defaults(GTK_TABLE(main_tb), colopts_lb, 0, 1, row, row+1);
gtk_misc_set_alignment(GTK_MISC(colopts_lb), 1.0f, 0.5f);
gtk_widget_show(colopts_lb);
colopts_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_EDIT);
tooltips_text = "Open a dialog box to change the visible columns.";
gtk_widget_set_tooltip_text(colopts_lb, tooltips_text);
gtk_widget_set_tooltip_text(colopts_bt, tooltips_text);
g_signal_connect(colopts_bt, "clicked", G_CALLBACK(colopts_edit_cb), NULL);
gtk_table_attach_defaults(GTK_TABLE(main_tb), colopts_bt, 1, 2, row, row+1);
row++;
/* Show 'em what we got */
gtk_widget_show_all(main_vb);
@ -271,6 +300,15 @@ capture_prefs_destroy(GtkWidget *w)
/* Yes. Destroy it. */
window_destroy(dlg);
}
/* Is there an column descriptions dialog associated with this
Preferences dialog? */
dlg = g_object_get_data(G_OBJECT(caller), COLOPTS_DIALOG_PTR_KEY);
if (dlg != NULL) {
/* Yes. Destroy it. */
window_destroy(dlg);
}
}
/*
@ -290,6 +328,209 @@ enum
N_COLUMN /* The number of columns */
};
static void
colopts_edit_cb(GtkWidget *w, gpointer data _U_)
{
GtkWidget *colopts_edit_dlg, *main_hb, *main_tb,
*ed_opts_fr, *main_vb,
*bbox, *ok_bt, *cancel_bt, *help_bt, *column_lb,
*col_interface_lb, *col_link_lb, *col_monitor_lb,
*col_buf_lb, *col_filter_lb, *col_pmode_lb,
*col_snap_lb;
int row = 0;
GtkWidget *caller = gtk_widget_get_toplevel(w);
/* Has an edit dialog box already been opened for that top-level
widget? */
colopts_edit_dlg = g_object_get_data(G_OBJECT(caller), COLOPTS_DIALOG_PTR_KEY);
if (colopts_edit_dlg != NULL) {
/* Yes. Just re-activate that dialog box. */
reactivate_window(colopts_edit_dlg);
return;
}
/* create a new dialog */
colopts_edit_dlg = dlg_conf_window_new("Wireshark: Preferences: Capture Options Columns");
gtk_window_set_default_size(GTK_WINDOW(colopts_edit_dlg), 300, 200);
main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
gtk_container_add(GTK_CONTAINER(colopts_edit_dlg), main_vb);
gtk_widget_show(main_vb);
/* create edit options frame */
ed_opts_fr = gtk_frame_new("Columns");
gtk_box_pack_start(GTK_BOX(main_vb), ed_opts_fr, FALSE, FALSE, 0);
gtk_widget_show(ed_opts_fr);
main_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5, TRUE);
gtk_container_set_border_width(GTK_CONTAINER(main_hb), 3);
gtk_container_add(GTK_CONTAINER(ed_opts_fr), main_hb);
gtk_widget_show(main_hb);
/* table to hold description text entry and hide button */
main_tb = gtk_table_new(IFOPTS_TABLE_ROWS, 4, FALSE);
gtk_box_pack_start(GTK_BOX(main_hb), main_tb, TRUE, FALSE, 10);
gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
gtk_table_set_col_spacings(GTK_TABLE(main_tb), 10);
gtk_widget_show(main_tb);
column_lb = gtk_label_new("Select the columns to be displayed");
gtk_table_attach_defaults(GTK_TABLE(main_tb), column_lb, 0, 2, row, row+1);
gtk_misc_set_alignment(GTK_MISC(column_lb), 0, 0.5f);
gtk_widget_show(column_lb);
row++;
/* create "Interface" label and button */
col_interface_cb = gtk_check_button_new();
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_interface_cb, 0, 1, row, row+1);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("INTERFACE"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_interface_cb), TRUE);
else
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_interface_cb), FALSE);
gtk_widget_show(col_interface_cb);
col_interface_lb = gtk_label_new("Interface and its addresses");
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_interface_lb, 1, 2, row, row+1);
gtk_misc_set_alignment(GTK_MISC(col_interface_lb), 0, 0.5f);
gtk_widget_show(col_interface_lb);
row++;
/* create "Link Layer" label and button */
col_link_cb = gtk_check_button_new();
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_link_cb, 0, 1, row, row+1);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("LINK"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_link_cb), TRUE);
else
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_link_cb), FALSE);
gtk_widget_show(col_link_cb);
col_link_lb = gtk_label_new("Link layer header");
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_link_lb, 1, 2, row, row+1);
gtk_misc_set_alignment(GTK_MISC(col_link_lb), 0, 0.5f);
gtk_widget_show(col_link_lb);
row++;
/* create "Promiscous Mode" label and button */
col_pmode_cb = gtk_check_button_new();
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_pmode_cb, 0, 1, row, row+1);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("PMODE"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_pmode_cb), TRUE);
else
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_pmode_cb), FALSE);
gtk_widget_show(col_pmode_cb);
col_pmode_lb = gtk_label_new("Promiscous Mode");
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_pmode_lb, 1, 2, row, row+1);
gtk_misc_set_alignment(GTK_MISC(col_pmode_lb), 0, 0.5f);
gtk_widget_show(col_pmode_lb);
row++;
/* create "Snap length in Bytes" label and button */
col_snap_cb = gtk_check_button_new();
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_snap_cb, 0, 1, row, row+1);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("SNAPLEN"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_snap_cb), TRUE);
else
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_snap_cb), FALSE);
gtk_widget_show(col_snap_cb);
col_snap_lb = gtk_label_new("Snap length in Bytes");
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_snap_lb, 1, 2, row, row+1);
gtk_misc_set_alignment(GTK_MISC(col_snap_lb), 0, 0.5f);
gtk_widget_show(col_snap_lb);
row++;
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
/* create "Buffer in Megabytes" label and button */
col_buf_cb = gtk_check_button_new();
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_buf_cb, 0, 1, row, row+1);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("BUFFER"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_buf_cb), TRUE);
else
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_buf_cb), FALSE);
gtk_widget_show(col_buf_cb);
col_buf_lb = gtk_label_new("Buffer in Megabytes");
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_buf_lb, 1, 2, row, row+1);
gtk_misc_set_alignment(GTK_MISC(col_buf_lb), 0, 0.5f);
gtk_widget_show(col_buf_lb);
row++;
#endif
#ifdef HAVE_PCAP_CREATE
/* create "monitor mode" label and button */
col_monitor_lb = gtk_label_new("Monitor mode");
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_monitor_lb, 1, 2, row, row+1);
gtk_misc_set_alignment(GTK_MISC(col_monitor_lb), 0, 0.5f);
gtk_widget_show(col_monitor_lb);
col_monitor_cb = gtk_check_button_new();
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_monitor_cb, 0, 1, row, row+1);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("MONITOR"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_monitor_cb), TRUE);
else
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_monitor_cb), FALSE);
gtk_widget_show(col_monitor_cb);
row++;
#endif
/* create "Capture Filter" label and button */
col_filter_lb = gtk_label_new("Capture filter");
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_filter_lb, 1, 2, row, row+1);
gtk_misc_set_alignment(GTK_MISC(col_filter_lb), 0, 0.5f);
gtk_widget_show(col_filter_lb);
col_filter_cb = gtk_check_button_new();
gtk_table_attach_defaults(GTK_TABLE(main_tb), col_filter_cb, 0, 1, row, row+1);
if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("FILTER"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_filter_cb), TRUE);
else
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_filter_cb), FALSE);
gtk_widget_show(col_filter_cb);
row++;
/* button row: OK and Cancel buttons */
bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
gtk_widget_show(bbox);
ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
gtk_widget_set_tooltip_text(ok_bt, "Save changes and exit dialog");
g_signal_connect(ok_bt, "clicked", G_CALLBACK(colopts_edit_ok_cb), colopts_edit_dlg);
cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
gtk_widget_set_tooltip_text(cancel_bt, "Cancel and exit dialog");
window_set_cancel_button(colopts_edit_dlg, cancel_bt, window_cancel_button_cb);
help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb),
(gpointer)HELP_CAPTURE_INTERFACE_OPTIONS_DIALOG);
gtk_widget_set_tooltip_text (help_bt, "Show topic specific help");
gtk_widget_grab_default(ok_bt);
g_signal_connect(colopts_edit_dlg, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
/* Call a handler when we're destroyed, so we can inform
our caller, if any, that we've been destroyed. */
g_signal_connect(colopts_edit_dlg, "destroy", G_CALLBACK(colopts_edit_destroy_cb), NULL);
/* Set the key for the new dialog to point to our caller. */
g_object_set_data(G_OBJECT(colopts_edit_dlg), COLOPTS_CALLER_PTR_KEY, caller);
/* Set the key for the caller to point to us */
g_object_set_data(G_OBJECT(caller), COLOPTS_DIALOG_PTR_KEY, colopts_edit_dlg);
gtk_widget_show(colopts_edit_dlg); /* triggers ifopts_edit_ifsel_cb() with the */
/* "interfaces" TreeView first row selected */
window_present(colopts_edit_dlg);
}
static void
ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
{
@ -303,7 +544,7 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
GtkWidget *list;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeView *list_view;
GtkTreeView *list_view;
GtkTreeSelection *selection;
int row = 0;
@ -603,6 +844,48 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
window_present(ifopts_edit_dlg);
}
/*
* User selected "OK". Create/write preferences strings.
*/
static void
colopts_edit_ok_cb(GtkWidget *w _U_, gpointer parent_w)
{
g_list_free(prefs.capture_columns);
prefs.capture_columns = NULL;
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(col_interface_cb))) {
prefs.capture_columns = g_list_append(prefs.capture_columns, g_strdup("INTERFACE"));
}
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(col_link_cb))) {
prefs.capture_columns = g_list_append(prefs.capture_columns, g_strdup("LINK"));
}
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(col_pmode_cb))) {
prefs.capture_columns = g_list_append(prefs.capture_columns, g_strdup("PMODE"));
}
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(col_snap_cb))) {
prefs.capture_columns = g_list_append(prefs.capture_columns, g_strdup("SNAPLEN"));
}
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(col_buf_cb))) {
prefs.capture_columns = g_list_append(prefs.capture_columns, g_strdup("BUFFER"));
}
#endif
#if defined (HAVE_PCAP_CREATE)
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(col_monitor_cb))) {
prefs.capture_columns = g_list_append(prefs.capture_columns, g_strdup("MONITOR"));
}
#endif
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(col_filter_cb))) {
prefs.capture_columns = g_list_append(prefs.capture_columns, g_strdup("FILTER"));
}
/* Now nuke this window. */
gtk_grab_remove(GTK_WIDGET(parent_w));
window_destroy(GTK_WIDGET(parent_w));
if (capture_dlg_window_present()) {
update_visible_tree_view_columns();
update_visible_columns_menu ();
}
}
/*
* User selected "OK". Create/write preferences strings.
*/
@ -634,6 +917,22 @@ ifopts_edit_ok_cb(GtkWidget *w _U_, gpointer parent_w)
window_destroy(GTK_WIDGET(parent_w));
}
static void
colopts_edit_destroy_cb(GtkWidget *win, gpointer data _U_)
{
GtkWidget *caller;
/* Get the widget that requested that we be popped up, if any.
(It should arrange to destroy us if it's destroyed, so
that we don't get a pointer to a non-existent window here.) */
caller = g_object_get_data(G_OBJECT(win), COLOPTS_CALLER_PTR_KEY);
if (caller != NULL) {
/* Tell it we no longer exist. */
g_object_set_data(G_OBJECT(caller), COLOPTS_DIALOG_PTR_KEY, NULL);
}
}
static void
ifopts_edit_destroy_cb(GtkWidget *win, gpointer data _U_)
{

View File

@ -424,8 +424,8 @@ prefs_page_cb(GtkWidget *w _U_, gpointer dummy _U_, PREFS_PAGE_E prefs_page)
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
gint col_offset;
prefs_tree_iter gui_iter, layout_iter, columns_iter;
gint layout_page, columns_page;
prefs_tree_iter gui_iter, layout_iter, columns_iter, capture_iter;
gint layout_page, columns_page, capture_page;
if (prefs_w != NULL) {
@ -556,8 +556,8 @@ prefs_page_cb(GtkWidget *w _U_, gpointer dummy _U_, PREFS_PAGE_E prefs_page)
/* capture prefs */
g_strlcpy(label_str, "Capture", MAX_TREE_NODE_NAME_LEN);
prefs_nb_page_add(prefs_nb, label_str, capture_prefs_show(), E_CAPTURE_PAGE_KEY);
prefs_tree_page_add(label_str, cts.page, store, NULL);
cts.page++;
capture_iter = prefs_tree_page_add(label_str, cts.page, store, NULL);
capture_page = cts.page++;
#ifdef _WIN32
}
#endif /* _WIN32 */
@ -620,6 +620,10 @@ prefs_page_cb(GtkWidget *w _U_, gpointer dummy _U_, PREFS_PAGE_E prefs_page)
gtk_tree_selection_select_iter(selection, &columns_iter);
gtk_notebook_set_current_page(g_object_get_data(G_OBJECT(prefs_w), E_PREFSW_NOTEBOOK_KEY), columns_page);
break;
case PREFS_PAGE_CAPTURE:
gtk_tree_selection_select_iter(selection, &capture_iter);
gtk_notebook_set_current_page(g_object_get_data(G_OBJECT(prefs_w), E_PREFSW_NOTEBOOK_KEY), capture_page);
break;
default:
/* Not implemented yet */
break;
@ -1829,6 +1833,7 @@ prefs_tree_select_cb(GtkTreeSelection *sel, gpointer dummy _U_)
}
/*
* Editor modelines
*

View File

@ -66,7 +66,8 @@
typedef enum {
PREFS_PAGE_USER_INTERFACE,
PREFS_PAGE_LAYOUT,
PREFS_PAGE_COLUMNS
PREFS_PAGE_COLUMNS,
PREFS_PAGE_CAPTURE
} PREFS_PAGE_E;
/** Show the preferences dialog.