diff options
-rw-r--r-- | epan/libwireshark.def | 2 | ||||
-rw-r--r-- | epan/prefs-int.h | 13 | ||||
-rw-r--r-- | epan/prefs.c | 965 | ||||
-rw-r--r-- | epan/prefs.h | 37 | ||||
-rw-r--r-- | ui/qt/CMakeLists.txt | 3 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 37 | ||||
-rw-r--r-- | ui/qt/Makefile.common | 3 | ||||
-rw-r--r-- | ui/qt/QtShark.pro | 9 | ||||
-rw-r--r-- | ui/qt/byte_view_tab.cpp | 1 | ||||
-rw-r--r-- | ui/qt/byte_view_text.h | 1 | ||||
-rw-r--r-- | ui/qt/capture_file_dialog.cpp | 2 | ||||
-rw-r--r-- | ui/qt/export_dissection_dialog.cpp | 1 | ||||
-rw-r--r-- | ui/qt/export_object_dialog.ui | 3 | ||||
-rw-r--r-- | ui/qt/file_set_dialog.ui | 3 | ||||
-rw-r--r-- | ui/qt/main_welcome.ui | 5 | ||||
-rw-r--r-- | ui/qt/main_window.h | 1 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 12 | ||||
-rw-r--r-- | ui/qt/preferences_dialog.cpp | 185 | ||||
-rw-r--r-- | ui/qt/preferences_dialog.h | 48 | ||||
-rw-r--r-- | ui/qt/preferences_dialog.ui | 236 | ||||
-rw-r--r-- | ui/qt/profile_dialog.cpp | 1 |
21 files changed, 1197 insertions, 371 deletions
diff --git a/epan/libwireshark.def b/epan/libwireshark.def index 9074cf9eb8..e7742d2117 100644 --- a/epan/libwireshark.def +++ b/epan/libwireshark.def @@ -738,6 +738,8 @@ prefs_module_has_submodules prefs_modules_foreach prefs_modules_foreach_submodules prefs_pref_foreach +prefs_pref_type_description +prefs_pref_type_name prefs_register_bool_preference prefs_register_enum_preference prefs_register_filename_preference diff --git a/epan/prefs-int.h b/epan/prefs-int.h index ec91db175f..9994a4555d 100644 --- a/epan/prefs-int.h +++ b/epan/prefs-int.h @@ -68,14 +68,23 @@ WS_VAR_IMPORT module_t *protocols_module; typedef void (*pref_custom_free_cb) (pref_t* pref); typedef void (*pref_custom_reset_cb) (pref_t* pref); typedef prefs_set_pref_e (*pref_custom_set_cb) (pref_t* pref, const gchar* value, gboolean* changed); -typedef void (*pref_custom_write_cb) (pref_t* pref, write_pref_arg_t* arg); +/* typedef void (*pref_custom_write_cb) (pref_t* pref, write_pref_arg_t* arg); Deprecated. */ +/* pref_custom_type_name_cb should return NULL for internal / hidden preferences. */ +typedef const char * (*pref_custom_type_name_cb) (void); +typedef char * (*pref_custom_type_description_cb) (void); +typedef gboolean (*pref_custom_is_default_cb) (pref_t* pref); +typedef char * (*pref_custom_to_str_cb) (pref_t* pref, gboolean default_val); /** Structure to hold callbacks for PREF_CUSTOM type */ struct pref_custom_cbs { pref_custom_free_cb free_cb; pref_custom_reset_cb reset_cb; pref_custom_set_cb set_cb; - pref_custom_write_cb write_cb; + /* pref_custom_write_cb write_cb; Deprecated. */ + pref_custom_type_name_cb type_name_cb; + pref_custom_type_description_cb type_description_cb; + pref_custom_is_default_cb is_default_cb; + pref_custom_to_str_cb to_str_cb; }; /** diff --git a/epan/prefs.c b/epan/prefs.c index 55a53dd306..2afb6886bd 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -64,7 +64,7 @@ static module_t *prefs_register_module_or_subtree(module_t *parent, const char *name, const char *title, const char *description, gboolean is_subtree, void (*apply_cb)(void), gboolean use_gui); static prefs_set_pref_e set_pref(gchar*, const gchar*, void *, gboolean); -static void write_string_list(FILE *, GList *, gboolean is_default); +static char * join_string_list(GList *); static void free_col_info(GList *); static void pre_init_prefs(void); static gboolean prefs_is_column_visible(const gchar *cols_hidden, fmt_data *cfmt); @@ -1240,23 +1240,27 @@ static prefs_set_pref_e console_log_level_set_cb(pref_t* pref, const gchar* valu return PREFS_SET_OK; } -static void console_log_level_write_cb(pref_t* pref, write_pref_arg_t* arg) -{ - const char *prefix = (arg->module->name != NULL) ? arg->module->name : arg->module->parent->name; - - fprintf(arg->pf, "# (debugging only, not in the Preferences dialog)\n"); - fprintf(arg->pf, "# A bitmask of glib log levels:\n" - "# G_LOG_LEVEL_ERROR = 4\n" - "# G_LOG_LEVEL_CRITICAL = 8\n" - "# G_LOG_LEVEL_WARNING = 16\n" - "# G_LOG_LEVEL_MESSAGE = 32\n" - "# G_LOG_LEVEL_INFO = 64\n" - "# G_LOG_LEVEL_DEBUG = 128\n"); - - if (*pref->varp.uint == pref->default_val.uint) - fprintf(arg->pf, "#"); - fprintf(arg->pf, "%s.%s: %u\n", prefix, - pref->name, *pref->varp.uint); +static const char * console_log_level_type_name_cb(void) { + return "Console log level (for debugging)"; +} + +static char * console_log_level_type_description_cb(void) { + return g_strdup_printf( + "A bitmask of log levels:\n" + "ERROR = 4\n" + "CRITICAL = 8\n" + "WARNING = 16\n" + "MESSAGE = 32\n" + "INFO = 64\n" + "DEBUG = 128"); +} + +static gboolean console_log_level_is_default_cb(pref_t* pref) { + return *pref->varp.uint == pref->default_val.uint; +} + +static char * console_log_level_to_str_cb(pref_t* pref, gboolean default_val) { + return g_strdup_printf("%u", default_val ? pref->default_val.uint : *pref->varp.uint); } /* @@ -1310,50 +1314,61 @@ static prefs_set_pref_e column_hidden_set_cb(pref_t* pref, const gchar* value, g return PREFS_SET_OK; } -static void column_hidden_write_cb(pref_t* pref, write_pref_arg_t* arg) -{ - GString *cols_hidden = g_string_new (""); - GList *clp, *col_l; - fmt_data *cfmt; - const char *prefix = (arg->module->name != NULL) ? arg->module->name : arg->module->parent->name; - pref_t *format_pref; - - format_pref = prefs_find_preference(gui_column_module, PRS_COL_FMT); - clp = *format_pref->varp.list; - col_l = NULL; - while (clp) { - gchar *prefs_fmt; - cfmt = (fmt_data *) clp->data; - col_l = g_list_append(col_l, g_strdup(cfmt->title)); - if ((cfmt->fmt == COL_CUSTOM) && (cfmt->custom_field)) { - prefs_fmt = g_strdup_printf("%s:%s:%d:%c", - col_format_to_string(cfmt->fmt), - cfmt->custom_field, - cfmt->custom_occurrence, - cfmt->resolved ? 'R' : 'U'); - } else { - prefs_fmt = g_strdup(col_format_to_string(cfmt->fmt)); - } - col_l = g_list_append(col_l, prefs_fmt); - if (!cfmt->visible) { - if (cols_hidden->len) { - g_string_append (cols_hidden, ","); - } - g_string_append (cols_hidden, prefs_fmt); +static const char * column_hidden_type_name_cb(void) { + return "Packet list hidden columns"; +} + +static char * column_hidden_type_description_cb(void) { + return g_strdup("List all columns to hide in the packet list."); +} + +static char * column_hidden_to_str_cb(pref_t* pref, gboolean default_val) { + GString *cols_hidden = g_string_new (""); + GList *clp; + fmt_data *cfmt; + pref_t *format_pref; + char *cols_hidden_str; + + if (default_val) + return g_strdup(pref->default_val.string); + + format_pref = prefs_find_preference(gui_column_module, PRS_COL_FMT); + clp = *format_pref->varp.list; + while (clp) { + gchar *prefs_fmt; + cfmt = (fmt_data *) clp->data; + if ((cfmt->fmt == COL_CUSTOM) && (cfmt->custom_field)) { + prefs_fmt = g_strdup_printf("%s:%s:%d:%c", + col_format_to_string(cfmt->fmt), + cfmt->custom_field, + cfmt->custom_occurrence, + cfmt->resolved ? 'R' : 'U'); + } else { + prefs_fmt = g_strdup(col_format_to_string(cfmt->fmt)); + } + if (!cfmt->visible) { + if (cols_hidden->len) { + g_string_append (cols_hidden, ","); + } + g_string_append (cols_hidden, prefs_fmt); + } + clp = clp->next; } - clp = clp->next; - } - fprintf (arg->pf, "\n# Packet list hidden columns.\n"); - fprintf (arg->pf, "# List all columns to hide in the packet list.\n"); - if (strcmp(cols_hidden->str, pref->default_val.string) == 0) - fprintf(arg->pf, "#"); - fprintf (arg->pf, "%s.%s: %s\n", prefix, pref->name, cols_hidden->str); - /* This frees the list of strings, but not the strings to which it - refers; they are free'ed in write_string_list(). */ - g_string_free (cols_hidden, TRUE); - g_list_free(col_l); + + cols_hidden_str = cols_hidden->str; + g_string_free (cols_hidden, FALSE); + return cols_hidden_str; } +static gboolean column_hidden_is_default_cb(pref_t* pref) { + char *cur_hidden_str = column_hidden_to_str_cb(pref, FALSE); + gboolean is_default = strcmp(cur_hidden_str, pref->default_val.string) == 0; + + g_free(cur_hidden_str); + return is_default; +} + + /* Number of columns "preference". This is only used internally and is not written to the * preference file */ @@ -1368,7 +1383,21 @@ static prefs_set_pref_e column_num_set_cb(pref_t* pref _U_, const gchar* value _ return PREFS_SET_OK; } -static void column_num_write_cb(pref_t* pref _U_, write_pref_arg_t* arg _U_) {} +static const char * column_num_type_name_cb(void) { + return NULL; +} + +static char * column_num_type_description_cb(void) { + return g_strdup(""); +} + +static gboolean column_num_is_default_cb(pref_t* pref _U_) { + return TRUE; +} + +static char * column_num_to_str_cb(pref_t* pref _U_, gboolean default_val _U_) { + return g_strdup(""); +} /* * Column format custom preference functions @@ -1500,69 +1529,82 @@ static prefs_set_pref_e column_format_set_cb(pref_t* pref, const gchar* value, g return PREFS_SET_OK; } -static void column_format_write_cb(pref_t* pref, write_pref_arg_t* arg) -{ - GList *clp = *pref->varp.list, *col_l, - *pref_col = g_list_first(clp), - *def_col = g_list_first(pref->default_val.list); - fmt_data *cfmt, *def_cfmt; - gchar *prefs_fmt; - gboolean is_default = TRUE; - pref_t *col_num_pref; - const char *prefix = (arg->module->name != NULL) ? arg->module->name : arg->module->parent->name; - - /* See if the column data has changed from the default */ - col_num_pref = prefs_find_preference(gui_column_module, PRS_COL_NUM); - if (*col_num_pref->varp.uint != col_num_pref->default_val.uint) { - is_default = FALSE; - } else { - while (pref_col && def_col) { - cfmt = (fmt_data *) pref_col->data; - def_cfmt = (fmt_data *) def_col->data; - if ((strcmp(cfmt->title, def_cfmt->title) != 0) || - (cfmt->fmt != def_cfmt->fmt) || - (((cfmt->fmt == COL_CUSTOM) && (cfmt->custom_field)) && - ((strcmp(cfmt->custom_field, def_cfmt->custom_field) != 0) || - (cfmt->resolved != def_cfmt->resolved)))) { - is_default = FALSE; - break; - } - pref_col = pref_col->next; - def_col = def_col->next; - } - } +static const char * column_format_type_name_cb(void) { + return "Packet list column format"; +} + +static char * column_format_type_description_cb(void) { + return g_strdup("Each pair of strings consists of a column title and its format"); +} - /* Now write the current columns */ - col_l = NULL; - while (clp) { - cfmt = (fmt_data *) clp->data; - col_l = g_list_append(col_l, g_strdup(cfmt->title)); - if ((cfmt->fmt == COL_CUSTOM) && (cfmt->custom_field)) { - prefs_fmt = g_strdup_printf("%s:%s:%d:%c", - col_format_to_string(cfmt->fmt), - cfmt->custom_field, - cfmt->custom_occurrence, - cfmt->resolved ? 'R' : 'U'); +static gboolean column_format_is_default_cb(pref_t* pref) { + GList *clp = *pref->varp.list, + *pref_col = g_list_first(clp), + *def_col = g_list_first(pref->default_val.list); + fmt_data *cfmt, *def_cfmt; + gboolean is_default = TRUE; + pref_t *col_num_pref; + + /* See if the column data has changed from the default */ + col_num_pref = prefs_find_preference(gui_column_module, PRS_COL_NUM); + if (*col_num_pref->varp.uint != col_num_pref->default_val.uint) { + is_default = FALSE; } else { - prefs_fmt = g_strdup(col_format_to_string(cfmt->fmt)); + while (pref_col && def_col) { + cfmt = (fmt_data *) pref_col->data; + def_cfmt = (fmt_data *) def_col->data; + if ((strcmp(cfmt->title, def_cfmt->title) != 0) || + (cfmt->fmt != def_cfmt->fmt) || + (((cfmt->fmt == COL_CUSTOM) && (cfmt->custom_field)) && + ((strcmp(cfmt->custom_field, def_cfmt->custom_field) != 0) || + (cfmt->resolved != def_cfmt->resolved)))) { + is_default = FALSE; + break; + } + + pref_col = pref_col->next; + def_col = def_col->next; + } } - col_l = g_list_append(col_l, prefs_fmt); - clp = clp->next; - } - fprintf (arg->pf, "\n# Packet list column format.\n"); - fprintf (arg->pf, "# Each pair of strings consists of a column title and its format.\n"); - if (is_default) - fprintf(arg->pf, "#"); - fprintf(arg->pf, "%s.%s: ", prefix, pref->name); - write_string_list(arg->pf, col_l, is_default); - fprintf(arg->pf, "\n"); - /* This frees the list of strings, but not the strings to which it - refers; they are free'ed in write_string_list(). */ - g_list_free(col_l); + return is_default; } +static char * column_format_to_str_cb(pref_t* pref, gboolean default_val) { + GList *pref_l = default_val ? pref->default_val.list : *pref->varp.list; + GList *clp = g_list_first(pref_l); + GList *col_l; + fmt_data *cfmt; + gchar *prefs_fmt; + char *column_format_str; + + col_l = NULL; + while (clp) { + cfmt = (fmt_data *) clp->data; + col_l = g_list_append(col_l, g_strdup(cfmt->title)); + if ((cfmt->fmt == COL_CUSTOM) && (cfmt->custom_field)) { + prefs_fmt = g_strdup_printf("%s:%s:%d:%c", + col_format_to_string(cfmt->fmt), + cfmt->custom_field, + cfmt->custom_occurrence, + cfmt->resolved ? 'R' : 'U'); + } else { + prefs_fmt = g_strdup(col_format_to_string(cfmt->fmt)); + } + col_l = g_list_append(col_l, prefs_fmt); + clp = clp->next; + } + + column_format_str = join_string_list(col_l); + + /* This frees the list of strings, but not the strings to which it + refers; they are free'ed in join_string_list(). */ + g_list_free(col_l); + return column_format_str; +} + + /* * Capture column custom preference functions */ @@ -1649,52 +1691,63 @@ static prefs_set_pref_e capture_column_set_cb(pref_t* pref, const gchar* value, return PREFS_SET_OK; } -static void capture_column_write_cb(pref_t* pref, write_pref_arg_t* arg) -{ - GList *clp = *pref->varp.list, - *col_l = NULL, - *pref_col = g_list_first(clp), - *def_col = g_list_first(pref->default_val.list); - gchar *col, *def_col_str; - gboolean is_default = TRUE; - const char *prefix = (arg->module->name != NULL) ? arg->module->name : arg->module->parent->name; - - /* See if the column data has changed from the default */ - while (pref_col && def_col) { - col = (gchar *)pref_col->data; - def_col_str = (gchar *) def_col->data; - if (strcmp(col, def_col_str) != 0) { - is_default = FALSE; - break; - } - pref_col = pref_col->next; - def_col = def_col->next; - } +static const char * capture_column_type_name_cb(void) { + return "Capture options dialog column list"; +} - /* Ensure the same column count */ - if (((pref_col == NULL) && (def_col != NULL)) || - ((pref_col != NULL) && (def_col == NULL))) - is_default = FALSE; +static char * capture_column_type_description_cb(void) { + return g_strdup_printf( + "List of columns to be displayed.\n" + "Possible values: INTERFACE,LINK,PMODE,SNAPLEN,MONITOR,BUFFER,FILTER\n"); +} + +static gboolean capture_column_is_default_cb(pref_t* pref) { + GList *clp = *pref->varp.list, + *pref_col = g_list_first(clp), + *def_col = g_list_first(pref->default_val.list); + gchar *col, *def_col_str; + gboolean is_default = TRUE; + + /* See if the column data has changed from the default */ + while (pref_col && def_col) { + col = (gchar *)pref_col->data; + def_col_str = (gchar *) def_col->data; + if (strcmp(col, def_col_str) != 0) { + is_default = FALSE; + break; + } + + pref_col = pref_col->next; + def_col = def_col->next; + } + + /* Ensure the same column count */ + if (((pref_col == NULL) && (def_col != NULL)) || + ((pref_col != NULL) && (def_col == NULL))) + is_default = FALSE; + + return is_default; +} + +static char * capture_column_to_str_cb(pref_t* pref, gboolean default_val) { + GList *pref_l = default_val ? pref->default_val.list : *pref->varp.list; + GList *clp = g_list_first(pref_l); + GList *col_l = NULL; + gchar *col, *capture_column_str; - while (clp) { - col = (gchar *) clp->data; - col_l = g_list_append(col_l, g_strdup(col)); - clp = clp->next; - } - fprintf(arg->pf, "\n# Capture options dialog column list.\n"); - fprintf(arg->pf, "# List of columns to be displayed.\n"); - fprintf(arg->pf, "# Possible values: INTERFACE,LINK,PMODE,SNAPLEN,MONITOR,BUFFER,FILTER\n"); - if (is_default) - fprintf(arg->pf, "#"); - fprintf(arg->pf, "%s.%s: ", prefix, pref->name); - write_string_list(arg->pf, col_l, is_default); - fprintf(arg->pf, "\n"); - /* This frees the list of strings, but not the strings to which it - refers; they are free'ed in write_string_list(). */ - g_list_free(col_l); + while (clp) { + col = (gchar *) clp->data; + col_l = g_list_append(col_l, g_strdup(col)); + clp = clp->next; + } + capture_column_str = join_string_list(col_l); + /* This frees the list of strings, but not the strings to which it + refers; they are free'ed in write_string_list(). */ + g_list_free(col_l); + return capture_column_str; } @@ -1724,8 +1777,7 @@ static prefs_set_pref_e colorized_frame_set_cb(pref_t* pref, const gchar* value, return PREFS_SET_OK; } -static void colorized_frame_write_cb(pref_t* pref _U_, write_pref_arg_t* arg _U_) -{ +static const char * colorized_frame_type_name_cb(void) { /* Don't write the colors of the 10 easy-access-colorfilters to the preferences * file until the colors can be changed in the GUI. Currently this is not really * possible since the STOCK-icons for these colors are hardcoded. @@ -1735,6 +1787,19 @@ static void colorized_frame_write_cb(pref_t* pref _U_, write_pref_arg_t* arg _U_ * the preferences. * */ + return NULL; +} + +static char * colorized_frame_type_description_cb(void) { + return g_strdup(""); +} + +static gboolean colorized_frame_is_default_cb(pref_t* pref _U_) { + return TRUE; +} + +static char * colorized_frame_to_str_cb(pref_t* pref _U_, gboolean default_val _U_) { + return g_strdup(""); } /* @@ -1820,14 +1885,20 @@ prefs_register_modules(void) custom_cbs.free_cb = column_hidden_free_cb; custom_cbs.reset_cb = column_hidden_reset_cb; custom_cbs.set_cb = column_hidden_set_cb; - custom_cbs.write_cb = column_hidden_write_cb; + custom_cbs.type_name_cb = column_hidden_type_name_cb; + custom_cbs.type_description_cb = column_hidden_type_description_cb; + custom_cbs.is_default_cb = column_hidden_is_default_cb; + custom_cbs.to_str_cb = column_hidden_to_str_cb; prefs_register_string_custom_preference(gui_column_module, PRS_COL_HIDDEN, "Packet list hidden columns", "List all columns to hide in the packet list", &custom_cbs, (const char **)&cols_hidden_list); custom_cbs.free_cb = column_format_free_cb; custom_cbs.reset_cb = column_format_reset_cb; custom_cbs.set_cb = column_format_set_cb; - custom_cbs.write_cb = column_format_write_cb; + custom_cbs.type_name_cb = column_format_type_name_cb; + custom_cbs.type_description_cb = column_format_type_description_cb; + custom_cbs.is_default_cb = column_format_is_default_cb; + custom_cbs.to_str_cb = column_format_to_str_cb; prefs_register_list_custom_preference(gui_column_module, PRS_COL_FMT, "Packet list column format", "Each pair of strings consists of a column title and its format", &custom_cbs, @@ -1839,7 +1910,10 @@ prefs_register_modules(void) custom_cbs.free_cb = custom_pref_no_cb; custom_cbs.reset_cb = column_num_reset_cb; custom_cbs.set_cb = column_num_set_cb; - custom_cbs.write_cb = column_num_write_cb; + custom_cbs.type_name_cb = column_num_type_name_cb; + custom_cbs.type_description_cb = column_num_type_description_cb; + custom_cbs.is_default_cb = column_num_is_default_cb; + custom_cbs.to_str_cb = column_num_to_str_cb; prefs_register_uint_custom_preference(gui_column_module, PRS_COL_NUM, "Number of columns", "Number of columns in col_list", &custom_cbs, &prefs.num_cols); @@ -1881,14 +1955,20 @@ prefs_register_modules(void) custom_cbs.free_cb = colorized_frame_free_cb; custom_cbs.reset_cb = colorized_frame_reset_cb; custom_cbs.set_cb = colorized_frame_set_cb; - custom_cbs.write_cb = colorized_frame_write_cb; + custom_cbs.type_name_cb = colorized_frame_type_name_cb; + custom_cbs.type_description_cb = colorized_frame_type_description_cb; + custom_cbs.is_default_cb = colorized_frame_is_default_cb; + custom_cbs.to_str_cb = colorized_frame_to_str_cb; prefs_register_string_custom_preference(gui_column_module, "colorized_frame.fg", "Colorized Foreground", "Filter Colorized Foreground", &custom_cbs, (const char **)&prefs.gui_colorized_fg); custom_cbs.free_cb = colorized_frame_free_cb; custom_cbs.reset_cb = colorized_frame_reset_cb; custom_cbs.set_cb = colorized_frame_set_cb; - custom_cbs.write_cb = colorized_frame_write_cb; + custom_cbs.type_name_cb = colorized_frame_type_name_cb; + custom_cbs.type_description_cb = colorized_frame_type_description_cb; + custom_cbs.is_default_cb = colorized_frame_is_default_cb; + custom_cbs.to_str_cb = colorized_frame_to_str_cb; prefs_register_string_custom_preference(gui_column_module, "colorized_frame.bg", "Colorized Background", "Filter Colorized Background", &custom_cbs, (const char **)&prefs.gui_colorized_bg); @@ -2037,7 +2117,10 @@ prefs_register_modules(void) custom_cbs.free_cb = custom_pref_no_cb; custom_cbs.reset_cb = console_log_level_reset_cb; custom_cbs.set_cb = console_log_level_set_cb; - custom_cbs.write_cb = console_log_level_write_cb; + custom_cbs.type_name_cb = console_log_level_type_name_cb; + custom_cbs.type_description_cb = console_log_level_type_description_cb; + custom_cbs.is_default_cb = console_log_level_is_default_cb; + custom_cbs.to_str_cb = console_log_level_to_str_cb; prefs_register_uint_custom_preference(console_module, "log.level", "logging level", "A bitmask of glib log levels", &custom_cbs, &prefs.console_log_level); @@ -2088,7 +2171,10 @@ prefs_register_modules(void) custom_cbs.free_cb = capture_column_free_cb; custom_cbs.reset_cb = capture_column_reset_cb; custom_cbs.set_cb = capture_column_set_cb; - custom_cbs.write_cb = capture_column_write_cb; + custom_cbs.type_name_cb = capture_column_type_name_cb; + custom_cbs.type_description_cb = capture_column_type_description_cb; + custom_cbs.is_default_cb = capture_column_is_default_cb; + custom_cbs.to_str_cb = capture_column_to_str_cb; prefs_register_list_custom_preference(capture_module, "columns", "Capture options dialog column list", "List of columns to be displayed", &custom_cbs, capture_column_init_cb, &prefs.capture_columns); @@ -2256,64 +2342,40 @@ prefs_get_string_list(const gchar *str) return(sl); } -static void -write_string_list(FILE *f, GList *sl, gboolean is_default) +static char * +join_string_list(GList *sl) { - char pref_str[8]; - GList *clp = g_list_first(sl); - gchar *str; - int cur_len = 0; - gchar *quoted_str; - size_t str_len; - gchar *strp, *quoted_strp, c; - guint item_count = 0; - gboolean first = TRUE; - - while (clp) { - item_count++; - str = clp->data; - - /* Allocate a buffer big enough to hold the entire string, with each - character quoted (that's the worst case). */ - str_len = strlen(str); - quoted_str = g_malloc(str_len*2 + 1); - - /* Now quote any " or \ characters in it. */ - strp = str; - quoted_strp = quoted_str; - while ((c = *strp++) != '\0') { - if (c == '"' || c == '\\') { - /* It has to be backslash-quoted. */ - *quoted_strp++ = '\\'; - } - *quoted_strp++ = c; - } - *quoted_strp = '\0'; - - { - cur_len = 0; - if (!first) { - pref_str[cur_len] = ','; cur_len++; - } + GString *joined_str = g_string_new(""); + GList *cur, *first = g_list_first(sl); + gchar *str; + gchar *quoted_str; + guint item_count = 0; + + cur = first = g_list_first(sl); + while (cur) { + item_count++; + str = cur->data; + + if (cur != first) { + g_string_append_c(joined_str, ','); + } - if (item_count % 2) { - /* Wrap the line. */ - pref_str[cur_len] = '\n'; cur_len++; - if (is_default) { - pref_str[cur_len] = '#'; cur_len++; + if (item_count % 2) { + /* Wrap the line. */ + g_string_append(joined_str, "\n\t"); + } else { + g_string_append_c(joined_str, ' '); } - pref_str[cur_len] = '\t'; cur_len++; - } else { - pref_str[cur_len] = ' '; cur_len++; - } - pref_str[cur_len] = '\0'; - fprintf(f, "%s\"%s\"", pref_str, quoted_str); - first = FALSE; + + quoted_str = g_strescape(str, ""); + g_string_append_printf(joined_str, "\"%s\"", quoted_str); + g_free(quoted_str); + + cur = cur->next; } - g_free(quoted_str); - g_free(str); - clp = clp->next; - } + str = joined_str->str; + g_string_free(joined_str, FALSE); + return str; } void @@ -3831,59 +3893,86 @@ typedef struct { gboolean is_gui_module; } write_gui_pref_arg_t; -/* - * Write out a single dissector preference. - */ -static void -write_pref(gpointer data, gpointer user_data) +const char * +prefs_pref_type_name(pref_t *pref) { - pref_t *pref = data; - write_pref_arg_t *arg = user_data; - const enum_val_t *enum_valp; - const char *val_string, *prefix; - gchar **desc_lines; - int i; + const char *type_name = "[Unknown]"; + + if (!pref) { + return type_name; /* ...or maybe assert? */ + } switch (pref->type) { + + case PREF_UINT: + switch (pref->info.base) { + + case 10: + type_name = "Decimal"; + break; + + case 8: + type_name = "Octal"; + break; + + case 16: + type_name = "Hexadecimal"; + break; + } + break; + + case PREF_BOOL: + type_name = "Boolean"; + break; + + case PREF_ENUM: + type_name = "Enumeration"; + break; + + case PREF_STRING: + type_name = "String"; + break; + + case PREF_FILENAME: + type_name = "Filename"; + break; + + case PREF_RANGE: + type_name = "Range"; + break; + + case PREF_COLOR: + type_name = "Color"; + break; + + case PREF_CUSTOM: + if (pref->custom_cbs.type_name_cb) + return pref->custom_cbs.type_name_cb(); + type_name = "Custom"; + break; + case PREF_OBSOLETE: - /* - * This preference is no longer supported; it's not a - * real preference, so we don't write it out (i.e., we - * treat it as if it weren't found in the list of - * preferences, and we weren't called in the first place). - */ - return; + type_name = "Obsolete"; + break; case PREF_STATIC_TEXT: + type_name = "Static text"; + break; + case PREF_UAT: - /* Nothing to do; don't bother printing the description */ - return; - default: - break; + type_name = "UAT"; + break; } + return type_name; +} - /* - * The prefix will either be the module name or the parent - * name if its a subtree - */ - prefix = (arg->module->name != NULL) ? arg->module->name : arg->module->parent->name; +char * +prefs_pref_type_description(pref_t *pref) +{ + char *type_desc = "An unkown preference type"; - /* - * Make multiple line descriptions appear as - * multiple commented lines in prefs file. - */ - if (pref->type != PREF_CUSTOM) { - if (pref->description && - (g_ascii_strncasecmp(pref->description,"", 2) != 0)) { - desc_lines = g_strsplit(pref->description,"\n",0); - for (i = 0; desc_lines[i] != NULL; ++i) { - fprintf(arg->pf, "\n# %s", desc_lines[i]); - } - fprintf(arg->pf, "\n"); - g_strfreev(desc_lines); - } else { - fprintf(arg->pf, "\n# No description\n"); - } + if (!pref) { + return g_strdup_printf("%s.", type_desc); /* ...or maybe assert? */ } switch (pref->type) { @@ -3892,113 +3981,330 @@ write_pref(gpointer data, gpointer user_data) switch (pref->info.base) { case 10: - fprintf(arg->pf, "# A decimal number.\n"); - if (pref->default_val.uint == *pref->varp.uint) - fprintf(arg->pf, "#"); - fprintf(arg->pf, "%s.%s: %u\n", prefix, - pref->name, *pref->varp.uint); + type_desc = "A decimal number"; break; case 8: - fprintf(arg->pf, "# An octal number.\n"); - if (pref->default_val.uint == *pref->varp.uint) - fprintf(arg->pf, "#"); - fprintf(arg->pf, "%s.%s: %#o\n", prefix, - pref->name, *pref->varp.uint); + type_desc = "An octal number"; break; case 16: - fprintf(arg->pf, "# A hexadecimal number.\n"); - if (pref->default_val.uint == *pref->varp.uint) - fprintf(arg->pf, "#"); - fprintf(arg->pf, "%s.%s: %#x\n", prefix, - pref->name, *pref->varp.uint); + type_desc = "A hexadecimal number"; break; } break; case PREF_BOOL: - fprintf(arg->pf, "# TRUE or FALSE (case-insensitive).\n"); - if (pref->default_val.boolval == *pref->varp.boolp) - fprintf(arg->pf, "#"); - fprintf(arg->pf, "%s.%s: %s\n", prefix, pref->name, - *pref->varp.boolp ? "TRUE" : "FALSE"); + type_desc = "TRUE or FALSE (case-insensitive)"; break; case PREF_ENUM: - /* - * For now, we save the "description" value, so that if we - * save the preferences older versions of Wireshark can at - * least read preferences that they supported; we support - * either the short name or the description when reading - * the preferences file or a "-o" option. - */ - fprintf(arg->pf, "# One of: "); - enum_valp = pref->info.enum_info.enumvals; - val_string = NULL; + { + const enum_val_t *enum_valp = pref->info.enum_info.enumvals; + GString *enum_str = g_string_new("One of: "); while (enum_valp->name != NULL) { - if (enum_valp->value == *pref->varp.enump) - val_string = enum_valp->description; - fprintf(arg->pf, "%s", enum_valp->description); + g_string_append(enum_str, enum_valp->description); enum_valp++; - if (enum_valp->name == NULL) - fprintf(arg->pf, "\n"); - else - fprintf(arg->pf, ", "); + if (enum_valp->name != NULL) + g_string_append(enum_str, ", "); } - fprintf(arg->pf, "# (case-insensitive).\n"); + g_string_append(enum_str, "\n(case-insensitive)."); + type_desc = enum_str->str; + g_string_free(enum_str, FALSE); + return type_desc; + break; + } + + case PREF_STRING: + type_desc = "A string"; + break; + + case PREF_FILENAME: + type_desc = "A path to a file"; + break; + + case PREF_RANGE: + { + type_desc = "A string denoting an positive integer range (e.g., \"1-20,30-40\")"; + break; + } + + case PREF_COLOR: + { + type_desc = "A six-digit hexadecimal RGB color triplet (e.g. fce94f)"; + break; + } + + case PREF_CUSTOM: + if (pref->custom_cbs.type_description_cb) + return pref->custom_cbs.type_description_cb(); + type_desc = "A custom value"; + break; + + case PREF_OBSOLETE: + type_desc = "An obsolete preference"; + break; + + case PREF_STATIC_TEXT: + type_desc = "[Static text]"; + break; + + case PREF_UAT: + type_desc = "Configuration data stored in its own file"; + break; + + default: + break; + } + return g_strdup_printf("%s.", type_desc); +} + +gboolean +prefs_pref_is_default(pref_t *pref) { + if (!pref) return FALSE; + + switch (pref->type) { + + case PREF_UINT: + if (pref->default_val.uint == *pref->varp.uint) + return TRUE; + break; + + case PREF_BOOL: + if (pref->default_val.boolval == *pref->varp.boolp) + return TRUE; + break; + + case PREF_ENUM: if (pref->default_val.enumval == *pref->varp.enump) - fprintf(arg->pf, "#"); - fprintf(arg->pf, "%s.%s: %s\n", prefix, - pref->name, val_string); + return TRUE; break; case PREF_STRING: case PREF_FILENAME: - fprintf(arg->pf, "# A string.\n"); if (!(strcmp(pref->default_val.string, *pref->varp.string))) - fprintf(arg->pf, "#"); - fprintf(arg->pf, "%s.%s: %s\n", prefix, pref->name, - *pref->varp.string); + return TRUE; break; case PREF_RANGE: { - char *range_string_p; - - range_string_p = range_convert_range(*pref->varp.range); - fprintf(arg->pf, "# A string denoting an positive integer range (e.g., \"1-20,30-40\").\n"); if ((ranges_are_equal(pref->default_val.range, *pref->varp.range))) - fprintf(arg->pf, "#"); - fprintf(arg->pf, "%s.%s: %s\n", prefix, pref->name, - range_string_p); + return TRUE; break; } case PREF_COLOR: { - fprintf (arg->pf, "# Each value is a six digit hexadecimal color value in the form rrggbb.\n"); if ((pref->default_val.color.red == pref->varp.color->red) && (pref->default_val.color.green == pref->varp.color->green) && (pref->default_val.color.blue == pref->varp.color->blue)) - fprintf(arg->pf, "#"); - fprintf (arg->pf, "%s.%s: %02x%02x%02x\n", prefix, pref->name, - (pref->varp.color->red * 255 / 65535), - (pref->varp.color->green * 255 / 65535), - (pref->varp.color->blue * 255 / 65535)); + return TRUE; + break; + } + + case PREF_CUSTOM: + return pref->custom_cbs.is_default_cb(pref); + + case PREF_OBSOLETE: + case PREF_STATIC_TEXT: + case PREF_UAT: + return FALSE; + /* g_assert_not_reached(); */ + break; + } + return FALSE; +} + +char * +prefs_pref_to_str(pref_t *pref, gboolean default_val) { + char *pref_text = "[Unknown]"; + guint pref_uint; + gboolean pref_boolval; + gint pref_enumval; + const char *pref_string; + range_t *pref_range; + color_t *pref_color; + + if (!pref) { + return g_strdup(pref_text); /* ...or maybe assert? */ + } + + if (default_val) { + pref_uint = pref->default_val.uint; + pref_boolval = pref->default_val.boolval; + pref_enumval = pref->default_val.enumval; + pref_string = pref->default_val.string; + pref_range = pref->default_val.range; + pref_color = &pref->default_val.color; + } else { + pref_uint = *pref->varp.uint; + pref_boolval = *pref->varp.boolp; + pref_enumval = *pref->varp.enump; + pref_string = *pref->varp.string; + pref_range = *pref->varp.range; + pref_color = pref->varp.color; + } + switch (pref->type) { + + case PREF_UINT: + switch (pref->info.base) { + + case 10: + return g_strdup_printf("%u", pref_uint); + break; + + case 8: + return g_strdup_printf("%#o", pref_uint); + break; + + case 16: + return g_strdup_printf("%#x", pref_uint); + break; + } + break; + + case PREF_BOOL: + return g_strdup_printf("%s", pref_boolval ? "TRUE" : "FALSE"); + break; + + case PREF_ENUM: + { + /* + * For now, we return the "description" value, so that if we + * save the preferences older versions of Wireshark can at + * least read preferences that they supported; we support + * either the short name or the description when reading + * the preferences file or a "-o" option. + */ + const enum_val_t *enum_valp = pref->info.enum_info.enumvals; + while (enum_valp->name != NULL) { + if (enum_valp->value == pref_enumval) + return g_strdup(enum_valp->description); + enum_valp++; + } break; } + case PREF_STRING: + case PREF_FILENAME: + return g_strdup(pref_string); + break; + + case PREF_RANGE: + pref_text = range_convert_range(pref_range); + break; + + case PREF_COLOR: + return g_strdup_printf("%02x%02x%02x", + (pref_color->red * 255 / 65535), + (pref_color->green * 255 / 65535), + (pref_color->blue * 255 / 65535)); + break; + case PREF_CUSTOM: - pref->custom_cbs.write_cb(pref, arg); + if (pref->custom_cbs.to_str_cb) + return pref->custom_cbs.to_str_cb(pref, default_val); + pref_text = "[Custom]"; break; case PREF_OBSOLETE: + pref_text = "[Obsolete]"; + break; + case PREF_STATIC_TEXT: + pref_text = "[Static text]"; + break; + case PREF_UAT: - g_assert_not_reached(); + { + uat_t *uat = (uat_t *) pref->varp.uat; + if (uat && uat->filename) + return g_strdup_printf("[Managed in the file \"%s\"]", uat->filename); + else + pref_text = "[Managed in an unknown file]"; break; } + + default: + break; + } + return g_strdup(pref_text); +} + +/* + * Write out a single dissector preference. + */ +static void +write_pref(gpointer data, gpointer user_data) +{ + pref_t *pref = data; + write_pref_arg_t *arg = user_data; + gchar **desc_lines; + int i; + + switch (pref->type) { + case PREF_OBSOLETE: + /* + * This preference is no longer supported; it's not a + * real preference, so we don't write it out (i.e., we + * treat it as if it weren't found in the list of + * preferences, and we weren't called in the first place). + */ + return; + + case PREF_STATIC_TEXT: + case PREF_UAT: + /* Nothing to do; don't bother printing the description */ + return; + default: + break; + } + + if (pref->type != PREF_CUSTOM || pref->custom_cbs.type_name_cb() != NULL) { + /* + * The prefix will either be the module name or the parent + * name if its a subtree + */ + const char *name_prefix = (arg->module->name != NULL) ? arg->module->name : arg->module->parent->name; + char *type_desc, *pref_text; + const char * def_prefix = prefs_pref_is_default(pref) ? "#" : ""; + + if (pref->type == PREF_CUSTOM) fprintf(arg->pf, "\n# %s", pref->custom_cbs.type_name_cb()); + fprintf(arg->pf, "\n"); + if (pref->description && + (g_ascii_strncasecmp(pref->description,"", 2) != 0)) { + if (pref->type != PREF_CUSTOM) { + /* We get duplicate lines otherwise. */ + + desc_lines = g_strsplit(pref->description,"\n",0); + for (i = 0; desc_lines[i] != NULL; ++i) { + fprintf(arg->pf, "# %s\n", desc_lines[i]); + } + g_strfreev(desc_lines); + } + } else { + fprintf(arg->pf, "# No description\n"); + } + + type_desc = prefs_pref_type_description(pref); + desc_lines = g_strsplit(type_desc,"\n",0); + for (i = 0; desc_lines[i] != NULL; ++i) { + fprintf(arg->pf, "# %s\n", desc_lines[i]); + } + g_strfreev(desc_lines); + g_free(type_desc); + + pref_text = prefs_pref_to_str(pref, FALSE); + fprintf(arg->pf, "%s%s.%s: ", def_prefix, name_prefix, pref->name); + desc_lines = g_strsplit(pref_text,"\n",0); + for (i = 0; desc_lines[i] != NULL; ++i) { + fprintf(arg->pf, "%s%s\n", i == 0 ? "" : def_prefix, desc_lines[i]); + } + if (i == 0) fprintf(arg->pf, "\n"); + g_strfreev(desc_lines); + g_free(pref_text); + } + } /* @@ -4136,3 +4442,16 @@ free_col_info(GList * list) g_list_free(list); list = NULL; } + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/epan/prefs.h b/epan/prefs.h index 9ca301c5d4..de0909eac1 100644 --- a/epan/prefs.h +++ b/epan/prefs.h @@ -456,6 +456,43 @@ extern void prefs_clear_string_list(GList *sl); */ extern void prefs_register_modules(void); +/** Fetch a short preference type name, e.g. "Integer". + * + * @param pref A preference. + * + * @return The preference type name. May be NULL. + */ +const char *prefs_pref_type_name(pref_t *pref); + +/** Fetch a long description of the preference type + * + * @param pref A preference. + * + * @return A description of the preference type including allowed + * values for enums. The description may include newlines. Must be + * g_free()d. + */ +char *prefs_pref_type_description(pref_t *pref); + +/** Check if a preference differs from its default value + * + * @param pref A preference. + * + * @return TRUE if the current value of the preference is the same as + * its default value or FALSE if they differ. + */ +gboolean prefs_pref_is_default(pref_t *pref); + +/** Fetch a string representation of the preference. + * + * @param pref A preference. + * @param default_val Return the default value if TRUE or the current value + * if FALSE. + * + * @return A string representation of the preference. Must be g_free()d. + */ +char *prefs_pref_to_str(pref_t *pref, gboolean default_val); + /* Read the preferences file, fill in "prefs", and return a pointer to it. If we got an error (other than "it doesn't exist") trying to read diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index 708881470d..743602cfb2 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -49,6 +49,7 @@ set(QTSHARK_H_SRC packet_list.h packet_list_model.h packet_range_group_box.h + preferences_dialog.h print_dialog.h profile_dialog.h progress_bar.h @@ -96,6 +97,7 @@ set(QTSHARK_CPP_SRC packet_list_model.cpp packet_list_record.cpp packet_range_group_box.cpp + preferences_dialog.cpp print_dialog.cpp profile_dialog.cpp progress_bar.cpp @@ -124,6 +126,7 @@ set(QTSHARK_UI packet_comment_dialog.ui packet_format_group_box.ui packet_range_group_box.ui + preferences_dialog.ui print_dialog.ui profile_dialog.ui search_frame.ui diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am index 761d3dc365..4a30d6ed39 100644 --- a/ui/qt/Makefile.am +++ b/ui/qt/Makefile.am @@ -87,64 +87,30 @@ export_object_dialog.cpp export_object_dialog.h: ui_export_object_dialog.h file_set_dialog.cpp file_set_dialog.h: ui_file_set_dialog.h -#ui_file_set_dialog.h: file_set_dialog.ui -# uic $< -o $@ - import_text_dialog.cpp import_text_dialog.h: ui_import_text_dialog.h -#ui_import_text_dialog.h: import_text_dialog.ui -# uic $< -o $@ - main_welcome.cpp main_welcome.h: ui_main_welcome.h -#ui_main_welcome.h: main_welcome.ui -# uic $< -o $@ - main_window.cpp main_window.h: ui_main_window.h -#ui_main_window.h: main_window.ui -# uic $< -o $@ - packet_comment_dialog.cpp packet_comment_dialog.h: ui_packet_comment_dialog.h -#ui_packet_comment_dialog.h: packet_comment_dialog.ui -# uic $< -o $@ - packet_format_group_box.cpp packet_format_group_box.h: ui_packet_format_group_box.h -#ui_packet_format_group_box.h: packet_format_group_box.ui -# uic $< -o $@ - packet_range_group_box.cpp packet_range_group_box.h: ui_packet_range_group_box.h -#ui_packet_range_group_box.h: packet_range_group_box.ui -# uic $< -o $@ +preferences_dialog.cpp preferences_dialog.h: ui_preferences_dialog.h print_dialog.cpp print_dialog.h: ui_print_dialog.h -#ui_print_dialog.h: print_dialog.ui -# uic $< -o $@ - profile_dialog.cpp profile_dialog.h: ui_profile_dialog.h -#ui_profile_dialog.h: profile_dialog.ui -# uic $< -o $@ - search_frame.cpp search_frame.h: ui_search_frame.h -#ui_search_frame.h: search_frame.ui -# uic $< -o $@ - splash_overlay.cpp splash_overlay.h: ui_splash_overlay.h -#ui_splash_overlay.h: splash_overlay.ui -# uic $< -o $@ - time_shift_dialog.cpp time_shift_dialog.h: ui_time_shift_dialog.h -#ui_time_shift_dialog.h: time_shift_dialog.ui -# uic $< -o $@ - doxygen: if HAVE_DOXYGEN $(DOXYGEN) doxygen.cfg @@ -206,6 +172,7 @@ EXTRA_DIST = \ packet_format_group_box.ui \ packet_range_group_box.ui \ packet_comment_dialog.ui \ + preferences_dialog.ui \ print_dialog.ui \ profile_dialog.ui \ QtShark.pro \ diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common index 4cf270f668..140974775b 100644 --- a/ui/qt/Makefile.common +++ b/ui/qt/Makefile.common @@ -39,6 +39,7 @@ GENERATED_NODIST_HEADER_FILES = \ ui_packet_comment_dialog.h \ ui_packet_format_group_box.h \ ui_packet_range_group_box.h \ + ui_preferences_dialog.h \ ui_print_dialog.h \ ui_profile_dialog.h \ ui_search_frame.h \ @@ -103,6 +104,7 @@ MOC_HDRS = \ packet_list.h \ packet_list_model.h \ packet_range_group_box.h \ + preferences_dialog.h \ print_dialog.h \ profile_dialog.h \ progress_bar.h \ @@ -187,6 +189,7 @@ WIRESHARK_QT_SRC = \ packet_list_model.cpp \ packet_list_record.cpp \ packet_range_group_box.cpp \ + preferences_dialog.cpp \ print_dialog.cpp \ profile_dialog.cpp \ progress_bar.cpp \ diff --git a/ui/qt/QtShark.pro b/ui/qt/QtShark.pro index 5184e667d0..fa3bf6f5d3 100644 --- a/ui/qt/QtShark.pro +++ b/ui/qt/QtShark.pro @@ -193,7 +193,8 @@ FORMS += main_window.ui \ search_frame.ui \ splash_overlay.ui \ time_shift_dialog.ui \ - profile_dialog.ui + profile_dialog.ui \ + preferences_dialog.ui win32 { ## These should be in config.pri ?? !isEmpty(PORTAUDIO_DIR) { @@ -226,7 +227,8 @@ HEADERS += $$HEADERS_WS_C \ search_frame.h \ splash_overlay.h \ tango_colors.h \ - profile_dialog.h + profile_dialog.h \ + preferences_dialog.h win32 { OBJECTS_WS_C = $$SOURCES_WS_C @@ -444,4 +446,5 @@ SOURCES += \ syntax_line_edit.cpp \ time_shift_dialog.cpp \ wireshark_application.cpp \ - profile_dialog.cpp + profile_dialog.cpp \ + preferences_dialog.cpp diff --git a/ui/qt/byte_view_tab.cpp b/ui/qt/byte_view_tab.cpp index b152ebea6a..a47402a65b 100644 --- a/ui/qt/byte_view_tab.cpp +++ b/ui/qt/byte_view_tab.cpp @@ -33,7 +33,6 @@ ByteViewTab::ByteViewTab(QWidget *parent) : addTab(); } -#include <QDebug> void ByteViewTab::addTab(const char *name, tvbuff_t *tvb, proto_tree *tree, QTreeWidget *protoTree, packet_char_enc encoding) { ByteViewText *byte_view_text = new ByteViewText(this, tvb, tree, protoTree, encoding); diff --git a/ui/qt/byte_view_text.h b/ui/qt/byte_view_text.h index dbd13baefe..c29d6e7971 100644 --- a/ui/qt/byte_view_text.h +++ b/ui/qt/byte_view_text.h @@ -31,6 +31,7 @@ #include <epan/tvbuff.h> #include "proto_tree.h" +#include <QPrinter> #include <QTextEdit> // XXX - Is there any reason we shouldn't add ByteViewImage, etc? diff --git a/ui/qt/capture_file_dialog.cpp b/ui/qt/capture_file_dialog.cpp index 8301e6cec8..ac15a79bc0 100644 --- a/ui/qt/capture_file_dialog.cpp +++ b/ui/qt/capture_file_dialog.cpp @@ -54,8 +54,6 @@ #include <QPushButton> -#include <QDebug> - #ifdef Q_WS_WIN // All of these routines are required by file_dlg_win32.c. // We don't yet have a good place for them so we'll add them as stubs here. diff --git a/ui/qt/export_dissection_dialog.cpp b/ui/qt/export_dissection_dialog.cpp index 33e6c946c9..7e38909571 100644 --- a/ui/qt/export_dissection_dialog.cpp +++ b/ui/qt/export_dissection_dialog.cpp @@ -43,7 +43,6 @@ #include <QGridLayout> #include <QPushButton> -#include <QDebug> #endif // Q_WS_WIN ExportDissectionDialog::ExportDissectionDialog(QWidget *parent, capture_file *cap_file, export_type_e export_type): diff --git a/ui/qt/export_object_dialog.ui b/ui/qt/export_object_dialog.ui index d362aeef9f..5cd532a393 100644 --- a/ui/qt/export_object_dialog.ui +++ b/ui/qt/export_object_dialog.ui @@ -22,6 +22,9 @@ <property name="rootIsDecorated"> <bool>false</bool> </property> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> <property name="itemsExpandable"> <bool>false</bool> </property> diff --git a/ui/qt/file_set_dialog.ui b/ui/qt/file_set_dialog.ui index 718f17786c..6722b98418 100644 --- a/ui/qt/file_set_dialog.ui +++ b/ui/qt/file_set_dialog.ui @@ -76,6 +76,9 @@ <property name="rootIsDecorated"> <bool>false</bool> </property> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> <property name="itemsExpandable"> <bool>false</bool> </property> diff --git a/ui/qt/main_welcome.ui b/ui/qt/main_welcome.ui index d484f8051b..284d4bcb5c 100644 --- a/ui/qt/main_welcome.ui +++ b/ui/qt/main_welcome.ui @@ -34,7 +34,7 @@ </sizepolicy> </property> <property name="currentIndex"> - <number>1</number> + <number>0</number> </property> <widget class="InterfaceTree" name="interfaceTree"> <property name="sizePolicy"> @@ -46,6 +46,9 @@ <property name="horizontalScrollBarPolicy"> <enum>Qt::ScrollBarAlwaysOff</enum> </property> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> <property name="columnCount"> <number>2</number> </property> diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index 73e6093a85..81a4552a97 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -224,6 +224,7 @@ private slots: void on_actionEditTimeShift_triggered(); void on_actionEditPacketComment_triggered(); void on_actionEditConfigurationProfiles_triggered(); + void on_actionEditPreferences_triggered(); void on_actionGoGoToPacket_triggered(); void resetPreviousFocus(); diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 00389d4c6d..1094f37a30 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -58,13 +58,14 @@ #include "ui/main_statusbar.h" #include "ui/ssl_key_export.h" -#include "wireshark_application.h" #include "capture_file_dialog.h" #include "export_object_dialog.h" -#include "print_dialog.h" #include "time_shift_dialog.h" #include "packet_comment_dialog.h" +#include "preferences_dialog.h" +#include "print_dialog.h" #include "profile_dialog.h" +#include "wireshark_application.h" #include <QMessageBox> #include <QClipboard> @@ -1303,6 +1304,13 @@ void MainWindow::on_actionEditConfigurationProfiles_triggered() cp_dialog.exec(); } +void MainWindow::on_actionEditPreferences_triggered() +{ + PreferencesDialog pref_dialog; + + pref_dialog.exec(); +} + // View Menu // Expand / collapse slots in proto_tree diff --git a/ui/qt/preferences_dialog.cpp b/ui/qt/preferences_dialog.cpp new file mode 100644 index 0000000000..1e12a5a560 --- /dev/null +++ b/ui/qt/preferences_dialog.cpp @@ -0,0 +1,185 @@ +/* preferences_dialog.cpp + * + * $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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include <glib.h> + +#include "color.h" +#include "packet-range.h" + +#include <epan/prefs.h> +#include <epan/prefs-int.h> + +#include "preferences_dialog.h" +#include "ui_preferences_dialog.h" + +#include <QMessageBox> +#include <QDebug> + +extern "C" { +// Callbacks prefs routines + +static guint +fill_advanced_prefs(module_t *module, gpointer root_ptr) +{ + QTreeWidgetItem *root_item = static_cast<QTreeWidgetItem *>(root_ptr); + + if (!module || !root_item) return 1; + + if (module->numprefs < 1 && !prefs_module_has_submodules(module)) return 0; + + QString module_title; +// if (module->parent == NULL) + module_title = module->title; +// else +// module_title = QString(module->parent->title) +": "+ module->title; + + QTreeWidgetItem *tl_item = new QTreeWidgetItem(root_item); + tl_item->setText(0, module_title); + tl_item->setToolTip(0, module->description); + tl_item->setFirstColumnSpanned(true); + + QList<QTreeWidgetItem *>tl_children; + for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = g_list_next(pref_l)) { + pref_t *pref = (pref_t *) pref_l->data; + + if (pref->type == PREF_OBSOLETE || pref->type == PREF_STATIC_TEXT) continue; + const char *type_name = prefs_pref_type_name(pref); + if (!type_name) continue; + + QTreeWidgetItem *item = new QTreeWidgetItem(); + QString full_name = QString(module->name ? module->name : module->parent->name) + "." + pref->name; + QFont font = item->font(0); + char *type_desc = prefs_pref_type_description(pref); + char *cur_value = prefs_pref_to_str(pref, false); + char *default_value = prefs_pref_to_str(pref, true); + bool is_default = false; + bool is_editable = true; + + if (pref->type == PREF_UAT) { + is_editable = false; + } else { + if (prefs_pref_is_default(pref)) is_default = true; + } + + item->setText(0, full_name); + item->setToolTip(0, pref->description); + item->setText(1, is_default ? "Default" : "Changed"); + item->setToolTip(1, "Has this value been changed?"); + item->setText(2, type_name); + item->setToolTip(2, type_desc); + item->setText(3, QString(cur_value).replace(QRegExp("\n\t"), " ")); + item->setToolTip(3, QString("Default: ") + default_value); + g_free(type_desc); + g_free(cur_value); + g_free(default_value); + + font.setBold(!is_default); + + if (!is_editable) { + item->setFlags(item->flags() ^ Qt::ItemIsEnabled); + } + font.setItalic(!is_editable); + item->setFont(0, font); + + item->setFont(0, font); + item->setFont(1, font); + item->setFont(2, font); + item->setFont(3, font); + tl_children << item; + } + tl_item->addChildren(tl_children); + + if(prefs_module_has_submodules(module)) + return prefs_modules_foreach_submodules(module, fill_advanced_prefs, tl_item); + + return 0; +} + + +} // extern "C" + +const int appearance_item_ = 0; +const int protocols_item_ = 4; +const int statistics_item_ = 5; +const int advanced_item_ = 6; + +PreferencesDialog::PreferencesDialog(QWidget *parent) : + QDialog(parent), + pd_ui_(new Ui::PreferencesDialog) +{ + pd_ui_->setupUi(this); + QTreeWidgetItem tmp_item; + + pd_ui_->advancedTree->setUpdatesEnabled(false); + prefs_modules_foreach_submodules(NULL, fill_advanced_prefs, (gpointer) &tmp_item); + pd_ui_->advancedTree->invisibleRootItem()->addChildren(tmp_item.takeChildren()); + pd_ui_->advancedTree->expandAll(); + pd_ui_->advancedTree->setSortingEnabled(true); + pd_ui_->advancedTree->sortByColumn(0, Qt::AscendingOrder); + pd_ui_->advancedTree->setColumnWidth(0, pd_ui_->advancedTree->width() * 2 / 5); + pd_ui_->advancedTree->resizeColumnToContents(1); + pd_ui_->advancedTree->resizeColumnToContents(2); + pd_ui_->advancedTree->setColumnWidth(3, pd_ui_->advancedTree->width() * 3 / 5); + pd_ui_->advancedTree->setUpdatesEnabled(true); + + pd_ui_->splitter->setStretchFactor(0, 1); + pd_ui_->splitter->setStretchFactor(1, 5); + + pd_ui_->prefsTree->invisibleRootItem()->child(appearance_item_)->setExpanded(true); + pd_ui_->prefsTree->invisibleRootItem()->child(advanced_item_)->setSelected(true); +} + +PreferencesDialog::~PreferencesDialog() +{ + delete pd_ui_; +} + +void PreferencesDialog::showEvent(QShowEvent *evt) +{ + Q_UNUSED(evt); + QStyleOption style_opt; + int new_prefs_tree_width = pd_ui_->prefsTree->style()->subElementRect(QStyle::SE_TreeViewDisclosureItem, &style_opt).left(); + QList<int> sizes = pd_ui_->splitter->sizes(); + + pd_ui_->prefsTree->resizeColumnToContents(0); + new_prefs_tree_width += pd_ui_->prefsTree->columnWidth(0); + sizes[1] += sizes[0] - new_prefs_tree_width; + sizes[0] = new_prefs_tree_width; + pd_ui_->splitter->setSizes(sizes); + pd_ui_->splitter->setStretchFactor(0, 0); +} + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/preferences_dialog.h b/ui/qt/preferences_dialog.h new file mode 100644 index 0000000000..67f9a48aa3 --- /dev/null +++ b/ui/qt/preferences_dialog.h @@ -0,0 +1,48 @@ +/* preferences_dialog.h + * + * $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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef PREFERENCES_DIALOG_H +#define PREFERENCES_DIALOG_H + +#include <QDialog> + +namespace Ui { +class PreferencesDialog; +} + +class PreferencesDialog : public QDialog +{ + Q_OBJECT + +public: + explicit PreferencesDialog(QWidget *parent = 0); + ~PreferencesDialog(); + +protected: + void showEvent(QShowEvent *evt); + +private: + Ui::PreferencesDialog *pd_ui_; +}; + +#endif // PREFERENCES_DIALOG_H diff --git a/ui/qt/preferences_dialog.ui b/ui/qt/preferences_dialog.ui new file mode 100644 index 0000000000..ffc65f87cc --- /dev/null +++ b/ui/qt/preferences_dialog.ui @@ -0,0 +1,236 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PreferencesDialog</class> + <widget class="QDialog" name="PreferencesDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>680</width> + <height>475</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QTreeWidget" name="prefsTree"> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> + <property name="headerHidden"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string notr="true">1</string> + </property> + </column> + <item> + <property name="text"> + <string>Appearance</string> + </property> + <property name="flags"> + <set>ItemIsDragEnabled|ItemIsUserCheckable</set> + </property> + <item> + <property name="text"> + <string>Layout</string> + </property> + <property name="flags"> + <set>ItemIsDragEnabled|ItemIsUserCheckable</set> + </property> + </item> + <item> + <property name="text"> + <string>Columns</string> + </property> + <property name="flags"> + <set>ItemIsDragEnabled|ItemIsUserCheckable</set> + </property> + </item> + <item> + <property name="text"> + <string>Font and Colors</string> + </property> + <property name="flags"> + <set>ItemIsDragEnabled|ItemIsUserCheckable</set> + </property> + </item> + </item> + <item> + <property name="text"> + <string>Capture</string> + </property> + <property name="flags"> + <set>ItemIsDragEnabled|ItemIsUserCheckable</set> + </property> + </item> + <item> + <property name="text"> + <string>Filter Expressions</string> + </property> + <property name="flags"> + <set>ItemIsDragEnabled|ItemIsUserCheckable</set> + </property> + </item> + <item> + <property name="text"> + <string>Name Resolution</string> + </property> + <property name="flags"> + <set>ItemIsDragEnabled|ItemIsUserCheckable</set> + </property> + </item> + <item> + <property name="text"> + <string>Protocols</string> + </property> + <property name="flags"> + <set>ItemIsDragEnabled|ItemIsUserCheckable</set> + </property> + </item> + <item> + <property name="text"> + <string>Statistics</string> + </property> + <property name="flags"> + <set>ItemIsDragEnabled|ItemIsUserCheckable</set> + </property> + </item> + <item> + <property name="text"> + <string>Advanced</string> + </property> + </item> + </widget> + <widget class="QStackedWidget" name="stackedWidget"> + <property name="currentIndex"> + <number>9</number> + </property> + <widget class="QFrame" name="appearanceFrame"/> + <widget class="QFrame" name="layoutFrame"/> + <widget class="QFrame" name="columnFrame"/> + <widget class="QFrame" name="fontColorFrame"/> + <widget class="QFrame" name="captureFrame"/> + <widget class="QFrame" name="filterFrame"/> + <widget class="QFrame" name="nameResolutionFrame"/> + <widget class="QFrame" name="protocolsFrame"/> + <widget class="QFrame" name="statisticsFrame"/> + <widget class="QFrame" name="advancedFrame"> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Search:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="advancedSearchLineEdit"/> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QTreeWidget" name="advancedTree"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>Name</string> + </property> + </column> + <column> + <property name="text"> + <string>Status</string> + </property> + </column> + <column> + <property name="text"> + <string>Type</string> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + </column> + </widget> + </item> + </layout> + </widget> + </widget> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>PreferencesDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>PreferencesDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/ui/qt/profile_dialog.cpp b/ui/qt/profile_dialog.cpp index a704a08fd3..403490b747 100644 --- a/ui/qt/profile_dialog.cpp +++ b/ui/qt/profile_dialog.cpp @@ -316,4 +316,3 @@ void ProfileDialog::editingFinished() * ex: set shiftwidth=4 tabstop=8 expandtab: * :indentSize=4:tabSize=8:noTabs=true: */ - |