diff options
Diffstat (limited to '')
-rw-r--r-- | ui/qt/decode_as_dialog.cpp | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/ui/qt/decode_as_dialog.cpp b/ui/qt/decode_as_dialog.cpp new file mode 100644 index 00000000..edc6ccc7 --- /dev/null +++ b/ui/qt/decode_as_dialog.cpp @@ -0,0 +1,231 @@ +/* decode_as_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 "decode_as_dialog.h" +#include <ui_decode_as_dialog.h> + +#include "epan/decode_as.h" +#include "epan/epan_dissect.h" + +#include "ui/decode_as_utils.h" +#include "ui/simple_dialog.h" +#include "wsutil/filesystem.h" +#include <wsutil/utf8_entities.h> + +#include <ui/qt/widgets/copy_from_profile_button.h> +#include <ui/qt/utils/qt_ui_utils.h> +#include "main_application.h" + +#include <ui/qt/utils/variant_pointer.h> + +#include <QComboBox> +#include <QFont> +#include <QFontMetrics> +#include <QLineEdit> +#include <QUrl> + +#include <QDebug> + +// To do: +// - Ranges +// - Add DCERPC support (or make DCERPC use a regular dissector table?) + +DecodeAsDialog::DecodeAsDialog(QWidget *parent, capture_file *cf, bool create_new) : + GeometryStateDialog(parent), + ui(new Ui::DecodeAsDialog), + model_(new DecodeAsModel(this, cf)), + delegate_(NULL) +{ + ui->setupUi(this); + loadGeometry(); + + delegate_ = new DecodeAsDelegate(ui->decodeAsTreeView, cf); + + ui->decodeAsTreeView->setModel(model_); + ui->decodeAsTreeView->setItemDelegate(delegate_); + + ui->newToolButton->setStockIcon("list-add"); + ui->deleteToolButton->setStockIcon("list-remove"); + ui->copyToolButton->setStockIcon("list-copy"); + ui->clearToolButton->setStockIcon("list-clear"); + +#ifdef Q_OS_MAC + ui->newToolButton->setAttribute(Qt::WA_MacSmallSize, true); + ui->deleteToolButton->setAttribute(Qt::WA_MacSmallSize, true); + ui->copyToolButton->setAttribute(Qt::WA_MacSmallSize, true); + ui->clearToolButton->setAttribute(Qt::WA_MacSmallSize, true); + ui->pathLabel->setAttribute(Qt::WA_MacSmallSize, true); +#endif + + setWindowTitle(mainApp->windowTitleString(tr("Decode As…"))); + + QString abs_path = gchar_free_to_qstring(get_persconffile_path(DECODE_AS_ENTRIES_FILE_NAME, TRUE)); + if (file_exists(abs_path.toUtf8().constData())) { + ui->pathLabel->setText(abs_path); + ui->pathLabel->setUrl(QUrl::fromLocalFile(abs_path).toString()); + ui->pathLabel->setToolTip(tr("Open ") + DECODE_AS_ENTRIES_FILE_NAME); + ui->pathLabel->setEnabled(true); + } + + CopyFromProfileButton *copy_button = new CopyFromProfileButton(this, DECODE_AS_ENTRIES_FILE_NAME); + ui->buttonBox->addButton(copy_button, QDialogButtonBox::ActionRole); + connect(copy_button, &CopyFromProfileButton::copyProfile, this, &DecodeAsDialog::copyFromProfile); + + fillTable(); + + connect(model_, &DecodeAsModel::modelReset, this, &DecodeAsDialog::modelRowsReset); + ui->clearToolButton->setEnabled(model_->rowCount() > 0); + + if (create_new) + on_newToolButton_clicked(); +} + +DecodeAsDialog::~DecodeAsDialog() +{ + delete ui; + delete model_; + delete delegate_; +} + +void DecodeAsDialog::fillTable() +{ + model_->fillTable(); + + resizeColumns(); + + //set selection as first row + if (model_->rowCount() > 0) { + const QModelIndex &new_index = model_->index(0, 0); + ui->decodeAsTreeView->setCurrentIndex(new_index); + } +} + +void DecodeAsDialog::resizeColumns() +{ + if (model_->rowCount() > 0) { + for (int i = 0; i < model_->columnCount(); i++) { + ui->decodeAsTreeView->resizeColumnToContents(i); + } + } +} + +void DecodeAsDialog::modelRowsReset() +{ + ui->deleteToolButton->setEnabled(false); + ui->copyToolButton->setEnabled(false); + ui->clearToolButton->setEnabled(false); +} + +void DecodeAsDialog::on_decodeAsTreeView_currentItemChanged(const QModelIndex ¤t, const QModelIndex&) +{ + if (current.isValid()) { + ui->deleteToolButton->setEnabled(true); + ui->copyToolButton->setEnabled(true); + ui->clearToolButton->setEnabled(true); + } else { + ui->deleteToolButton->setEnabled(false); + ui->copyToolButton->setEnabled(false); + ui->clearToolButton->setEnabled(false); + } +} + +void DecodeAsDialog::copyFromProfile(QString filename) +{ + const gchar *err = NULL; + + if (!model_->copyFromProfile(filename, &err)) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Error while loading %s: %s", filename.toUtf8().constData(), err); + } + + resizeColumns(); + + ui->clearToolButton->setEnabled(model_->rowCount() > 0); +} + +void DecodeAsDialog::addRecord(bool copy_from_current) +{ + const QModelIndex ¤t = ui->decodeAsTreeView->currentIndex(); + if (copy_from_current && !current.isValid()) return; + +// XXX - This doesn't appear to work as intended to give "edit triggers on demand" + ui->decodeAsTreeView->setEditTriggers(ui->decodeAsTreeView->editTriggers() | QAbstractItemView::CurrentChanged | QAbstractItemView::AnyKeyPressed); + + // should not fail, but you never know. + if (!model_->insertRows(model_->rowCount(), 1)) { + qDebug() << "Failed to add a new record"; + return; + } + const QModelIndex &new_index = model_->index(model_->rowCount() - 1, 0); + if (copy_from_current) { + model_->copyRow(new_index.row(), current.row()); + } + + resizeColumns(); + + // due to an EditTrigger, this will also start editing. + ui->decodeAsTreeView->setCurrentIndex(new_index); +} + +void DecodeAsDialog::on_newToolButton_clicked() +{ + addRecord(); +} + +void DecodeAsDialog::on_deleteToolButton_clicked() +{ + const QModelIndex ¤t = ui->decodeAsTreeView->currentIndex(); + if (model_ && current.isValid()) { + if (!model_->removeRows(current.row(), 1)) { + qDebug() << "Failed to remove row"; + } + } +} + +void DecodeAsDialog::on_copyToolButton_clicked() +{ + addRecord(true); +} + +void DecodeAsDialog::on_clearToolButton_clicked() +{ + model_->clearAll(); +} + +void DecodeAsDialog::applyChanges() +{ + model_->applyChanges(); + mainApp->queueAppSignal(MainApplication::PacketDissectionChanged); +} + +void DecodeAsDialog::on_buttonBox_clicked(QAbstractButton *button) +{ + ui->buttonBox->setFocus(); + + switch (ui->buttonBox->standardButton(button)) { + case QDialogButtonBox::Ok: + applyChanges(); + break; + case QDialogButtonBox::Save: + { + gchar* err = NULL; + + applyChanges(); + if (save_decode_as_entries(&err) < 0) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err); + g_free(err); + } + } + break; + case QDialogButtonBox::Help: + mainApp->helpTopicAction(HELP_DECODE_AS_SHOW_DIALOG); + break; + default: + break; + } +} |