update epan/dissectors/pidl/drsuapi/drsuapi.idl from samba
[wireshark-sm.git] / ui / qt / decode_as_dialog.cpp
blobc45fae2eaea83d34bb7b9cc1dff4a6b1274f489d
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
8 */
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>
27 #include <QComboBox>
28 #include <QFont>
29 #include <QFontMetrics>
30 #include <QLineEdit>
31 #include <QUrl>
33 #include <QDebug>
35 // To do:
36 // - Ranges
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)),
43 delegate_(NULL)
45 ui->setupUi(this);
46 loadGeometry();
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");
58 #ifdef Q_OS_MAC
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);
64 #endif
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);
80 fillTable();
82 connect(model_, &DecodeAsModel::modelReset, this, &DecodeAsDialog::modelRowsReset);
83 ui->clearToolButton->setEnabled(model_->rowCount() > 0);
85 if (create_new)
86 on_newToolButton_clicked();
89 DecodeAsDialog::~DecodeAsDialog()
91 delete ui;
92 delete model_;
93 delete delegate_;
96 void DecodeAsDialog::fillTable()
98 model_->fillTable();
100 resizeColumns();
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 &current, const QModelIndex&)
127 if (current.isValid()) {
128 ui->deleteToolButton->setEnabled(true);
129 ui->copyToolButton->setEnabled(true);
130 ui->clearToolButton->setEnabled(true);
131 } else {
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);
146 resizeColumns();
148 ui->clearToolButton->setEnabled(model_->rowCount() > 0);
151 void DecodeAsDialog::addRecord(bool copy_from_current)
153 const QModelIndex &current = 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";
162 return;
164 const QModelIndex &new_index = model_->index(model_->rowCount() - 1, 0);
165 if (copy_from_current) {
166 model_->copyRow(new_index.row(), current.row());
169 resizeColumns();
171 // due to an EditTrigger, this will also start editing.
172 ui->decodeAsTreeView->setCurrentIndex(new_index);
175 void DecodeAsDialog::on_newToolButton_clicked()
177 addRecord();
180 void DecodeAsDialog::on_deleteToolButton_clicked()
182 const QModelIndex &current = 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()
192 addRecord(true);
195 void DecodeAsDialog::on_clearToolButton_clicked()
197 model_->clearAll();
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:
212 applyChanges();
213 break;
214 case QDialogButtonBox::Save:
216 char* err = NULL;
218 applyChanges();
219 if (save_decode_as_entries(&err) < 0) {
220 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err);
221 g_free(err);
224 break;
225 case QDialogButtonBox::Help:
226 mainApp->helpTopicAction(HELP_DECODE_AS_SHOW_DIALOG);
227 break;
228 default:
229 break;