diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc index 491a800779..ca5b6c5a8f 100644 --- a/docbook/release-notes.adoc +++ b/docbook/release-notes.adoc @@ -78,6 +78,8 @@ They previously shipped with Npcap 1.55. * It is possible to set extcap passwords on cli for tshark and other cli tools. +* Extcap configuration dialog now supports and remembers empty strings. There are new buttons to reset a value back to default value. + === Removed Features and Support * CMake: The options starting with DISABLE_something were renamed ENABLE_something for consistency. diff --git a/ui/qt/extcap_argument.cpp b/ui/qt/extcap_argument.cpp index aaf0059ec1..aa67b69dcd 100644 --- a/ui/qt/extcap_argument.cpp +++ b/ui/qt/extcap_argument.cpp @@ -46,19 +46,16 @@ #include ExtArgTimestamp::ExtArgTimestamp(extcap_arg * argument, QObject * parent) : - ExtcapArgument(argument, parent) {} + ExtcapArgument(argument, parent), tsBox(0) {} QWidget * ExtArgTimestamp::createEditor(QWidget * parent) { - QDateTimeEdit * tsBox; QString text = defaultValue(); - if (_argument->pref_valptr && *_argument->pref_valptr) + if (_argument->pref_valptr && strlen(*_argument->pref_valptr)) { QString storeValue(*_argument->pref_valptr); - - if (storeValue.length() > 0 && storeValue.compare(text) != 0) - text = storeValue.trimmed(); + text = storeValue.trimmed(); } #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) @@ -118,16 +115,30 @@ QString ExtArgTimestamp::prefValue() return value(); } +bool ExtArgTimestamp::isSetDefaultValueSupported() +{ + return TRUE; +} + +void ExtArgTimestamp::setDefaultValue() +{ + QDateTime t; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) + t = QDateTime::fromSecsSinceEpoch(defaultValue().toInt()); +#else + t = QDateTime::fromTime_t(defaultValue().toInt()); +#endif + tsBox->setDateTime(t); +} + + + ExtArgSelector::ExtArgSelector(extcap_arg * argument, QObject * parent) : ExtcapArgument(argument, parent), boxSelection(0) {} QWidget * ExtArgSelector::createEditor(QWidget * parent) { - int counter = 0; - int selected = -1; - const char *prefval = (_argument->pref_valptr && strlen(*_argument->pref_valptr)) ? *_argument->pref_valptr : NULL; - QString stored(prefval ? prefval : ""); - QWidget * editor = new QWidget(parent); QHBoxLayout * layout = new QHBoxLayout(); QMargins margins = layout->contentsMargins(); @@ -144,20 +155,12 @@ QWidget * ExtArgSelector::createEditor(QWidget * parent) while (iter != values.constEnd()) { boxSelection->addItem((*iter).value(), (*iter).call()); - - if (!prefval && (*iter).isDefault()) - selected = counter; - else if (prefval && stored.compare((*iter).call()) == 0) - selected = counter; - - counter++; ++iter; } - - if (selected > -1 && selected < boxSelection->count()) - boxSelection->setCurrentIndex(selected); } + setDefaultValue(); + if (reload()) { QString btnText(tr("Reload data")); @@ -185,7 +188,7 @@ void ExtArgSelector::onReloadTriggered() int selected = -1; QString call = boxSelection->currentData().toString(); - const char *prefval = _argument->pref_valptr ? *_argument->pref_valptr : NULL; + const char *prefval = (_argument->pref_valptr && strlen(*_argument->pref_valptr)) ? *_argument->pref_valptr : NULL; QString stored(prefval ? prefval : ""); if (call != stored) stored = call; @@ -241,14 +244,48 @@ QString ExtArgSelector::value() return data.toString(); } +bool ExtArgSelector::isSetDefaultValueSupported() +{ + return TRUE; +} + +void ExtArgSelector::setDefaultValue() +{ + int counter = 0; + int selected = -1; + + const char *prefval = (_argument->pref_valptr && strlen(*_argument->pref_valptr)) ? *_argument->pref_valptr : NULL; + QString stored(prefval ? prefval : ""); + + if (values.length() > 0) + { + ExtcapValueList::const_iterator iter = values.constBegin(); + + while (iter != values.constEnd()) + { + if (!prefval && (*iter).isDefault()) + selected = counter; + else if (prefval && stored.compare((*iter).call()) == 0) + selected = counter; + + counter++; + ++iter; + } + + if (selected > -1 && selected < boxSelection->count()) + boxSelection->setCurrentIndex(selected); + } + +} + + + ExtArgRadio::ExtArgRadio(extcap_arg * argument, QObject * parent) : ExtcapArgument(argument, parent), selectorGroup(0), callStrings(0) {} QWidget * ExtArgRadio::createEditor(QWidget * parent) { - int count = 0; - bool anyChecked = false; selectorGroup = new QButtonGroup(parent); QWidget * radioButtons = new QWidget; @@ -270,12 +307,6 @@ QWidget * ExtArgRadio::createEditor(QWidget * parent) QString callString = (*iter).call(); callStrings->append(callString); - if ((*iter).isDefault()) - { - radio->setChecked(true); - anyChecked = true; - } - connect(radio, SIGNAL(clicked(bool)), SLOT(onBoolChanged(bool))); selectorGroup->addButton(radio, count); @@ -286,9 +317,7 @@ QWidget * ExtArgRadio::createEditor(QWidget * parent) } } - /* No default was provided, and not saved value exists */ - if (anyChecked == false && count > 0) - ((QRadioButton*)(selectorGroup->button(0)))->setChecked(true); + setDefaultValue(); radioButtons->setLayout(vrLayout); @@ -333,6 +362,39 @@ bool ExtArgRadio::isValid() return valid; } +bool ExtArgRadio::isSetDefaultValueSupported() +{ + return TRUE; +} + +void ExtArgRadio::setDefaultValue() +{ + int count = 0; + bool anyChecked = false; + + if (values.length() > 0 ) + { + ExtcapValueList::const_iterator iter = values.constBegin(); + + while (iter != values.constEnd()) + { + if ((*iter).isDefault()) + { + selectorGroup->button(count)->setChecked(true); + anyChecked = true; + } + count++; + ++iter; + } + } + + /* No default was provided, and not saved value exists */ + if (anyChecked == false && count > 0) + ((QRadioButton*)(selectorGroup->button(0)))->setChecked(true); +} + + + ExtArgBool::ExtArgBool(extcap_arg * argument, QObject * parent) : ExtcapArgument(argument, parent), boolBox(0) {} @@ -349,7 +411,7 @@ QWidget * ExtArgBool::createEditor(QWidget * parent) if (_argument->tooltip != NULL) boolBox->setToolTip(QString().fromUtf8(_argument->tooltip)); - const char *prefval = _argument->pref_valptr ? *_argument->pref_valptr : NULL; + const char *prefval = (_argument->pref_valptr && strlen(*_argument->pref_valptr)) ? *_argument->pref_valptr : NULL; if (prefval) { QRegularExpression regexp(EXTCAP_BOOLEAN_REGEX); @@ -416,6 +478,18 @@ QString ExtArgBool::defaultValue() return defaultBool() ? QString("true") : QString("false"); } +bool ExtArgBool::isSetDefaultValueSupported() +{ + return TRUE; +} + +void ExtArgBool::setDefaultValue() +{ + boolBox->setCheckState(defaultBool() ? Qt::Checked : Qt::Unchecked); +} + + + ExtArgText::ExtArgText(extcap_arg * argument, QObject * parent) : ExtcapArgument(argument, parent), textBox(0) { @@ -425,12 +499,11 @@ QWidget * ExtArgText::createEditor(QWidget * parent) { QString text = defaultValue(); - if (_argument->pref_valptr && *_argument->pref_valptr) + /* Prefs can contain empty string. We accept it. */ + if (_argument->pref_valptr && (*_argument->pref_valptr)) { QString storeValue(*_argument->pref_valptr); - - if (storeValue.length() > 0 && storeValue.compare(text) != 0) - text = storeValue.trimmed(); + text = storeValue.trimmed(); } textBox = new QLineEdit(text, parent); @@ -512,6 +585,18 @@ bool ExtArgText::isValid() return valid; } +bool ExtArgText::isSetDefaultValueSupported() +{ + return TRUE; +} + +void ExtArgText::setDefaultValue() +{ + textBox->setText(defaultValue()); +} + + + ExtArgNumber::ExtArgNumber(extcap_arg * argument, QObject * parent) : ExtArgText(argument, parent) {} @@ -519,12 +604,10 @@ QWidget * ExtArgNumber::createEditor(QWidget * parent) { QString text = defaultValue(); - if (_argument->pref_valptr && *_argument->pref_valptr) + if (_argument->pref_valptr && strlen(*_argument->pref_valptr)) { QString storeValue(*_argument->pref_valptr); - - if (storeValue.length() > 0 && storeValue.compare(text) != 0) - text = storeValue; + text = storeValue; } textBox = (QLineEdit *)ExtArgText::createEditor(parent); @@ -908,3 +991,13 @@ void ExtcapArgument::onBoolChanged(bool) { emit valueChanged(); } + +bool ExtcapArgument::isSetDefaultValueSupported() +{ + return FALSE; +} + +void ExtcapArgument::setDefaultValue() +{ +} + diff --git a/ui/qt/extcap_argument.h b/ui/qt/extcap_argument.h index 28f2e0f646..63f15c456f 100644 --- a/ui/qt/extcap_argument.h +++ b/ui/qt/extcap_argument.h @@ -66,6 +66,7 @@ private: }; + class ExtcapArgument: public QObject { Q_OBJECT @@ -98,6 +99,10 @@ public: virtual int argNr() const; static ExtcapArgument * create(extcap_arg * argument = Q_NULLPTR, QObject * parent = Q_NULLPTR); + virtual bool isSetDefaultValueSupported(); + +public Q_SLOTS: + virtual void setDefaultValue(); Q_SIGNALS: void valueChanged(); @@ -125,8 +130,11 @@ private Q_SLOTS: }; + + class ExtArgText : public ExtcapArgument { + Q_OBJECT public: ExtArgText(extcap_arg * argument, QObject *parent = Q_NULLPTR); @@ -134,14 +142,22 @@ public: virtual QWidget * createEditor(QWidget * parent); virtual QString value(); virtual bool isValid(); + virtual bool isSetDefaultValueSupported(); + +public Q_SLOTS: + virtual void setDefaultValue(); protected: QLineEdit * textBox; }; + + class ExtArgNumber : public ExtArgText { + Q_OBJECT + public: ExtArgNumber(extcap_arg * argument, QObject *parent = Q_NULLPTR); @@ -149,6 +165,8 @@ public: virtual QString defaultValue(); }; + + class ExtArgSelector : public ExtcapArgument { Q_OBJECT @@ -159,6 +177,10 @@ public: virtual QWidget * createEditor(QWidget * parent); virtual QString value(); virtual bool isValid(); + virtual bool isSetDefaultValueSupported(); + +public Q_SLOTS: + virtual void setDefaultValue(); private: @@ -169,14 +191,22 @@ private Q_SLOTS: }; + + class ExtArgRadio : public ExtcapArgument { + Q_OBJECT + public: ExtArgRadio(extcap_arg * argument, QObject *parent = Q_NULLPTR); virtual QWidget * createEditor(QWidget * parent); virtual QString value(); virtual bool isValid(); + virtual bool isSetDefaultValueSupported(); + +public Q_SLOTS: + virtual void setDefaultValue(); private: @@ -184,8 +214,12 @@ private: QList * callStrings; }; + + class ExtArgBool : public ExtcapArgument { + Q_OBJECT + public: ExtArgBool(extcap_arg * argument, QObject *parent = Q_NULLPTR); @@ -197,6 +231,10 @@ public: virtual bool isValid(); virtual QString defaultValue(); virtual QString prefValue(); + virtual bool isSetDefaultValueSupported(); + +public Q_SLOTS: + virtual void setDefaultValue(); private: @@ -205,6 +243,8 @@ private: bool defaultBool(); }; + + class ExtArgTimestamp : public ExtcapArgument { Q_OBJECT @@ -217,12 +257,17 @@ public: virtual QString defaultValue(); virtual QString value(); virtual QString prefValue(); + virtual bool isSetDefaultValueSupported(); + +public Q_SLOTS: + virtual void setDefaultValue(); private Q_SLOTS: void onDateTimeChanged(QDateTime); private: QDateTime ts; + QDateTimeEdit *tsBox; }; #endif /* UI_QT_EXTCAP_ARGUMENT_H_ */ diff --git a/ui/qt/extcap_argument_file.cpp b/ui/qt/extcap_argument_file.cpp index 89d52627fc..bac7a5b9c4 100644 --- a/ui/qt/extcap_argument_file.cpp +++ b/ui/qt/extcap_argument_file.cpp @@ -59,7 +59,8 @@ QWidget * ExtcapArgumentFileSelection::createEditor(QWidget * parent) textBox = new QLineEdit(text, parent); textBox->setReadOnly(true); - const char *prefval = _argument->pref_valptr ? *_argument->pref_valptr : NULL; + /* Value is empty if no file is selected */ + const char *prefval = (_argument->pref_valptr && (*_argument->pref_valptr)) ? *_argument->pref_valptr : NULL; if (prefval) { QString storeValue(prefval); @@ -161,3 +162,9 @@ bool ExtcapArgumentFileSelection::isValid() return valid; } + +void ExtcapArgumentFileSelection::setDefaultValue() +{ + clearFilename(); +} + diff --git a/ui/qt/extcap_argument_file.h b/ui/qt/extcap_argument_file.h index 1eee7e637b..9dac908d59 100644 --- a/ui/qt/extcap_argument_file.h +++ b/ui/qt/extcap_argument_file.h @@ -31,6 +31,8 @@ public: virtual bool isValid(); + virtual void setDefaultValue(); + protected: QLineEdit * textBox; diff --git a/ui/qt/extcap_argument_multiselect.cpp b/ui/qt/extcap_argument_multiselect.cpp index 050250a416..b89e1410b2 100644 --- a/ui/qt/extcap_argument_multiselect.cpp +++ b/ui/qt/extcap_argument_multiselect.cpp @@ -99,6 +99,8 @@ void ExtArgMultiSelect::checkItemsWalker(QStandardItem * item, QStringList defau treeView->setExpanded(index, true); index = index.parent(); } + } else { + item->setCheckState(Qt::Unchecked); } } @@ -110,7 +112,8 @@ QWidget * ExtArgMultiSelect::createEditor(QWidget * parent) if (items.length() == 0) return new QWidget(); - if (_argument->pref_valptr && *_argument->pref_valptr) + /* 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); @@ -166,7 +169,7 @@ QString ExtArgMultiSelect::value() ++iter; } - return result.join(QString(",")); + return result.join(QString(',')); } void ExtArgMultiSelect::itemChanged(QStandardItem *) @@ -197,3 +200,31 @@ bool ExtArgMultiSelect::isValid() return valid; } + +QString ExtArgMultiSelect::defaultValue() +{ + QStringList checked; + + QList 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); +} + diff --git a/ui/qt/extcap_argument_multiselect.h b/ui/qt/extcap_argument_multiselect.h index a5701ac707..b64573df52 100644 --- a/ui/qt/extcap_argument_multiselect.h +++ b/ui/qt/extcap_argument_multiselect.h @@ -29,6 +29,11 @@ public: virtual QString value(); virtual bool isValid(); + virtual QString defaultValue(); + virtual bool isSetDefaultValueSupported(); + +public Q_SLOTS: + virtual void setDefaultValue(); protected: virtual QList valueWalker(ExtcapValueList list, QStringList &defaults); diff --git a/ui/qt/extcap_options_dialog.cpp b/ui/qt/extcap_options_dialog.cpp index 27bc41ca9f..550e478e62 100644 --- a/ui/qt/extcap_options_dialog.cpp +++ b/ui/qt/extcap_options_dialog.cpp @@ -58,7 +58,8 @@ ExtcapOptionsDialog::ExtcapOptionsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ExtcapOptionsDialog), device_name(""), - device_idx(0) + device_idx(0), + defaultValueIcon_(QApplication::style()->standardIcon(QStyle::SP_BrowserReload)) { ui->setupUi(this); @@ -333,6 +334,14 @@ void ExtcapOptionsDialog::updateWidgets() { editWidget->setProperty(QString("extcap").toLocal8Bit(), VariantPointer::asQVariant(argument)); layout->addWidget(editWidget, counter, 1, Qt::AlignVCenter); + + if (argument->isSetDefaultValueSupported()) + { + QPushButton *button = new QPushButton(defaultValueIcon_,""); + button->setToolTip(tr("Restore default value of the item")); + layout->addWidget(button, counter, 2, Qt::AlignVCenter); + connect(button, SIGNAL(clicked()), argument, SLOT(setDefaultValue())); + } } if (argument->isRequired() && ! argument->isValid()) @@ -468,12 +477,13 @@ void ExtcapOptionsDialog::resetValues() { ExtcapArgumentList::const_iterator iter; QString value; - bool doStore = false; int count = ui->verticalLayout->count(); if (count > 0) { QList layouts; + + /* Find all layouts */ if (qobject_cast(ui->verticalLayout->itemAt(0)->widget())) { QTabWidget * tabs = qobject_cast(ui->verticalLayout->itemAt(0)->widget()); @@ -485,12 +495,14 @@ void ExtcapOptionsDialog::resetValues() else layouts.append(ui->verticalLayout->itemAt(0)->layout()); + /* Loop over all layouts */ for (int cnt = 0; cnt < layouts.count(); cnt++) { QGridLayout * layout = qobject_cast(layouts.at(cnt)); if (! layout) continue; + /* Loop over all widgets in column 1 on layout */ for (int row = 0; row < layout->rowCount(); row++) { QWidget * child = Q_NULLPTR; @@ -510,22 +522,7 @@ void ExtcapOptionsDialog::resetValues() /* value<> can fail */ if (arg) { - arg->resetValue(); - - /* replacing the edit widget after resetting will lead to default value */ - QWidget * newWidget = arg->createEditor((QWidget *) this); - if (newWidget != NULL) - { - newWidget->setProperty(QString("extcap").toLocal8Bit(), VariantPointer::asQVariant(arg)); - QLayoutItem * oldItem = layout->replaceWidget(child, newWidget); - if (oldItem) - { - delete child; - delete oldItem; - } - } - - doStore = true; + arg->setDefaultValue(); } } } @@ -533,12 +530,8 @@ void ExtcapOptionsDialog::resetValues() } - /* this stores all values to the preferences */ - if (doStore) - { - storeValues(); - anyValueChanged(); - } + /* Values are stored when dialog is commited, just check validity*/ + anyValueChanged(); } } diff --git a/ui/qt/extcap_options_dialog.h b/ui/qt/extcap_options_dialog.h index 6e90eef494..3799d0bce3 100644 --- a/ui/qt/extcap_options_dialog.h +++ b/ui/qt/extcap_options_dialog.h @@ -53,6 +53,7 @@ private: Ui::ExtcapOptionsDialog *ui; QString device_name; guint device_idx; + QIcon defaultValueIcon_; ExtcapArgumentList extcapArguments;