1 /* decode_as_dialog.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
10 #include "decode_as_dialog.h"
11 #include <ui_decode_as_dialog.h>
13 #include "epan/decode_as.h"
14 #include "epan/epan_dissect.h"
16 #include "ui/decode_as_utils.h"
17 #include "ui/simple_dialog.h"
18 #include "wsutil/filesystem.h"
19 #include <wsutil/utf8_entities.h>
21 #include <ui/qt/widgets/copy_from_profile_button.h>
22 #include <ui/qt/utils/qt_ui_utils.h>
23 #include "main_application.h"
25 #include <ui/qt/utils/variant_pointer.h>
29 #include <QFontMetrics>
37 // - Add DCERPC support (or make DCERPC use a regular dissector table?)
39 DecodeAsDialog::DecodeAsDialog(QWidget
*parent
, capture_file
*cf
, bool create_new
) :
40 GeometryStateDialog(parent
),
41 ui(new Ui::DecodeAsDialog
),
42 model_(new DecodeAsModel(this, cf
)),
48 delegate_
= new DecodeAsDelegate(ui
->decodeAsTreeView
, cf
);
50 ui
->decodeAsTreeView
->setModel(model_
);
51 ui
->decodeAsTreeView
->setItemDelegate(delegate_
);
53 ui
->newToolButton
->setStockIcon("list-add");
54 ui
->deleteToolButton
->setStockIcon("list-remove");
55 ui
->copyToolButton
->setStockIcon("list-copy");
56 ui
->clearToolButton
->setStockIcon("list-clear");
59 ui
->newToolButton
->setAttribute(Qt::WA_MacSmallSize
, true);
60 ui
->deleteToolButton
->setAttribute(Qt::WA_MacSmallSize
, true);
61 ui
->copyToolButton
->setAttribute(Qt::WA_MacSmallSize
, true);
62 ui
->clearToolButton
->setAttribute(Qt::WA_MacSmallSize
, true);
63 ui
->pathLabel
->setAttribute(Qt::WA_MacSmallSize
, true);
66 setWindowTitle(mainApp
->windowTitleString(tr("Decode As…")));
68 QString abs_path
= gchar_free_to_qstring(get_persconffile_path(DECODE_AS_ENTRIES_FILE_NAME
, true));
69 if (file_exists(abs_path
.toUtf8().constData())) {
70 ui
->pathLabel
->setText(abs_path
);
71 ui
->pathLabel
->setUrl(QUrl::fromLocalFile(abs_path
).toString());
72 ui
->pathLabel
->setToolTip(tr("Open ") + DECODE_AS_ENTRIES_FILE_NAME
);
73 ui
->pathLabel
->setEnabled(true);
76 CopyFromProfileButton
*copy_button
= new CopyFromProfileButton(this, DECODE_AS_ENTRIES_FILE_NAME
);
77 ui
->buttonBox
->addButton(copy_button
, QDialogButtonBox::ActionRole
);
78 connect(copy_button
, &CopyFromProfileButton::copyProfile
, this, &DecodeAsDialog::copyFromProfile
);
82 connect(model_
, &DecodeAsModel::modelReset
, this, &DecodeAsDialog::modelRowsReset
);
83 ui
->clearToolButton
->setEnabled(model_
->rowCount() > 0);
86 on_newToolButton_clicked();
89 DecodeAsDialog::~DecodeAsDialog()
96 void DecodeAsDialog::fillTable()
102 //set selection as first row
103 if (model_
->rowCount() > 0) {
104 const QModelIndex
&new_index
= model_
->index(0, 0);
105 ui
->decodeAsTreeView
->setCurrentIndex(new_index
);
109 void DecodeAsDialog::resizeColumns()
111 if (model_
->rowCount() > 0) {
112 for (int i
= 0; i
< model_
->columnCount(); i
++) {
113 ui
->decodeAsTreeView
->resizeColumnToContents(i
);
118 void DecodeAsDialog::modelRowsReset()
120 ui
->deleteToolButton
->setEnabled(false);
121 ui
->copyToolButton
->setEnabled(false);
122 ui
->clearToolButton
->setEnabled(false);
125 void DecodeAsDialog::on_decodeAsTreeView_currentItemChanged(const QModelIndex
¤t
, const QModelIndex
&)
127 if (current
.isValid()) {
128 ui
->deleteToolButton
->setEnabled(true);
129 ui
->copyToolButton
->setEnabled(true);
130 ui
->clearToolButton
->setEnabled(true);
132 ui
->deleteToolButton
->setEnabled(false);
133 ui
->copyToolButton
->setEnabled(false);
134 ui
->clearToolButton
->setEnabled(false);
138 void DecodeAsDialog::copyFromProfile(QString filename
)
140 const char *err
= NULL
;
142 if (!model_
->copyFromProfile(filename
, &err
)) {
143 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "Error while loading %s: %s", filename
.toUtf8().constData(), err
);
148 ui
->clearToolButton
->setEnabled(model_
->rowCount() > 0);
151 void DecodeAsDialog::addRecord(bool copy_from_current
)
153 const QModelIndex
¤t
= ui
->decodeAsTreeView
->currentIndex();
154 if (copy_from_current
&& !current
.isValid()) return;
156 // XXX - This doesn't appear to work as intended to give "edit triggers on demand"
157 ui
->decodeAsTreeView
->setEditTriggers(ui
->decodeAsTreeView
->editTriggers() | QAbstractItemView::CurrentChanged
| QAbstractItemView::AnyKeyPressed
);
159 // should not fail, but you never know.
160 if (!model_
->insertRows(model_
->rowCount(), 1)) {
161 qDebug() << "Failed to add a new record";
164 const QModelIndex
&new_index
= model_
->index(model_
->rowCount() - 1, 0);
165 if (copy_from_current
) {
166 model_
->copyRow(new_index
.row(), current
.row());
171 // due to an EditTrigger, this will also start editing.
172 ui
->decodeAsTreeView
->setCurrentIndex(new_index
);
175 void DecodeAsDialog::on_newToolButton_clicked()
180 void DecodeAsDialog::on_deleteToolButton_clicked()
182 const QModelIndex
¤t
= ui
->decodeAsTreeView
->currentIndex();
183 if (model_
&& current
.isValid()) {
184 if (!model_
->removeRows(current
.row(), 1)) {
185 qDebug() << "Failed to remove row";
190 void DecodeAsDialog::on_copyToolButton_clicked()
195 void DecodeAsDialog::on_clearToolButton_clicked()
200 void DecodeAsDialog::applyChanges()
202 model_
->applyChanges();
203 mainApp
->queueAppSignal(MainApplication::PacketDissectionChanged
);
206 void DecodeAsDialog::on_buttonBox_clicked(QAbstractButton
*button
)
208 ui
->buttonBox
->setFocus();
210 switch (ui
->buttonBox
->standardButton(button
)) {
211 case QDialogButtonBox::Ok
:
214 case QDialogButtonBox::Save
:
219 if (save_decode_as_entries(&err
) < 0) {
220 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", err
);
225 case QDialogButtonBox::Help
:
226 mainApp
->helpTopicAction(HELP_DECODE_AS_SHOW_DIALOG
);