diff --git a/epan/column.c b/epan/column.c index d7348e11c5..58a346a09b 100644 --- a/epan/column.c +++ b/epan/column.c @@ -647,7 +647,7 @@ get_column_title(gint col) { return(cfmt->title); } -gchar * +const gchar * get_column_custom_field(gint col) { GList *clp = g_list_nth(prefs.col_list, col); fmt_data *cfmt; diff --git a/epan/column.h b/epan/column.h index 78aea67d5b..b5aff2d3fb 100644 --- a/epan/column.h +++ b/epan/column.h @@ -41,7 +41,7 @@ gint get_column_format(gint); void get_column_format_matches(gboolean *, gint); gint get_column_format_from_str(gchar *); gchar *get_column_title(gint); -gchar *get_column_custom_field(gint); +const gchar *get_column_custom_field(gint); const gchar *get_column_width_string(gint, gint); const char *get_column_longest_string(gint); gint get_column_char_width(gint format); diff --git a/epan/libwireshark.def b/epan/libwireshark.def index b9e2804129..34c4430d21 100644 --- a/epan/libwireshark.def +++ b/epan/libwireshark.def @@ -597,8 +597,10 @@ postseq_cleanup_all_protocols prefs DATA prefs_apply prefs_apply_all +prefs_clear_string_list prefs_is_capture_device_hidden prefs_find_module +prefs_get_string_list prefs_get_title_by_name prefs_is_registered_protocol prefs_module_has_submodules diff --git a/epan/prefs.c b/epan/prefs.c index ab1ae76cdc..1b4c20188e 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -58,9 +58,7 @@ static module_t *prefs_register_module_or_subtree(module_t *parent, void (*apply_cb)(void)); static struct preference *find_preference(module_t *, const char *); static prefs_set_pref_e set_pref(gchar*, gchar*, void *); -static GList *get_string_list(gchar *); static gchar *put_string_list(GList *); -static void clear_string_list(GList *); static void free_col_info(e_prefs *); #define PF_NAME "preferences" @@ -806,8 +804,8 @@ prefs_register_modules(void) /* Parse through a list of comma-separated, possibly quoted strings. Return a list of the string data. */ -static GList * -get_string_list(gchar *str) +GList * +prefs_get_string_list(gchar *str) { enum { PRE_STRING, IN_QUOT, NOT_IN_QUOT }; @@ -830,7 +828,7 @@ get_string_list(gchar *str) /* We were in the middle of a quoted string or backslash escape, and ran out of characters; that's an error. */ g_free(slstr); - clear_string_list(sl); + prefs_clear_string_list(sl); return NULL; } slstr[j] = '\0'; @@ -956,8 +954,8 @@ put_string_list(GList *sl) return(pref_str); } -static void -clear_string_list(GList *sl) +void +prefs_clear_string_list(GList *sl) { GList *l = sl; @@ -1157,9 +1155,10 @@ init_prefs(void) { prefs.gui_marked_bg.blue = 0; prefs.gui_colorized_fg = g_strdup("000000,000000,000000,000000,000000,000000,000000,000000,000000,000000"); prefs.gui_colorized_bg = g_strdup("ffc0c0,ffc0ff,e0c0e0,c0c0ff,c0e0e0,c0ffff,c0ffc0,ffffc0,e0e0c0,e0e0e0"); - prefs.gui_geometry_save_position = 0; - prefs.gui_geometry_save_size = 1; - prefs.gui_geometry_save_maximized= 1; + prefs.gui_geometry_save_position = FALSE; + prefs.gui_geometry_save_size = TRUE; + prefs.gui_geometry_save_maximized= TRUE; + prefs.gui_geometry_save_column_width = FALSE; prefs.gui_console_open = console_open_never; prefs.gui_fileopen_style = FO_STYLE_LAST_OPENED; prefs.gui_recent_files_count_max = 10; @@ -1631,6 +1630,7 @@ prefs_is_capture_device_hidden(const char *name) #define PRS_GUI_GEOMETRY_SAVE_POSITION "gui.geometry.save.position" #define PRS_GUI_GEOMETRY_SAVE_SIZE "gui.geometry.save.size" #define PRS_GUI_GEOMETRY_SAVE_MAXIMIZED "gui.geometry.save.maximized" +#define PRS_GUI_GEOMETRY_SAVE_COLUMN_WIDTH "gui.geometry.save.column_width" #define PRS_GUI_GEOMETRY_MAIN_X "gui.geometry.main.x" #define PRS_GUI_GEOMETRY_MAIN_Y "gui.geometry.main.y" #define PRS_GUI_GEOMETRY_MAIN_WIDTH "gui.geometry.main.width" @@ -1777,12 +1777,12 @@ set_pref(gchar *pref_name, gchar *value, void *private_data _U_) if (prefs.pr_cmd) g_free(prefs.pr_cmd); prefs.pr_cmd = g_strdup(value); } else if (strcmp(pref_name, PRS_COL_FMT) == 0) { - col_l = get_string_list(value); + col_l = prefs_get_string_list(value); if (col_l == NULL) return PREFS_SET_SYNTAX_ERR; if ((g_list_length(col_l) % 2) != 0) { /* A title didn't have a matching format. */ - clear_string_list(col_l); + prefs_clear_string_list(col_l); return PREFS_SET_SYNTAX_ERR; } /* Check to make sure all column formats are valid. */ @@ -1791,7 +1791,7 @@ set_pref(gchar *pref_name, gchar *value, void *private_data _U_) /* Make sure the title isn't empty. */ if (strcmp(col_l_elt->data, "") == 0) { /* It is. */ - clear_string_list(col_l); + prefs_clear_string_list(col_l); return PREFS_SET_SYNTAX_ERR; } @@ -1802,7 +1802,7 @@ set_pref(gchar *pref_name, gchar *value, void *private_data _U_) if (strncmp(col_l_elt->data, cust_format, cust_format_len) != 0) { if (get_column_format_from_str(col_l_elt->data) == -1) { /* It's not a valid column format. */ - clear_string_list(col_l); + prefs_clear_string_list(col_l); return PREFS_SET_SYNTAX_ERR; } } @@ -1831,7 +1831,7 @@ set_pref(gchar *pref_name, gchar *value, void *private_data _U_) col_l_elt = col_l_elt->next; prefs.col_list = g_list_append(prefs.col_list, cfmt); } - clear_string_list(col_l); + prefs_clear_string_list(col_l); } else if (strcmp(pref_name, PRS_STREAM_CL_FG) == 0) { cval = strtoul(value, NULL, 16); prefs.st_client_fg.pixel = 0; @@ -1954,6 +1954,13 @@ set_pref(gchar *pref_name, gchar *value, void *private_data _U_) else { prefs.gui_geometry_save_maximized = FALSE; } + } else if (strcmp(pref_name, PRS_GUI_GEOMETRY_SAVE_COLUMN_WIDTH) == 0) { + if (g_ascii_strcasecmp(value, "true") == 0) { + prefs.gui_geometry_save_column_width = TRUE; + } + else { + prefs.gui_geometry_save_column_width = FALSE; + } } else if (strcmp(pref_name, PRS_GUI_GEOMETRY_MAIN_X) == 0) { /* deprecated */ } else if (strcmp(pref_name, PRS_GUI_GEOMETRY_MAIN_Y) == 0) { /* deprecated */ } else if (strcmp(pref_name, PRS_GUI_GEOMETRY_MAIN_WIDTH) == 0) { /* deprecated */ @@ -2613,11 +2620,16 @@ write_prefs(char **pf_path_return) fprintf(pf, PRS_GUI_GEOMETRY_SAVE_SIZE ": %s\n", prefs.gui_geometry_save_size == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "\n# Save window maximized state at exit (GTK2 only)?\n"); + fprintf(pf, "\n# Save window maximized state at exit?\n"); fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(pf, PRS_GUI_GEOMETRY_SAVE_MAXIMIZED ": %s\n", prefs.gui_geometry_save_maximized == TRUE ? "TRUE" : "FALSE"); + fprintf(pf, "\n# Save packet list column widths?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); + fprintf(pf, PRS_GUI_GEOMETRY_SAVE_COLUMN_WIDTH ": %s\n", + prefs.gui_geometry_save_column_width == TRUE ? "TRUE" : "FALSE"); + fprintf(pf, "\n# Open a console window (WIN32 only)?\n"); fprintf(pf, "# One of: NEVER, AUTOMATIC, ALWAYS\n"); fprintf(pf, PRS_GUI_CONSOLE_OPEN ": %s\n", @@ -2909,6 +2921,7 @@ copy_prefs(e_prefs *dest, e_prefs *src) dest->gui_geometry_save_position = src->gui_geometry_save_position; dest->gui_geometry_save_size = src->gui_geometry_save_size; dest->gui_geometry_save_maximized = src->gui_geometry_save_maximized; + dest->gui_geometry_save_column_width = src->gui_geometry_save_column_width; dest->gui_webbrowser = g_strdup(src->gui_webbrowser); dest->gui_window_title = g_strdup(src->gui_window_title); dest->console_log_level = src->console_log_level; diff --git a/epan/prefs.h b/epan/prefs.h index f8419440be..2b632cb151 100644 --- a/epan/prefs.h +++ b/epan/prefs.h @@ -122,6 +122,7 @@ typedef struct _e_prefs { gboolean gui_geometry_save_position; gboolean gui_geometry_save_size; gboolean gui_geometry_save_maximized; + gboolean gui_geometry_save_column_width; console_open_e gui_console_open; guint gui_recent_files_count_max; guint gui_fileopen_style; @@ -359,6 +360,14 @@ typedef guint (*pref_cb)(pref_t *pref, gpointer user_data); extern guint prefs_pref_foreach(module_t *module, pref_cb callback, gpointer user_data); +/* Parse through a list of comma-separated, possibly quoted strings. + * Return a list of the string data. + */ +extern GList *prefs_get_string_list(gchar *str); + +/* Clear the given list of string data. */ +extern void prefs_clear_string_list(GList *sl); + /* * Register all non-dissector modules' preferences. */ diff --git a/gtk/font_utils.c b/gtk/font_utils.c index 53455a6ced..a559f80657 100644 --- a/gtk/font_utils.c +++ b/gtk/font_utils.c @@ -92,7 +92,7 @@ view_zoom_in_cb(GtkWidget *w _U_, gpointer d _U_) save_gui_zoom_level = recent.gui_zoom_level; recent.gui_zoom_level++; - switch (user_font_apply()) { + switch (user_font_apply(FALSE)) { case FA_SUCCESS: break; @@ -118,7 +118,7 @@ view_zoom_out_cb(GtkWidget *w _U_, gpointer d _U_) save_gui_zoom_level = recent.gui_zoom_level; recent.gui_zoom_level--; - switch (user_font_apply()) { + switch (user_font_apply(FALSE)) { case FA_SUCCESS: break; @@ -144,7 +144,7 @@ view_zoom_100_cb(GtkWidget *w _U_, gpointer d _U_) save_gui_zoom_level = recent.gui_zoom_level; recent.gui_zoom_level = 0; - switch (user_font_apply()) { + switch (user_font_apply(FALSE)) { case FA_SUCCESS: break; @@ -238,7 +238,7 @@ font_zoom(char *gui_font_name) } fa_ret_t -user_font_apply(void) { +user_font_apply(gboolean saved_column_width) { char *gui_font_name; PangoFontDescription *new_r_font, *new_b_font; PangoFontDescription *old_r_font = NULL, *old_b_font = NULL; @@ -276,7 +276,7 @@ user_font_apply(void) { } /* the font(s) seem to be ok */ - packet_list_set_font(new_r_font); + packet_list_set_font(new_r_font, saved_column_width); set_ptree_font_all(new_r_font); old_r_font = m_r_font; old_b_font = m_b_font; diff --git a/gtk/font_utils.h b/gtk/font_utils.h index 441dcb7fb2..10eb949aca 100644 --- a/gtk/font_utils.h +++ b/gtk/font_utils.h @@ -49,9 +49,11 @@ typedef enum { /** Applies a new user font, corresponding to the preferences font name and recent zoom level. * Will also redraw the screen. * + * @param saved_column_width set if using saved column widths + * * @return if the new font could be set or not */ -extern fa_ret_t user_font_apply(void); +extern fa_ret_t user_font_apply(gboolean saved_column_width); /** Test, if the given font name is available. * diff --git a/gtk/gui_prefs.c b/gtk/gui_prefs.c index 68d5ff53ec..fd316432d0 100644 --- a/gtk/gui_prefs.c +++ b/gtk/gui_prefs.c @@ -60,6 +60,7 @@ static gint recent_files_count_changed_cb(GtkWidget *recent_files_entry _U_, #define GEOMETRY_POSITION_KEY "geometry_position" #define GEOMETRY_SIZE_KEY "geometry_size" #define GEOMETRY_MAXIMIZED_KEY "geometry_maximized" +#define GEOMETRY_COLUMN_WIDTH_KEY "geometry_column_width" #define GUI_CONSOLE_OPEN_KEY "console_open" #define GUI_FILEOPEN_KEY "fileopen_behavior" @@ -157,7 +158,7 @@ gui_prefs_show(void) GtkWidget *recent_files_count_max_te, *ask_unsaved_cb, *find_wrap_cb; GtkWidget *use_pref_save_cb; GtkWidget *webbrowser_te; - GtkWidget *save_position_cb, *save_size_cb, *save_maximized_cb; + GtkWidget *save_position_cb, *save_size_cb, *save_maximized_cb, *save_column_width_cb; GtkTooltips *tooltips = gtk_tooltips_new(); @@ -215,6 +216,12 @@ gui_prefs_show(void) "maximed state of the main window.", NULL); g_object_set_data(G_OBJECT(main_vb), GEOMETRY_MAXIMIZED_KEY, save_maximized_cb); + save_column_width_cb = create_preference_check_button(main_tb, pos++, + "Save column widths:", NULL, prefs.gui_geometry_save_column_width); + gtk_tooltips_set_tip(tooltips, save_column_width_cb, "Whether to save the " + "column widths.", NULL); + g_object_set_data(G_OBJECT(main_vb), GEOMETRY_COLUMN_WIDTH_KEY, save_column_width_cb); + #ifdef _WIN32 /* How the console window should be opened */ console_open_om = create_preference_option_menu(main_tb, pos++, @@ -363,6 +370,8 @@ gui_prefs_fetch(GtkWidget *w) gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), GEOMETRY_SIZE_KEY)); prefs.gui_geometry_save_maximized = gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), GEOMETRY_MAXIMIZED_KEY)); + prefs.gui_geometry_save_column_width = + gtk_toggle_button_get_active(g_object_get_data(G_OBJECT(w), GEOMETRY_COLUMN_WIDTH_KEY)); #ifdef _WIN32 prefs.gui_console_open = fetch_enum_value( g_object_get_data(G_OBJECT(w), GUI_CONSOLE_OPEN_KEY), gui_console_open_vals); @@ -420,7 +429,7 @@ gui_prefs_apply(GtkWidget *w _U_ , gboolean redissect) if (font_changed) { /* This redraws the hex dump windows. */ - switch (user_font_apply()) { + switch (user_font_apply(FALSE)) { case FA_SUCCESS: break; diff --git a/gtk/main.c b/gtk/main.c index 221b6de04e..4e413f602a 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -2540,7 +2540,7 @@ main(int argc, char *argv[]) menu_auto_scroll_live_changed(auto_scroll_live); #endif - switch (user_font_apply()) { + switch (user_font_apply(prefs->gui_geometry_save_column_width)) { case FA_SUCCESS: break; case FA_FONT_NOT_RESIZEABLE: @@ -3963,5 +3963,6 @@ void change_configuration_profile (const gchar *profile_name) /* Recreate the packet list according to new preferences */ packet_list_recreate (); - user_font_apply(); + cfile.cinfo.columns_changed = FALSE; /* Reset value */ + user_font_apply(prefs.gui_geometry_save_column_width); } diff --git a/gtk/packet_list.c b/gtk/packet_list.c index 782c56114a..b1cefb4de7 100644 --- a/gtk/packet_list.c +++ b/gtk/packet_list.c @@ -48,6 +48,7 @@ #include "keys.h" #include "font_utils.h" #include "packet_history.h" +#include "recent.h" #include @@ -433,7 +434,7 @@ packet_list_set_sel_browse(gboolean val, gboolean force_set) /* Set the font of the packet list window. */ void -packet_list_set_font(PangoFontDescription *font) +packet_list_set_font(PangoFontDescription *font, gboolean saved_column_width) { int i; gint col_width; @@ -448,13 +449,18 @@ packet_list_set_font(PangoFontDescription *font) /* Compute default column sizes. */ for (i = 0; i < cfile.cinfo.num_cols; i++) { - layout = gtk_widget_create_pango_layout(packet_list, - get_column_width_string(get_column_format(i), i)); - pango_layout_get_pixel_size(layout, &col_width, NULL); - g_object_unref(G_OBJECT(layout)); - + col_width = -1; + if (saved_column_width) { + col_width = recent_get_column_width(i); + } + if (col_width == -1) { + layout = gtk_widget_create_pango_layout(packet_list, + get_column_width_string(get_column_format(i), i)); + pango_layout_get_pixel_size(layout, &col_width, NULL); + g_object_unref(G_OBJECT(layout)); + } gtk_clist_set_column_width(GTK_CLIST(packet_list), i, - col_width); + col_width); } } @@ -486,7 +492,7 @@ packet_list_new(e_prefs *prefs) gtk_container_add(GTK_CONTAINER(pkt_scrollw), packet_list); packet_list_set_sel_browse(prefs->gui_plist_sel_browse, FALSE); - packet_list_set_font(user_font_get_regular()); + packet_list_set_font(user_font_get_regular(), prefs->gui_geometry_save_column_width); gtk_widget_set_name(packet_list, "packet list"); g_signal_connect(packet_list, "select-row", G_CALLBACK(packet_list_select_cb), NULL); g_signal_connect(packet_list, "unselect-row", G_CALLBACK(packet_list_unselect_cb), NULL); @@ -796,13 +802,18 @@ packet_list_set_text(gint row, gint column, const gchar *text) void packet_list_set_cls_time_width(gint column) { - gint width; + gint width = -1; PangoLayout *layout; - layout = gtk_widget_create_pango_layout(packet_list, - get_column_longest_string(COL_CLS_TIME)); - pango_layout_get_pixel_size(layout, &width, NULL); - g_object_unref(G_OBJECT(layout)); + if (prefs.gui_geometry_save_column_width) { + width = recent_get_column_width(column); + } + if (width == -1) { + layout = gtk_widget_create_pango_layout(packet_list, + get_column_longest_string(COL_CLS_TIME)); + pango_layout_get_pixel_size(layout, &width, NULL); + g_object_unref(G_OBJECT(layout)); + } gtk_clist_set_column_width(GTK_CLIST(packet_list), column, width); } @@ -952,3 +963,23 @@ packet_list_set_sort_column(void) packet_list_thaw(); } + +void +packet_list_recent_write_all(FILE *rf) +{ + gint col; + + fprintf (rf, "%s:", RECENT_KEY_COL_WIDTH); + for (col = 0; col < cfile.cinfo.num_cols; col++) { + if (cfile.cinfo.col_fmt[col] == COL_CUSTOM) { + fprintf (rf, " %%Cus:%s,", get_column_custom_field(col)); + } else { + fprintf (rf, " %s,", col_format_to_string(cfile.cinfo.col_fmt[col])); + } + fprintf (rf, " %d", GTK_CLIST(packet_list)->column[col].width); + if (col != cfile.cinfo.num_cols-1) { + fprintf (rf, ","); + } + } + fprintf (rf, "\n"); +} diff --git a/gtk/packet_list.h b/gtk/packet_list.h index d6cb2d1efa..bffdce7f1c 100644 --- a/gtk/packet_list.h +++ b/gtk/packet_list.h @@ -25,6 +25,8 @@ #ifndef __PACKET_LIST_H__ #define __PACKET_LIST_H__ +#define RECENT_KEY_COL_WIDTH "column.width" + /** @file * Packet list pane. * @ingroup main_window_group @@ -92,8 +94,9 @@ extern gboolean packet_list_get_event_row_column(GtkWidget *widget, /** Set the font of the packet list. * * @param font the new font + * @param saved_column_width set if using saved column widths */ -extern void packet_list_set_font(PangoFontDescription *font); +extern void packet_list_set_font(PangoFontDescription *font, gboolean saved_column_width); /** Set the selection mode of the packet list window. * @@ -131,4 +134,11 @@ typedef enum { * @param copy_type Mode in which to copy data (e.g. tab-separated, CSV) */ extern void packet_list_copy_summary_cb(GtkWidget * w _U_, gpointer data _U_, copy_summary_type copy_type); + +/** Write all packet list geometry values to the recent file. + * + * @param rf recent file handle from caller + */ +extern void packet_list_recent_write_all(FILE *rf); + #endif /* __PACKET_LIST_H__ */ diff --git a/gtk/recent.c b/gtk/recent.c index 36e39217b6..c4b4ab0a1d 100644 --- a/gtk/recent.c +++ b/gtk/recent.c @@ -39,7 +39,9 @@ #include "main_menu.h" #include #include +#include #include "gui_utils.h" +#include "packet_list.h" #if 0 #include "dlg_utils.h" #endif @@ -105,6 +107,23 @@ find_index_from_string_array(const char *needle, const char **haystack, int defa return default_value; } +static void +free_col_width_info(recent_settings_t *rs) +{ + col_width_data *cfmt; + + while (rs->col_width_list != NULL) { + cfmt = rs->col_width_list->data; + if (cfmt->cfield) { + g_free(cfmt->cfield); + } + g_free(cfmt); + rs->col_width_list = g_list_remove_link(rs->col_width_list, rs->col_width_list); + } + g_list_free(rs->col_width_list); + rs->col_width_list = NULL; +} + /* Attempt to Write out "recent" to the user's recent file. If we got an error report it with a dialog box and return FALSE, otherwise return TRUE. */ @@ -236,7 +255,7 @@ write_recent(void) fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_HEIGHT ": %d\n", recent.gui_geometry_main_height); - fprintf(rf, "\n# Main window maximized (GTK2 only!).\n"); + fprintf(rf, "\n# Main window maximized.\n"); fprintf(rf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED ": %s\n", recent.gui_geometry_main_maximized == TRUE ? "TRUE" : "FALSE"); @@ -266,6 +285,10 @@ write_recent(void) recent.gui_geometry_status_pane_right); } + fprintf(rf, "\n# Packet list column pixel widths.\n"); + fprintf(rf, "# Each pair of strings consists of a column format and its pixel width.\n"); + packet_list_recent_write_all(rf); + fprintf(rf, "\n# Warn if running with elevated permissions (e.g. as root).\n"); fprintf(rf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_ELEVATED ": %s\n", @@ -303,7 +326,7 @@ write_recent_geom(gpointer key _U_, gpointer value, gpointer rf) { window_geometry_t *geom = value; - fprintf(rf, "\n# Geometry and maximized state (GTK2 only) of %s window.\n", geom->key); + fprintf(rf, "\n# Geometry and maximized state of %s window.\n", geom->key); fprintf(rf, "# Decimal integers.\n"); fprintf(rf, RECENT_GUI_GEOMETRY "%s.x: %d\n", geom->key, geom->x); fprintf(rf, RECENT_GUI_GEOMETRY "%s.y: %d\n", geom->key, geom->y); @@ -325,6 +348,10 @@ read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_) { long num; char *p; + GList *col_l, *col_l_elt; + col_width_data *cfmt; + const gchar *cust_format = col_format_to_string(COL_CUSTOM); + int cust_format_len = strlen(cust_format); if (strcmp(key, RECENT_KEY_MAIN_TOOLBAR_SHOW) == 0) { if (g_ascii_strcasecmp(value, "true") == 0) { @@ -354,7 +381,7 @@ read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_) else { recent.airpcap_driver_check_show = FALSE; } - }else if (strcmp(key, RECENT_KEY_PACKET_LIST_SHOW) == 0) { + } else if (strcmp(key, RECENT_KEY_PACKET_LIST_SHOW) == 0) { if (g_ascii_strcasecmp(value, "true") == 0) { recent.packet_list_show = TRUE; } @@ -492,6 +519,66 @@ read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_) else { recent.privs_warn_if_no_npf = FALSE; } + } else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) { + col_l = prefs_get_string_list(value); + if (col_l == NULL) + return PREFS_SET_SYNTAX_ERR; + if ((g_list_length(col_l) % 2) != 0) { + /* A title didn't have a matching width. */ + prefs_clear_string_list(col_l); + return PREFS_SET_SYNTAX_ERR; + } + /* Check to make sure all column formats are valid. */ + col_l_elt = g_list_first(col_l); + while(col_l_elt) { + /* Make sure the format isn't empty. */ + if (strcmp(col_l_elt->data, "") == 0) { + /* It is. */ + prefs_clear_string_list(col_l); + return PREFS_SET_SYNTAX_ERR; + } + + /* Check the format. */ + if (strncmp(col_l_elt->data, cust_format, cust_format_len) != 0) { + if (get_column_format_from_str(col_l_elt->data) == -1) { + /* It's not a valid column format. */ + prefs_clear_string_list(col_l); + return PREFS_SET_SYNTAX_ERR; + } + } + + /* Go past the format. */ + col_l_elt = col_l_elt->next; + + /* Go past the width. */ + col_l_elt = col_l_elt->next; + } + free_col_width_info(&recent); + recent.col_width_list = NULL; + col_l_elt = g_list_first(col_l); + while(col_l_elt) { + gchar *fmt = g_strdup(col_l_elt->data); + cfmt = (col_width_data *) g_malloc(sizeof(col_width_data)); + if (strncmp(fmt, cust_format, cust_format_len) != 0) { + cfmt->cfmt = get_column_format_from_str(fmt); + cfmt->cfield = NULL; + } else { + cfmt->cfmt = COL_CUSTOM; + cfmt->cfield = g_strdup(&fmt[cust_format_len+1]); /* add 1 for ':' */ + } + g_free (fmt); + if (cfmt->cfmt == -1) + return PREFS_SET_SYNTAX_ERR; /* string was bad */ + + col_l_elt = col_l_elt->next; + cfmt->width = strtol(col_l_elt->data, &p, 0); + if (p == col_l_elt->data || *p != '\0') + return PREFS_SET_SYNTAX_ERR; /* number was bad */ + + col_l_elt = col_l_elt->next; + recent.col_width_list = g_list_append(recent.col_width_list, cfmt); + } + prefs_clear_string_list(col_l); } return PREFS_SET_OK; @@ -600,6 +687,8 @@ recent_read_static(char **rf_path_return, int *rf_errno_return) recent.privs_warn_if_elevated = TRUE; recent.privs_warn_if_no_npf = TRUE; + recent.col_width_list = NULL; + /* Construct the pathname of the user's recent file. */ rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE, FALSE); @@ -656,4 +745,29 @@ recent_read_dynamic(char **rf_path_return, int *rf_errno_return) } } +gint +recent_get_column_width(gint col) +{ + GList *col_l; + col_width_data *col_w; + gint cfmt; + const gchar *cfield = NULL; + cfmt = get_column_format(col); + if (cfmt == COL_CUSTOM) { + cfield = get_column_custom_field(col); + } + + col_l = g_list_first(recent.col_width_list); + while (col_l) { + col_w = (col_width_data *) col_l->data; + if (col_w->cfmt == cfmt) { + if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) { + return col_w->width; + } + } + col_l = col_l->next; + } + + return -1; +} diff --git a/gtk/recent.h b/gtk/recent.h index ff3aba9142..25b4b56cec 100644 --- a/gtk/recent.h +++ b/gtk/recent.h @@ -39,6 +39,12 @@ /** ???. */ #define RECENT_KEY_DISPLAY_FILTER "recent.display_filter" +typedef struct _col_width_data { + gint cfmt; + gchar *cfield; + gint width; +} col_width_data; + /** Recent settings. */ typedef struct recent_settings_tag { gboolean main_toolbar_show; @@ -59,17 +65,18 @@ typedef struct recent_settings_tag { gint gui_geometry_main_width; gint gui_geometry_main_height; - gboolean gui_geometry_main_maximized; /* this is valid in GTK2 only */ + gboolean gui_geometry_main_maximized; gboolean has_gui_geometry_main_upper_pane; /* gui_geometry_main_upper_pane is valid */ - gint gui_geometry_main_upper_pane; /* this is autodetected in GTK2 only */ + gint gui_geometry_main_upper_pane; 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 */ + gint gui_geometry_main_lower_pane; gboolean has_gui_geometry_status_pane; /* gui_geometry_status_pane is valid */ - gint gui_geometry_status_pane_left; /* this is autodetected in GTK2 only */ - gint gui_geometry_status_pane_right; /* this is autodetected in GTK2 only */ + gint gui_geometry_status_pane_left; + gint gui_geometry_status_pane_right; gboolean privs_warn_if_elevated; gboolean privs_warn_if_no_npf; + GList *col_width_list; /* column widths */ } recent_settings_t; /** Global recent settings. */ @@ -114,4 +121,10 @@ extern void write_recent_geom(gpointer key, gpointer value, gpointer rf); */ extern int recent_set_arg(char *prefarg); +/** Get the column width for the given column + * + * @param col column number + */ +extern gint recent_get_column_width(gint col); + #endif /* recent.h */