forked from osmocom/wireshark
231 lines
5.9 KiB
C++
231 lines
5.9 KiB
C++
/* 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 {
|
|
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);
|
|
}
|
|
|