summaryrefslogtreecommitdiffstats
path: root/ui/qt/extcap_argument_multiselect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/qt/extcap_argument_multiselect.cpp')
-rw-r--r--ui/qt/extcap_argument_multiselect.cpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/ui/qt/extcap_argument_multiselect.cpp b/ui/qt/extcap_argument_multiselect.cpp
new file mode 100644
index 00000000..6f816b98
--- /dev/null
+++ b/ui/qt/extcap_argument_multiselect.cpp
@@ -0,0 +1,230 @@
+/* extcap_argument_multiselect.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <extcap_argument.h>
+#include <extcap_argument_file.h>
+
+#include <wsutil/utf8_entities.h>
+
+#include <QObject>
+#include <QWidget>
+#include <QLabel>
+#include <QLineEdit>
+#include <QBoxLayout>
+#include <QPushButton>
+#include <QVariant>
+
+#include <epan/prefs.h>
+#include <ui/qt/utils/color_utils.h>
+
+#include <extcap_parser.h>
+#include <extcap_argument_multiselect.h>
+
+ExtArgMultiSelect::ExtArgMultiSelect(extcap_arg * argument, QObject *parent) :
+ ExtcapArgument(argument, parent), treeView(0), viewModel(0) {}
+
+ExtArgMultiSelect::~ExtArgMultiSelect()
+{
+ if (treeView != 0)
+ delete treeView;
+ if (viewModel != 0)
+ delete viewModel;
+}
+
+QList<QStandardItem *> ExtArgMultiSelect::valueWalker(ExtcapValueList list, QStringList &defaults)
+{
+ ExtcapValueList::iterator iter = list.begin();
+ QList<QStandardItem *> items;
+
+ while (iter != list.end())
+ {
+ QStandardItem * item = new QStandardItem((*iter).value());
+ if ((*iter).enabled() == false)
+ {
+ item->setCheckable(false);
+ }
+ else
+ {
+ item->setCheckable(true);
+ }
+
+ item->setData((*iter).call(), Qt::UserRole);
+ if ((*iter).isDefault())
+ defaults << (*iter).call();
+
+ item->setSelectable(false);
+ item->setEditable(false);
+ QList<QStandardItem *> childs = valueWalker((*iter).children(), defaults);
+ if (childs.length() > 0)
+ item->appendRows(childs);
+
+ items << item;
+ ++iter;
+ }
+
+ return items;
+}
+
+void ExtArgMultiSelect::checkItemsWalker(QStandardItem * item, QStringList defaults)
+{
+ QModelIndexList results;
+ QModelIndex index;
+
+ if (item->hasChildren())
+ {
+ for (int row = 0; row < item->rowCount(); row++)
+ {
+ QStandardItem * child = item->child(row);
+ if (child != 0)
+ {
+ checkItemsWalker(child, defaults);
+ }
+ }
+ }
+
+ QString data = item->data(Qt::UserRole).toString();
+
+ if (defaults.contains(data))
+ {
+ item->setCheckState(Qt::Checked);
+ index = item->index();
+ while (index.isValid())
+ {
+ treeView->setExpanded(index, true);
+ index = index.parent();
+ }
+ } else if (item->isCheckable()) {
+ item->setCheckState(Qt::Unchecked);
+ }
+}
+
+QWidget * ExtArgMultiSelect::createEditor(QWidget * parent)
+{
+ QStringList checked;
+
+ QList<QStandardItem *> items = valueWalker(values, checked);
+ if (items.length() == 0)
+ return new QWidget();
+
+ /* Value can be empty if no items are checked */
+ if (_argument->pref_valptr && (*_argument->pref_valptr))
+ {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ checked = QString(*_argument->pref_valptr).split(",", Qt::SkipEmptyParts);
+#else
+ checked = QString(*_argument->pref_valptr).split(",", QString::SkipEmptyParts);
+#endif
+ }
+
+ viewModel = new QStandardItemModel();
+ QList<QStandardItem *>::const_iterator iter = items.constBegin();
+ while (iter != items.constEnd())
+ {
+ ((QStandardItemModel *)viewModel)->appendRow((*iter));
+ ++iter;
+ }
+
+ treeView = new QTreeView(parent);
+ treeView->setModel(viewModel);
+
+ /* Shows at minimum 6 entries at most desktops */
+ treeView->setMinimumHeight(100);
+ treeView->setHeaderHidden(true);
+ treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ treeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ for (int row = 0; row < viewModel->rowCount(); row++)
+ checkItemsWalker(((QStandardItemModel*)viewModel)->item(row), checked);
+
+ connect (viewModel,
+ SIGNAL(itemChanged(QStandardItem *)),
+ SLOT(itemChanged(QStandardItem *)));
+
+ return treeView;
+}
+
+QString ExtArgMultiSelect::value()
+{
+ if (viewModel == 0)
+ return QString();
+
+ QStringList result;
+ QModelIndexList checked = viewModel->match(viewModel->index(0, 0), Qt::CheckStateRole, Qt::Checked, -1, Qt::MatchExactly | Qt::MatchRecursive);
+ if (checked.size() <= 0)
+ return QString();
+
+ QModelIndexList::const_iterator iter = checked.constBegin();
+ while (iter != checked.constEnd())
+ {
+ QModelIndex index = (QModelIndex)(*iter);
+
+ result << viewModel->data(index, Qt::UserRole).toString();
+
+ ++iter;
+ }
+
+ return result.join(QString(','));
+}
+
+void ExtArgMultiSelect::itemChanged(QStandardItem *)
+{
+ emit valueChanged();
+}
+
+bool ExtArgMultiSelect::isValid()
+{
+ bool valid = true;
+
+ if (isRequired())
+ {
+ if (viewModel == 0)
+ valid = false;
+ else
+ {
+ QModelIndexList checked = viewModel->match(viewModel->index(0, 0), Qt::CheckStateRole, Qt::Checked, -1, Qt::MatchExactly | Qt::MatchRecursive);
+ if (checked.size() <= 0)
+ valid = false;
+ }
+ }
+
+ QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
+ QString txtStyle("QTreeView { background-color: %1; } ");
+ if (viewModel != 0)
+ treeView->setStyleSheet(txtStyle.arg(valid ? QString("") : lblInvalidColor));
+
+ return valid;
+}
+
+QString ExtArgMultiSelect::defaultValue()
+{
+ QStringList checked;
+
+ QList<QStandardItem *> items = valueWalker(values, checked);
+
+ return checked.join(QString(','));
+}
+
+bool ExtArgMultiSelect::isSetDefaultValueSupported()
+{
+ return TRUE;
+}
+
+void ExtArgMultiSelect::setDefaultValue()
+{
+ QStringList checked;
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ checked = defaultValue().split(",", Qt::SkipEmptyParts);
+#else
+ checked = defaultValue().split(",", QString::SkipEmptyParts);
+#endif
+ for (int row = 0; row < viewModel->rowCount(); row++)
+ checkItemsWalker(((QStandardItemModel*)viewModel)->item(row), checked);
+}
+