aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2012-10-18 21:14:43 +0000
committerGerald Combs <gerald@wireshark.org>2012-10-18 21:14:43 +0000
commit576b24c96ee4ac4ca7fb9fc116b6e8ce3704227d (patch)
treef8e0abf64215eb0083a475acfdcea3806e4c0ba5
parent05c1e47f68b609702ec13a09e5ebc1a572841e12 (diff)
Move ui-independent object export routines to the common ui directory.
Implement DICOM, HTTP, and SMB object exports. Rename the GTK+ export files. C++-ize epan/tap.h. Fix an apparent memory leak in eo_save_all_clicked_cb. The Qt dialog has an indeterminate progress bar. I tried adding something similar to the GTK+ dialog but event processing led down a rabbit hole. svn path=/trunk/; revision=45647
-rw-r--r--epan/epan.h16
-rw-r--r--epan/tap.h14
-rw-r--r--ui/CMakeLists.txt1
-rw-r--r--ui/Makefile.common1
-rw-r--r--ui/export_object.c192
-rw-r--r--ui/export_object.h5
-rw-r--r--ui/gtk/CMakeLists.txt2
-rw-r--r--ui/gtk/Makefile.common4
-rw-r--r--ui/gtk/export_object_dlg.c (renamed from ui/gtk/export_object.c)175
-rw-r--r--ui/gtk/export_object_dlg.h (renamed from ui/gtk/export_object_gtk.h)6
-rw-r--r--ui/gtk/libgtkui.vcproj8
-rw-r--r--ui/gtk/main_menubar.c2
-rw-r--r--ui/qt/QtShark.pro9
-rw-r--r--ui/qt/export_dissection_dialog.cpp3
-rw-r--r--ui/qt/export_object_dialog.cpp316
-rw-r--r--ui/qt/export_object_dialog.h102
-rw-r--r--ui/qt/export_object_dialog.ui156
-rw-r--r--ui/qt/main_window.cpp12
-rw-r--r--ui/qt/main_window.h3
-rw-r--r--ui/qt/main_window.ui36
-rw-r--r--ui/qt/main_window_slots.cpp24
-rw-r--r--wsutil/str_util.h16
22 files changed, 894 insertions, 209 deletions
diff --git a/epan/epan.h b/epan/epan.h
index 24d751e3d1..c668fa0423 100644
--- a/epan/epan.h
+++ b/epan/epan.h
@@ -21,8 +21,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef EPAN_H
-#define EPAN_H
+#ifndef __EPAN_H__
+#define __EPAN_H__
#ifdef __cplusplus
extern "C" {
@@ -47,16 +47,16 @@ typedef struct _epan_dissect_t epan_dissect_t;
@b Sections:
- \ref proto_pub
*/
-/*
+/*
Ref 1
Epan
-Ethereal Packet ANalyzer (XXX - is this correct?) the packet analyzing engine. Source code can be found in the epan directory.
+Ethereal Packet ANalyzer (XXX - is this correct?) the packet analyzing engine. Source code can be found in the epan directory.
-Protocol-Tree - Keep data of the capture file protocol information.
+Protocol-Tree - Keep data of the capture file protocol information.
-Dissectors - The various protocol dissectors in epan/dissectors.
+Dissectors - The various protocol dissectors in epan/dissectors.
-Plugins - Some of the protocol dissectors are implemented as plugins. Source code can be found at plugins.
+Plugins - Some of the protocol dissectors are implemented as plugins. Source code can be found at plugins.
Display-Filters - the display filter engine at epan/dfilter
@@ -191,4 +191,4 @@ epan_get_runtime_version_info(GString *str);
}
#endif /* __cplusplus */
-#endif /* EPAN_H */
+#endif /* __EPAN_H__ */
diff --git a/epan/tap.h b/epan/tap.h
index 22d0fcd9ea..6c1b95ea11 100644
--- a/epan/tap.h
+++ b/epan/tap.h
@@ -22,11 +22,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef _TAP_H_
-#define _TAP_H_
+#ifndef __TAP_H__
+#define __TAP_H__
#include <epan/epan.h>
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
typedef void (*tap_reset_cb)(void *tapdata);
typedef gboolean (*tap_packet_cb)(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data);
typedef void (*tap_draw_cb)(void *tapdata);
@@ -61,4 +65,8 @@ extern gboolean have_filtering_tap_listeners(void);
extern guint union_of_tap_listener_flags(void);
extern const void *fetch_tapped_data(int tap_id, int idx);
-#endif
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TAP_H__ */
diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt
index 8e092743ad..003ccc3fc1 100644
--- a/ui/CMakeLists.txt
+++ b/ui/CMakeLists.txt
@@ -24,6 +24,7 @@
set(COMMON_UI_SRC
alert_box.c
+ export_object.c
export_object_dicom.c
export_object_http.c
export_object_smb.c
diff --git a/ui/Makefile.common b/ui/Makefile.common
index 9a498c1e37..5a8c96d1da 100644
--- a/ui/Makefile.common
+++ b/ui/Makefile.common
@@ -45,6 +45,7 @@ GENERATOR_FILES = \
WIRESHARK_UI_SRC = \
alert_box.c \
+ export_object.c \
export_object_dicom.c \
export_object_http.c \
export_object_smb.c \
diff --git a/ui/export_object.c b/ui/export_object.c
new file mode 100644
index 0000000000..83a905b32a
--- /dev/null
+++ b/ui/export_object.c
@@ -0,0 +1,192 @@
+/* export_object.c
+ * Common routines for tracking & saving objects found in streams of data
+ * Copyright 2007, Stephen Fisher (see AUTHORS file)
+ *
+ * $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 <string.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+
+#include <epan/packet_info.h>
+#include <epan/tap.h>
+
+#include <wsutil/file_util.h>
+
+#include <ui/alert_box.h>
+
+#include "export_object.h"
+
+gboolean
+eo_save_entry(const gchar *save_as_filename, export_object_entry_t *entry, gboolean show_err)
+{
+ int to_fd;
+ gint64 bytes_left;
+ int bytes_to_write;
+ ssize_t bytes_written;
+ guint8 *ptr;
+ int err;
+
+ to_fd = ws_open(save_as_filename, O_WRONLY | O_CREAT | O_EXCL |
+ O_BINARY, 0644);
+ if(to_fd == -1) { /* An error occurred */
+ if (show_err)
+ open_failure_alert_box(save_as_filename, errno, TRUE);
+ return FALSE;
+ }
+
+ /*
+ * The third argument to _write() on Windows is an unsigned int,
+ * so, on Windows, that's the size of the third argument to
+ * ws_write().
+ *
+ * The third argument to write() on UN*X is a size_t, although
+ * the return value is an ssize_t, so one probably shouldn't
+ * write more than the max value of an ssize_t.
+ *
+ * In either case, there's no guarantee that a gint64 such as
+ * payload_len can be passed to ws_write(), so we write in
+ * chunks of, at most 2^31 bytes.
+ */
+ ptr = entry->payload_data;
+ bytes_left = entry->payload_len;
+ while (bytes_left != 0) {
+ if (bytes_left > 0x40000000)
+ bytes_to_write = 0x40000000;
+ else
+ bytes_to_write = (int)bytes_left;
+ bytes_written = ws_write(to_fd, ptr, bytes_to_write);
+ if(bytes_written <= 0) {
+ if (bytes_written < 0)
+ err = errno;
+ else
+ err = WTAP_ERR_SHORT_WRITE;
+ if (show_err)
+ write_failure_alert_box(save_as_filename, err);
+ ws_close(to_fd);
+ return FALSE;
+ }
+ bytes_left -= bytes_written;
+ ptr += bytes_written;
+ }
+ if (ws_close(to_fd) < 0) {
+ if (show_err)
+ write_failure_alert_box(save_as_filename, errno);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+#define HINIBBLE(x) (((x) >> 4) & 0xf)
+#define LONIBBLE(x) ((x) & 0xf)
+#define HEXTOASCII(x) (((x) < 10) ? ((x) + '0') : ((x) - 10 + 'a'))
+#define MAXFILELEN 255
+
+static GString *eo_rename(GString *gstr, int dup)
+{
+ GString *gstr_tmp;
+ gchar *tmp_ptr;
+ GString *ext_str;
+
+ gstr_tmp = g_string_new("(");
+ g_string_append_printf (gstr_tmp, "%d)", dup);
+ if ( (tmp_ptr = strrchr(gstr->str, '.')) != NULL ) {
+ /* Retain the extension */
+ ext_str = g_string_new(tmp_ptr);
+ gstr = g_string_truncate(gstr, gstr->len - ext_str->len);
+ if ( gstr->len >= (MAXFILELEN - (strlen(gstr_tmp->str) + ext_str->len)) )
+ gstr = g_string_truncate(gstr, MAXFILELEN - (strlen(gstr_tmp->str) + ext_str->len));
+ gstr = g_string_append(gstr, gstr_tmp->str);
+ gstr = g_string_append(gstr, ext_str->str);
+ g_string_free(ext_str, TRUE);
+ }
+ else {
+ if ( gstr->len >= (MAXFILELEN - strlen(gstr_tmp->str)) )
+ gstr = g_string_truncate(gstr, MAXFILELEN - strlen(gstr_tmp->str));
+ gstr = g_string_append(gstr, gstr_tmp->str);
+ }
+ g_string_free(gstr_tmp, TRUE);
+ return gstr;
+}
+
+GString *
+eo_massage_str(const gchar *in_str, gsize maxlen, int dup)
+{
+ gchar *tmp_ptr;
+ /* The characters in "reject" come from:
+ * http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx.
+ * Add to the list as necessary for other OS's.
+ */
+ const gchar *reject = "<>:\"/\\|?*"
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
+ "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
+ GString *out_str;
+ GString *ext_str;
+
+ out_str = g_string_new("");
+
+ /* Find all disallowed characters/bytes and replace them with %xx */
+ while ( (tmp_ptr = strpbrk(in_str, reject)) != NULL ) {
+ out_str = g_string_append_len(out_str, in_str, tmp_ptr - in_str);
+ out_str = g_string_append_c(out_str, '%');
+ out_str = g_string_append_c(out_str, HEXTOASCII(HINIBBLE(*tmp_ptr)));
+ out_str = g_string_append_c(out_str, HEXTOASCII(LONIBBLE(*tmp_ptr)));
+ in_str = tmp_ptr + 1;
+ }
+ out_str = g_string_append(out_str, in_str);
+ if ( out_str->len > maxlen ) {
+ if ( (tmp_ptr = strrchr(out_str->str, '.')) != NULL ) {
+ /* Retain the extension */
+ ext_str = g_string_new(tmp_ptr);
+ out_str = g_string_truncate(out_str, maxlen - ext_str->len);
+ out_str = g_string_append(out_str, ext_str->str);
+ g_string_free(ext_str, TRUE);
+ }
+ else
+ out_str = g_string_truncate(out_str, maxlen);
+ }
+ if ( dup != 0 )
+ out_str = eo_rename(out_str, dup);
+ return out_str;
+}
+
+const char *
+ct2ext(const char *content_type)
+{
+ /* TODO: Map the content type string to an extension string. If no match,
+ * return NULL. */
+ return content_type;
+}
diff --git a/ui/export_object.h b/ui/export_object.h
index 83379d39e6..d7711588cd 100644
--- a/ui/export_object.h
+++ b/ui/export_object.h
@@ -50,6 +50,11 @@ typedef struct _export_object_entry_t {
void object_list_add_entry(export_object_list_t *object_list, export_object_entry_t *entry);
export_object_entry_t *object_list_get_entry(export_object_list_t *object_list, int row);
+gboolean eo_save_entry(const gchar *save_as_filename, export_object_entry_t *entry, gboolean show_err);
+GString *eo_massage_str(const gchar *in_str, gsize maxlen, int dup);
+const char *ct2ext(const char *content_type);
+
+
/* Protocol specific */
gboolean eo_dicom_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_,
const void *data);
diff --git a/ui/gtk/CMakeLists.txt b/ui/gtk/CMakeLists.txt
index 28ee495379..4f0bb7563e 100644
--- a/ui/gtk/CMakeLists.txt
+++ b/ui/gtk/CMakeLists.txt
@@ -45,7 +45,7 @@ set(WIRESHARK_GTK_SRC
drag_and_drop.c
edit_packet_comment_dlg.c
expert_comp_table.c
- export_object.c
+ export_object_dlg.c
export_sslkeys.c
filter_autocomplete.c
file_dlg.c
diff --git a/ui/gtk/Makefile.common b/ui/gtk/Makefile.common
index d45febca11..ea2cc7a7b0 100644
--- a/ui/gtk/Makefile.common
+++ b/ui/gtk/Makefile.common
@@ -64,7 +64,7 @@ WIRESHARK_GTK_SRC = \
drag_and_drop.c \
edit_packet_comment_dlg.c \
expert_comp_table.c \
- export_object.c \
+ export_object_dlg.c \
export_sslkeys.c \
filter_autocomplete.c \
file_dlg.c \
@@ -252,7 +252,7 @@ noinst_HEADERS = \
expert_comp_dlg.h \
expert_comp_table.h \
expert_indicators.h \
- export_object_gtk.h \
+ export_object_dlg.h \
export_sslkeys.h \
file_dlg.h \
file_import_dlg.h \
diff --git a/ui/gtk/export_object.c b/ui/gtk/export_object_dlg.c
index 130bbb1cf6..5e5177a880 100644
--- a/ui/gtk/export_object.c
+++ b/ui/gtk/export_object_dlg.c
@@ -26,16 +26,6 @@
#include "config.h"
-#include <string.h>
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
#include <gtk/gtk.h>
#include <epan/packet_info.h>
@@ -45,7 +35,6 @@
#include <wsutil/file_util.h>
#include <wsutil/str_util.h>
-#include <ui/alert_box.h>
#include <ui/export_object.h>
#include <ui/simple_dialog.h>
@@ -55,7 +44,7 @@
#include "help_dlg.h"
#include "main.h"
#include "stock_icons.h"
-#include "export_object_gtk.h"
+#include "export_object_dlg.h"
/* When a protocol needs intermediate data structures to construct the
export objects, then it must specifiy a function that cleans up all
@@ -143,78 +132,13 @@ eo_win_destroy_cb(GtkWindow *win _U_, gpointer data)
if (eo_protocoldata_reset != NULL) eo_protocoldata_reset();
}
-static gboolean
-eo_save_entry(gchar *save_as_filename, export_object_entry_t *entry, gboolean show_err)
-{
- int to_fd;
- gint64 bytes_left;
- int bytes_to_write;
- ssize_t bytes_written;
- guint8 *ptr;
- int err;
-
- to_fd = ws_open(save_as_filename, O_WRONLY | O_CREAT | O_EXCL |
- O_BINARY, 0644);
- if(to_fd == -1) { /* An error occurred */
- if (show_err)
- open_failure_alert_box(save_as_filename, errno, TRUE);
- g_free(save_as_filename);
- return FALSE;
- }
-
- /*
- * The third argument to _write() on Windows is an unsigned int,
- * so, on Windows, that's the size of the third argument to
- * ws_write().
- *
- * The third argument to write() on UN*X is a size_t, although
- * the return value is an ssize_t, so one probably shouldn't
- * write more than the max value of an ssize_t.
- *
- * In either case, there's no guarantee that a gint64 such as
- * payload_len can be passed to ws_write(), so we write in
- * chunks of, at most 2^31 bytes.
- */
- ptr = entry->payload_data;
- bytes_left = entry->payload_len;
- while (bytes_left != 0) {
- if (bytes_left > 0x40000000)
- bytes_to_write = 0x40000000;
- else
- bytes_to_write = (int)bytes_left;
- bytes_written = ws_write(to_fd, ptr, bytes_to_write);
- if(bytes_written <= 0) {
- if (bytes_written < 0)
- err = errno;
- else
- err = WTAP_ERR_SHORT_WRITE;
- if (show_err)
- write_failure_alert_box(save_as_filename, err);
- ws_close(to_fd);
- g_free(save_as_filename);
- return FALSE;
- }
- bytes_left -= bytes_written;
- ptr += bytes_written;
- }
- if (ws_close(to_fd) < 0) {
- if (show_err)
- write_failure_alert_box(save_as_filename, errno);
- g_free(save_as_filename);
- return FALSE;
- }
-
- g_free(save_as_filename);
- return TRUE;
-}
-
-
static void
eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
{
GtkWidget *save_as_w;
export_object_list_t *object_list = arg;
export_object_entry_t *entry = NULL;
+ gchar *filename = NULL;
entry = g_slist_nth_data(object_list->entries,
object_list->row_selected);
@@ -233,98 +157,20 @@ eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_as_w),
entry->filename);
- if(gtk_dialog_run(GTK_DIALOG(save_as_w)) == GTK_RESPONSE_ACCEPT)
- eo_save_entry(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_as_w)), entry, TRUE);
+ if(gtk_dialog_run(GTK_DIALOG(save_as_w)) == GTK_RESPONSE_ACCEPT) {
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_as_w));
+ eo_save_entry(filename, entry, TRUE);
+ }
+ g_free(filename);
window_destroy(save_as_w);
}
-#define HINIBBLE(x) (((x) >> 4) & 0xf)
-#define LONIBBLE(x) ((x) & 0xf)
-#define HEXTOASCII(x) (((x) < 10) ? ((x) + '0') : ((x) - 10 + 'a'))
#define MAXFILELEN 255
-
-static GString *eo_rename(GString *gstr, int dup)
-{
- GString *gstr_tmp;
- gchar *tmp_ptr;
- GString *ext_str;
-
- gstr_tmp = g_string_new("(");
- g_string_append_printf (gstr_tmp, "%d)", dup);
- if ( (tmp_ptr = strrchr(gstr->str, '.')) != NULL ) {
- /* Retain the extension */
- ext_str = g_string_new(tmp_ptr);
- gstr = g_string_truncate(gstr, gstr->len - ext_str->len);
- if ( gstr->len >= (MAXFILELEN - (strlen(gstr_tmp->str) + ext_str->len)) )
- gstr = g_string_truncate(gstr, MAXFILELEN - (strlen(gstr_tmp->str) + ext_str->len));
- gstr = g_string_append(gstr, gstr_tmp->str);
- gstr = g_string_append(gstr, ext_str->str);
- g_string_free(ext_str, TRUE);
- }
- else {
- if ( gstr->len >= (MAXFILELEN - strlen(gstr_tmp->str)) )
- gstr = g_string_truncate(gstr, MAXFILELEN - strlen(gstr_tmp->str));
- gstr = g_string_append(gstr, gstr_tmp->str);
- }
- g_string_free(gstr_tmp, TRUE);
- return gstr;
-}
-
-static GString *
-eo_massage_str(const gchar *in_str, gsize maxlen, int dup)
-{
- gchar *tmp_ptr;
- /* The characters in "reject" come from:
- * http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx.
- * Add to the list as necessary for other OS's.
- */
- const gchar *reject = "<>:\"/\\|?*"
- "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
- "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
- "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
- GString *out_str;
- GString *ext_str;
-
- out_str = g_string_new("");
-
- /* Find all disallowed characters/bytes and replace them with %xx */
- while ( (tmp_ptr = strpbrk(in_str, reject)) != NULL ) {
- out_str = g_string_append_len(out_str, in_str, tmp_ptr - in_str);
- out_str = g_string_append_c(out_str, '%');
- out_str = g_string_append_c(out_str, HEXTOASCII(HINIBBLE(*tmp_ptr)));
- out_str = g_string_append_c(out_str, HEXTOASCII(LONIBBLE(*tmp_ptr)));
- in_str = tmp_ptr + 1;
- }
- out_str = g_string_append(out_str, in_str);
- if ( out_str->len > maxlen ) {
- if ( (tmp_ptr = strrchr(out_str->str, '.')) != NULL ) {
- /* Retain the extension */
- ext_str = g_string_new(tmp_ptr);
- out_str = g_string_truncate(out_str, maxlen - ext_str->len);
- out_str = g_string_append(out_str, ext_str->str);
- g_string_free(ext_str, TRUE);
- }
- else
- out_str = g_string_truncate(out_str, maxlen);
- }
- if ( dup != 0 )
- out_str = eo_rename(out_str, dup);
- return out_str;
-}
-
-static const char *
-ct2ext(const char *content_type)
-{
- /* TODO: Map the content type string to an extension string. If no match,
- * return NULL. */
- return content_type;
-}
-
static void
eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
{
- gchar *save_as_fullpath;
+ gchar *save_as_fullpath = NULL;
export_object_list_t *object_list = arg;
export_object_entry_t *entry;
GtkWidget *save_in_w;
@@ -347,6 +193,7 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
save_in_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_in_w));
if ((strlen(save_in_path) < MAXFILELEN)) {
do {
+ g_free(save_as_fullpath);
if (entry->filename)
safe_filename = eo_massage_str(entry->filename,
MAXFILELEN - strlen(save_in_path), count);
@@ -367,6 +214,8 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
count = 0;
if (!eo_save_entry(save_as_fullpath, entry, FALSE))
all_saved = FALSE;
+ g_free(save_as_fullpath);
+ save_as_fullpath = NULL;
}
else
all_saved = FALSE;
@@ -437,7 +286,7 @@ void object_list_add_entry(export_object_list_t *object_list, export_object_entr
}
export_object_entry_t *object_list_get_entry(export_object_list_t *object_list, int row) {
- return g_slist_nth_data(object_list->entries, row);
+ return g_slist_nth_data(object_list->entries, row);
}
static void
diff --git a/ui/gtk/export_object_gtk.h b/ui/gtk/export_object_dlg.h
index e1a6bc1132..e45c7f8d95 100644
--- a/ui/gtk/export_object_gtk.h
+++ b/ui/gtk/export_object_dlg.h
@@ -24,12 +24,12 @@
* USA.
*/
-#ifndef __EXPORT_OBJECT_GTK_H__
-#define __EXPORT_OBJECT_GTK_H__
+#ifndef __EXPORT_OBJECT_DLG_H__
+#define __EXPORT_OBJECT_DLG_H__
/* Protocol specific */
void eo_dicom_cb(GtkWidget *widget _U_, gpointer data _U_);
void eo_http_cb(GtkWidget *widget _U_, gpointer data _U_);
void eo_smb_cb(GtkWidget *widget _U_, gpointer data _U_);
-#endif /* __EXPORT_OBJECT_GTK_H__ */
+#endif /* __EXPORT_OBJECT_DLG_H__ */
diff --git a/ui/gtk/libgtkui.vcproj b/ui/gtk/libgtkui.vcproj
index 61126533e6..ab5be3088c 100644
--- a/ui/gtk/libgtkui.vcproj
+++ b/ui/gtk/libgtkui.vcproj
@@ -145,11 +145,7 @@
>
</File>
<File
- RelativePath=".\export_object.c"
- >
- </File>
- <File
- RelativePath=".\export_object_http.c"
+ RelativePath=".\export_object_dlg.c"
>
</File>
<File
@@ -783,7 +779,7 @@
>
</File>
<File
- RelativePath=".\export_object.h"
+ RelativePath=".\export_object_dlg.h"
>
</File>
<File
diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c
index a52e64ca82..671ae8d3f7 100644
--- a/ui/gtk/main_menubar.c
+++ b/ui/gtk/main_menubar.c
@@ -63,7 +63,7 @@
#include "ui/gtk/capture_dlg.h"
#include "ui/gtk/capture_if_dlg.h"
#include "ui/gtk/color_dlg.h"
-#include "ui/gtk/export_object_gtk.h"
+#include "ui/gtk/export_object_dlg.h"
#include "ui/gtk/filter_dlg.h"
#include "ui/gtk/profile_dlg.h"
#include "ui/gtk/dlg_utils.h"
diff --git a/ui/qt/QtShark.pro b/ui/qt/QtShark.pro
index 6441ab06c2..dec7b3d2d1 100644
--- a/ui/qt/QtShark.pro
+++ b/ui/qt/QtShark.pro
@@ -181,7 +181,8 @@ FORMS += main_window.ui \
import_text_dialog.ui \
file_set_dialog.ui \
packet_range_group_box.ui \
- packet_format_group_box.ui
+ packet_format_group_box.ui \
+ export_object_dialog.ui
win32 { ## These should be in config.pri ??
!isEmpty(PORTAUDIO_DIR) {
@@ -206,7 +207,8 @@ win32 { ## These should be in config.pri ??
HEADERS += $$HEADERS_WS_C \
export_dissection_dialog.h \
- packet_format_group_box.h
+ packet_format_group_box.h \
+ export_object_dialog.h
win32 {
OBJECTS_WS_C = $$SOURCES_WS_C
@@ -413,4 +415,5 @@ SOURCES += \
syntax_line_edit.cpp \
wireshark_application.cpp \
export_dissection_dialog.cpp \
- packet_format_group_box.cpp
+ packet_format_group_box.cpp \
+ export_object_dialog.cpp
diff --git a/ui/qt/export_dissection_dialog.cpp b/ui/qt/export_dissection_dialog.cpp
index c8c74a9e80..4f8c0f814e 100644
--- a/ui/qt/export_dissection_dialog.cpp
+++ b/ui/qt/export_dissection_dialog.cpp
@@ -42,7 +42,6 @@
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QPushButton>
-#include <QMessageBox>
#include <QDebug>
#endif // Q_WS_WIN
@@ -114,8 +113,6 @@ ExportDissectionDialog::ExportDissectionDialog(QWidget *parent, capture_file *ca
// Grow the dialog to account for the extra widgets.
resize(width(), height() + (packet_range_group_box_.height() * 2 / 3));
- qDebug() << "FIX: ExportDissectionDialog help button";
-
#else // Q_WS_WIN
#endif // Q_WS_WIN
}
diff --git a/ui/qt/export_object_dialog.cpp b/ui/qt/export_object_dialog.cpp
new file mode 100644
index 0000000000..49546de70f
--- /dev/null
+++ b/ui/qt/export_object_dialog.cpp
@@ -0,0 +1,316 @@
+/* export_object_dialog.cpp
+ *
+ * $Id: main_window.h 45589 2012-10-16 18:14:16Z gerald $
+ *
+ * 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 "export_object_dialog.h"
+#include "ui_export_object_dialog.h"
+#include "wireshark_application.h"
+
+#include <QDialogButtonBox>
+#include <QPushButton>
+#include <QMessageBox>
+#include <QFileDialog>
+
+#include <ui/alert_box.h>
+
+#include <epan/filesystem.h>
+
+#include <wsutil/str_util.h>
+
+extern "C" {
+
+// object_list_add_entry and object_list_get_entry are defined in ui/export_object.h
+
+void object_list_add_entry(export_object_list_t *object_list, export_object_entry_t *entry) {
+ if (object_list && object_list->eod) object_list->eod->addObjectEntry(entry);
+}
+
+export_object_entry_t *object_list_get_entry(export_object_list_t *object_list, int row) {
+ if (object_list && object_list->eod) return object_list->eod->objectEntry(row);
+ return NULL;
+}
+
+// Called by taps
+
+/* Runs at the beginning of tapping only */
+static void
+eo_reset(void *tapdata)
+{
+ export_object_list_t *object_list = (export_object_list_t *) tapdata;
+ if (object_list) object_list->eod->resetObjects();
+}
+
+} // extern "C"
+
+ExportObjectDialog::ExportObjectDialog(QWidget *parent, capture_file *cf, ObjectType object_type) :
+ QDialog(parent),
+ eo_ui_(new Ui::ExportObjectDialog),
+ cap_file_(cf),
+ save_bt_(NULL),
+ save_all_bt_(NULL),
+ tap_name_(NULL),
+ name_(NULL),
+ tap_packet_(NULL),
+ eo_protocoldata_resetfn_(NULL)
+{
+ QPushButton *close_bt;
+
+ eo_ui_->setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+#if defined(Q_WS_MAC)
+ eo_ui_->progressLabel->setAttribute(Qt::WA_MacSmallSize, true);
+ eo_ui_->progressBar->setAttribute(Qt::WA_MacSmallSize, true);
+#endif
+
+ export_object_list_.eod = this;
+
+ switch (object_type) {
+ case Dicom:
+ tap_name_ = "dicom_eo";
+ name_ = "DICOM";
+ tap_packet_ = eo_dicom_packet;
+ break;
+ case Http:
+ tap_name_ = "http_eo";
+ name_ = "HTTP";
+ tap_packet_ = eo_http_packet;
+ break;
+ case Smb:
+ tap_name_ = "smb_eo";
+ name_ = "SMB";
+ tap_packet_ = eo_smb_packet;
+ eo_protocoldata_resetfn_ = eo_smb_cleanup;
+ break;
+ }
+
+ save_bt_ = eo_ui_->buttonBox->button(QDialogButtonBox::Save);
+ save_all_bt_ = eo_ui_->buttonBox->button(QDialogButtonBox::SaveAll);
+ close_bt = eo_ui_->buttonBox->button(QDialogButtonBox::Close);
+
+ if (save_bt_) save_bt_->setEnabled(false);
+ if (save_all_bt_) save_all_bt_->setEnabled(false);
+ if (close_bt) close_bt->setDefault(true);
+
+ connect(wsApp, SIGNAL(captureFileClosing(const capture_file*)),
+ this, SLOT(captureFileClosing(const capture_file*)));
+}
+
+ExportObjectDialog::~ExportObjectDialog()
+{
+ delete eo_ui_;
+}
+
+void ExportObjectDialog::show()
+{
+ GString *error_msg;
+
+ if (!cap_file_) destroy(); // Assert?
+
+ /* Data will be gathered via a tap callback */
+ error_msg = register_tap_listener(tap_name_, (void *)&export_object_list_, NULL, 0,
+ eo_reset,
+ tap_packet_,
+ NULL);
+
+ if (error_msg) {
+ QMessageBox::warning(
+ this,
+ tr("Tap registration error"),
+ QString("Unable to register ") + name_ + QString(" tap: ") + error_msg->str,
+ QMessageBox::Ok
+ );
+ g_string_free(error_msg, TRUE);
+ return;
+ }
+
+ QDialog::show();
+ cf_retap_packets(cap_file_);
+ eo_ui_->progressFrame->hide();
+ for (int i = 0; i < eo_ui_->objectTree->columnCount(); i++)
+ eo_ui_->objectTree->resizeColumnToContents(i);
+
+}
+
+void ExportObjectDialog::addObjectEntry(export_object_entry_t *entry)
+{
+ QTreeWidgetItem *entry_item;
+ gchar *size_str;
+
+ if (!entry) return;
+
+ size_str = format_size(entry->payload_len, format_size_unit_bytes|format_size_prefix_si);
+
+ entry_item = new QTreeWidgetItem(eo_ui_->objectTree);
+ entry_item->setData(0, Qt::UserRole, qVariantFromValue(entry));
+
+ entry_item->setText(0, QString().setNum(entry->pkt_num));
+ entry_item->setText(1, entry->hostname);
+ entry_item->setText(2, entry->content_type);
+ entry_item->setText(3, size_str);
+ entry_item->setText(2, entry->filename);
+ g_free(size_str);
+ // Not perfect but better than nothing.
+ entry_item->setTextAlignment(3, Qt::AlignRight);
+
+ if (save_all_bt_) save_all_bt_->setEnabled(true);
+}
+
+export_object_entry_t *ExportObjectDialog::objectEntry(int row)
+{
+ QTreeWidgetItem *item = eo_ui_->objectTree->topLevelItem(row);
+
+ if (item) return item->data(0, Qt::UserRole).value<export_object_entry_t *>();
+
+ return NULL;
+}
+
+void ExportObjectDialog::resetObjects()
+{
+ if (eo_protocoldata_resetfn_) eo_protocoldata_resetfn_();
+ if (save_bt_) save_bt_->setEnabled(false);
+ if (save_all_bt_) save_all_bt_->setEnabled(false);
+}
+
+void ExportObjectDialog::accept()
+{
+ // Don't close the dialog.
+}
+
+void ExportObjectDialog::captureFileClosing(const capture_file *cf)
+{
+ if (cap_file_ && cf == cap_file_) {
+ close();
+ }
+}
+
+void ExportObjectDialog::on_buttonBox_helpRequested()
+{
+ wsApp->helpTopicAction(HELP_EXPORT_OBJECT_LIST);
+}
+
+void ExportObjectDialog::on_objectTree_currentItemChanged(QTreeWidgetItem *item, QTreeWidgetItem *previous)
+{
+ Q_UNUSED(previous);
+
+ if (!item) {
+ if (save_bt_) save_bt_->setEnabled(false);
+ return;
+ }
+
+ if (save_bt_) save_bt_->setEnabled(true);
+
+ export_object_entry_t *entry = item->data(0, Qt::UserRole).value<export_object_entry_t *>();
+ if (entry && cap_file_) {
+ cf_goto_frame(cap_file_, entry->pkt_num);
+ }
+}
+
+void ExportObjectDialog::on_buttonBox_clicked(QAbstractButton *button)
+{
+ switch (eo_ui_->buttonBox->standardButton(button)) {
+ case QDialogButtonBox::Save:
+ saveCurrentEntry();
+ break;
+ case QDialogButtonBox::SaveAll:
+ saveAllEntries();
+ break;
+ default: // Help, Cancel
+ break;
+ }
+}
+
+void ExportObjectDialog::saveCurrentEntry()
+{
+ QTreeWidgetItem *item = eo_ui_->objectTree->currentItem();
+ export_object_entry_t *entry;
+ QDir path(wsApp->lastOpenDir());
+ QString file_name;
+
+ if (!item) return;
+
+ entry = item->data(0, Qt::UserRole).value<export_object_entry_t *>();
+ if (!entry) return;
+
+ file_name = QFileDialog::getSaveFileName(this, tr("Wireshark: Save Object As..."),
+ path.filePath(entry->filename));
+
+ if (file_name.length() > 0) {
+ eo_save_entry(file_name.toUtf8().constData(), entry, TRUE);
+ }
+}
+
+#define MAXFILELEN 255
+void ExportObjectDialog::saveAllEntries()
+{
+ int i;
+ QTreeWidgetItem *item;
+ QDir path(wsApp->lastOpenDir());
+ QString file_path;
+ bool all_saved = true;
+
+ file_path = QFileDialog::getSaveFileName(this, tr("Wireshark: Save All Objects In..."),
+ path.canonicalPath(), QString(), NULL,
+ QFileDialog::ShowDirsOnly);
+
+ if (file_path.length() < 1 || file_path.length() > MAXFILELEN) return;
+
+ for (i = 0, item = eo_ui_->objectTree->topLevelItem(i); item != NULL; i++) {
+ int count = 0;
+ QString file_name;
+ export_object_entry_t *entry = item->data(0, Qt::UserRole).value<export_object_entry_t *>();
+
+ if (!entry) continue;
+
+ do {
+ GString *safe_filename;
+
+ path.setCurrent(file_path);
+ if (entry->filename)
+ safe_filename = eo_massage_str(entry->filename,
+ MAXFILELEN - file_path.length(), count);
+ else {
+ char generic_name[256];
+ const char *ext;
+ ext = ct2ext(entry->content_type);
+ g_snprintf(generic_name, sizeof(generic_name),
+ "object%u%s%s", entry->pkt_num, ext ? "." : "",
+ ext ? ext : "");
+ safe_filename = eo_massage_str(generic_name,
+ MAXFILELEN - file_path.length(), count);
+ }
+ file_name = path.filePath(safe_filename->str);
+ g_string_free(safe_filename, TRUE);
+ } while (g_file_test(file_path.toUtf8().constData(), G_FILE_TEST_EXISTS) && ++count < 1000);
+ count = 0;
+ if (!eo_save_entry(file_path.toUtf8().constData(), entry, FALSE))
+ all_saved = false;
+ }
+ if (!all_saved) {
+ QMessageBox::warning(
+ this,
+ tr("Object Export"),
+ tr("Some files could not be saved."),
+ QMessageBox::Ok
+ );
+ }
+}
diff --git a/ui/qt/export_object_dialog.h b/ui/qt/export_object_dialog.h
new file mode 100644
index 0000000000..9256dc4e41
--- /dev/null
+++ b/ui/qt/export_object_dialog.h
@@ -0,0 +1,102 @@
+/* export_object_dialog.h
+ *
+ * $Id: main_window.h 45589 2012-10-16 18:14:16Z gerald $
+ *
+ * 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 EXPORT_OBJECT_DIALOG_H
+#define EXPORT_OBJECT_DIALOG_H
+
+#include "config.h"
+
+#include <glib.h>
+
+#include <file.h>
+
+#include <epan/packet_info.h>
+#include <epan/prefs.h>
+#include <epan/tap.h>
+
+#include <ui/export_object.h>
+
+#include <QDialog>
+#include <QMetaType>
+#include <QTreeWidgetItem>
+#include <QAbstractButton>
+
+Q_DECLARE_METATYPE(export_object_entry_t *)
+
+namespace Ui {
+class ExportObjectDialog;
+}
+
+struct _export_object_list_t {
+ class ExportObjectDialog *eod;
+};
+
+
+class ExportObjectDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ enum ObjectType { Dicom, Http, Smb };
+
+ explicit ExportObjectDialog(QWidget *parent, capture_file *cf, ObjectType object_type);
+ ~ExportObjectDialog();
+
+ void show();
+
+ void addObjectEntry(export_object_entry_t *entry);
+ export_object_entry_t *objectEntry(int row);
+ void resetObjects();
+
+private slots:
+ void accept();
+ void captureFileClosing(const capture_file *cf);
+ void on_buttonBox_helpRequested();
+ void on_objectTree_currentItemChanged(QTreeWidgetItem *item, QTreeWidgetItem *previous);
+ void on_buttonBox_clicked(QAbstractButton *button);
+
+private:
+ void saveCurrentEntry();
+ void saveAllEntries();
+
+ /* When a protocol needs intermediate data structures to construct the
+ export objects, then it must specifiy a function that cleans up all
+ those data structures. This function is passed to export_object_window
+ and called when tap reset or windows closes occurs. If no function is needed
+ a NULL value should be passed instead */
+ typedef void (*eo_protocoldata_reset_cb)(void);
+
+ Ui::ExportObjectDialog *eo_ui_;
+ capture_file *cap_file_;
+
+ QPushButton *save_bt_;
+ QPushButton *save_all_bt_;
+
+ export_object_list_t export_object_list_;
+ const gchar *tap_name_;
+ const gchar *name_;
+ tap_packet_cb tap_packet_;
+ eo_protocoldata_reset_cb eo_protocoldata_resetfn_;
+};
+
+#endif // EXPORT_OBJECT_DIALOG_H
diff --git a/ui/qt/export_object_dialog.ui b/ui/qt/export_object_dialog.ui
new file mode 100644
index 0000000000..f6e9681188
--- /dev/null
+++ b/ui/qt/export_object_dialog.ui
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ExportObjectDialog</class>
+ <widget class="QDialog" name="ExportObjectDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>750</width>
+ <height>520</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTreeWidget" name="objectTree">
+ <column>
+ <property name="text">
+ <string>Packet</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>New Column</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Content Type</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Size</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Filename</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="progressFrame">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,1">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="progressLabel">
+ <property name="text">
+ <string>Searching for objects</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="styleSheet">
+ <string notr="true">QProgressBar { width: 10em; }</string>
+ </property>
+ <property name="maximum">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>387</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Help|QDialogButtonBox::Save|QDialogButtonBox::SaveAll</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ExportObjectDialog</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>ExportObjectDialog</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/main_window.cpp b/ui/qt/main_window.cpp
index 65e9b9f324..cde782d8a0 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -104,8 +104,8 @@ MainWindow::MainWindow(QWidget *parent) :
main_ui_->goToFrame->hide();
go_to_margins = main_ui_->goToHB->contentsMargins();
- go_to_margins.setTop(0);
- go_to_margins.setBottom(0);
+// go_to_margins.setTop(0);
+// go_to_margins.setBottom(0);
main_ui_->goToHB->setContentsMargins(go_to_margins);
// XXX For some reason the cursor is drawn funny with an input mask set
// https://bugreports.qt-project.org/browse/QTBUG-7174
@@ -202,8 +202,6 @@ MainWindow::MainWindow(QWidget *parent) :
connect(proto_tree, SIGNAL(protoItemSelected(QString&)),
main_ui_->statusBar, SLOT(pushFieldStatus(QString&)));
- connect(proto_tree, SIGNAL(protoItemSelected(bool)),
- main_ui_->actionViewExpandSubtrees, SLOT(setEnabled(bool)));
connect(proto_tree, SIGNAL(protoItemSelected(field_info *)),
this, SLOT(setMenusForSelectedTreeRow(field_info *)));
@@ -1081,7 +1079,7 @@ void MainWindow::setMenusForCaptureFile(bool force_disable)
main_ui_->menuFileExportPacketDissections->setEnabled(false);
main_ui_->actionFileExportPacketBytes->setEnabled(false);
main_ui_->actionFileExportSSLSessionKeys->setEnabled(false);
- main_ui_->actionFileExportObjects->setEnabled(false);
+ main_ui_->menuFileExportObjects->setEnabled(false);
main_ui_->actionViewReload->setEnabled(false);
} else {
main_ui_->actionFileMerge->setEnabled(cf_can_write_with_wiretap(cap_file_));
@@ -1122,7 +1120,7 @@ void MainWindow::setMenusForCaptureFile(bool force_disable)
main_ui_->menuFileExportPacketDissections->setEnabled(true);
main_ui_->actionFileExportPacketBytes->setEnabled(true);
main_ui_->actionFileExportSSLSessionKeys->setEnabled(true);
- main_ui_->actionFileExportObjects->setEnabled(true);
+ main_ui_->menuFileExportObjects->setEnabled(true);
main_ui_->actionViewReload->setEnabled(true);
}
}
@@ -1136,7 +1134,7 @@ void MainWindow::setMenusForCaptureInProgress(bool capture_in_progress) {
main_ui_->menuFileExportPacketDissections->setEnabled(capture_in_progress);
main_ui_->actionFileExportPacketBytes->setEnabled(capture_in_progress);
main_ui_->actionFileExportSSLSessionKeys->setEnabled(capture_in_progress);
- main_ui_->actionFileExportObjects->setEnabled(capture_in_progress);
+ main_ui_->menuFileExportObjects->setEnabled(capture_in_progress);
main_ui_->menuFileSet->setEnabled(!capture_in_progress);
main_ui_->actionFileQuit->setEnabled(true);
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index a16c3e0b83..71e6d6af0d 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -169,6 +169,9 @@ private slots:
void on_actionFileExportAsPSML_triggered();
void on_actionFileExportAsPDML_triggered();
void on_actionFileExportPacketBytes_triggered();
+ void on_actionFileExportObjectsDICOM_triggered();
+ void on_actionFileExportObjectsHTTP_triggered();
+ void on_actionFileExportObjectsSMB_triggered();
void on_actionGoGoToPacket_triggered();
void resetPreviousFocus();
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 105e15f635..c4a01e3dfb 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -39,6 +39,12 @@
<item row="0" column="0">
<widget class="QFrame" name="goToFrame">
<layout class="QHBoxLayout" name="goToHB">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -122,6 +128,14 @@
<addaction name="actionFileExportAsPSML"/>
<addaction name="actionFileExportAsPDML"/>
</widget>
+ <widget class="QMenu" name="menuFileExportObjects">
+ <property name="title">
+ <string>Export Objects</string>
+ </property>
+ <addaction name="actionFileExportObjectsDICOM"/>
+ <addaction name="actionFileExportObjectsHTTP"/>
+ <addaction name="actionFileExportObjectsSMB"/>
+ </widget>
<addaction name="actionFileOpen"/>
<addaction name="menuOpenRecentCaptureFile"/>
<addaction name="actionFileMerge"/>
@@ -137,7 +151,7 @@
<addaction name="menuFileExportPacketDissections"/>
<addaction name="actionFileExportPacketBytes"/>
<addaction name="actionFileExportSSLSessionKeys"/>
- <addaction name="actionFileExportObjects"/>
+ <addaction name="menuFileExportObjects"/>
<addaction name="separator"/>
<addaction name="actionFilePrint"/>
<addaction name="separator"/>
@@ -611,11 +625,6 @@
<string>Export SSL Session Keys...</string>
</property>
</action>
- <action name="actionFileExportObjects">
- <property name="text">
- <string>Export Objects...</string>
- </property>
- </action>
<action name="actionFilePrint">
<property name="text">
<string>&amp;Print...</string>
@@ -713,6 +722,21 @@
<string>As PDML XML...</string>
</property>
</action>
+ <action name="actionFileExportObjectsHTTP">
+ <property name="text">
+ <string>&amp;HTTP...</string>
+ </property>
+ </action>
+ <action name="actionFileExportObjectsDICOM">
+ <property name="text">
+ <string>&amp;DICOM...</string>
+ </property>
+ </action>
+ <action name="actionFileExportObjectsSMB">
+ <property name="text">
+ <string>&amp;SMB...</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 450b3148fe..875c93bc30 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -60,6 +60,7 @@
#include "wireshark_application.h"
#include "capture_file_dialog.h"
+#include "export_object_dialog.h"
//
// Public slots
@@ -573,8 +574,7 @@ void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
// proto_can_match_selected(cf->finfo_selected, cf->edt));
// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/AnalyzeMenu/PrepareaFilter",
// proto_can_match_selected(cf->finfo_selected, cf->edt));
-// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/ExpandSubtrees",
-// cf->finfo_selected->tree_type != -1);
+ main_ui_->actionViewExpandSubtrees->setEnabled(cap_file_->finfo_selected->tree_type != -1);
// prev_abbrev = g_object_get_data(G_OBJECT(ui_manager_tree_view_menu), "menu_abbrev");
// if (!prev_abbrev || (strcmp (prev_abbrev, abbrev) != 0)) {
// /* No previous protocol or protocol changed - update Protocol Preferences menu */
@@ -610,7 +610,7 @@ void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/AnalyzeMenu/ApplyasColumn", FALSE);
// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/AnalyzeMenu/ApplyAsFilter", FALSE);
// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/AnalyzeMenu/PrepareaFilter", FALSE);
-// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/ExpandSubtrees", FALSE);
+ main_ui_->actionViewExpandSubtrees->setEnabled(false);
}
}
@@ -799,6 +799,24 @@ void MainWindow::on_actionFileExportSSLSessionKeys_triggered()
}
}
+void MainWindow::on_actionFileExportObjectsDICOM_triggered()
+{
+ ExportObjectDialog *eod = new ExportObjectDialog(this, cap_file_, ExportObjectDialog::Dicom);
+ eod->show();
+}
+
+void MainWindow::on_actionFileExportObjectsHTTP_triggered()
+{
+ ExportObjectDialog *eod = new ExportObjectDialog(this, cap_file_, ExportObjectDialog::Http);
+ eod->show();
+}
+
+void MainWindow::on_actionFileExportObjectsSMB_triggered()
+{
+ ExportObjectDialog *eod = new ExportObjectDialog(this, cap_file_, ExportObjectDialog::Smb);
+ eod->show();
+}
+
// View Menu
// Expand / collapse slots in proto_tree
diff --git a/wsutil/str_util.h b/wsutil/str_util.h
index c43e2e05de..302afd0096 100644
--- a/wsutil/str_util.h
+++ b/wsutil/str_util.h
@@ -25,6 +25,10 @@
#ifndef __STR_UTIL_H__
#define __STR_UTIL_H__
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
/** Convert all upper-case ASCII letters to their ASCII lower-case
* equivalents, in place, with a simple non-locale-dependent
* ASCII mapping (A-Z -> a-z).
@@ -84,6 +88,13 @@ typedef enum {
/* XXX format_size_prefix_default_for_this_particular_os ? */
} format_size_flags_e;
+#ifdef __cplusplus
+/* Should we just have separate unit and prefix enums instead? */
+format_size_flags_e operator|(format_size_flags_e lhs, format_size_flags_e rhs) {
+ return (format_size_flags_e) ((int)lhs| (int)rhs);
+}
+#endif /* __cplusplus */
+
/** Given a size, return its value in a human-readable format
*
* Prefixes up to "T/Ti" (tera, tebi) are currently supported.
@@ -95,4 +106,9 @@ typedef enum {
*/
gchar *format_size(gint64 size, format_size_flags_e flags);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
#endif /* __STR_UTIL_H__ */