update epan/dissectors/pidl/drsuapi/drsuapi.idl from samba
[wireshark-sm.git] / ui / qt / models / uat_delegate.cpp
blob4e7d25b3c759617f194890a4828c4bbdd1a56090
1 /* uat_delegate.cpp
2 * Delegates for editing various field types in a UAT record.
4 * Copyright 2016 Peter Wu <peter@lekensteyn.nl>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include <ui/qt/models/uat_delegate.h>
14 #include <epan/packet.h> // for get_dissector_names()
15 #include "epan/value_string.h"
16 #include <wsutil/ws_assert.h>
17 #include <QRegularExpression>
18 #include <QComboBox>
19 #include <QEvent>
20 #include <QFileDialog>
21 #include <QLineEdit>
22 #include <QCheckBox>
23 #include <QColorDialog>
25 #include <ui/qt/widgets/display_filter_edit.h>
26 #include <ui/qt/widgets/dissector_syntax_line_edit.h>
27 #include <ui/qt/widgets/field_filter_edit.h>
28 #include <ui/qt/widgets/editor_file_dialog.h>
29 #include <ui/qt/widgets/path_selection_edit.h>
31 // The Qt docs suggest overriding updateEditorGeometry, but the
32 // defaults seem sane.
34 UatDelegate::UatDelegate(QObject *parent) : QStyledItemDelegate(parent)
38 uat_field_t *UatDelegate::indexToField(const QModelIndex &index) const
40 const QVariant v = index.model()->data(index, Qt::UserRole);
41 return static_cast<uat_field_t *>(v.value<void *>());
44 QWidget *UatDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
45 const QModelIndex &index) const
47 uat_field_t *field = indexToField(index);
48 QWidget *editor = nullptr;
50 switch (field->mode) {
51 case PT_TXTMOD_DIRECTORYNAME:
52 case PT_TXTMOD_FILENAME:
53 if (index.isValid()) {
54 QString filename_old = index.model()->data(index, Qt::EditRole).toString();
55 PathSelectionEdit * pathEdit = new PathSelectionEdit(field->title, QString(), field->mode != PT_TXTMOD_DIRECTORYNAME, parent);
56 connect(pathEdit, &PathSelectionEdit::pathChanged, this, &UatDelegate::pathHasChanged);
57 return pathEdit;
59 break;
60 case PT_TXTMOD_COLOR:
61 if (index.isValid()) {
62 QColor color(index.model()->data(index, Qt::DecorationRole).toString());
63 QColorDialog * colorDialog = new QColorDialog(color, parent);
64 // Don't fall through and set setAutoFillBackground(true)
65 return colorDialog;
67 break;
69 case PT_TXTMOD_ENUM:
71 // Note: the string repr. is written, not the integer value.
72 QComboBox *cb_editor = new QComboBox(parent);
73 const value_string *enum_vals = (const value_string *)field->fld_data;
74 for (int i = 0; enum_vals[i].strptr != nullptr; i++) {
75 cb_editor->addItem(enum_vals[i].strptr);
77 editor = cb_editor;
78 cb_editor->setMinimumWidth(cb_editor->minimumSizeHint().width());
79 break;
82 case PT_TXTMOD_DISSECTOR:
84 editor = new DissectorSyntaxLineEdit(parent);
85 break;
88 case PT_TXTMOD_STRING:
89 // TODO add a live validator? Should SyntaxLineEdit be used?
90 editor = QStyledItemDelegate::createEditor(parent, option, index);
91 break;
93 case PT_TXTMOD_DISPLAY_FILTER:
94 editor = new DisplayFilterEdit(parent);
95 break;
97 case PT_TXTMOD_PROTO_FIELD:
98 editor = new FieldFilterEdit(parent);
99 break;
101 case PT_TXTMOD_HEXBYTES:
103 // Requires input of the form "ab cd ef" (with possibly no or a colon
104 // separator instead of a single whitespace) for the editor to accept.
105 QRegularExpression hexbytes_regex("([0-9a-f]{2}[ :]?)*");
106 hexbytes_regex.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
107 // QString types from QStyledItemDelegate are documented to return a
108 // QLineEdit. Note that Qt returns a subclass from QLineEdit which
109 // automatically adapts the width to the typed contents.
110 QLineEdit *le_editor = static_cast<QLineEdit *>(
111 QStyledItemDelegate::createEditor(parent, option, index));
112 le_editor->setValidator(new QRegularExpressionValidator(hexbytes_regex, le_editor));
113 editor = le_editor;
114 break;
117 case PT_TXTMOD_BOOL:
118 // model will handle creating checkbox
119 break;
121 case PT_TXTMOD_NONE:
122 break;
124 default:
125 ws_assert_not_reached();
126 break;
129 if (editor) {
130 editor->setAutoFillBackground(true);
132 return editor;
135 void UatDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
137 uat_field_t *field = indexToField(index);
139 switch (field->mode) {
140 case PT_TXTMOD_DIRECTORYNAME:
141 case PT_TXTMOD_FILENAME:
142 if (index.isValid() && qobject_cast<PathSelectionEdit *>(editor))
143 qobject_cast<PathSelectionEdit *>(editor)->setPath(index.model()->data(index, Qt::EditRole).toString());
144 break;
145 case PT_TXTMOD_ENUM:
147 QComboBox *combobox = static_cast<QComboBox *>(editor);
148 const QString &data = index.model()->data(index, Qt::EditRole).toString();
149 combobox->setCurrentText(data);
151 break;
153 case PT_TXTMOD_COLOR:
155 if (qobject_cast<QColorDialog *>(editor))
157 QColor color(index.model()->data(index, Qt::DecorationRole).toString());
158 qobject_cast<QColorDialog *>(editor)->setCurrentColor(color);
160 break;
163 default:
164 QStyledItemDelegate::setEditorData(editor, index);
168 void UatDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
169 const QModelIndex &index) const
171 uat_field_t *field = indexToField(index);
173 switch (field->mode) {
174 case PT_TXTMOD_DIRECTORYNAME:
175 case PT_TXTMOD_FILENAME:
176 if (index.isValid() && qobject_cast<PathSelectionEdit *>(editor))
177 const_cast<QAbstractItemModel *>(index.model())->setData(index, qobject_cast<PathSelectionEdit *>(editor)->path(), Qt::EditRole);
178 break;
179 case PT_TXTMOD_ENUM:
181 QComboBox *combobox = static_cast<QComboBox *>(editor);
182 const QString &data = combobox->currentText();
183 model->setData(index, data, Qt::EditRole);
184 break;
186 case PT_TXTMOD_COLOR:
187 //do nothing, dialog signals will update table
188 if (qobject_cast<QColorDialog *>(editor))
190 QColor newColor = qobject_cast<QColorDialog *>(editor)->currentColor();
191 const_cast<QAbstractItemModel *>(index.model())->setData(index, newColor.name(), Qt::EditRole);
193 break;
195 default:
196 QStyledItemDelegate::setModelData(editor, model, index);
200 void UatDelegate::updateEditorGeometry(QWidget *editor,
201 const QStyleOptionViewItem &option,
202 const QModelIndex &index) const
204 uat_field_t *field = indexToField(index);
206 switch (field->mode) {
207 case PT_TXTMOD_DIRECTORYNAME:
208 case PT_TXTMOD_FILENAME:
209 editor->setGeometry(option.rect);
210 break;
211 default:
212 QStyledItemDelegate::updateEditorGeometry(editor, option, index);
216 void UatDelegate::pathHasChanged(QString)
218 PathSelectionEdit * editor = qobject_cast<PathSelectionEdit *>(sender());
219 if (editor)
220 emit commitData(editor);