aboutsummaryrefslogtreecommitdiffstats
path: root/ui/qt
diff options
context:
space:
mode:
authorMoshe Kaplan <me@moshekaplan.com>2016-11-24 09:37:01 -0500
committerMichael Mann <mmann78@netscape.net>2016-12-02 16:07:35 +0000
commit20c57cb298e4f3b7ac66a22fb7477e4cf424a11b (patch)
tree3929a45a2f0df5182af007af697edfa9a55a4634 /ui/qt
parent9ca313cfbe4993a0a36520d216a3e4282b0b7b99 (diff)
Enable exporting objects with tshark
A new "--export-object <protocol>,<destdir>" option is added to tshark. This required refactoring Export Object behavior in all GUIs to give the export object handling to the dissector, rather than the ui layer. Included in the refactoring was fixing some serious memory leaks in Qt Export Object dialog, crash due to memory scope issues in GTK Export Object dialog, and addition sorting column feature in Qt dialog (set up by creating a widget to manage the items that were previously leaking memory) Bug: 9319 Ping-Bug: 13174 Change-Id: I515d7662fa1f150f672b1476716f347ec27deb9b Reviewed-on: https://code.wireshark.org/review/18927 Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Peter Wu <peter@lekensteyn.nl> Tested-by: Michael Mann <mmann78@netscape.net> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'ui/qt')
-rw-r--r--ui/qt/CMakeLists.txt2
-rw-r--r--ui/qt/Makefile.am2
-rw-r--r--ui/qt/export_object_action.cpp65
-rw-r--r--ui/qt/export_object_action.h64
-rw-r--r--ui/qt/export_object_dialog.cpp209
-rw-r--r--ui/qt/export_object_dialog.h28
-rw-r--r--ui/qt/main_window.cpp24
-rw-r--r--ui/qt/main_window.h8
-rw-r--r--ui/qt/main_window.ui30
-rw-r--r--ui/qt/main_window_slots.cpp36
10 files changed, 314 insertions, 154 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 3cd9d2e503..9899ad7477 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -60,6 +60,7 @@ set(WIRESHARK_QT_HEADERS
endpoint_dialog.h
expert_info_dialog.h
export_dissection_dialog.h
+ export_object_action.h
export_object_dialog.h
export_pdu_dialog.h
field_filter_edit.h
@@ -227,6 +228,7 @@ set(WIRESHARK_QT_SRC
enabled_protocols_dialog.cpp
endpoint_dialog.cpp
export_dissection_dialog.cpp
+ export_object_action.cpp
export_object_dialog.cpp
export_pdu_dialog.cpp
field_filter_edit.cpp
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index f543f42c0a..bb83a45a6a 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -190,6 +190,7 @@ MOC_HDRS = \
endpoint_dialog.h \
expert_info_dialog.h \
export_dissection_dialog.h \
+ export_object_action.h \
export_object_dialog.h \
export_pdu_dialog.h \
field_filter_edit.h \
@@ -471,6 +472,7 @@ WIRESHARK_QT_SRC = \
enabled_protocols_dialog.cpp \
endpoint_dialog.cpp \
export_dissection_dialog.cpp \
+ export_object_action.cpp \
export_object_dialog.cpp \
export_pdu_dialog.cpp \
field_filter_edit.cpp \
diff --git a/ui/qt/export_object_action.cpp b/ui/qt/export_object_action.cpp
new file mode 100644
index 0000000000..7b9363ba72
--- /dev/null
+++ b/ui/qt/export_object_action.cpp
@@ -0,0 +1,65 @@
+/* conversation_colorize_action.cpp
+ *
+ * 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 <epan/packet_info.h>
+#include <epan/proto_data.h>
+#include <epan/packet.h>
+#include <wsutil/utf8_entities.h>
+#include "export_object_action.h"
+
+#include <QMenu>
+
+#include "qt_ui_utils.h"
+
+ExportObjectAction::ExportObjectAction(QObject *parent, register_eo_t *eo) :
+ QAction(parent),
+ eo_(eo)
+{
+ if (eo_) {
+ setText( QString("%1%2").arg(proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo)))).arg(UTF8_HORIZONTAL_ELLIPSIS));
+ }
+}
+
+void ExportObjectAction::captureFileOpened()
+{
+ setEnabled(true);
+}
+
+void ExportObjectAction::captureFileClosed()
+{
+ setEnabled(false);
+}
+
+/*
+ * 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/export_object_action.h b/ui/qt/export_object_action.h
new file mode 100644
index 0000000000..5328f24b31
--- /dev/null
+++ b/ui/qt/export_object_action.h
@@ -0,0 +1,64 @@
+/* export_object_action.h
+ *
+ * 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 EXPORTOBJECTACTION_H
+#define EXPORTOBJECTACTION_H
+
+#include "config.h"
+
+#include <glib.h>
+#include <epan/packet_info.h>
+#include <epan/export_object.h>
+
+#include <QAction>
+
+// Actions for "Export Objects" menu items.
+
+class ExportObjectAction : public QAction
+{
+ Q_OBJECT
+public:
+ ExportObjectAction(QObject *parent, register_eo_t *eo = NULL);
+
+ register_eo_t* exportObject() {return eo_;}
+
+public slots:
+ void captureFileOpened();
+ void captureFileClosed();
+
+private:
+ register_eo_t *eo_;
+};
+
+#endif // EXPORTOBJECTACTION_H
+
+/*
+ * 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/export_object_dialog.cpp b/ui/qt/export_object_dialog.cpp
index 29126334ca..8592332feb 100644
--- a/ui/qt/export_object_dialog.cpp
+++ b/ui/qt/export_object_dialog.cpp
@@ -28,6 +28,7 @@
#include <wsutil/filesystem.h>
#include <wsutil/str_util.h>
+#include "qt_ui_utils.h"
#include "wireshark_application.h"
#include <QDialogButtonBox>
@@ -37,14 +38,21 @@
extern "C" {
-// object_list_add_entry and object_list_get_entry are defined in ui/export_object.h
+static void
+object_list_add_entry(void *gui_data, export_object_entry_t *entry) {
+ export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data;
-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);
+ 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);
+static export_object_entry_t*
+object_list_get_entry(void *gui_data, int row) {
+ export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data;
+
+ if (object_list && object_list->eod)
+ return object_list->eod->objectEntry(row);
+
return NULL;
}
@@ -54,21 +62,94 @@ export_object_entry_t *object_list_get_entry(export_object_list_t *object_list,
static void
eo_reset(void *tapdata)
{
- export_object_list_t *object_list = (export_object_list_t *) tapdata;
+ export_object_list_t *tap_object = (export_object_list_t *)tapdata;
+ export_object_list_gui_t *object_list = (export_object_list_gui_t *)tap_object->gui_data;
if (object_list && object_list->eod) object_list->eod->resetObjects();
}
} // extern "C"
-ExportObjectDialog::ExportObjectDialog(QWidget &parent, CaptureFile &cf, ObjectType object_type) :
+
+enum {
+ COL_PACKET,
+ COL_HOSTNAME,
+ COL_CONTENT_TYPE,
+ COL_SIZE,
+ COL_FILENAME
+};
+
+enum {
+ export_object_row_type_ = 1000
+};
+
+class ExportObjectTreeWidgetItem : public QTreeWidgetItem
+{
+public:
+ ExportObjectTreeWidgetItem(QTreeWidget *parent, export_object_entry_t *entry) :
+ QTreeWidgetItem (parent, export_object_row_type_),
+ entry_(entry)
+ {
+ // Not perfect but better than nothing.
+ setTextAlignment(COL_SIZE, Qt::AlignRight);
+ }
+ ~ExportObjectTreeWidgetItem() {
+ eo_free_entry(entry_);
+ }
+
+ export_object_entry_t *entry() { return entry_; }
+
+ virtual QVariant data(int column, int role) const {
+ if (!entry_ || role != Qt::DisplayRole) {
+ return QTreeWidgetItem::data(column, role);
+ }
+
+ switch (column) {
+ case COL_PACKET:
+ return QString::number(entry_->pkt_num);
+ case COL_HOSTNAME:
+ return entry_->hostname;
+ case COL_CONTENT_TYPE:
+ return entry_->content_type;
+ case COL_SIZE:
+ return file_size_to_qstring(entry_->payload_len);
+ case COL_FILENAME:
+ return entry_->filename;
+ default:
+ break;
+ }
+ return QTreeWidgetItem::data(column, role);
+ }
+
+ bool operator< (const QTreeWidgetItem &other) const
+ {
+ if (!entry_ || other.type() != export_object_row_type_) {
+ return QTreeWidgetItem::operator< (other);
+ }
+
+ const ExportObjectTreeWidgetItem *other_row = static_cast<const ExportObjectTreeWidgetItem *>(&other);
+
+ switch (treeWidget()->sortColumn()) {
+ case COL_PACKET:
+ return entry_->pkt_num < other_row->entry_->pkt_num;
+ case COL_SIZE:
+ return entry_->payload_len < other_row->entry_->payload_len;
+ default:
+ break;
+ }
+
+ return QTreeWidgetItem::operator< (other);
+ }
+
+private:
+ export_object_entry_t *entry_;
+};
+
+ExportObjectDialog::ExportObjectDialog(QWidget &parent, CaptureFile &cf, register_eo_t* eo) :
WiresharkDialog(parent, cf),
eo_ui_(new Ui::ExportObjectDialog),
save_bt_(NULL),
save_all_bt_(NULL),
- tap_name_(NULL),
- name_(NULL),
- tap_packet_(NULL),
- eo_protocoldata_resetfn_(NULL)
+ eo_(eo)
{
QPushButton *close_bt;
@@ -80,42 +161,17 @@ ExportObjectDialog::ExportObjectDialog(QWidget &parent, CaptureFile &cf, ObjectT
eo_ui_->progressBar->setAttribute(Qt::WA_MacSmallSize, true);
#endif
- export_object_list_.eod = this;
+ eo_gui_data_.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 Imf:
- tap_name_ = "imf_eo";
- name_ = "IMF";
- tap_packet_ = eo_imf_packet;
- break;
- case Smb:
- tap_name_ = "smb_eo";
- name_ = "SMB";
- tap_packet_ = eo_smb_packet;
- eo_protocoldata_resetfn_ = eo_smb_cleanup;
- break;
- case Tftp:
- tap_name_ = "tftp_eo";
- name_ = "TFTP";
- tap_packet_ = eo_tftp_packet;
- break;
- }
+ export_object_list_.add_entry = object_list_add_entry;
+ export_object_list_.get_entry = object_list_get_entry;
+ export_object_list_.gui_data = (void*)&eo_gui_data_;
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);
- setWindowTitle(wsApp->windowTitleString(QStringList() << tr("Export") << tr("%1 object list").arg(name_)));
+ setWindowTitle(wsApp->windowTitleString(QStringList() << tr("Export") << tr("%1 object list").arg(proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo))))));
if (save_bt_) save_bt_->setEnabled(false);
if (save_all_bt_) save_all_bt_->setEnabled(false);
@@ -131,46 +187,37 @@ ExportObjectDialog::ExportObjectDialog(QWidget &parent, CaptureFile &cf, ObjectT
ExportObjectDialog::~ExportObjectDialog()
{
delete eo_ui_;
- export_object_list_.eod = NULL;
+ eo_gui_data_.eod = NULL;
removeTapListeners();
}
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(4, entry->filename);
- g_free(size_str);
- // Not perfect but better than nothing.
- entry_item->setTextAlignment(3, Qt::AlignRight);
+ new ExportObjectTreeWidgetItem(eo_ui_->objectTree, entry);
if (save_all_bt_) save_all_bt_->setEnabled(true);
}
export_object_entry_t *ExportObjectDialog::objectEntry(int row)
{
- QTreeWidgetItem *item = eo_ui_->objectTree->topLevelItem(row);
+ QTreeWidgetItem *cur_ti = eo_ui_->objectTree->topLevelItem(row);
+ ExportObjectTreeWidgetItem *eo_ti = dynamic_cast<ExportObjectTreeWidgetItem *>(cur_ti);
- if (item) return item->data(0, Qt::UserRole).value<export_object_entry_t *>();
+ if (eo_ti) {
+ return eo_ti->entry();
+ }
return NULL;
}
void ExportObjectDialog::resetObjects()
{
- if (eo_protocoldata_resetfn_) eo_protocoldata_resetfn_();
+ export_object_gui_reset_cb reset_cb = get_eo_reset_func(eo_);
+ if (reset_cb)
+ reset_cb();
+
if (save_bt_) save_bt_->setEnabled(false);
if (save_all_bt_) save_all_bt_->setEnabled(false);
}
@@ -178,9 +225,9 @@ void ExportObjectDialog::resetObjects()
void ExportObjectDialog::show()
{
/* Data will be gathered via a tap callback */
- if (!registerTapListener(tap_name_, &export_object_list_, NULL, 0,
+ if (!registerTapListener(get_eo_tap_listener_name(eo_), &export_object_list_, NULL, 0,
eo_reset,
- tap_packet_,
+ get_eo_packet_func(eo_),
NULL)) {
return;
}
@@ -191,6 +238,8 @@ void ExportObjectDialog::show()
for (int i = 0; i < eo_ui_->objectTree->columnCount(); i++)
eo_ui_->objectTree->resizeColumnToContents(i);
+ eo_ui_->objectTree->setSortingEnabled(true);
+ eo_ui_->objectTree->sortByColumn(COL_PACKET, Qt::AscendingOrder);
}
void ExportObjectDialog::accept()
@@ -217,7 +266,13 @@ void ExportObjectDialog::on_objectTree_currentItemChanged(QTreeWidgetItem *item,
if (save_bt_) save_bt_->setEnabled(true);
- export_object_entry_t *entry = item->data(0, Qt::UserRole).value<export_object_entry_t *>();
+ ExportObjectTreeWidgetItem *eo_ti = dynamic_cast<ExportObjectTreeWidgetItem *>(item);
+
+ if (!eo_ti) {
+ return;
+ }
+
+ export_object_entry_t *entry = eo_ti->entry();
if (entry && !file_closed_) {
cf_goto_frame(cap_file_.capFile(), entry->pkt_num);
}
@@ -244,10 +299,15 @@ void ExportObjectDialog::saveCurrentEntry()
QDir path(wsApp->lastOpenDir());
QString file_name;
- if (!item) return;
+ ExportObjectTreeWidgetItem *eo_ti = dynamic_cast<ExportObjectTreeWidgetItem *>(item);
+ if (!eo_ti) {
+ return;
+ }
- entry = item->data(0, Qt::UserRole).value<export_object_entry_t *>();
- if (!entry) return;
+ entry = eo_ti->entry();
+ if (!entry) {
+ return;
+ }
file_name = QFileDialog::getSaveFileName(this, wsApp->windowTitleString(tr("Save Object As" UTF8_HORIZONTAL_ELLIPSIS)),
path.filePath(entry->filename));
@@ -257,7 +317,6 @@ void ExportObjectDialog::saveCurrentEntry()
}
}
-#define MAXFILELEN 255
void ExportObjectDialog::saveAllEntries()
{
int i;
@@ -280,13 +339,17 @@ void ExportObjectDialog::saveAllEntries()
save_in_dir.canonicalPath(),
QFileDialog::ShowDirsOnly);
- if (save_in_path.length() < 1 || save_in_path.length() > MAXFILELEN) return;
+ if (save_in_path.length() < 1 || save_in_path.length() > EXPORT_OBJECT_MAXFILELEN) return;
for (i = 0; (item = eo_ui_->objectTree->topLevelItem(i)) != NULL; i++) {
int count = 0;
gchar *save_as_fullpath = NULL;
- export_object_entry_t *entry = item->data(0, Qt::UserRole).value<export_object_entry_t *>();
+ ExportObjectTreeWidgetItem *eo_ti = dynamic_cast<ExportObjectTreeWidgetItem *>(item);
+ if (!eo_ti) {
+ continue;
+ }
+ export_object_entry_t *entry = eo_ti->entry();
if (!entry) continue;
do {
@@ -295,16 +358,16 @@ void ExportObjectDialog::saveAllEntries()
g_free(save_as_fullpath);
if (entry->filename)
safe_filename = eo_massage_str(entry->filename,
- MAXFILELEN - save_in_path.length(), count);
+ EXPORT_OBJECT_MAXFILELEN - save_in_path.length(), count);
else {
char generic_name[256];
const char *ext;
- ext = ct2ext(entry->content_type);
+ ext = eo_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 - save_in_path.length(), count);
+ EXPORT_OBJECT_MAXFILELEN - save_in_path.length(), count);
}
save_as_fullpath = g_build_filename(save_in_path.toUtf8().constData(),
safe_filename->str, NULL);
diff --git a/ui/qt/export_object_dialog.h b/ui/qt/export_object_dialog.h
index 9084017a80..e400a128b8 100644
--- a/ui/qt/export_object_dialog.h
+++ b/ui/qt/export_object_dialog.h
@@ -31,25 +31,22 @@
#include <epan/packet_info.h>
#include <epan/prefs.h>
#include <epan/tap.h>
+#include <epan/export_object.h>
-#include <ui/export_object.h>
+#include <ui/export_object_ui.h>
#include "wireshark_dialog.h"
-#include <QMetaType>
-
class QTreeWidgetItem;
class QAbstractButton;
-Q_DECLARE_METATYPE(export_object_entry_t *)
-
namespace Ui {
class ExportObjectDialog;
}
-struct _export_object_list_t {
+typedef struct _export_object_list_gui_t {
class ExportObjectDialog *eod;
-};
+} export_object_list_gui_t;
class ExportObjectDialog : public WiresharkDialog
@@ -57,9 +54,7 @@ class ExportObjectDialog : public WiresharkDialog
Q_OBJECT
public:
- enum ObjectType { Dicom, Http, Imf, Smb, Tftp };
-
- explicit ExportObjectDialog(QWidget &parent, CaptureFile &cf, ObjectType object_type);
+ explicit ExportObjectDialog(QWidget &parent, CaptureFile &cf, register_eo_t* eo);
~ExportObjectDialog();
@@ -81,23 +76,14 @@ 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_;
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_;
+ export_object_list_gui_t eo_gui_data_;
+ register_eo_t* eo_;
};
#endif // EXPORT_OBJECT_DIALOG_H
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index 169fb943f4..8ed0f6a087 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -30,6 +30,7 @@
#include <epan/prefs.h>
#include <epan/stats_tree_priv.h>
#include <epan/plugin_if.h>
+#include <epan/export_object.h>
#include "ui/commandline.h"
@@ -54,6 +55,7 @@
#include "capture_interfaces_dialog.h"
#endif
#include "conversation_colorize_action.h"
+#include "export_object_action.h"
#include "display_filter_edit.h"
#include "export_dissection_dialog.h"
#include "file_set_dialog.h"
@@ -347,6 +349,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addDynamicMenus()));
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addExternalMenus()));
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initConversationMenus()));
+ connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initExportObjectsMenus()));
connect(wsApp, SIGNAL(profileChanging()), this, SLOT(saveWindowGeometry()));
connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(layoutPanes()));
@@ -1927,6 +1930,27 @@ void MainWindow::initConversationMenus()
connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeActionTriggered()));
}
+void MainWindow::addExportObjectsMenuItem(gpointer data, gpointer user_data)
+{
+ register_eo_t *eo = (register_eo_t*)data;
+ MainWindow *window = (MainWindow*)user_data;
+
+ ExportObjectAction *export_action = new ExportObjectAction(window->main_ui_->menuFileExportObjects, eo);
+ window->main_ui_->menuFileExportObjects->addAction(export_action);
+
+ //initially disable until a file is loaded (then file signals will take over)
+ export_action->setEnabled(false);
+
+ connect(&window->capture_file_, SIGNAL(captureFileOpened()), export_action, SLOT(captureFileOpened()));
+ connect(&window->capture_file_, SIGNAL(captureFileClosed()), export_action, SLOT(captureFileClosed()));
+ connect(export_action, SIGNAL(triggered()), window, SLOT(applyExportObject()));
+}
+
+void MainWindow::initExportObjectsMenus()
+{
+ eo_iterate_tables(addExportObjectsMenuItem, this);
+}
+
// Titlebar
void MainWindow::setTitlebarForCaptureFile()
{
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 5320fc7f13..cda9116ebb 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -292,6 +292,8 @@ private slots:
void initViewColorizeMenu();
void initConversationMenus();
+ static void addExportObjectsMenuItem(gpointer data, gpointer user_data);
+ void initExportObjectsMenus();
// in main_window_slots.cpp
/**
@@ -387,11 +389,6 @@ private slots:
void on_actionFileExportAsPDML_triggered();
void on_actionFileExportAsJSON_triggered();
void on_actionFileExportPacketBytes_triggered();
- void on_actionFileExportObjectsDICOM_triggered();
- void on_actionFileExportObjectsHTTP_triggered();
- void on_actionFileExportObjectsIMF_triggered();
- void on_actionFileExportObjectsSMB_triggered();
- void on_actionFileExportObjectsTFTP_triggered();
void on_actionFilePrint_triggered();
void on_actionFileExportPDU_triggered();
@@ -489,6 +486,7 @@ private slots:
void on_actionAnalyzePAFOrNotSelected_triggered();
void applyConversationFilter();
+ void applyExportObject();
void on_actionAnalyzeEnabledProtocols_triggered();
void on_actionAnalyzeDecodeAs_triggered();
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 7c4085d6af..a72b241d7e 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -178,11 +178,6 @@
<property name="title">
<string>Export Objects</string>
</property>
- <addaction name="actionFileExportObjectsDICOM"/>
- <addaction name="actionFileExportObjectsHTTP"/>
- <addaction name="actionFileExportObjectsIMF"/>
- <addaction name="actionFileExportObjectsSMB"/>
- <addaction name="actionFileExportObjectsTFTP"/>
</widget>
<addaction name="actionFileOpen"/>
<addaction name="menuOpenRecentCaptureFile"/>
@@ -1245,26 +1240,6 @@
<string>As JSON…</string>
</property>
</action>
- <action name="actionFileExportObjectsHTTP">
- <property name="text">
- <string>&amp;HTTP…</string>
- </property>
- </action>
- <action name="actionFileExportObjectsIMF">
- <property name="text">
- <string>&amp;IMF…</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>
<action name="actionEditCopyDescription">
<property name="text">
<string>Description</string>
@@ -2076,11 +2051,6 @@
<string>Show or hide the display filter toolbar</string>
</property>
</action>
- <action name="actionFileExportObjectsTFTP">
- <property name="text">
- <string>&amp;TFTP</string>
- </property>
- </action>
<action name="actionStatisticsConversations">
<property name="text">
<string>Conversations</string>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 1b2ac37c11..dfdc8ac433 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -43,6 +43,7 @@
#include "ui/commandline.h"
#include "epan/color_filters.h"
+#include "epan/export_object.h"
#include "wsutil/file_util.h"
#include "wsutil/filesystem.h"
@@ -102,6 +103,7 @@
#include "dissector_tables_dialog.h"
#include "endpoint_dialog.h"
#include "expert_info_dialog.h"
+#include "export_object_action.h"
#include "export_object_dialog.h"
#include "export_pdu_dialog.h"
#ifdef HAVE_EXTCAP
@@ -1863,36 +1865,11 @@ void MainWindow::on_actionFileExportSSLSessionKeys_triggered()
}
}
-void MainWindow::on_actionFileExportObjectsDICOM_triggered()
-{
- new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Dicom);
-}
-
void MainWindow::on_actionStatisticsHpfeeds_triggered()
{
openStatisticsTreeDialog("hpfeeds");
}
-void MainWindow::on_actionFileExportObjectsHTTP_triggered()
-{
- new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Http);
-}
-
-void MainWindow::on_actionFileExportObjectsIMF_triggered()
-{
- new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Imf);
-}
-
-void MainWindow::on_actionFileExportObjectsSMB_triggered()
-{
- new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Smb);
-}
-
-void MainWindow::on_actionFileExportObjectsTFTP_triggered()
-{
- new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Tftp);
-}
-
void MainWindow::on_actionFilePrint_triggered()
{
PrintDialog pdlg(this, capture_file_.capFile());
@@ -2645,6 +2622,15 @@ void MainWindow::applyConversationFilter()
}
}
+void MainWindow::applyExportObject()
+{
+ ExportObjectAction *export_action = qobject_cast<ExportObjectAction*>(sender());
+ if (!export_action)
+ return;
+
+ new ExportObjectDialog(*this, capture_file_, export_action->exportObject());
+}
+
// XXX We could probably create the analyze and prepare actions
// dynamically using FilterActions and consolidate the methods
// below into one callback.