For open dialogs, offer a list of sets of extensions, not of file types;
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 8 Nov 2013 01:08:42 +0000 (01:08 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 8 Nov 2013 01:08:42 +0000 (01:08 +0000)
.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.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@53156 f5534014-38df-0310-8fa8-9805f1628bb7

ui/qt/capture_file_dialog.cpp
ui/qt/capture_file_dialog.h
ui/win32/file_dlg_win32.c
wiretap/file_access.c
wiretap/wtap.h

index 450b4711065a6ec14590e1fe032ce04e2346e8cc..2ff11b190a4772042285575ce492e66cd1bcebc3 100644 (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";
+
+    /*
+     * 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;
 
-        filters << fileType(ft);
+    /* Include all the file types Wireshark supports. */
+    for (et = 0; et < wtap_get_num_file_type_extensions(); et++) {
+        filters << fileExtensionType(et);
     }
 
     return filters;
index fdfa51c7d0a0caca4a6c0e6d2743f4afa791278f..54f9e1d341f7ac60bd69a92db4d810ba44ac47f9 100644 (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);
 
index 1ceb2e451c04b6c9aa7ca37b4d3d586942f2a8db..311b8fa3d1aacb664b34832fe5fee85e123ef38d 100644 (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;
index 3134332b8630b0f742c3419a1d070ac9e5323be8..4f79e60328e2039727d8afb227508266b82ef88a 100644 (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.
-                */
-               extensions_set = g_strsplit(file_type_extensions[i].extensions,
-                   ";", 0);
-
-               /*
-                * Add each of those extensions to the list.
+                * Add all this file extension type's extensions, with
+                * compressed variants.
                 */
-               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;
 
index 59c34f42a0a3802d5d74fe99d0e8be30f6d985a5..a2d79bebc4f5eb6a083eb9c6a5f258ccd7c0ecc7 100644 (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);