aboutsummaryrefslogtreecommitdiffstats
path: root/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'gtk')
-rw-r--r--gtk/Makefile.am1
-rw-r--r--gtk/Makefile.common1
-rw-r--r--gtk/about_dlg.c2
-rw-r--r--gtk/help_dlg.c3
-rw-r--r--gtk/help_dlg.h1
-rw-r--r--gtk/main.c334
-rw-r--r--gtk/main.h11
-rw-r--r--gtk/menu.c4
-rw-r--r--gtk/profile_dlg.c791
-rw-r--r--gtk/profile_dlg.h41
-rw-r--r--gtk/recent.c37
-rw-r--r--gtk/recent.h3
12 files changed, 1105 insertions, 124 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index f9e2c878a0..8d997dc255 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -98,6 +98,7 @@ noinst_HEADERS = \
plugins_dlg.h \
prefs_dlg.h \
print_prefs.h \
+ profile_dlg.h \
proto_dlg.h \
proto_draw.h \
proto_hier_stats_dlg.h \
diff --git a/gtk/Makefile.common b/gtk/Makefile.common
index 4f7abf58ec..7f3aeb19ac 100644
--- a/gtk/Makefile.common
+++ b/gtk/Makefile.common
@@ -96,6 +96,7 @@ WIRESHARK_GTK_SRC = \
prefs_dlg.c \
print_dlg.c \
print_prefs.c \
+ profile_dlg.c \
progress_dlg.c \
proto_dlg.c \
proto_draw.c \
diff --git a/gtk/about_dlg.c b/gtk/about_dlg.c
index 1ef9c0ac7d..9bb1e890f1 100644
--- a/gtk/about_dlg.c
+++ b/gtk/about_dlg.c
@@ -369,7 +369,7 @@ about_folders_page_new(void)
g_free((void *) path);
/* pers conf */
- path = get_persconffile_path("", FALSE);
+ path = get_persconffile_path("", FALSE, FALSE);
about_folders_row(table, "Personal configuration", path,
"\"dfilters\", \"preferences\", \"ethers\", ...");
g_free((void *) path);
diff --git a/gtk/help_dlg.c b/gtk/help_dlg.c
index ecf1009108..223aaa5c3c 100644
--- a/gtk/help_dlg.c
+++ b/gtk/help_dlg.c
@@ -410,6 +410,9 @@ topic_action(topic_action_e action)
case(HELP_COLORING_RULES_DIALOG):
help_topic_html("ChCustColorizationSection.html");
break;
+ case(HELP_CONFIG_PROFILES_DIALOG):
+ help_topic_html("ChCustConfigProfilesSection.html");
+ break;
case(HELP_PRINT_DIALOG):
help_topic_html("ChIOPrintSection.html");
break;
diff --git a/gtk/help_dlg.h b/gtk/help_dlg.h
index e19ed45db9..fd9ef88ae7 100644
--- a/gtk/help_dlg.h
+++ b/gtk/help_dlg.h
@@ -57,6 +57,7 @@ typedef enum {
HELP_CAPTURE_FILTERS_DIALOG,
HELP_DISPLAY_FILTERS_DIALOG,
HELP_COLORING_RULES_DIALOG,
+ HELP_CONFIG_PROFILES_DIALOG,
HELP_PRINT_DIALOG,
HELP_FIND_DIALOG,
HELP_FILESET_DIALOG,
diff --git a/gtk/main.c b/gtk/main.c
index e6e8113026..3b4fba7109 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -98,6 +98,7 @@
#include "merge.h"
#include "u3.h"
#include "uat_gui.h"
+#include "epan/uat.h"
#ifdef HAVE_LIBPCAP
@@ -210,7 +211,7 @@ GtkWidget *top_level = NULL, *tree_view, *byte_nb_ptr, *tv_scrollw;
GtkWidget *pkt_scrollw;
static GtkWidget *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
static GtkWidget *main_first_pane, *main_second_pane;
-static GtkWidget *status_pane;
+static GtkWidget *status_pane_left, *status_pane_right;
static GtkWidget *menubar, *main_vbox, *main_tb, *stat_hbox, *filter_tb;
static GtkWidget *priv_warning_dialog;
@@ -222,10 +223,13 @@ static int airpcap_dll_ret_val = -1;
static GtkWidget *info_bar;
static GtkWidget *packets_bar = NULL;
+static GtkWidget *profile_bar = NULL;
static GtkWidget *welcome_pane;
static guint main_ctx, file_ctx, help_ctx;
static guint packets_ctx;
+static guint profile_ctx;
static gchar *packets_str = NULL;
+static gchar *profile_str = NULL;
GString *comp_info_str, *runtime_info_str;
gboolean have_capture_file = FALSE; /* XXX - is there an aquivalent in cfile? */
@@ -1033,6 +1037,29 @@ void packets_bar_update(void)
}
}
+/*
+ * update the packets statusbar to the current values
+ */
+void profile_bar_update(void)
+{
+ const char *profile_name;
+ if (profile_bar) {
+ /* remove old status */
+ if(profile_str) {
+ g_free(profile_str);
+ gtk_statusbar_pop(GTK_STATUSBAR(profile_bar), profile_ctx);
+ }
+
+ profile_name = get_profile_name ();
+ if (!profile_name) {
+ profile_name = DEFAULT_PROFILE;
+ }
+ profile_str = g_strdup_printf (" Profile: %s", profile_name);
+
+ gtk_statusbar_push(GTK_STATUSBAR(profile_bar), profile_ctx, profile_str);
+ }
+}
+
void
main_set_for_capture_file(gboolean have_capture_file_in)
{
@@ -1168,11 +1195,13 @@ main_load_window_geometry(GtkWidget *widget)
window_set_geometry(widget, &geom);
if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
- gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
+ gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane)
gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
- if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_status_pane)
- gtk_paned_set_position(GTK_PANED(status_pane), recent.gui_geometry_status_pane);
+ if (recent.has_gui_geometry_status_pane && recent.gui_geometry_status_pane_left)
+ gtk_paned_set_position(GTK_PANED(status_pane_left), recent.gui_geometry_status_pane_left);
+ if (recent.has_gui_geometry_status_pane && recent.gui_geometry_status_pane_right)
+ gtk_paned_set_position(GTK_PANED(status_pane_right), recent.gui_geometry_status_pane_right);
}
@@ -1200,7 +1229,8 @@ main_save_window_geometry(GtkWidget *widget)
recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
- recent.gui_geometry_status_pane = gtk_paned_get_position(GTK_PANED(status_pane));
+ recent.gui_geometry_status_pane_left = gtk_paned_get_position(GTK_PANED(status_pane_left));
+ recent.gui_geometry_status_pane_right = gtk_paned_get_position(GTK_PANED(status_pane_right));
#endif
}
@@ -1303,6 +1333,7 @@ print_usage(gboolean print_ver) {
fprintf(output, "\n");
fprintf(output, "User interface:\n");
+ fprintf(output, " -C <config profile> start with specified configuration profile\n");
fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
fprintf(output, " -m <font> set the font name used for most text\n");
fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
@@ -2146,6 +2177,112 @@ get_gui_runtime_info(GString *str
}
+static e_prefs *
+read_configuration_files(char **gdp_path, char **dp_path)
+{
+ int gpf_open_errno, gpf_read_errno;
+ int cf_open_errno, df_open_errno;
+ int gdp_open_errno, gdp_read_errno;
+ int dp_open_errno, dp_read_errno;
+ char *gpf_path, *pf_path;
+ char *cf_path, *df_path;
+ int pf_open_errno, pf_read_errno;
+ e_prefs *prefs;
+
+ /* Read the preference files. */
+ prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
+ &pf_open_errno, &pf_read_errno, &pf_path);
+
+ if (gpf_path != NULL) {
+ if (gpf_open_errno != 0) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "Could not open global preferences file\n\"%s\": %s.", gpf_path,
+ strerror(gpf_open_errno));
+ }
+ if (gpf_read_errno != 0) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
+ strerror(gpf_read_errno));
+ }
+ }
+ if (pf_path != NULL) {
+ if (pf_open_errno != 0) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "Could not open your preferences file\n\"%s\": %s.", pf_path,
+ strerror(pf_open_errno));
+ }
+ if (pf_read_errno != 0) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
+ strerror(pf_read_errno));
+ }
+ g_free(pf_path);
+ pf_path = NULL;
+ }
+
+#ifdef _WIN32
+ /* if the user wants a console to be always there, well, we should open one for him */
+ if (prefs->gui_console_open == console_open_always) {
+ create_console();
+ }
+#endif
+
+ /* Fill in capture options with values from the preferences */
+ prefs_to_capture_opts();
+
+ /* Read the capture filter file. */
+ read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
+ if (cf_path != NULL) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "Could not open your capture filter file\n\"%s\": %s.", cf_path,
+ strerror(cf_open_errno));
+ g_free(cf_path);
+ }
+
+ /* Read the display filter file. */
+ read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
+ if (df_path != NULL) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "Could not open your display filter file\n\"%s\": %s.", df_path,
+ strerror(df_open_errno));
+ g_free(df_path);
+ }
+
+ /* Read the disabled protocols file. */
+ read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
+ dp_path, &dp_open_errno, &dp_read_errno);
+ if (*gdp_path != NULL) {
+ if (gdp_open_errno != 0) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "Could not open global disabled protocols file\n\"%s\": %s.",
+ *gdp_path, strerror(gdp_open_errno));
+ }
+ if (gdp_read_errno != 0) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "I/O error reading global disabled protocols file\n\"%s\": %s.",
+ *gdp_path, strerror(gdp_read_errno));
+ }
+ g_free(*gdp_path);
+ *gdp_path = NULL;
+ }
+ if (*dp_path != NULL) {
+ if (dp_open_errno != 0) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
+ strerror(dp_open_errno));
+ }
+ if (dp_read_errno != 0) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
+ strerror(dp_read_errno));
+ }
+ g_free(*dp_path);
+ *dp_path = NULL;
+ }
+
+ return prefs;
+}
+
/* And now our feature presentation... [ fade to music ] */
int
main(int argc, char *argv[])
@@ -2162,14 +2299,7 @@ main(int argc, char *argv[])
char *rf_path;
int rf_open_errno;
- char *gpf_path, *pf_path;
- char *cf_path, *df_path;
char *gdp_path, *dp_path;
- int gpf_open_errno, gpf_read_errno;
- int pf_open_errno, pf_read_errno;
- int cf_open_errno, df_open_errno;
- int gdp_open_errno, gdp_read_errno;
- int dp_open_errno, dp_read_errno;
int err;
#ifdef HAVE_LIBPCAP
gboolean start_capture = FALSE;
@@ -2194,7 +2324,7 @@ main(int argc, char *argv[])
/*gchar *cant_get_if_list_errstr;*/
#endif
-#define OPTSTRING_INIT "a:b:c:Df:g:Hhi:klLm:nN:o:P:pQr:R:Ss:t:vw:X:y:z:"
+#define OPTSTRING_INIT "a:b:c:C:Df:g:Hhi:klLm:nN:o:P:pQr:R:Ss:t:vw:X:y:z:"
#if defined HAVE_LIBPCAP && defined _WIN32
#define OPTSTRING_WIN32 "B:"
@@ -2315,6 +2445,14 @@ main(int argc, char *argv[])
optind_initial = optind;
while ((opt = getopt(argc, argv, optstring)) != -1) {
switch (opt) {
+ case 'C': /* Configuration Profile */
+ if (profile_exists (optarg)) {
+ set_profile_name (optarg);
+ } else {
+ cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
+ exit(1);
+ }
+ break;
case 'h': /* Print help and exit */
print_usage(TRUE);
exit(0);
@@ -2502,94 +2640,7 @@ main(int argc, char *argv[])
splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
- /* Read the preference files. */
- prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
- &pf_open_errno, &pf_read_errno, &pf_path);
-
- if (gpf_path != NULL) {
- if (gpf_open_errno != 0) {
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "Could not open global preferences file\n\"%s\": %s.", gpf_path,
- strerror(gpf_open_errno));
- }
- if (gpf_read_errno != 0) {
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
- strerror(gpf_read_errno));
- }
- }
- if (pf_path != NULL) {
- if (pf_open_errno != 0) {
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "Could not open your preferences file\n\"%s\": %s.", pf_path,
- strerror(pf_open_errno));
- }
- if (pf_read_errno != 0) {
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
- strerror(pf_read_errno));
- }
- g_free(pf_path);
- pf_path = NULL;
- }
-
-#ifdef _WIN32
- /* if the user wants a console to be always there, well, we should open one for him */
- if (prefs->gui_console_open == console_open_always) {
- create_console();
- }
-#endif
-
- /* Fill in capture options with values from the preferences */
- prefs_to_capture_opts();
-
- /* Read the capture filter file. */
- read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
- if (cf_path != NULL) {
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "Could not open your capture filter file\n\"%s\": %s.", cf_path,
- strerror(cf_open_errno));
- g_free(cf_path);
- }
-
- /* Read the display filter file. */
- read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
- if (df_path != NULL) {
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "Could not open your display filter file\n\"%s\": %s.", df_path,
- strerror(df_open_errno));
- g_free(df_path);
- }
-
- /* Read the disabled protocols file. */
- read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
- &dp_path, &dp_open_errno, &dp_read_errno);
- if (gdp_path != NULL) {
- if (gdp_open_errno != 0) {
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "Could not open global disabled protocols file\n\"%s\": %s.",
- gdp_path, strerror(gdp_open_errno));
- }
- if (gdp_read_errno != 0) {
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "I/O error reading global disabled protocols file\n\"%s\": %s.",
- gdp_path, strerror(gdp_read_errno));
- }
- g_free(gdp_path);
- }
- if (dp_path != NULL) {
- if (dp_open_errno != 0) {
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
- strerror(dp_open_errno));
- }
- if (dp_read_errno != 0) {
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
- strerror(dp_read_errno));
- }
- g_free(dp_path);
- }
+ prefs = read_configuration_files (&gdp_path, &dp_path);
/* Read the (static part) of the recent file. Only the static part of it will be read, */
/* as we don't have the gui now to fill the recent lists which is done in the dynamic part. */
@@ -2630,6 +2681,9 @@ main(int argc, char *argv[])
break;
/*** all non capture option specific ***/
+ case 'C':
+ /* Configuration profile settings were already processed just ignore them this time*/
+ break;
case 'D': /* Print a list of capture devices and exit */
#ifdef HAVE_LIBPCAP
capture_opts_list_interfaces(FALSE);
@@ -2910,7 +2964,7 @@ main(int argc, char *argv[])
/* read in rc file from global and personal configuration paths. */
rc_file = get_datafile_path(RC_FILE);
gtk_rc_parse(rc_file);
- rc_file = get_persconffile_path(RC_FILE, FALSE);
+ rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
gtk_rc_parse(rc_file);
font_init();
@@ -3321,10 +3375,23 @@ static GtkWidget *packets_bar_new(void)
packets_bar = gtk_statusbar_new();
packets_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(packets_bar), "packets");
packets_bar_update();
+#if GTK_MAJOR_VERSION >= 2
+ gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(packets_bar), FALSE);
+#endif
return packets_bar;
}
+static GtkWidget *profile_bar_new(void)
+{
+ /* tip: tooltips don't work on statusbars! */
+ profile_bar = gtk_statusbar_new();
+ profile_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(profile_bar), "profile");
+ profile_bar_update();
+
+ return profile_bar;
+}
+
/*
* Helper for main_widgets_rearrange()
@@ -3377,7 +3444,9 @@ void main_widgets_rearrange(void) {
gtk_widget_ref(stat_hbox);
gtk_widget_ref(info_bar);
gtk_widget_ref(packets_bar);
- gtk_widget_ref(status_pane);
+ gtk_widget_ref(profile_bar);
+ gtk_widget_ref(status_pane_left);
+ gtk_widget_ref(status_pane_right);
gtk_widget_ref(main_pane_v1);
gtk_widget_ref(main_pane_v2);
gtk_widget_ref(main_pane_h1);
@@ -3387,7 +3456,8 @@ void main_widgets_rearrange(void) {
/* empty all containers participating */
gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
gtk_container_foreach(GTK_CONTAINER(stat_hbox), foreach_remove_a_child, stat_hbox);
- gtk_container_foreach(GTK_CONTAINER(status_pane), foreach_remove_a_child, status_pane);
+ gtk_container_foreach(GTK_CONTAINER(status_pane_left), foreach_remove_a_child, status_pane_left);
+ gtk_container_foreach(GTK_CONTAINER(status_pane_right), foreach_remove_a_child, status_pane_right);
gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
@@ -3486,9 +3556,11 @@ void main_widgets_rearrange(void) {
#endif
/* statusbar */
- gtk_box_pack_start(GTK_BOX(stat_hbox), status_pane, TRUE, TRUE, 0);
- gtk_paned_pack1(GTK_PANED(status_pane), info_bar, FALSE, FALSE);
- gtk_paned_pack2(GTK_PANED(status_pane), packets_bar, FALSE, FALSE);
+ gtk_box_pack_start(GTK_BOX(stat_hbox), status_pane_left, TRUE, TRUE, 0);
+ gtk_paned_pack1(GTK_PANED(status_pane_left), info_bar, FALSE, FALSE);
+ gtk_paned_pack2(GTK_PANED(status_pane_left), status_pane_right, TRUE, FALSE);
+ gtk_paned_pack1(GTK_PANED(status_pane_right), packets_bar, TRUE, FALSE);
+ gtk_paned_pack2(GTK_PANED(status_pane_right), profile_bar, FALSE, FALSE);
/* hide widgets on users recent settings */
main_widgets_show_or_hide();
@@ -4067,9 +4139,9 @@ main_widgets_show_or_hide(void)
}
if (recent.statusbar_show) {
- gtk_widget_show(status_pane);
+ gtk_widget_show(status_pane_left);
} else {
- gtk_widget_hide(status_pane);
+ gtk_widget_hide(status_pane_left);
}
if (recent.filter_toolbar_show) {
@@ -4833,14 +4905,20 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
packets_bar = packets_bar_new();
gtk_widget_show(packets_bar);
+ /* profile statusbar */
+ profile_bar = profile_bar_new();
+ gtk_widget_show(profile_bar);
+
/* Filter/status hbox */
stat_hbox = gtk_hbox_new(FALSE, 1);
gtk_container_border_width(GTK_CONTAINER(stat_hbox), 0);
gtk_widget_show(stat_hbox);
/* Pane for the statusbar */
- status_pane = gtk_hpaned_new();
- gtk_widget_show(status_pane);
+ status_pane_left = gtk_hpaned_new();
+ gtk_widget_show(status_pane_left);
+ status_pane_right = gtk_hpaned_new();
+ gtk_widget_show(status_pane_right);
/* Pane for the welcome screen */
welcome_pane = welcome_new();
@@ -4938,3 +5016,37 @@ prefs_to_capture_opts(void)
/* Set the name resolution code's flags from the preferences. */
g_resolv_flags = prefs.name_resolve;
}
+
+
+/* Change configuration profile */
+void change_configuration_profile (const gchar *profile_name)
+{
+ char *gdp_path, *dp_path;
+
+ /* First set profile name and update the status bar */
+ set_profile_name (profile_name);
+ profile_bar_update ();
+
+ /* Reset current preferences and apply the new */
+ prefs_reset();
+ (void) read_configuration_files (&gdp_path, &dp_path);
+ prefs_apply_all();
+ uat_reload_all();
+
+ /* Update window view and redraw the toolbar */
+ update_main_window_name();
+ toolbar_redraw_all();
+
+ /* Enable all protocols and disable from the disabled list */
+ proto_enable_all();
+ if (gdp_path == NULL && dp_path == NULL) {
+ set_disabled_protos_list();
+ }
+
+ /* Reload color filters */
+ color_filters_reload();
+
+ /* Recreate the packet list according to new preferences */
+ packet_list_recreate ();
+ user_font_apply();
+}
diff --git a/gtk/main.h b/gtk/main.h
index fdb9b8540f..acb6ca1bd1 100644
--- a/gtk/main.h
+++ b/gtk/main.h
@@ -333,14 +333,23 @@ extern void dnd_open_file_cmd(gchar *cf_names_freeme);
/** Update the packets statusbar to the current values. */
extern void packets_bar_update(void);
+/** Update the profile statusbar to the current values. */
+extern void profile_bar_update(void);
+
#ifdef _WIN32
/** Win32 only: Create a console. Beware: cannot be closed again. */
extern void create_console(void);
#endif
-/* Fill in capture options with values from the preferences */
+/** Fill in capture options with values from the preferences */
extern void prefs_to_capture_opts(void);
+/** Change configuration profile */
+extern void change_configuration_profile(const gchar *profile_name);
+
+#define DEFAULT_PROFILE "Default"
+
+
extern GtkWidget *pkt_scrollw;
#endif /* __MAIN_H__ */
diff --git a/gtk/menu.c b/gtk/menu.c
index 6df8c26ace..0962d6686e 100644
--- a/gtk/menu.c
+++ b/gtk/menu.c
@@ -46,6 +46,7 @@
#include "capture_dlg.h"
#include "color_dlg.h"
#include "filter_dlg.h"
+#include "profile_dlg.h"
#include "dlg_utils.h"
#include "capture_file_dlg.h"
#include "fileset_dlg.h"
@@ -520,6 +521,9 @@ static GtkItemFactoryEntry menu_items[] =
ITEM_FACTORY_ENTRY("/Edit/Find Next Reference", NULL, reftime_frame_cb, REFTIME_FIND_NEXT, NULL, NULL),
ITEM_FACTORY_ENTRY("/Edit/Find Previous Reference", NULL, reftime_frame_cb, REFTIME_FIND_PREV, NULL, NULL),
ITEM_FACTORY_ENTRY("/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL),
+#if GTK_MAJOR_VERSION >= 2
+ ITEM_FACTORY_ENTRY("/Edit/_Configuration Profiles...", "<shift><control>A", profile_dialog_cb, 0, NULL, NULL),
+#endif
ITEM_FACTORY_STOCK_ENTRY("/Edit/_Preferences...", "<shift><control>P", prefs_cb,
0, GTK_STOCK_PREFERENCES),
ITEM_FACTORY_ENTRY("/_View", NULL, NULL, 0, "<Branch>", NULL),
diff --git a/gtk/profile_dlg.c b/gtk/profile_dlg.c
new file mode 100644
index 0000000000..a08b6077ef
--- /dev/null
+++ b/gtk/profile_dlg.c
@@ -0,0 +1,791 @@
+/* profile_dlg.c
+ * Dialog box for profiles editing
+ * Stig Bjørlykke <stig@bjorlykke.org>, 2008
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <epan/filesystem.h>
+#include <wiretap/file_util.h>
+
+#include "gtk/main.h"
+#include "profile_dlg.h"
+#include "dlg_utils.h"
+#include "gui_utils.h"
+#include "simple_dialog.h"
+#include "compat_macros.h"
+#include "gtkglobals.h"
+#include "help_dlg.h"
+#include <epan/prefs.h>
+
+#if GTK_MAJOR_VERSION >= 2
+
+#define E_PROF_PROFILE_L_KEY "profile_profile_l"
+#define E_PROF_COPY_BT_KEY "profile_copy_bt"
+#define E_PROF_DEL_BT_KEY "profile_del_bt"
+#define E_PROF_NAME_TE_KEY "profile_name_te"
+#define E_PROF_SELFUNC_KEY "profile_selfunc"
+#define E_PROF_SELARG_KEY "profile_selarg"
+
+static GtkWidget *global_profile_w = NULL;
+static GList *current_profiles = NULL;
+static GList *edited_profiles = NULL;
+
+#define PROF_STAT_DEFAULT 1
+#define PROF_STAT_EXISTS 2
+#define PROF_STAT_NEW 3
+#define PROF_STAT_CHANGED 4
+#define PROF_STAT_COPY 5
+
+typedef struct {
+ char *name; /* profile name */
+ char *reference; /* profile reference */
+ int status;
+} profile_def;
+
+static GList *
+add_profile_entry(GList *fl, const char *profilename, const char *reference, int status)
+{
+ profile_def *profile;
+
+ profile = (profile_def *) g_malloc(sizeof(profile_def));
+ profile->name = g_strdup(profilename);
+ profile->reference = g_strdup(reference);
+ profile->status = status;
+ return g_list_append(fl, profile);
+}
+
+static GList *
+remove_profile_entry(GList *fl, GList *fl_entry)
+{
+ profile_def *profile;
+
+ profile = (profile_def *) fl_entry->data;
+ g_free(profile->name);
+ g_free(profile->reference);
+ g_free(profile);
+ return g_list_remove_link(fl, fl_entry);
+}
+
+static GList *
+add_to_profile_list(const char *name, const char *expression, int status)
+{
+ edited_profiles = add_profile_entry(edited_profiles, name, expression, status);
+
+ return g_list_last(edited_profiles);
+}
+
+static void
+remove_from_profile_list(GList *fl_entry)
+{
+ edited_profiles = remove_profile_entry(edited_profiles, fl_entry);
+}
+
+static void
+empty_profile_list(gboolean edit_list)
+{
+ GList **flpp;
+
+ if (edit_list) {
+ flpp = &edited_profiles;
+
+ while(*flpp) {
+ *flpp = remove_profile_entry(*flpp, g_list_first(*flpp));
+ }
+
+ g_assert(g_list_length(*flpp) == 0);
+ }
+
+ flpp = &current_profiles;
+
+ while(*flpp) {
+ *flpp = remove_profile_entry(*flpp, g_list_first(*flpp));
+ }
+
+ g_assert(g_list_length(*flpp) == 0);
+}
+
+static void
+copy_profile_list(void)
+{
+ GList *flp_src;
+ profile_def *profile;
+
+ flp_src = edited_profiles;
+
+ /* throw away the "old" destination list - a NULL list is ok here */
+ empty_profile_list(FALSE);
+
+ /* copy the list entries */
+ while(flp_src) {
+ profile = (flp_src)->data;
+
+ current_profiles = add_profile_entry(current_profiles, profile->name,
+ profile->reference, profile->status);
+ flp_src = g_list_next(flp_src);
+ }
+}
+
+
+static GtkTreeIter *
+fill_list(GtkWidget *main_w)
+{
+ ETH_DIR *dir; /* scanned directory */
+ ETH_DIRENT *file; /* current file */
+ GList *fl_entry;
+ profile_def *profile;
+ GtkTreeView *profile_l;
+ GtkListStore *store;
+ GtkTreeIter iter, *l_select = NULL;
+ const gchar *profile_name = get_profile_name ();
+ const gchar *profiles_dir, *name;
+ gchar *filename;
+
+ profile_l = GTK_TREE_VIEW(OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY));
+ store = GTK_LIST_STORE(gtk_tree_view_get_model(profile_l));
+
+ fl_entry = add_to_profile_list(DEFAULT_PROFILE, DEFAULT_PROFILE, PROF_STAT_DEFAULT);
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter, 0, DEFAULT_PROFILE, 1, fl_entry, -1);
+ if (profile_name == NULL || strlen(profile_name) == 0) {
+ l_select = g_memdup(&iter, sizeof(iter));
+ }
+
+ /* fill in data */
+ profiles_dir = get_profiles_dir();
+ if ((dir = eth_dir_open(profiles_dir, 0, NULL)) != NULL) {
+ while ((file = eth_dir_read_name(dir)) != NULL) {
+ name = eth_dir_get_name(file);
+ filename = g_strdup_printf ("%s%s%s", profiles_dir, G_DIR_SEPARATOR_S, name);
+
+ if (test_for_directory(filename) == EISDIR) {
+ fl_entry = add_to_profile_list(name, name, PROF_STAT_EXISTS);
+ profile = (profile_def *) fl_entry->data;
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter, 0, profile->name, 1, fl_entry, -1);
+
+ if (profile_name && profile->name) {
+ if (strcmp(profile_name, profile->name) == 0) {
+ /*
+ * XXX - We're assuming that we can just copy a GtkTreeIter
+ * and use it later without any crashes. This may not be a
+ * valid assumption.
+ */
+ l_select = g_memdup(&iter, sizeof(iter));
+ }
+ }
+ }
+ g_free (filename);
+ }
+ eth_dir_close (dir);
+ }
+
+ /* Make the current list an the edited list equal */
+ copy_profile_list ();
+
+ return l_select;
+}
+
+static void
+profile_select(GtkWidget *main_w, GtkTreeView *profile_l, gboolean destroy)
+{
+ GList *fl_entry;
+ profile_def *profile;
+ GtkTreeSelection *sel;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(profile_l));
+
+ if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
+ gtk_tree_model_get(model, &iter, 1, &fl_entry, -1);
+ if (fl_entry) {
+ profile = (profile_def *) fl_entry->data;
+ if (strcmp(profile->name, DEFAULT_PROFILE)!=0) {
+ change_configuration_profile (profile->name);
+ } else {
+ change_configuration_profile (NULL);
+ }
+ }
+ }
+
+ if (destroy) {
+ /*
+ * Destroy the profile dialog box.
+ */
+ empty_profile_list (TRUE);
+ window_destroy(main_w);
+ }
+}
+
+static void
+profile_dlg_select(GtkTreeView *profile_l, gpointer main_w_arg)
+{
+ GtkWidget *main_w = GTK_WIDGET(main_w_arg);
+
+ profile_select(main_w, profile_l, TRUE);
+}
+
+static void
+profile_apply(GtkWidget *main_w, gboolean destroy)
+{
+ GtkTreeView *profile_l = GTK_TREE_VIEW(OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY));
+
+ profile_select(main_w, profile_l, destroy);
+}
+
+static void
+profile_dlg_save(void)
+{
+ char *pf_dir_path, *pf_dir_path2;
+ GList *fl1, *fl2;
+ profile_def *profile1, *profile2;
+ gboolean found;
+
+ fl1 = g_list_first(edited_profiles);
+ while (fl1) {
+ found = FALSE;
+ profile1 = (profile_def *) fl1->data;
+ if (profile1->status == PROF_STAT_NEW) {
+ /* We do not create a directory for the default profile */
+ if (strcmp(profile1->name, DEFAULT_PROFILE)!=0) {
+ if (create_persconffile_profile(profile1->name, &pf_dir_path) == -1) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "Can't create directory\n\"%s\":\n%s.",
+ pf_dir_path, strerror(errno));
+
+ g_free(pf_dir_path);
+ }
+ profile1->status = PROF_STAT_EXISTS;
+ }
+ } else if (profile1->status == PROF_STAT_CHANGED) {
+ if (strcmp(profile1->reference, profile1->name)!=0) {
+ /* Rename old profile directory to new */
+ if (rename_persconffile_profile(profile1->reference, profile1->name,
+ &pf_dir_path, &pf_dir_path2) == -1) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "Can't rename directory\n\"%s\" to\n\"%s\":\n%s.",
+ pf_dir_path, pf_dir_path2, strerror(errno));
+
+ g_free(pf_dir_path);
+ }
+ profile1->status = PROF_STAT_EXISTS;
+ }
+ }
+ fl1 = g_list_next(fl1);
+ }
+
+ fl1 = g_list_first(current_profiles);
+ while (fl1) {
+ found = FALSE;
+ profile1 = (profile_def *) fl1->data;
+ fl2 = g_list_first(edited_profiles);
+ while (fl2) {
+ profile2 = (profile_def *) fl2->data;
+ if (strcmp(profile1->name, profile2->name)==0) {
+ /* Profile exists in both lists */
+ found = TRUE;
+ } else if (strcmp(profile1->name, profile2->reference)==0) {
+ /* Profile has been renamed */
+ found = TRUE;
+ }
+ fl2 = fl2->next;
+ }
+ if (!found) {
+ /* Exists in existing list and not in edited, this is a deleted profile */
+ if (delete_persconffile_profile(profile1->name, &pf_dir_path) == -1) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "Can't delete profile directory\n\"%s\":\n%s.",
+ pf_dir_path, strerror(errno));
+
+ g_free(pf_dir_path);
+ }
+ }
+ fl1 = g_list_next(fl1);
+ }
+
+ copy_profile_list();
+}
+
+static void
+profile_dlg_ok_cb(GtkWidget *ok_bt, gpointer data _U_)
+{
+ profile_dlg_save();
+
+ /*
+ * Destroy the dialog box and apply the profile.
+ */
+ profile_apply(gtk_widget_get_toplevel(ok_bt), TRUE);
+}
+
+static void
+profile_dlg_apply_cb(GtkWidget *apply_bt, gpointer data _U_)
+{
+ profile_dlg_save();
+
+ /*
+ * Apply the profile, but don't destroy the dialog box.
+ */
+ profile_apply(gtk_widget_get_toplevel(apply_bt), FALSE);
+}
+
+/* cancel button pressed, revert changes and exit dialog */
+static void
+profile_dlg_cancel_cb(GtkWidget *cancel_bt, gpointer data _U_)
+{
+ GtkWidget *main_w = gtk_widget_get_toplevel(cancel_bt);
+
+ empty_profile_list (TRUE);
+ window_destroy(GTK_WIDGET(main_w));
+}
+
+/* Treat this as a cancel, by calling "profile_dlg_cancel_cb()" */
+static gboolean
+profile_dlg_delete_event_cb(GtkWidget *main_w, GdkEvent *event _U_,
+ gpointer data)
+{
+ profile_dlg_cancel_cb(main_w, data);
+ return FALSE;
+}
+
+static void
+profile_dlg_destroy_cb(GtkWidget *w _U_, gpointer data _U_)
+{
+ global_profile_w = NULL;
+}
+
+
+static gint
+profile_sel_list_button_cb(GtkWidget *list, GdkEventButton *event,
+ gpointer data _U_)
+{
+ void (* func)(GtkWidget *, gpointer);
+ gpointer func_arg;
+
+ if (event->type == GDK_2BUTTON_PRESS) {
+ func = OBJECT_GET_DATA(list, E_PROF_SELFUNC_KEY);
+ func_arg = OBJECT_GET_DATA(list, E_PROF_SELARG_KEY);
+
+ if (func)
+ (*func)(list, func_arg);
+ }
+
+ return FALSE;
+}
+
+static void
+profile_sel_list_cb(GtkTreeSelection *sel, gpointer data _U_)
+{
+ GtkWidget *profile_l = GTK_WIDGET(gtk_tree_selection_get_tree_view(sel));
+ GtkWidget *main_w = gtk_widget_get_toplevel(profile_l);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkWidget *name_te = OBJECT_GET_DATA(main_w, E_PROF_NAME_TE_KEY);
+ GtkWidget *copy_bt = OBJECT_GET_DATA(main_w, E_PROF_COPY_BT_KEY);
+ GtkWidget *del_bt = OBJECT_GET_DATA(main_w, E_PROF_DEL_BT_KEY);
+ profile_def *profile;
+ gchar *name = NULL;
+ GList *fl_entry;
+ gint sensitivity = FALSE;
+
+ if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
+ gtk_tree_model_get(model, &iter, 1, &fl_entry, -1);
+ if (fl_entry) {
+ profile= (profile_def *) fl_entry->data;
+ name = g_strdup(profile->name);
+ if (profile->status!=PROF_STAT_DEFAULT) {
+ sensitivity = TRUE;
+ }
+ }
+ }
+
+ /*
+ * Did you know that this function is called when the window is destroyed?
+ * Funny, that.
+ * This means that we have to:
+ *
+ * attach to the top-level window data items containing pointers to
+ * the widgets we affect here;
+ *
+ * give each of those widgets their own destroy callbacks;
+ *
+ * clear that pointer when the widget is destroyed;
+ *
+ * don't do anything to the widget if the pointer we get back is
+ * null;
+ *
+ * so that if we're called after any of the widgets we'd affect are
+ * destroyed, we know that we shouldn't do anything to those widgets.
+ */
+ if (name_te != NULL) {
+ gtk_entry_set_text(GTK_ENTRY(name_te), name ? name : "");
+ gtk_widget_set_sensitive(name_te, sensitivity);
+ }
+ if (copy_bt != NULL)
+ gtk_widget_set_sensitive(copy_bt, sensitivity);
+ if (del_bt != NULL)
+ gtk_widget_set_sensitive(del_bt, sensitivity);
+ if (name != NULL)
+ g_free(name);
+}
+
+static void
+profile_new_bt_clicked_cb(GtkWidget *w, gpointer data _U_)
+{
+ GtkWidget *main_w = gtk_widget_get_toplevel(w);
+ GtkTreeView *profile_l = GTK_TREE_VIEW(OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY));
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GList *fl_entry;
+ const gchar *name = "New profile";
+
+ /* Add a new entry to the profile list. */
+ fl_entry = add_to_profile_list(name, "", PROF_STAT_NEW);
+
+ store = GTK_LIST_STORE(gtk_tree_view_get_model(profile_l));
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter, 0, name, 1, fl_entry, -1);
+ /* Select the item. */
+ gtk_tree_selection_select_iter(gtk_tree_view_get_selection(profile_l), &iter);
+}
+
+#if 0
+static void
+profile_copy_bt_clicked_cb(GtkWidget *w, gpointer data _U_)
+{
+ GtkWidget *main_w = gtk_widget_get_toplevel(w);
+ GtkWidget *name_te = OBJECT_GET_DATA(main_w, E_PROF_NAME_TE_KEY);
+ GtkTreeView *profile_l = GTK_TREE_VIEW(OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY));
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GList *fl_entry;
+ const gchar *name = gtk_entry_get_text(GTK_ENTRY(name_te));
+ gchar *new_name;
+
+ new_name = g_strdup_printf ("%s (copy)", name);
+
+ /* Add a new entry to the profile list. */
+ fl_entry = add_to_profile_list(new_name, name, PROF_STAT_COPY);
+
+ store = GTK_LIST_STORE(gtk_tree_view_get_model(profile_l));
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter, 0, new_name, 1, fl_entry, -1);
+ /* Select the item. */
+ gtk_tree_selection_select_iter(gtk_tree_view_get_selection(profile_l), &iter);
+ g_free (new_name);
+}
+#endif
+
+static void
+profile_name_te_changed_cb(GtkWidget *w, gpointer data _U_)
+{
+ GtkWidget *main_w = gtk_widget_get_toplevel(w);
+ GtkWidget *name_te = OBJECT_GET_DATA(main_w, E_PROF_NAME_TE_KEY);
+ GtkWidget *profile_l = OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY);
+ profile_def *profile;
+ GList *fl_entry;
+ const gchar *name = "";
+
+ GtkTreeSelection *sel;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(profile_l));
+ name = gtk_entry_get_text(GTK_ENTRY(name_te));
+
+ /* if something was selected */
+ if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
+ gtk_tree_model_get(model, &iter, 1, &fl_entry, -1);
+ if (fl_entry != NULL) {
+ profile = (profile_def *) fl_entry->data;
+
+ if (strlen(name) > 0 && profile) {
+ if (profile->status != PROF_STAT_DEFAULT) {
+ g_free(profile->name);
+ profile->name = g_strdup(name);
+ if (profile->status != PROF_STAT_NEW) {
+ profile->status = PROF_STAT_CHANGED;
+ }
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, name, -1);
+ }
+ }
+ }
+ }
+}
+
+static void
+profile_del_bt_clicked_cb(GtkWidget *w, gpointer data _U_)
+{
+ GtkWidget *main_w = gtk_widget_get_toplevel(w);
+ GtkWidget *profile_l = OBJECT_GET_DATA(main_w, E_PROF_PROFILE_L_KEY);
+ GList *fl_entry;
+
+ GtkTreeSelection *sel;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(profile_l));
+ /* If something was selected */
+ if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
+ gtk_tree_model_get(model, &iter, 1, &fl_entry, -1);
+
+ if (fl_entry != NULL) {
+ remove_from_profile_list (fl_entry);
+ gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+ }
+ }
+
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ gtk_tree_selection_select_iter(sel, &iter);
+ }
+}
+
+static GtkWidget *
+profile_dialog_new(void)
+{
+ GtkWidget *main_w, /* main window */
+ *main_vb, /* main container */
+ *bbox, /* button container */
+ *ok_bt, /* "OK" button */
+ *apply_bt, /* "Apply" button */
+ *cancel_bt, /* "Cancel" button */
+ *help_bt; /* "Help" button */
+ GtkWidget *profile_vb, /* profile settings box */
+ *props_vb;
+ GtkWidget *top_hb,
+ *list_bb,
+ *new_bt,
+#if 0
+ *copy_bt,
+#endif
+ *del_bt,
+ *profile_sc,
+ *profile_l,
+ *middle_hb,
+ *name_lb,
+ *name_te,
+ *profile_fr,
+ *edit_fr,
+ *props_fr;
+ GtkTooltips *tooltips;
+ GtkListStore *store;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ GtkTreeSelection *sel;
+ GtkTreeIter *l_select;
+
+ /* Get a pointer to a static variable holding the type of profile on
+ which we're working, so we can pass that pointer to callback
+ routines. */
+
+ tooltips = gtk_tooltips_new ();
+
+ main_w = dlg_window_new("Wireshark: Configuration Profiles");
+ gtk_window_set_default_size(GTK_WINDOW(main_w), 400, 400);
+
+ main_vb = gtk_vbox_new(FALSE, 0);
+ gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
+ gtk_container_add(GTK_CONTAINER(main_w), main_vb);
+ gtk_widget_show(main_vb);
+
+ /* Container for each row of widgets */
+ profile_vb = gtk_vbox_new(FALSE, 0);
+ gtk_container_border_width(GTK_CONTAINER(profile_vb), 0);
+ gtk_container_add(GTK_CONTAINER(main_vb), profile_vb);
+ gtk_widget_show(profile_vb);
+
+ /* Top row: Buttons and profile list */
+ top_hb = gtk_hbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(profile_vb), top_hb);
+ gtk_widget_show(top_hb);
+
+ edit_fr = gtk_frame_new("Edit");
+ gtk_box_pack_start(GTK_BOX(top_hb), edit_fr, FALSE, FALSE, 0);
+ gtk_widget_show(edit_fr);
+
+ list_bb = gtk_vbox_new(TRUE, 0);
+ gtk_container_border_width(GTK_CONTAINER(list_bb), 5);
+ gtk_container_add(GTK_CONTAINER(edit_fr), list_bb);
+ gtk_widget_show(list_bb);
+
+ new_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_NEW);
+ SIGNAL_CONNECT(new_bt, "clicked", profile_new_bt_clicked_cb, NULL);
+ gtk_widget_show(new_bt);
+ gtk_box_pack_start (GTK_BOX (list_bb), new_bt, FALSE, FALSE, 0);
+ gtk_tooltips_set_tip (tooltips, new_bt,
+ "Create a new profile (with default properties)", NULL);
+
+#if 0
+ copy_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_COPY);
+ gtk_widget_set_sensitive(copy_bt, FALSE);
+ SIGNAL_CONNECT(copy_bt, "clicked", profile_copy_bt_clicked_cb, NULL);
+ OBJECT_SET_DATA(main_w, E_PROF_COPY_BT_KEY, copy_bt);
+ gtk_widget_show(copy_bt);
+ gtk_box_pack_start (GTK_BOX (list_bb), copy_bt, FALSE, FALSE, 0);
+ gtk_tooltips_set_tip (tooltips, copy_bt,
+ "Copy the selected profile", NULL);
+#endif
+
+ del_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_DELETE);
+ gtk_widget_set_sensitive(del_bt, FALSE);
+ SIGNAL_CONNECT(del_bt, "clicked", profile_del_bt_clicked_cb, NULL);
+ OBJECT_SET_DATA(main_w, E_PROF_DEL_BT_KEY, del_bt);
+ gtk_widget_show(del_bt);
+ gtk_box_pack_start (GTK_BOX (list_bb), del_bt, FALSE, FALSE, 0);
+ gtk_tooltips_set_tip (tooltips, del_bt, "Delete the selected profile", NULL);
+
+ profile_fr = gtk_frame_new("Configuration Profiles");
+ gtk_box_pack_start(GTK_BOX(top_hb), profile_fr, TRUE, TRUE, 0);
+ gtk_widget_show(profile_fr);
+
+ profile_sc = scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(profile_sc),
+ GTK_SHADOW_IN);
+
+ gtk_container_set_border_width (GTK_CONTAINER (profile_sc), 5);
+ gtk_container_add(GTK_CONTAINER(profile_fr), profile_sc);
+ gtk_widget_show(profile_sc);
+
+ store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
+ profile_l = tree_view_new(GTK_TREE_MODEL(store));
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(profile_l), FALSE);
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
+ gtk_tree_view_column_set_sort_column_id(column, 0);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(profile_l), column);
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(profile_l));
+ gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+ SIGNAL_CONNECT(sel, "changed", profile_sel_list_cb, profile_vb);
+ SIGNAL_CONNECT(profile_l, "button_press_event", profile_sel_list_button_cb, NULL);
+ OBJECT_SET_DATA(main_w, E_PROF_PROFILE_L_KEY, profile_l);
+ gtk_container_add(GTK_CONTAINER(profile_sc), profile_l);
+ gtk_widget_show(profile_l);
+
+ OBJECT_SET_DATA(profile_l, E_PROF_SELFUNC_KEY, profile_dlg_select);
+ OBJECT_SET_DATA(profile_l, E_PROF_SELARG_KEY, main_w);
+
+ /* fill in data */
+ l_select = fill_list(main_w);
+
+ g_object_unref(G_OBJECT(store));
+
+ props_fr = gtk_frame_new("Properties");
+ gtk_box_pack_start(GTK_BOX(profile_vb), props_fr, FALSE, FALSE, 0);
+ gtk_widget_show(props_fr);
+
+ props_vb = gtk_vbox_new(FALSE, 3);
+ gtk_container_border_width(GTK_CONTAINER(props_vb), 5);
+ gtk_container_add(GTK_CONTAINER(props_fr), props_vb);
+ gtk_widget_show(props_vb);
+
+ /* row: Profile name entry */
+ middle_hb = gtk_hbox_new(FALSE, 3);
+ gtk_container_add(GTK_CONTAINER(props_vb), middle_hb);
+ gtk_widget_show(middle_hb);
+
+ name_lb = gtk_label_new("Profile name:");
+ gtk_box_pack_start(GTK_BOX(middle_hb), name_lb, FALSE, FALSE, 0);
+ gtk_widget_show(name_lb);
+
+ name_te = gtk_entry_new();
+ gtk_box_pack_start(GTK_BOX(middle_hb), name_te, TRUE, TRUE, 0);
+ OBJECT_SET_DATA(main_w, E_PROF_NAME_TE_KEY, name_te);
+ SIGNAL_CONNECT(name_te, "changed", profile_name_te_changed_cb, NULL);
+ gtk_widget_show(name_te);
+
+ /* button row (create all possible buttons and hide the unrequired later - it's a lot easier) */
+ bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
+ gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
+ gtk_widget_show(bbox);
+
+ ok_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_OK);
+ SIGNAL_CONNECT(ok_bt, "clicked", profile_dlg_ok_cb, NULL);
+ gtk_tooltips_set_tip (tooltips, ok_bt, "Apply the profiles and close this dialog", NULL);
+
+ /* Catch the "activate" signal on the profile name and profile
+ list 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 widget that *doesn't*
+ handle the Return key has the input focus. */
+ dlg_set_activate(name_te, ok_bt);
+
+ apply_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_APPLY);
+ SIGNAL_CONNECT(apply_bt, "clicked", profile_dlg_apply_cb, NULL);
+ gtk_tooltips_set_tip (tooltips, apply_bt, "Apply the profiles and keep this dialog open", NULL);
+
+ cancel_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
+ gtk_tooltips_set_tip (tooltips, cancel_bt, "Cancel the changes", NULL);
+ SIGNAL_CONNECT(cancel_bt, "clicked", profile_dlg_cancel_cb, NULL);
+ window_set_cancel_button(main_w, cancel_bt, NULL);
+
+ help_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_HELP);
+ SIGNAL_CONNECT(help_bt, "clicked", topic_cb, HELP_CONFIG_PROFILES_DIALOG);
+ gtk_tooltips_set_tip (tooltips, help_bt, "Show topic specific help", NULL);
+
+ if(ok_bt) {
+ gtk_widget_grab_default(ok_bt);
+ }
+
+
+ /* DO SELECTION THINGS *AFTER* SHOWING THE DIALOG! */
+ /* otherwise the updatings can get confused */
+ if (l_select) {
+ gtk_tree_selection_select_iter(sel, l_select);
+ g_free(l_select);
+ }
+
+ SIGNAL_CONNECT(main_w, "delete_event", profile_dlg_delete_event_cb, NULL);
+ SIGNAL_CONNECT(main_w, "destroy", profile_dlg_destroy_cb, NULL);
+
+ gtk_widget_show(main_w);
+
+ window_present(main_w);
+
+ return main_w;
+}
+
+#endif
+
+
+/* Create a profile dialog for editing display profiles; this is to be used
+ as a callback for menu items, toolbars, etc.. */
+void
+profile_dialog_cb(GtkWidget *w _U_)
+{
+#if GTK_MAJOR_VERSION >= 2
+ /* Has a profiles dialog box already been opened */
+ if (global_profile_w != NULL) {
+ /* Yes. Just reactivate it. */
+ reactivate_window(global_profile_w);
+ } else {
+ global_profile_w = profile_dialog_new ();
+ }
+#endif
+}
+
diff --git a/gtk/profile_dlg.h b/gtk/profile_dlg.h
new file mode 100644
index 0000000000..df6fcb391b
--- /dev/null
+++ b/gtk/profile_dlg.h
@@ -0,0 +1,41 @@
+/* profile_dlg.h
+ * Definitions for dialog box for profiles editing.
+ * Stig Bjørlykke <stig@bjorlykke.org>, 2008
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PROFILE_DLG_H__
+#define __PROFILE_DLG_H__
+
+/** @file
+ * "Configuration Profiles" dialog box
+ * @ingroup dialog_group
+ */
+
+
+/** User requested the "Configuration Profiles" dialog box by menu or toolbar.
+ *
+ * @param widget parent widget
+ */
+void profile_dialog_cb(GtkWidget *widget);
+
+#endif /* profile_dlg.h */
diff --git a/gtk/recent.c b/gtk/recent.c
index 913812094d..7f0dfe46ea 100644
--- a/gtk/recent.c
+++ b/gtk/recent.c
@@ -72,7 +72,8 @@
#define RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED "gui.geometry_main_maximized"
#define RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE "gui.geometry_main_upper_pane"
#define RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE "gui.geometry_main_lower_pane"
-#define RECENT_GUI_GEOMETRY_STATUS_PANE "gui.geometry_status_pane"
+#define RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT "gui.geometry_status_pane"
+#define RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT "gui.geometry_status_pane_right"
#define RECENT_GUI_FILEOPEN_REMEMBERED_DIR "gui.fileopen_remembered_dir"
#define RECENT_GUI_GEOMETRY "gui.geom."
#define RECENT_KEY_PRIVS_WARN_IF_ELEVATED "privs.warn_if_elevated"
@@ -133,7 +134,7 @@ write_recent(void)
return FALSE;
}
- rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE);
+ rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE, TRUE);
if ((rf = eth_fopen(rf_path, "w")) == NULL) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"Can't open recent file\n\"%s\": %s.", rf_path,
@@ -259,9 +260,16 @@ write_recent(void)
fprintf(rf, "\n# Statusbar left pane size.\n");
fprintf(rf, "# (GTK1: has no effect here, command line -o usage only).\n");
fprintf(rf, "# Decimal number.\n");
- if (recent.gui_geometry_status_pane != 0) {
- fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE ": %d\n",
- recent.gui_geometry_status_pane);
+ if (recent.gui_geometry_status_pane_left != 0) {
+ fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT ": %d\n",
+ recent.gui_geometry_status_pane_left);
+ }
+ fprintf(rf, "\n# Statusbar middle pane size.\n");
+ fprintf(rf, "# (GTK1: has no effect here, command line -o usage only).\n");
+ fprintf(rf, "# Decimal number.\n");
+ if (recent.gui_geometry_status_pane_right != 0) {
+ fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT ": %d\n",
+ recent.gui_geometry_status_pane_right);
}
fprintf(rf, "\n# Warn if running with elevated permissions (e.g. as root).\n");
@@ -446,13 +454,21 @@ read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_)
return PREFS_SET_SYNTAX_ERR; /* number must be positive */
recent.gui_geometry_main_lower_pane = num;
recent.has_gui_geometry_main_lower_pane = TRUE;
- } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE) == 0) {
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ if (num <= 0)
+ return PREFS_SET_SYNTAX_ERR; /* number must be positive */
+ recent.gui_geometry_status_pane_right = num;
+ recent.has_gui_geometry_status_pane = TRUE;
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT) == 0) {
num = strtol(value, &p, 0);
if (p == value || *p != '\0')
return PREFS_SET_SYNTAX_ERR; /* number was bad */
if (num <= 0)
return PREFS_SET_SYNTAX_ERR; /* number must be positive */
- recent.gui_geometry_status_pane = num;
+ recent.gui_geometry_status_pane_left = num;
recent.has_gui_geometry_status_pane = TRUE;
} else if (strcmp(key, RECENT_GUI_FILEOPEN_REMEMBERED_DIR) == 0) {
if(u3_active())
@@ -580,7 +596,8 @@ recent_read_static(char **rf_path_return, int *rf_errno_return)
/* pane size of zero will autodetect */
recent.gui_geometry_main_upper_pane = 0;
recent.gui_geometry_main_lower_pane = 0;
- recent.gui_geometry_status_pane = 0;
+ recent.gui_geometry_status_pane_left = (DEF_WIDTH/3);
+ recent.gui_geometry_status_pane_right = (DEF_WIDTH/3);
/* the following are only used if GTK2 is used (as GTK1 cannot read these geometry values) */
/* or if set through command line */
@@ -598,7 +615,7 @@ recent_read_static(char **rf_path_return, int *rf_errno_return)
recent.privs_warn_if_no_npf = TRUE;
/* Construct the pathname of the user's recent file. */
- rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE);
+ rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE, FALSE);
/* Read the user's recent file, if it exists. */
*rf_path_return = NULL;
@@ -630,7 +647,7 @@ recent_read_dynamic(char **rf_path_return, int *rf_errno_return)
/* Construct the pathname of the user's recent file. */
- rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE);
+ rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE, FALSE);
/* Read the user's recent file, if it exists. */
*rf_path_return = NULL;
diff --git a/gtk/recent.h b/gtk/recent.h
index 0a2fa6c0bb..ff3aba9142 100644
--- a/gtk/recent.h
+++ b/gtk/recent.h
@@ -66,7 +66,8 @@ typedef struct recent_settings_tag {
gboolean has_gui_geometry_main_lower_pane; /* gui_geometry_main_lower_pane is valid */
gint gui_geometry_main_lower_pane; /* this is autodetected in GTK2 only */
gboolean has_gui_geometry_status_pane; /* gui_geometry_status_pane is valid */
- gint gui_geometry_status_pane; /* this is autodetected in GTK2 only */
+ gint gui_geometry_status_pane_left; /* this is autodetected in GTK2 only */
+ gint gui_geometry_status_pane_right; /* this is autodetected in GTK2 only */
gboolean privs_warn_if_elevated;
gboolean privs_warn_if_no_npf;
} recent_settings_t;