forked from osmocom/wireshark
![Gerald Combs](/assets/img/avatar_default.png)
Remove the editor modeline blocks from most of the source files in ui/qt by running perl -i -p0e 's{ \n+ /[ *\n]+ editor \s+ modelines .* shiftwidth= .* \*/ \s+ } {\n}gsix' $( ag -g '\.(cpp|h)' ) then cleaning up the remaining files by hand. This *shouldn't* affect anyone since - All of the source files in ui/qt use 4 space indentation, which matches the default in our top-level .editorconfig - The one notable editor that's likely to be used on these files and *doesn't* support EditorConfig (Qt Creator) defaults to 4 space indentation.
289 lines
9.5 KiB
C++
289 lines
9.5 KiB
C++
/* export_dissection_dialog.cpp
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* Copyright 1998 Gerald Combs
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include "export_dissection_dialog.h"
|
|
|
|
#ifdef Q_OS_WIN
|
|
#include <windows.h>
|
|
#include "ui/packet_range.h"
|
|
#include "ui/win32/file_dlg_win32.h"
|
|
#else // Q_OS_WIN
|
|
|
|
#include "ui/alert_box.h"
|
|
#include "ui/help_url.h"
|
|
#include "ui/util.h"
|
|
|
|
#include <epan/print.h>
|
|
#include <wsutil/filesystem.h>
|
|
|
|
#include <ui/qt/utils/qt_ui_utils.h>
|
|
|
|
|
|
#include <QDialogButtonBox>
|
|
#include <QGridLayout>
|
|
#include <QPushButton>
|
|
#endif // Q_OS_WIN
|
|
|
|
#include <epan/prefs.h>
|
|
#include "wireshark_application.h"
|
|
|
|
#if !defined(Q_OS_WIN)
|
|
static const QStringList export_extensions = QStringList()
|
|
<< ""
|
|
<< "txt"
|
|
<< ""
|
|
<< "csv"
|
|
<< "psml"
|
|
<< "pdml"
|
|
<< "c"
|
|
<< "json";
|
|
|
|
#endif
|
|
|
|
ExportDissectionDialog::ExportDissectionDialog(QWidget *parent, capture_file *cap_file, export_type_e export_type, QString selRange):
|
|
WiresharkFileDialog(parent),
|
|
export_type_(export_type),
|
|
cap_file_(cap_file)
|
|
#if !defined(Q_OS_WIN)
|
|
, save_bt_(NULL)
|
|
#else
|
|
, sel_range_(selRange)
|
|
#endif /* Q_OS_WIN */
|
|
{
|
|
setWindowTitle(wsApp->windowTitleString(tr("Export Packet Dissections")));
|
|
|
|
switch (prefs.gui_fileopen_style) {
|
|
|
|
case FO_STYLE_LAST_OPENED:
|
|
/* The user has specified that we should start out in the last directory
|
|
* we looked in. If we've already opened a file, use its containing
|
|
* directory, if we could determine it, as the directory, otherwise
|
|
* use the "last opened" directory saved in the preferences file if
|
|
* there was one.
|
|
*/
|
|
setDirectory(wsApp->lastOpenDir());
|
|
break;
|
|
|
|
case FO_STYLE_SPECIFIED:
|
|
/* The user has specified that we should always start out in a
|
|
* specified directory; if they've specified that directory,
|
|
* start out by showing the files in that dir.
|
|
*/
|
|
if (prefs.gui_fileopen_dir[0] != '\0')
|
|
setDirectory(prefs.gui_fileopen_dir);
|
|
break;
|
|
}
|
|
|
|
#if !defined(Q_OS_WIN)
|
|
QDialogButtonBox *button_box = findChild<QDialogButtonBox *>();
|
|
// Add extra widgets
|
|
// https://wiki.qt.io/Qt_project_org_faq#How_can_I_add_widgets_to_my_QFileDialog_instance.3F
|
|
setOption(QFileDialog::DontUseNativeDialog, true);
|
|
QGridLayout *fd_grid = qobject_cast<QGridLayout*>(layout());
|
|
QHBoxLayout *h_box = new QHBoxLayout();
|
|
QStringList name_filters;
|
|
int last_row;
|
|
|
|
setAcceptMode(QFileDialog::AcceptSave);
|
|
setLabelText(FileType, tr("Export As:"));
|
|
|
|
// export_type_map_keys() sorts alphabetically. We don't want that.
|
|
name_filters
|
|
<< tr("Plain text (*.txt)")
|
|
<< tr("Comma Separated Values - summary (*.csv)")
|
|
<< tr("PSML - summary (*.psml, *.xml)")
|
|
<< tr("PDML - details (*.pdml, *.xml)")
|
|
<< tr("JSON (*.json)")
|
|
<< tr("C Arrays - bytes (*.c, *.h)");
|
|
export_type_map_[name_filters[0]] = export_type_text;
|
|
export_type_map_[name_filters[1]] = export_type_csv;
|
|
export_type_map_[name_filters[2]] = export_type_psml;
|
|
export_type_map_[name_filters[3]] = export_type_pdml;
|
|
export_type_map_[name_filters[4]] = export_type_json;
|
|
export_type_map_[name_filters[5]] = export_type_carrays;
|
|
setNameFilters(name_filters);
|
|
selectNameFilter(export_type_map_.key(export_type));
|
|
exportTypeChanged(export_type_map_.key(export_type));
|
|
|
|
last_row = fd_grid->rowCount();
|
|
fd_grid->addItem(new QSpacerItem(1, 1), last_row, 0);
|
|
fd_grid->addLayout(h_box, last_row, 1);
|
|
|
|
print_args_.file = NULL;
|
|
/* Init the export range */
|
|
packet_range_init(&print_args_.range, cap_file_);
|
|
/* Default to displayed packets */
|
|
print_args_.range.process_filtered = TRUE;
|
|
|
|
packet_range_group_box_.initRange(&print_args_.range, selRange);
|
|
h_box->addWidget(&packet_range_group_box_);
|
|
|
|
h_box->addWidget(&packet_format_group_box_, 0, Qt::AlignTop);
|
|
|
|
if (button_box) {
|
|
button_box->addButton(QDialogButtonBox::Help);
|
|
connect(button_box, SIGNAL(helpRequested()), this, SLOT(on_buttonBox_helpRequested()));
|
|
|
|
save_bt_ = button_box->button(QDialogButtonBox::Save);
|
|
}
|
|
|
|
if (save_bt_) {
|
|
connect(&packet_range_group_box_, SIGNAL(validityChanged(bool)),
|
|
this, SLOT(checkValidity()));
|
|
connect(&packet_format_group_box_, SIGNAL(formatChanged()),
|
|
this, SLOT(checkValidity()));
|
|
}
|
|
connect(this, SIGNAL(filterSelected(QString)), this, SLOT(exportTypeChanged(QString)));
|
|
|
|
// Grow the dialog to account for the extra widgets.
|
|
resize(width(), height() + (packet_range_group_box_.height() * 2 / 3));
|
|
|
|
connect(this, SIGNAL(accepted()), this, SLOT(dialogAccepted()));
|
|
#else // Q_OS_WIN
|
|
#endif // Q_OS_WIN
|
|
}
|
|
|
|
ExportDissectionDialog::~ExportDissectionDialog()
|
|
{
|
|
#if !defined(Q_OS_WIN)
|
|
g_free(print_args_.file);
|
|
packet_range_cleanup(&print_args_.range);
|
|
#endif
|
|
}
|
|
|
|
void ExportDissectionDialog::show()
|
|
{
|
|
#if !defined(Q_OS_WIN)
|
|
if (cap_file_) {
|
|
WiresharkFileDialog::show();
|
|
}
|
|
#else // Q_OS_WIN
|
|
win32_export_file((HWND)parentWidget()->effectiveWinId(), windowTitle().toStdWString().c_str(), cap_file_, export_type_, sel_range_.toStdString().c_str());
|
|
#endif // Q_OS_WIN
|
|
}
|
|
|
|
#ifndef Q_OS_WIN
|
|
void ExportDissectionDialog::dialogAccepted()
|
|
{
|
|
if (selectedFiles().length() > 0) {
|
|
cf_print_status_t status;
|
|
QString file_name = selectedFiles()[0];
|
|
|
|
/* Fill in our print (and export) args */
|
|
|
|
print_args_.file = qstring_strdup(file_name);
|
|
print_args_.format = PR_FMT_TEXT;
|
|
print_args_.to_file = TRUE;
|
|
print_args_.cmd = NULL;
|
|
print_args_.print_summary = TRUE;
|
|
print_args_.print_col_headings = TRUE;
|
|
print_args_.print_dissections = print_dissections_as_displayed;
|
|
print_args_.print_hex = FALSE;
|
|
print_args_.print_formfeed = FALSE;
|
|
|
|
switch (export_type_) {
|
|
case export_type_text: /* Text */
|
|
print_args_.print_summary = packet_format_group_box_.summaryEnabled();
|
|
print_args_.print_col_headings = packet_format_group_box_.includeColumnHeadingsEnabled();
|
|
print_args_.print_dissections = print_dissections_none;
|
|
if (packet_format_group_box_.detailsEnabled()) {
|
|
if (packet_format_group_box_.allCollapsedEnabled())
|
|
print_args_.print_dissections = print_dissections_collapsed;
|
|
else if (packet_format_group_box_.asDisplayedEnabled())
|
|
print_args_.print_dissections = print_dissections_as_displayed;
|
|
else if (packet_format_group_box_.allExpandedEnabled())
|
|
print_args_.print_dissections = print_dissections_expanded;
|
|
}
|
|
print_args_.print_hex = packet_format_group_box_.bytesEnabled();
|
|
print_args_.stream = print_stream_text_new(TRUE, print_args_.file);
|
|
if (print_args_.stream == NULL) {
|
|
open_failure_alert_box(print_args_.file, errno, TRUE);
|
|
return;
|
|
}
|
|
status = cf_print_packets(cap_file_, &print_args_, TRUE);
|
|
break;
|
|
case export_type_csv: /* CSV */
|
|
status = cf_write_csv_packets(cap_file_, &print_args_);
|
|
break;
|
|
case export_type_carrays: /* C Arrays */
|
|
status = cf_write_carrays_packets(cap_file_, &print_args_);
|
|
break;
|
|
case export_type_psml: /* PSML */
|
|
status = cf_write_psml_packets(cap_file_, &print_args_);
|
|
break;
|
|
case export_type_pdml: /* PDML */
|
|
status = cf_write_pdml_packets(cap_file_, &print_args_);
|
|
break;
|
|
case export_type_json: /* JSON */
|
|
status = cf_write_json_packets(cap_file_, &print_args_);
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
switch (status) {
|
|
case CF_PRINT_OK:
|
|
break;
|
|
case CF_PRINT_OPEN_ERROR:
|
|
open_failure_alert_box(print_args_.file, errno, TRUE);
|
|
break;
|
|
case CF_PRINT_WRITE_ERROR:
|
|
write_failure_alert_box(print_args_.file, errno);
|
|
break;
|
|
}
|
|
|
|
if (selectedFiles().length() > 0) {
|
|
gchar *dirname;
|
|
/* Save the directory name for future file dialogs. */
|
|
dirname = get_dirname(print_args_.file); /* Overwrites file_name data */
|
|
set_last_open_dir(dirname);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ExportDissectionDialog::exportTypeChanged(QString name_filter)
|
|
{
|
|
export_type_ = export_type_map_.value(name_filter);
|
|
if (export_type_ == export_type_text) {
|
|
packet_format_group_box_.setEnabled(true);
|
|
print_args_.format = PR_FMT_TEXT;
|
|
} else {
|
|
packet_format_group_box_.setEnabled(false);
|
|
}
|
|
|
|
checkValidity();
|
|
setDefaultSuffix(export_extensions[export_type_]);
|
|
}
|
|
|
|
void ExportDissectionDialog::checkValidity()
|
|
{
|
|
bool enable = true;
|
|
|
|
if (!save_bt_) return;
|
|
|
|
if (!packet_range_group_box_.isValid()) enable = false;
|
|
|
|
if (export_type_ == export_type_text) {
|
|
if (! packet_format_group_box_.summaryEnabled() &&
|
|
! packet_format_group_box_.detailsEnabled() &&
|
|
! packet_format_group_box_.bytesEnabled())
|
|
{
|
|
enable = false;
|
|
}
|
|
}
|
|
|
|
save_bt_->setEnabled(enable);
|
|
}
|
|
|
|
void ExportDissectionDialog::on_buttonBox_helpRequested()
|
|
{
|
|
wsApp->helpTopicAction(HELP_EXPORT_FILE_DIALOG);
|
|
}
|
|
#endif // Q_OS_WIN
|