aboutsummaryrefslogtreecommitdiffstats
path: root/ui/qt/models/uat_delegate.cpp
diff options
context:
space:
mode:
authorRoland Knall <roland.knall@br-automation.com>2017-07-25 16:47:16 +0200
committerRoland Knall <rknall@gmail.com>2017-07-26 12:22:04 +0000
commit02e80019f2dc8f01e51d8bdc62a1cabff69fd51e (patch)
tree7cc68dab8e8ac9713b8c50176dd52fc36c0c0b11 /ui/qt/models/uat_delegate.cpp
parentea998190cfe5a051224490172cfaedc69b777ff6 (diff)
Qt: Create models directory
Following the move for widgets and utils directory, moving models and delegates to the utils directory. Guidelines for this directory are: - Implementation of a model - Implementation of a delegate - Utility class for data storage used by a model Note: additionally all includes affected by this move have been changed to absolute path includes, instead of relative ones. Change-Id: I3bb868af7d3570437682b722a0cd46c906628570 Reviewed-on: https://code.wireshark.org/review/22790 Reviewed-by: Roland Knall <rknall@gmail.com>
Diffstat (limited to 'ui/qt/models/uat_delegate.cpp')
-rw-r--r--ui/qt/models/uat_delegate.cpp217
1 files changed, 217 insertions, 0 deletions
diff --git a/ui/qt/models/uat_delegate.cpp b/ui/qt/models/uat_delegate.cpp
new file mode 100644
index 0000000000..ee149a2fc8
--- /dev/null
+++ b/ui/qt/models/uat_delegate.cpp
@@ -0,0 +1,217 @@
+/* uat_delegate.cpp
+ * Delegates for editing various field types in a UAT record.
+ *
+ * Copyright 2016 Peter Wu <peter@lekensteyn.nl>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <ui/qt/models/uat_delegate.h>
+#include "epan/value_string.h"
+#include <QComboBox>
+#include <QEvent>
+#include <QFileDialog>
+#include <QLineEdit>
+#include <QCheckBox>
+
+#include <ui/qt/widgets/display_filter_edit.h>
+
+UatDelegate::UatDelegate(QObject *parent) : QStyledItemDelegate(parent)
+{
+}
+
+uat_field_t *UatDelegate::indexToField(const QModelIndex &index) const
+{
+ const QVariant v = index.model()->data(index, Qt::UserRole);
+ return static_cast<uat_field_t *>(v.value<void *>());
+}
+
+QWidget *UatDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ uat_field_t *field = indexToField(index);
+
+ switch (field->mode) {
+ case PT_TXTMOD_DIRECTORYNAME:
+ case PT_TXTMOD_FILENAME:
+ // TODO tab navigation from this field is broken.
+ // Do not create editor, a dialog will be opened in editorEvent
+ return 0;
+
+ case PT_TXTMOD_ENUM:
+ {
+ // Note: the string repr. is written, not the integer value.
+ QComboBox *editor = new QComboBox(parent);
+ const value_string *enum_vals = (const value_string *)field->fld_data;
+ for (int i = 0; enum_vals[i].strptr != NULL; i++) {
+ editor->addItem(enum_vals[i].strptr);
+ }
+ return editor;
+ }
+
+ case PT_TXTMOD_STRING:
+ // TODO add a live validator? Should SyntaxLineEdit be used?
+ return QStyledItemDelegate::createEditor(parent, option, index);
+
+ case PT_TXTMOD_DISPLAY_FILTER:
+ {
+ DisplayFilterEdit *editor = new DisplayFilterEdit(parent);
+ return editor;
+ }
+ case PT_TXTMOD_HEXBYTES:
+ {
+ // Requires input of the form "ab cd ef" (with possibly no or a colon
+ // separator instead of a single whitespace) for the editor to accept.
+ QRegExp hexbytes_regex("([0-9a-f]{2}[ :]?)*");
+ hexbytes_regex.setCaseSensitivity(Qt::CaseInsensitive);
+ // QString types from QStyledItemDelegate are documented to return a
+ // QLineEdit. Note that Qt returns a subclass from QLineEdit which
+ // automatically adapts the width to the typed contents.
+ QLineEdit *editor = static_cast<QLineEdit *>(
+ QStyledItemDelegate::createEditor(parent, option, index));
+ editor->setValidator(new QRegExpValidator(hexbytes_regex, editor));
+ return editor;
+ }
+
+ case PT_TXTMOD_BOOL:
+ {
+ // model will handle creating checkbox
+ return 0;
+ }
+
+ case PT_TXTMOD_NONE:
+ return 0;
+
+ default:
+ g_assert_not_reached();
+ return 0;
+ }
+}
+
+void UatDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ uat_field_t *field = indexToField(index);
+
+ switch (field->mode) {
+ case PT_TXTMOD_ENUM:
+ {
+ QComboBox *combobox = static_cast<QComboBox *>(editor);
+ const QString &data = index.model()->data(index, Qt::EditRole).toString();
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ combobox->setCurrentText(data);
+#else
+ int new_index = combobox->findText(data);
+ if (new_index >= 0) {
+ combobox->setCurrentIndex(new_index);
+ }
+#endif
+
+ break;
+ }
+
+ default:
+ QStyledItemDelegate::setEditorData(editor, index);
+ }
+}
+
+void UatDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const
+{
+ uat_field_t *field = indexToField(index);
+
+ switch (field->mode) {
+ case PT_TXTMOD_ENUM:
+ {
+ QComboBox *combobox = static_cast<QComboBox *>(editor);
+ const QString &data = combobox->currentText();
+ model->setData(index, data, Qt::EditRole);
+ break;
+ }
+
+ default:
+ QStyledItemDelegate::setModelData(editor, model, index);
+ }
+}
+
+#if 0
+// Qt docs suggest overriding updateEditorGeometry, but the defaults seem sane.
+void UatDelegate::updateEditorGeometry(QWidget *editor,
+ const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ QStyledItemDelegate::updateEditorGeometry(editor, option, index);
+}
+#endif
+
+bool UatDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
+{
+ uat_field_t *field = indexToField(index);
+
+ switch (field->mode) {
+ case PT_TXTMOD_DIRECTORYNAME:
+ case PT_TXTMOD_FILENAME:
+ if (event && (event->type() == QEvent::MouseButtonRelease ||
+ event->type() == QEvent::MouseButtonDblClick)) {
+ // Ignore these mouse events, only handle MouseButtonPress.
+ return false;
+ }
+ if (index.isValid()) {
+ QString filename_old = model->data(index, Qt::EditRole).toString();
+ QString filename = openFileDialog(field, filename_old);
+ // TODO should this overwrite only when !filename.isEmpty()?
+ model->setData(index, filename, Qt::EditRole);
+ }
+ // returns false to ensure that QAbstractItemView::edit does not assume
+ // the editing state. This causes the view's currentIndex to be changed
+ // to the cell where this delegate was "created", as desired.
+ return false;
+
+ default:
+ return QStyledItemDelegate::editorEvent(event, model, option, index);
+ }
+}
+
+QString UatDelegate::openFileDialog(uat_field_t *field, const QString &cur_path) const
+{
+ // Note: file dialogs have their parent widget set to NULL because we do not
+ // have an editor nor the view that would attach us.
+ switch (field->mode) {
+ case PT_TXTMOD_DIRECTORYNAME:
+ return QFileDialog::getExistingDirectory(NULL, field->title, cur_path);
+
+ case PT_TXTMOD_FILENAME:
+ return QFileDialog::getOpenFileName(NULL, field->title, cur_path,
+ QString(), NULL, QFileDialog::DontConfirmOverwrite);
+
+ default:
+ g_assert_not_reached();
+ return 0;
+ }
+}
+
+/* * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */