2012-10-18 21:14:43 +00:00
|
|
|
/* export_object_dialog.cpp
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-02-07 11:26:45 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2012-10-18 21:14:43 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "export_object_dialog.h"
|
2015-06-25 16:17:03 +00:00
|
|
|
#include <ui_export_object_dialog.h>
|
2014-12-29 22:12:43 +00:00
|
|
|
|
|
|
|
#include <ui/alert_box.h>
|
2015-10-04 17:10:29 +00:00
|
|
|
#include <wsutil/utf8_entities.h>
|
2014-12-29 22:12:43 +00:00
|
|
|
|
2012-10-18 21:14:43 +00:00
|
|
|
#include "wireshark_application.h"
|
2018-05-16 00:02:26 +00:00
|
|
|
#include "ui/qt/widgets/wireshark_file_dialog.h"
|
2019-11-21 14:57:32 +00:00
|
|
|
#include <ui/qt/widgets/export_objects_view.h>
|
|
|
|
#include <ui/qt/models/export_objects_model.h>
|
2012-10-18 21:14:43 +00:00
|
|
|
|
|
|
|
#include <QDialogButtonBox>
|
2015-08-24 19:30:56 +00:00
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QPushButton>
|
2019-11-21 14:57:32 +00:00
|
|
|
#include <QComboBox>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QFile>
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QDesktopServices>
|
2016-11-24 14:37:01 +00:00
|
|
|
|
|
|
|
ExportObjectDialog::ExportObjectDialog(QWidget &parent, CaptureFile &cf, register_eo_t* eo) :
|
2014-12-29 22:12:43 +00:00
|
|
|
WiresharkDialog(parent, cf),
|
2012-10-18 21:14:43 +00:00
|
|
|
eo_ui_(new Ui::ExportObjectDialog),
|
|
|
|
save_bt_(NULL),
|
|
|
|
save_all_bt_(NULL),
|
2017-12-26 16:46:48 +00:00
|
|
|
model_(eo, this),
|
|
|
|
proxyModel_(this)
|
2012-10-18 21:14:43 +00:00
|
|
|
{
|
|
|
|
QPushButton *close_bt;
|
|
|
|
|
|
|
|
eo_ui_->setupUi(this);
|
|
|
|
setAttribute(Qt::WA_DeleteOnClose, true);
|
|
|
|
|
2017-12-26 16:46:48 +00:00
|
|
|
proxyModel_.setSourceModel(&model_);
|
|
|
|
eo_ui_->objectTree->setModel(&proxyModel_);
|
|
|
|
|
2018-07-24 22:09:20 +00:00
|
|
|
proxyModel_.setFilterFixedString("");
|
|
|
|
proxyModel_.setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
|
|
proxyModel_.setFilterKeyColumn(-1);
|
|
|
|
|
2013-04-24 11:07:25 +00:00
|
|
|
#if defined(Q_OS_MAC)
|
2012-10-18 21:14:43 +00:00
|
|
|
eo_ui_->progressLabel->setAttribute(Qt::WA_MacSmallSize, true);
|
|
|
|
eo_ui_->progressBar->setAttribute(Qt::WA_MacSmallSize, true);
|
|
|
|
#endif
|
|
|
|
|
2017-12-26 16:46:48 +00:00
|
|
|
connect(&model_, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
2019-11-21 14:57:32 +00:00
|
|
|
this, SLOT(modelDataChanged(QModelIndex, int, int)));
|
2017-12-26 16:46:48 +00:00
|
|
|
connect(&model_, SIGNAL(modelReset()), this, SLOT(modelRowsReset()));
|
2019-11-21 14:57:32 +00:00
|
|
|
connect(eo_ui_->filterLine, &QLineEdit::textChanged, &proxyModel_, &ExportObjectProxyModel::setTextFilterString);
|
|
|
|
connect(eo_ui_->objectTree, &ExportObjectsTreeView::currentIndexChanged, this, &ExportObjectDialog::currentHasChanged);
|
2012-10-18 21:14:43 +00:00
|
|
|
|
|
|
|
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);
|
2019-11-21 14:57:32 +00:00
|
|
|
if (eo_ui_->buttonBox->button(QDialogButtonBox::Open))
|
|
|
|
{
|
|
|
|
QPushButton * open = eo_ui_->buttonBox->button(QDialogButtonBox::Open);
|
|
|
|
open->setText(tr("Preview"));
|
|
|
|
open->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
contentTypes << tr("All Content-Types");
|
|
|
|
eo_ui_->cmbContentType->addItems(contentTypes);
|
2012-10-18 21:14:43 +00:00
|
|
|
|
2016-11-24 14:37:01 +00:00
|
|
|
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))))));
|
2014-06-02 14:54:00 +00:00
|
|
|
|
2012-10-18 21:14:43 +00:00
|
|
|
if (save_bt_) save_bt_->setEnabled(false);
|
|
|
|
if (save_all_bt_) save_all_bt_->setEnabled(false);
|
|
|
|
if (close_bt) close_bt->setDefault(true);
|
|
|
|
|
2018-04-17 14:23:31 +00:00
|
|
|
connect(&cap_file_, SIGNAL(captureEvent(CaptureEvent)),
|
|
|
|
this, SLOT(captureEvent(CaptureEvent)));
|
2012-10-18 21:14:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ExportObjectDialog::~ExportObjectDialog()
|
|
|
|
{
|
|
|
|
delete eo_ui_;
|
2017-12-26 16:46:48 +00:00
|
|
|
model_.removeTap();
|
2015-08-24 19:30:56 +00:00
|
|
|
removeTapListeners();
|
2012-10-18 21:14:43 +00:00
|
|
|
}
|
|
|
|
|
2019-11-21 14:57:32 +00:00
|
|
|
void ExportObjectDialog::currentHasChanged(QModelIndex current)
|
2012-10-18 21:14:43 +00:00
|
|
|
{
|
2019-11-21 14:57:32 +00:00
|
|
|
if (current.isValid())
|
|
|
|
{
|
|
|
|
QModelIndex sibl = current.sibling(current.row(), ExportObjectModel::colPacket);
|
|
|
|
if (eo_ui_->buttonBox->button(QDialogButtonBox::Open))
|
|
|
|
{
|
|
|
|
QString cont = sibl.sibling(current.row(), ExportObjectModel::colContent).data().toString();
|
|
|
|
/* For security reasons application and unknown are disabled */
|
|
|
|
eo_ui_->buttonBox->button(QDialogButtonBox::Open)->setEnabled(! cont.startsWith("application/") && ! cont.startsWith("unknown/"));
|
|
|
|
}
|
|
|
|
wsApp->gotoFrame(sibl.data().toInt());
|
|
|
|
}
|
2012-10-18 21:14:43 +00:00
|
|
|
}
|
|
|
|
|
2019-11-21 14:57:32 +00:00
|
|
|
void ExportObjectDialog::modelDataChanged(const QModelIndex&, int from, int to)
|
2012-10-18 21:14:43 +00:00
|
|
|
{
|
2017-12-26 16:46:48 +00:00
|
|
|
bool enabled = (model_.rowCount() > 0);
|
|
|
|
if (save_bt_) save_bt_->setEnabled(enabled);
|
|
|
|
if (save_all_bt_) save_all_bt_->setEnabled(enabled);
|
2019-11-21 14:57:32 +00:00
|
|
|
|
|
|
|
for (int row = from; row <= to; row++)
|
|
|
|
{
|
|
|
|
QModelIndex idx = model_.index(row, ExportObjectModel::colContent);
|
|
|
|
if (idx.isValid())
|
|
|
|
{
|
|
|
|
QString dataType = idx.data().toString();
|
|
|
|
if (dataType.length() > 0 && ! contentTypes.contains(dataType))
|
|
|
|
{
|
|
|
|
contentTypes << dataType;
|
|
|
|
contentTypes.sort(Qt::CaseInsensitive);
|
|
|
|
QString selType = eo_ui_->cmbContentType->currentText();
|
|
|
|
eo_ui_->cmbContentType->clear();
|
|
|
|
eo_ui_->cmbContentType->addItems(contentTypes);
|
|
|
|
if (contentTypes.contains(selType) )
|
|
|
|
eo_ui_->cmbContentType->setCurrentText(selType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-10-18 21:14:43 +00:00
|
|
|
}
|
|
|
|
|
2017-12-26 16:46:48 +00:00
|
|
|
void ExportObjectDialog::modelRowsReset()
|
2012-10-18 21:14:43 +00:00
|
|
|
{
|
2019-11-21 14:57:32 +00:00
|
|
|
contentTypes.clear();
|
|
|
|
contentTypes << tr("All Content-Types");
|
|
|
|
eo_ui_->cmbContentType->clear();
|
|
|
|
eo_ui_->cmbContentType->addItems(contentTypes);
|
|
|
|
|
2012-10-18 21:14:43 +00:00
|
|
|
if (save_bt_) save_bt_->setEnabled(false);
|
|
|
|
if (save_all_bt_) save_all_bt_->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
2012-10-18 21:51:38 +00:00
|
|
|
void ExportObjectDialog::show()
|
|
|
|
{
|
|
|
|
/* Data will be gathered via a tap callback */
|
2017-12-26 16:46:48 +00:00
|
|
|
if (!registerTapListener(model_.getTapListenerName(), model_.getTapData(), NULL, 0,
|
|
|
|
ExportObjectModel::resetTap,
|
|
|
|
model_.getTapPacketFunc(),
|
2015-08-24 19:30:56 +00:00
|
|
|
NULL)) {
|
2012-10-18 21:51:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDialog::show();
|
2014-12-29 22:12:43 +00:00
|
|
|
cap_file_.retapPackets();
|
2012-10-18 21:51:38 +00:00
|
|
|
eo_ui_->progressFrame->hide();
|
2017-12-26 16:46:48 +00:00
|
|
|
for (int i = 0; i < eo_ui_->objectTree->model()->columnCount(); i++)
|
2012-10-18 21:51:38 +00:00
|
|
|
eo_ui_->objectTree->resizeColumnToContents(i);
|
|
|
|
|
2017-12-26 16:46:48 +00:00
|
|
|
eo_ui_->objectTree->sortByColumn(ExportObjectModel::colPacket, Qt::AscendingOrder);
|
2012-10-18 21:51:38 +00:00
|
|
|
}
|
|
|
|
|
2019-11-21 14:57:32 +00:00
|
|
|
void ExportObjectDialog::keyPressEvent(QKeyEvent *evt)
|
|
|
|
{
|
|
|
|
if(evt->key() == Qt::Key_Enter || evt->key() == Qt::Key_Return)
|
|
|
|
return;
|
|
|
|
QDialog::keyPressEvent(evt);
|
|
|
|
}
|
|
|
|
|
2012-10-18 21:14:43 +00:00
|
|
|
void ExportObjectDialog::accept()
|
|
|
|
{
|
|
|
|
// Don't close the dialog.
|
|
|
|
}
|
|
|
|
|
2018-03-28 08:04:50 +00:00
|
|
|
void ExportObjectDialog::captureEvent(CaptureEvent e)
|
2012-10-18 21:14:43 +00:00
|
|
|
{
|
2018-03-28 08:04:50 +00:00
|
|
|
if ((e.captureContext() == CaptureEvent::File) &&
|
|
|
|
(e.eventType() == CaptureEvent::Closing))
|
2017-12-26 16:46:48 +00:00
|
|
|
{
|
|
|
|
close();
|
|
|
|
}
|
2012-10-18 21:14:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExportObjectDialog::on_buttonBox_helpRequested()
|
|
|
|
{
|
|
|
|
wsApp->helpTopicAction(HELP_EXPORT_OBJECT_LIST);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExportObjectDialog::on_buttonBox_clicked(QAbstractButton *button)
|
|
|
|
{
|
|
|
|
switch (eo_ui_->buttonBox->standardButton(button)) {
|
|
|
|
case QDialogButtonBox::Save:
|
|
|
|
saveCurrentEntry();
|
|
|
|
break;
|
|
|
|
case QDialogButtonBox::SaveAll:
|
|
|
|
saveAllEntries();
|
|
|
|
break;
|
2019-11-21 14:57:32 +00:00
|
|
|
case QDialogButtonBox::Open:
|
|
|
|
{
|
|
|
|
QString temp;
|
|
|
|
saveCurrentEntry(&temp);
|
|
|
|
|
|
|
|
if (temp.length() > 0)
|
|
|
|
QDesktopServices::openUrl(QUrl(QString("file:///").append(temp), QUrl::TolerantMode));
|
|
|
|
break;
|
|
|
|
}
|
2012-10-18 21:14:43 +00:00
|
|
|
default: // Help, Cancel
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 14:57:32 +00:00
|
|
|
void ExportObjectDialog::on_cmbContentType_currentIndexChanged(int index)
|
|
|
|
{
|
|
|
|
QString filterString = index <= 0 ? "" : eo_ui_->cmbContentType->currentText();
|
|
|
|
proxyModel_.setContentFilterString(filterString);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExportObjectDialog::saveCurrentEntry(QString *tempFile)
|
2012-10-18 21:14:43 +00:00
|
|
|
{
|
|
|
|
QDir path(wsApp->lastOpenDir());
|
|
|
|
|
2018-10-26 00:54:51 +00:00
|
|
|
QModelIndex proxyIndex = eo_ui_->objectTree->currentIndex();
|
|
|
|
if (!proxyIndex.isValid())
|
|
|
|
return;
|
|
|
|
|
|
|
|
QModelIndex current = proxyModel_.mapToSource(proxyIndex);
|
2017-12-26 16:46:48 +00:00
|
|
|
if (!current.isValid())
|
2016-11-24 14:37:01 +00:00
|
|
|
return;
|
2012-10-18 21:14:43 +00:00
|
|
|
|
2019-11-21 14:57:32 +00:00
|
|
|
QString entry_filename = current.sibling(current.row(), ExportObjectModel::colFilename).data().toString();
|
2017-12-26 16:46:48 +00:00
|
|
|
if (entry_filename.isEmpty())
|
2016-11-24 14:37:01 +00:00
|
|
|
return;
|
2012-10-18 21:14:43 +00:00
|
|
|
|
2019-11-21 14:57:32 +00:00
|
|
|
QString file_name;
|
|
|
|
if (!tempFile)
|
|
|
|
{
|
|
|
|
GString *safe_filename = eo_massage_str(entry_filename.toUtf8().constData(), EXPORT_OBJECT_MAXFILELEN, 0);
|
2020-09-29 00:40:05 +00:00
|
|
|
file_name = WiresharkFileDialog::getSaveFileName(this, wsApp->windowTitleString(tr("Save Object As…")),
|
2019-11-21 14:57:32 +00:00
|
|
|
safe_filename->str);
|
|
|
|
g_string_free(safe_filename, TRUE);
|
|
|
|
} else {
|
2020-02-29 09:34:31 +00:00
|
|
|
QString path = QDir::tempPath().append("/").append(entry_filename);
|
2019-11-21 14:57:32 +00:00
|
|
|
/* This means, the system must remove the file! */
|
|
|
|
file_name = path;
|
|
|
|
if (QFileInfo::exists(path))
|
|
|
|
QFile::remove(path);
|
|
|
|
*tempFile = path;
|
|
|
|
}
|
2012-10-18 21:14:43 +00:00
|
|
|
|
2017-12-26 16:46:48 +00:00
|
|
|
model_.saveEntry(current, file_name);
|
2012-10-18 21:14:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExportObjectDialog::saveAllEntries()
|
|
|
|
{
|
2015-03-17 18:45:43 +00:00
|
|
|
QDir save_in_dir(wsApp->lastOpenDir());
|
|
|
|
QString save_in_path;
|
2012-10-18 21:14:43 +00:00
|
|
|
|
2015-03-17 18:45:43 +00:00
|
|
|
//
|
|
|
|
// We want the user to be able to specify a directory in which
|
|
|
|
// to drop files for all the objects, not a file name.
|
|
|
|
//
|
|
|
|
// XXX - what we *really* want is something that asks the user
|
|
|
|
// for an existing directory *but* lets them create a new
|
2017-04-05 19:15:27 +00:00
|
|
|
// directory in the process. That's what we get on macOS,
|
2015-03-17 18:45:43 +00:00
|
|
|
// as the native dialog is used, and it supports that; does
|
|
|
|
// that also work on Windows and with Qt's own dialog?
|
|
|
|
//
|
2020-09-29 00:40:05 +00:00
|
|
|
save_in_path = WiresharkFileDialog::getExistingDirectory(this, wsApp->windowTitleString(tr("Save All Objects In…")),
|
2015-03-17 18:45:43 +00:00
|
|
|
save_in_dir.canonicalPath(),
|
|
|
|
QFileDialog::ShowDirsOnly);
|
|
|
|
|
2019-01-01 21:04:44 +00:00
|
|
|
if (save_in_path.length() < 1)
|
2017-12-26 16:46:48 +00:00
|
|
|
return;
|
|
|
|
|
2019-01-01 22:12:15 +00:00
|
|
|
model_.saveAllEntries(save_in_path);
|
2012-10-18 21:14:43 +00:00
|
|
|
}
|
2012-10-24 15:51:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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:
|
|
|
|
*/
|