summaryrefslogtreecommitdiffstats
path: root/ui/qt/decode_as_dialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/qt/decode_as_dialog.cpp')
-rw-r--r--ui/qt/decode_as_dialog.cpp231
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 &current, 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 &current = 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 &current = 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;
+ }
+}