For open dialogs, offer a list of sets of extensions, not of file types;

.cap, for example, doesn't refer to a particular file type - a whole
bunch of file types use .cap.

Also offer, in addition to "All Files", "All Capture Files", which
matches all the extensions we know about.

svn path=/trunk/; revision=53156
This commit is contained in:
Guy Harris 2013-11-08 01:08:42 +00:00
parent 28129427d4
commit bf4e84aba6
5 changed files with 243 additions and 76 deletions

View File

@ -299,6 +299,36 @@ int CaptureFileDialog::mergeType() {
}
#else // not Q_OS_WINDOWS
QString CaptureFileDialog::fileExtensionType(int et, bool extension_globs)
{
QString filter;
GSList *extensions_list;
GSList *extension;
filter = wtap_get_file_extension_type_name(et);
if (!extension_globs) {
return filter;
}
filter += " (";
extensions_list = wtap_get_file_extension_type_extensions(et);
/* Construct the list of patterns. */
for (extension = extensions_list; extension != NULL;
extension = g_slist_next(extension)) {
if (!filter.endsWith('('))
filter += ' ';
filter += "*.";
filter += (char *)extension->data;
}
wtap_free_extensions_list(extensions_list);
filter += ')';
return filter;
/* XXX - does QStringList's destructor destroy the strings in the list? */
}
QString CaptureFileDialog::fileType(int ft, bool extension_globs)
{
QString filter;
@ -332,7 +362,7 @@ QString CaptureFileDialog::fileType(int ft, bool extension_globs)
filter += "*.";
filter += (char *)extension->data;
}
wtap_free_file_extensions_list(extensions_list);
wtap_free_extensions_list(extensions_list);
}
filter += ')';
return filter;
@ -341,17 +371,54 @@ QString CaptureFileDialog::fileType(int ft, bool extension_globs)
QStringList CaptureFileDialog::buildFileOpenTypeList() {
QStringList filters;
int ft;
QString filter, sep;
GSList *extensions_list;
GSList *extension;
int et;
/*
* Microsoft's UI guidelines say, of the file filters in open and
* save dialogs:
*
* For meta-filters, remove the file extension list to eliminate
* clutter. Examples: "All files," "All pictures," "All music,"
* and "All videos."
*
* On both Windows XP and Windows 7, Wordpad doesn't do that, but
* Paint does.
*
* XXX - on Windows, does Qt do that here? For "All Capture Files",
* the filter will be a bit long, so it *really* shouldn't be shown.
* What about other platforms?
*/
/* Add the "All Files" entry. */
filters << QString(tr("All Files (*.*)"));
/* Include all the file types Wireshark supports. */
for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
if (ft == WTAP_FILE_UNKNOWN)
continue; /* not a real file type */
/*
* Add an "All Capture Files" entry, with all the extensions we
* know about.
*/
filter = "All Capture Files";
filters << fileType(ft);
/*
* Construct its list of patterns from a list of all extensions
* we support.
*/
extensions_list = wtap_get_all_file_extensions_list();
sep = " (";
for (extension = extensions_list; extension != NULL;
extension = g_slist_next(extension)) {
filter += sep;
filter += "*.";
filter += (char *)extension->data;
sep = " ";
}
filter += ")";
filters << filter;
/* Include all the file types Wireshark supports. */
for (et = 0; et < wtap_get_num_file_type_extensions(); et++) {
filters << fileExtensionType(et);
}
return filters;

View File

@ -89,6 +89,7 @@ private:
void addMergeControls(QVBoxLayout &v_box);
void addDisplayFilterEdit();
void addPreview(QVBoxLayout &v_box);
QString fileExtensionType(int et, bool extension_globs = true);
QString fileType(int ft, bool extension_globs = true);
QStringList buildFileOpenTypeList(void);

View File

@ -1351,56 +1351,34 @@ open_file_hook_proc(HWND of_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
return 0;
}
/* Generate a list of the file types we can save this file as.
"g_filetype" is the type it has now.
"encap" is the encapsulation for its packets (which could be
"unknown" or "per-packet").
"filtered" is TRUE if we're to save only the packets that passed
the display filter (in which case we have to save it using Wiretap)
and FALSE if we're to save the entire file (in which case, if we're
saving it in the type it has already, we can just copy it).
The same applies for sel_curr, sel_all, sel_m_only, sel_m_range and sel_man_range
*/
/* Generate a list of the file types we can filter for in the open dialog. */
static void
append_file_type(GArray *sa, int ft)
append_file_extension_type(GArray *sa, int et)
{
GString* pattern_str = g_string_new("");
GString* description_str = g_string_new("");
const struct file_extension_info *extension_info;
gchar sep;
GSList *extensions_list, *extension;
TCHAR *str16;
guint16 zero = 0;
extensions_list = wtap_get_file_extensions_list(ft, TRUE);
if (extensions_list == NULL) {
/* This file type doesn't have any particular extension
conventionally used for it, so we'll just use "*.*"
as the pattern; on Windows, that matches all file names
- even those with no extension - so we don't need to
worry about compressed file extensions. (It does not
do so on UN*X; the right pattern on UN*X would just
be "*".) */
g_string_printf(pattern_str, "*.*");
} else {
/* Construct the list of patterns. */
g_string_printf(pattern_str, "");
sep = '\0';
for (extension = extensions_list; extension != NULL;
extension = g_slist_next(extension)) {
if (sep != '\0')
g_string_append_c(pattern_str, sep);
g_string_append_printf(pattern_str, "*.%s", (char *)extension->data);
sep = ';';
}
wtap_free_file_extensions_list(extensions_list);
/* Construct the list of patterns. */
extensions_list = wtap_get_file_extension_type_extensions(et);
g_string_printf(pattern_str, "");
sep = '\0';
for (extension = extensions_list; extension != NULL;
extension = g_slist_next(extension)) {
if (sep != '\0')
g_string_append_c(pattern_str, sep);
g_string_append_printf(pattern_str, "*.%s", (char *)extension->data);
sep = ';';
}
wtap_free_extensions_list(extensions_list);
/* Construct the description. */
g_string_printf(description_str, "%s (%s)", wtap_file_type_string(ft),
g_string_printf(description_str, "%s (%s)",
wtap_get_file_extension_type_name(et),
pattern_str->str);
str16 = utf_8to16(description_str->str);
sa = g_array_append_vals(sa, str16, (guint) strlen(description_str->str));
@ -1472,17 +1450,14 @@ build_file_open_type_list(void) {
g_string_append_printf(pattern_str, "*.%s", (char *)extension->data);
sep = ';';
}
wtap_free_file_extensions_list(extensions_list);
wtap_free_extensions_list(extensions_list);
str16 = utf_8to16(pattern_str->str);
sa = g_array_append_vals(sa, str16, (guint) strlen(pattern_str->str));
sa = g_array_append_val(sa, zero);
/* Include all the file types Wireshark supports. */
for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
if (ft == WTAP_FILE_UNKNOWN)
continue; /* not a real file type */
append_file_type(sa, ft);
/* Include all the file type extensions Wireshark supports. */
for (et = 0; et < wtap_get_num_file_type_extensions; et++) {
append_file_extension_type(sa, et);
}
/* terminate the array */
@ -1491,6 +1466,68 @@ build_file_open_type_list(void) {
return (TCHAR *) g_array_free(sa, FALSE /*free_segment*/);
}
/* Generate a list of the file types we can save this file as.
"g_filetype" is the type it has now.
"encap" is the encapsulation for its packets (which could be
"unknown" or "per-packet").
"filtered" is TRUE if we're to save only the packets that passed
the display filter (in which case we have to save it using Wiretap)
and FALSE if we're to save the entire file (in which case, if we're
saving it in the type it has already, we can just copy it).
The same applies for sel_curr, sel_all, sel_m_only, sel_m_range and sel_man_range
*/
static void
append_file_type(GArray *sa, int ft)
{
GString* pattern_str = g_string_new("");
GString* description_str = g_string_new("");
gchar sep;
GSList *extensions_list, *extension;
TCHAR *str16;
guint16 zero = 0;
extensions_list = wtap_get_file_extensions_list(ft, TRUE);
if (extensions_list == NULL) {
/* This file type doesn't have any particular extension
conventionally used for it, so we'll just use "*.*"
as the pattern; on Windows, that matches all file names
- even those with no extension - so we don't need to
worry about compressed file extensions. (It does not
do so on UN*X; the right pattern on UN*X would just
be "*".) */
g_string_printf(pattern_str, "*.*");
} else {
/* Construct the list of patterns. */
g_string_printf(pattern_str, "");
sep = '\0';
for (extension = extensions_list; extension != NULL;
extension = g_slist_next(extension)) {
if (sep != '\0')
g_string_append_c(pattern_str, sep);
g_string_append_printf(pattern_str, "*.%s", (char *)extension->data);
sep = ';';
}
wtap_free_extensions_list(extensions_list);
}
/* Construct the description. */
g_string_printf(description_str, "%s (%s)", wtap_file_type_string(ft),
pattern_str->str);
str16 = utf_8to16(description_str->str);
sa = g_array_append_vals(sa, str16, (guint) strlen(description_str->str));
sa = g_array_append_val(sa, zero);
g_string_free(description_str, TRUE);
str16 = utf_8to16(pattern_str->str);
sa = g_array_append_vals(sa, str16, (guint) strlen(pattern_str->str));
sa = g_array_append_val(sa, zero);
g_string_free(pattern_str, TRUE);
}
static TCHAR *
build_file_save_type_list(GArray *savable_file_types) {
guint i;

View File

@ -177,6 +177,76 @@ void wtap_register_file_type_extension(const struct file_extension_info *ei) {
file_type_extensions = (const struct file_extension_info*)(void *)file_type_extensions_arr->data;
}
int wtap_get_num_file_type_extensions(void)
{
return file_type_extensions_arr->len;
}
const char *wtap_get_file_extension_type_name(int extension_type)
{
return file_type_extensions[extension_type].name;
}
static GSList *add_extensions_for_file_extensions_type(int extension_type,
GSList *extensions, GSList *compressed_file_extensions)
{
gchar **extensions_set, **extensionp, *extension;
/*
* Split the extension-list string into a set of extensions.
*/
extensions_set = g_strsplit(file_type_extensions[extension_type].extensions,
";", 0);
/*
* Add each of those extensions to the list.
*/
for (extensionp = extensions_set; *extensionp != NULL; extensionp++) {
extension = *extensionp;
/*
* Add the extension, and all compressed variants
* of it.
*/
extensions = add_extensions(extensions, extension,
compressed_file_extensions);
}
g_strfreev(extensions_set);
return extensions;
}
/* Return a list of file extensions that are used by the specified file
extension type.
All strings in the list are allocated with g_malloc() and must be freed
with g_free(). */
GSList *wtap_get_file_extension_type_extensions(guint extension_type)
{
GSList *compressed_file_extensions;
GSList *extensions;
if (extension_type >= file_type_extensions_arr->len)
return NULL; /* not a valid extension type */
extensions = NULL; /* empty list, to start with */
/*
* Get the list of compressed-file extensions.
*/
compressed_file_extensions = wtap_get_compressed_file_extensions();
/*
* Add all this file extension type's extensions, with compressed
* variants.
*/
extensions = add_extensions_for_file_extensions_type(extension_type,
extensions, compressed_file_extensions);
g_slist_free(compressed_file_extensions);
return extensions;
}
/* Return a list of all extensions that are used by all file types,
including compressed extensions, e.g. not just "pcap" but also
"pcap.gz" if we can read gzipped files.
@ -188,7 +258,6 @@ GSList *wtap_get_all_file_extensions_list(void)
GSList *compressed_file_extensions;
GSList *extensions;
unsigned int i;
gchar **extensions_set, **extensionp, *extension;
init_file_type_extensions();
@ -201,27 +270,11 @@ GSList *wtap_get_all_file_extensions_list(void)
for (i = 0; i < file_type_extensions_arr->len; i++) {
/*
* Split the extension-list string into a set of extensions.
* Add all this file extension type's extensions, with
* compressed variants.
*/
extensions_set = g_strsplit(file_type_extensions[i].extensions,
";", 0);
/*
* Add each of those extensions to the list.
*/
for (extensionp = extensions_set; *extensionp != NULL;
extensionp++) {
extension = *extensionp;
/*
* Add the extension, and all compressed variants
* of it.
*/
extensions = add_extensions(extensions, extension,
compressed_file_extensions);
}
g_strfreev(extensions_set);
extensions = add_extensions_for_file_extensions_type(i,
extensions, compressed_file_extensions);
}
g_slist_free(compressed_file_extensions);
@ -1318,9 +1371,10 @@ GSList *wtap_get_file_extensions_list(int filetype, gboolean include_compressed)
}
/*
* Free a list returned by wtap_get_file_extensions_list().
* Free a list returned by wtap_get_file_extension_type_extensions(),
* wtap_get_all_file_extensions_list, or wtap_get_file_extensions_list().
*/
void wtap_free_file_extensions_list(GSList *extensions)
void wtap_free_extensions_list(GSList *extensions)
{
GSList *extension;

View File

@ -1367,7 +1367,7 @@ const char *wtap_default_file_extension(int filetype);
WS_DLL_PUBLIC
GSList *wtap_get_file_extensions_list(int filetype, gboolean include_compressed);
WS_DLL_PUBLIC
void wtap_free_file_extensions_list(GSList *extensions);
void wtap_free_extensions_list(GSList *extensions);
WS_DLL_PUBLIC
const char *wtap_encap_string(int encap);
@ -1381,10 +1381,18 @@ const char *wtap_strerror(int err);
/*** get available number of file types and encapsulations ***/
WS_DLL_PUBLIC
int wtap_get_num_file_type_extensions(void);
WS_DLL_PUBLIC
int wtap_get_num_encap_types(void);
WS_DLL_PUBLIC
int wtap_get_num_file_types(void);
/*** get information for file type extension ***/
WS_DLL_PUBLIC
const char *wtap_get_file_extension_type_name(int extension_type);
WS_DLL_PUBLIC
GSList *wtap_get_file_extension_type_extensions(guint extension_type);
/*** dynamically register new file types and encapsulations ***/
WS_DLL_PUBLIC
void wtap_register_file_type_extension(const struct file_extension_info *ei);