extcap: Add regular expression validation support

Regular expressions follow the Qt Regex syntax, which is
 formulated after the Perl Regex syntax. A more detailed
 overview of the possible rules can be found at:
 http://doc.qt.io/qt-4.8/qregexp.html

 If a required option is present, even the double-click on
 the interface will first start the options dialog (Qt only)

 Required fields are marked bold and put first in the dialog.
 Additionally if validation failes (which it will if a required
 field is kept empty, but also if a non-required textfield is
 violating the defined regex), the label of the field is marked
 with red.

Change-Id: If04a1146d0dfa778332ab2a39122c7a6ee1e93d2
Reviewed-on: https://code.wireshark.org/review/12914
Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org>
This commit is contained in:
Roland Knall 2015-12-29 15:35:43 +01:00 committed by Stig Bjørlykke
parent a7e3ba03ce
commit cfd5457ec0
13 changed files with 598 additions and 319 deletions

View File

@ -74,9 +74,10 @@ def extcap_config(interface):
values = []
args.append ( (0, '--delay', 'Time delay', 'Time delay between packages', 'integer', '{range=1,15}') )
args.append ( (1, '--message', 'Message', 'Package message content', 'string', '') )
args.append ( (1, '--message', 'Message', 'Package message content', 'string', '{required=true}') )
args.append ( (2, '--verify', 'Verify', 'Verify package content', 'boolflag', '') )
args.append ( (3, '--remote', 'Remote Channel', 'Remote Channel Selector', 'selector', ''))
args.append ( (4, '--fake_ip', 'Fake IP Address', 'Use this ip address as sender', 'string', '{validation=\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b}'))
values.append ( (3, "if1", "Remote1", "true" ) )
values.append ( (3, "if2", "Remote2", "false" ) )
@ -140,7 +141,7 @@ def ip_checksum(iph):
csum = csum & 0xFFFF ^ 0xFFFF
return csum
def pcap_fake_package ( message ):
def pcap_fake_package ( message, fake_ip ):
pcap = bytearray()
#length = 14 bytes [ eth ] + 20 bytes [ ip ] + messagelength
@ -172,13 +173,16 @@ def pcap_fake_package ( message ):
pcap = append_bytes(pcap, struct.pack('b', int ( '40', 16) ))
pcap = append_bytes(pcap, struct.pack('B', 0xFE )) # Protocol (2 = unspecified)
pcap = append_bytes(pcap, struct.pack('<H', int ( '0000', 16) )) # Checksum
pcap = append_bytes(pcap, struct.pack('>L', int ( '7F000001', 16) )) # Source IP
parts = fake_ip.split('.')
ipadr = (int(parts[0]) << 24) + (int(parts[1]) << 16) + (int(parts[2]) << 8) + int(parts[3])
pcap = append_bytes(pcap, struct.pack('>L', ipadr )) # Source IP
pcap = append_bytes(pcap, struct.pack('>L', int ( '7F000001', 16) )) # Dest IP
pcap = append_bytes(pcap, message)
return pcap
def extcap_capture(interface, fifo, delay, verify, message, remote):
def extcap_capture(interface, fifo, delay, verify, message, remote, fake_ip):
global doExit
signal.signal(signal.SIGINT, signalHandler)
@ -198,7 +202,7 @@ def extcap_capture(interface, fifo, delay, verify, message, remote):
while doExit == False:
out = str( "%s|%04X%s|%s" % ( remote.strip(), len(message), message, verify ) )
try:
fh.write (pcap_fake_package(out))
fh.write (pcap_fake_package(out, fake_ip))
time.sleep(tdelay)
except IOError:
doExit = True
@ -216,6 +220,7 @@ if __name__ == '__main__':
# Capture options
delay = 0
message = ""
fake_ip = ""
parser = argparse.ArgumentParser(
prog="Extcap Example",
@ -236,6 +241,7 @@ if __name__ == '__main__':
parser.add_argument("--delay", help="Demonstrates an integer variable", type=int, default=0, choices=[0, 1, 2, 3, 4, 5] )
parser.add_argument("--remote", help="Demonstrates a selector choice", default="if1", choices=["if1", "if2"] )
parser.add_argument("--message", help="Demonstrates string variable", nargs='?', default="" )
parser.add_argument("--fake_ip", help="Add a fake sender IP adress", nargs='?', default="127.0.0.1" )
args, unknown = parser.parse_known_args()
if ( len(sys.argv) <= 1 ):
@ -260,6 +266,10 @@ if __name__ == '__main__':
if ( args.message == None or len(args.message) == 0 ):
message = "Extcap Test"
fake_ip = args.fake_ip
if ( args.fake_ip == None or len(args.fake_ip) < 7 or len(args.fake_ip.split('.')) != 4 ):
fake_ip = "127.0.0.1"
if args.extcap_config:
extcap_config(interface)
elif args.extcap_dlts:
@ -267,7 +277,7 @@ if __name__ == '__main__':
elif args.capture:
if args.fifo is None:
sys.exit(ERROR_FIFO)
extcap_capture(interface, args.fifo, args.delay, args.verify, message, args.remote)
extcap_capture(interface, args.fifo, args.delay, args.verify, message, args.remote, fake_ip)
else:
usage()
sys.exit(ERROR_USAGE)

View File

@ -440,7 +440,7 @@ extcap_get_if_configuration(const char * ifname) {
}
gboolean
extcap_has_configuration(const char * ifname) {
extcap_has_configuration(const char * ifname, gboolean is_required) {
GList * arguments = 0;
GList * walker = 0, * item = 0;
@ -455,7 +455,11 @@ extcap_has_configuration(const char * ifname) {
while ( item != NULL && ! found )
{
if ( (extcap_arg *)(item->data) != NULL )
{
/* Should required options be present, or any kind of options */
if ( ! is_required || ((extcap_arg *)(item->data))->is_required )
found = TRUE;
}
item = item->next;
}
@ -869,7 +873,7 @@ void extcap_debug_arguments ( extcap_arg *arg_iter )
for ( walker = g_list_first ( arg_iter->value_list ); walker; walker = walker->next )
{
v = (extcap_value *)walker->data;
if (v->is_default == TRUE)
if (v->is_default)
printf("*");
printf("\tcall=\"%p\" display=\"%p\"\n", v->call, v->display);
printf("\tcall=\"%s\" display=\"%s\"\n", v->call, v->display);

View File

@ -67,7 +67,7 @@ GList *
extcap_get_if_configuration(const char * ifname);
gboolean
extcap_has_configuration(const char * ifname);
extcap_has_configuration(const char * ifname, gboolean is_required);
#ifdef WIN32
HANDLE

View File

@ -300,6 +300,21 @@ extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) {
return NULL ;
}
/* caught a regex quantifier end bracket and not the end of the line.
* let's find the correct end bracket */
if ( *(e+1) != '{' && strlen ( e ) > 1 ) {
gchar *f = (e + 1);
while ( ( f = g_strstr_len(f, -1, "}") ) != NULL) {
if ( strlen ( f ) <= 1 || *(f+1) == '{' )
break;
f++;
}
if ( f != NULL )
e = f;
}
if ((eq = g_strstr_len(b, -1, "=")) == NULL) {
/* printf("debug - tokenizer - invalid, missing =\n"); */
extcap_free_tokenized_sentence(rs);
@ -349,6 +364,8 @@ extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) {
tv->param_type = EXTCAP_PARAM_PARENT;
} else if (g_ascii_strcasecmp(tv->arg, "required") == 0) {
tv->param_type = EXTCAP_PARAM_REQUIRED;
} else if (g_ascii_strcasecmp(tv->arg, "validation") == 0) {
tv->param_type = EXTCAP_PARAM_VALIDATION;
} else {
tv->param_type = EXTCAP_PARAM_UNKNOWN;
}
@ -480,6 +497,7 @@ extcap_arg *extcap_new_arg(void) {
r->default_complex = NULL;
r->fileexists = FALSE;
r->fileextension = NULL;
r->regexp = NULL;
r->is_required = FALSE;
r->values = NULL;
@ -509,6 +527,9 @@ void extcap_free_arg(extcap_arg *a) {
if (a->fileextension != NULL)
g_free(a->fileextension);
if (a->regexp != NULL)
g_free(a->regexp);
if (a->range_start != NULL)
extcap_free_complex(a->range_start);
@ -605,6 +626,11 @@ extcap_arg *extcap_parse_arg_sentence(GList * args, extcap_token_sentence *s) {
target_arg->fileextension = g_strdup(v->value);
}
if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_VALIDATION))
!= NULL) {
target_arg->regexp = g_strdup(v->value);
}
if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_REQUIRED))
!= NULL) {
target_arg->is_required = (v->value[0] == 't' || v->value[0] == 'T');

View File

@ -69,7 +69,8 @@ typedef enum {
EXTCAP_PARAM_FILE_MUSTEXIST,
EXTCAP_PARAM_FILE_EXTENSION,
EXTCAP_PARAM_PARENT,
EXTCAP_PARAM_REQUIRED
EXTCAP_PARAM_REQUIRED,
EXTCAP_PARAM_VALIDATION
} extcap_param_type;
/* Values for a given sentence; values are all stored as a call
@ -112,6 +113,8 @@ typedef struct _extcap_arg {
gboolean is_required;
gchar * regexp;
extcap_arg_type arg_type;
extcap_complex *range_start;

View File

@ -40,19 +40,18 @@
#include <QStandardItem>
#include <QStandardItemModel>
#include <QItemSelectionModel>
#include <QTreeView>
#include <epan/prefs.h>
#include <color_utils.h>
#include <extcap_parser.h>
#include <extcap_argument_file.h>
#include <extcap_argument_multiselect.h>
class ExtArgSelector : public ExtcapArgument
{
public:
ExtArgSelector(extcap_arg * argument) :
ExtcapArgument(argument), boxSelection(0) {};
ExtArgSelector::ExtArgSelector(extcap_arg * argument) :
ExtcapArgument(argument), boxSelection(0) {}
virtual QWidget * createEditor(QWidget * parent)
QWidget * ExtArgSelector::createEditor(QWidget * parent)
{
int counter = 0;
int selected = -1;
@ -82,7 +81,21 @@ public:
return boxSelection;
}
virtual QString value()
bool ExtArgSelector::isValid()
{
bool valid = true;
if ( value().length() == 0 && isRequired() )
valid = false;
QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
QString cmbBoxStyle("QComboBox { background-color: %1; } ");
boxSelection->setStyleSheet( cmbBoxStyle.arg(valid ? QString("") : lblInvalidColor) );
return valid;
}
QString ExtArgSelector::value()
{
if ( boxSelection == 0 )
return QString();
@ -96,20 +109,10 @@ public:
return data.toString();
}
private:
ExtArgRadio::ExtArgRadio(extcap_arg * argument) :
ExtcapArgument(argument), selectorGroup(0), callStrings(0) {}
QComboBox * boxSelection;
};
class ExtArgRadio : public ExtcapArgument
{
public:
ExtArgRadio(extcap_arg * argument) :
ExtcapArgument(argument), selectorGroup(0), callStrings(0)
{
};
virtual QWidget * createEditor(QWidget * parent)
QWidget * ExtArgRadio::createEditor(QWidget * parent)
{
int count = 0;
@ -168,7 +171,7 @@ public:
return radioButtons;
}
virtual QString value()
QString ExtArgRadio::value()
{
int idx = 0;
if ( selectorGroup == 0 || callStrings == 0 )
@ -181,24 +184,40 @@ public:
return QString();
}
private:
QButtonGroup * selectorGroup;
QList<QString> * callStrings;
};
class ExtArgBool : public ExtcapArgument
bool ExtArgRadio::isValid()
{
public:
ExtArgBool(extcap_arg * argument) :
ExtcapArgument(argument), boolBox(0) {};
bool valid = true;
int idx = 0;
virtual QWidget * createLabel(QWidget * parent)
if ( isRequired() )
{
if ( selectorGroup == 0 || callStrings == 0 )
valid = false;
else
{
idx = selectorGroup->checkedId();
if ( idx == -1 || callStrings->length() <= idx )
valid = false;
}
}
/* If nothing is selected, but a selection is required, the only thing that
* can be marked is the label */
QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
_label->setStyleSheet ( label_style.arg(valid ? QString("") : lblInvalidColor) );
return valid;
}
ExtArgBool::ExtArgBool(extcap_arg * argument) :
ExtcapArgument(argument), boolBox(0) {}
QWidget * ExtArgBool::createLabel(QWidget * parent)
{
return new QWidget(parent);
}
virtual QWidget * createEditor(QWidget * parent)
QWidget * ExtArgBool::createEditor(QWidget * parent)
{
boolBox = new QCheckBox(QString().fromUtf8(_argument->display), parent);
if ( _argument->tooltip != NULL )
@ -219,7 +238,7 @@ public:
return boolBox;
}
virtual QString call()
QString ExtArgBool::call()
{
if ( boolBox == NULL )
return QString("");
@ -230,14 +249,21 @@ public:
return QString(boolBox->checkState() == Qt::Checked ? _argument->call : "");
}
virtual QString value()
QString ExtArgBool::value()
{
if ( boolBox == NULL || _argument->arg_type == EXTCAP_ARG_BOOLFLAG )
return QString();
return QString(boolBox->checkState() == Qt::Checked ? "true" : "false");
}
virtual QString defaultValue()
bool ExtArgBool::isValid()
{
/* A bool is allways valid, but the base function checks on string length,
* which will fail with boolflags */
return true;
}
QString ExtArgBool::defaultValue()
{
if ( _argument != 0 && _argument->default_complex != NULL )
if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
@ -246,22 +272,13 @@ public:
return QString("false");
}
private:
QCheckBox * boolBox;
};
class ExtArgText : public ExtcapArgument
{
public:
ExtArgText(extcap_arg * argument) :
ExtArgText::ExtArgText(extcap_arg * argument) :
ExtcapArgument(argument), textBox(0)
{
_default = new QVariant(QString(""));
};
}
virtual QWidget * createEditor(QWidget * parent)
QWidget * ExtArgText::createEditor(QWidget * parent)
{
textBox = new QLineEdit(_default->toString(), parent);
@ -275,7 +292,7 @@ public:
return textBox;
}
virtual QString value()
QString ExtArgText::value()
{
if ( textBox == 0 )
return QString();
@ -283,15 +300,34 @@ public:
return textBox->text();
}
virtual bool isValid()
bool ExtArgText::isValid()
{
if ( isRequired() && value().length() == 0 )
return false;
bool valid = true;
return true;
if ( isRequired() && value().length() == 0 )
valid = false;
/* validation should only be checked if there is a value. if the argument
* must be present (isRequired) the check above will handle that */
if ( valid && _argument->regexp != NULL && value().length() > 0)
{
QString regexp = QString().fromUtf8(_argument->regexp);
if ( regexp.length() > 0 )
{
QRegExp expr(regexp);
if ( ! expr.isValid() || expr.indexIn(value(), 0) == -1 )
valid = false;
}
}
virtual QString defaultValue()
QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
QString txtStyle("QLineEdit { background-color: %1; } ");
textBox->setStyleSheet( txtStyle.arg(valid ? QString("") : lblInvalidColor) );
return valid;
}
QString ExtArgText::defaultValue()
{
if ( _argument != 0 && _argument->default_complex != 0)
{
@ -303,18 +339,10 @@ public:
return QString();
}
protected:
ExtArgNumber::ExtArgNumber(extcap_arg * argument) :
ExtArgText(argument) {}
QLineEdit * textBox;
};
class ExtArgNumber : public ExtArgText
{
public:
ExtArgNumber(extcap_arg * argument) :
ExtArgText(argument) {};
virtual QWidget * createEditor(QWidget * parent)
QWidget * ExtArgNumber::createEditor(QWidget * parent)
{
textBox = (QLineEdit *)ExtArgText::createEditor(parent);
textBox->disconnect(SIGNAL(textChanged(QString)));
@ -348,9 +376,9 @@ public:
connect(textBox, SIGNAL(textChanged(QString)), SLOT(onStringChanged(QString)));
return textBox;
};
}
virtual QString defaultValue()
QString ExtArgNumber::defaultValue()
{
QString result;
@ -371,8 +399,6 @@ public:
return result;
}
};
ExtcapValue::~ExtcapValue() {}
void ExtcapValue::setChildren(ExtcapValueList children)
@ -388,7 +414,8 @@ void ExtcapValue::setChildren(ExtcapValueList children)
}
ExtcapArgument::ExtcapArgument(extcap_arg * argument, QObject *parent) :
QObject(parent), _argument(argument), _default(0)
QObject(parent), _argument(argument), _default(0), _label(0),
label_style(QString("QLabel { color: %1; }"))
{
if ( _argument->values != 0 )
{
@ -441,13 +468,20 @@ QWidget * ExtcapArgument::createLabel(QWidget * parent)
if ( _argument == 0 || _argument->display == 0 )
return 0;
QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
QString text = QString().fromUtf8(_argument->display);
QLabel * label = new QLabel(text, parent);
if ( _argument->tooltip != 0 )
label->setToolTip(QString().fromUtf8(_argument->tooltip));
_label = new QLabel(text, parent);
return label;
_label->setProperty("isRequired", QString(isRequired() ? "true" : "false"));
_label->setStyleSheet ( label_style.arg(QString("")) );
if ( _argument->tooltip != 0 )
_label->setToolTip(QString().fromUtf8(_argument->tooltip));
return _label;
}
QWidget * ExtcapArgument::createEditor(QWidget *)
@ -468,6 +502,11 @@ QString ExtcapArgument::value()
bool ExtcapArgument::isValid()
{
/* Unrequired arguments are always valid, except if validity checks fail,
* which must be checked in an derived class, not here */
if ( ! isRequired() )
return true;
return value().length() > 0;
}

View File

@ -27,9 +27,16 @@
#include <QLabel>
#include <QVariant>
#include <QList>
#include <QLineEdit>
#include <QComboBox>
#include <QButtonGroup>
#include <QCheckBox>
#include <extcap_parser.h>
#define EXTCAP_GUI_BLANK_LABEL "QLabel { color : ; }"
#define EXTCAP_GUI_ERROR_LABEL "QLabel { color : red; }"
class ExtcapValue;
typedef QList<ExtcapValue> ExtcapValueList;
@ -108,6 +115,9 @@ protected:
extcap_arg * _argument;
QVariant * _default;
QWidget * _label;
const QString label_style;
private Q_SLOTS:
@ -117,6 +127,78 @@ private Q_SLOTS:
};
class ExtArgText : public ExtcapArgument
{
public:
ExtArgText(extcap_arg * argument);
virtual QWidget * createEditor(QWidget * parent);
virtual QString value();
virtual bool isValid();
virtual QString defaultValue();
protected:
QLineEdit * textBox;
};
class ExtArgNumber : public ExtArgText
{
public:
ExtArgNumber(extcap_arg * argument);
virtual QWidget * createEditor(QWidget * parent);
virtual QString defaultValue();
};
class ExtArgSelector : public ExtcapArgument
{
public:
ExtArgSelector(extcap_arg * argument);
virtual QWidget * createEditor(QWidget * parent);
virtual QString value();
virtual bool isValid();
private:
QComboBox * boxSelection;
};
class ExtArgRadio : public ExtcapArgument
{
public:
ExtArgRadio(extcap_arg * argument);
virtual QWidget * createEditor(QWidget * parent);
virtual QString value();
virtual bool isValid();
private:
QButtonGroup * selectorGroup;
QList<QString> * callStrings;
};
class ExtArgBool : public ExtcapArgument
{
public:
ExtArgBool(extcap_arg * argument);
virtual QWidget * createLabel(QWidget * parent);
virtual QWidget * createEditor(QWidget * parent);
virtual QString call();
virtual QString value();
virtual bool isValid();
virtual QString defaultValue();
private:
QCheckBox * boolBox;
};
#endif /* UI_QT_EXTCAP_ARGUMENT_H_ */
/*

View File

@ -35,8 +35,10 @@
#include <QFileInfo>
#include <QVariant>
#include <extcap_parser.h>
#include <epan/prefs.h>
#include <color_utils.h>
#include <extcap_parser.h>
ExtcapArgumentFileSelection::ExtcapArgumentFileSelection (extcap_arg * argument) :
ExtcapArgument(argument), textBox(0)
@ -118,9 +120,16 @@ void ExtcapArgumentFileSelection::openFileDialog()
bool ExtcapArgumentFileSelection::isValid()
{
if ( textBox->text().length() > 0 )
return true;
return false;
bool valid = false;
if ( textBox->text().length() > 0 || ! isRequired() )
valid = true;
QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
QString txtStyle("QLineEdit { background-color: %1; } ");
textBox->setStyleSheet( txtStyle.arg(valid ? QString("") : lblInvalidColor) );
return valid;
}
/*

View File

@ -32,11 +32,14 @@
#include <QPushButton>
#include <QVariant>
#include <epan/prefs.h>
#include <color_utils.h>
#include <extcap_parser.h>
#include <extcap_argument_multiselect.h>
ExtArgMultiSelect::ExtArgMultiSelect(extcap_arg * argument) :
ExtcapArgument(argument), treeView(0), viewModel(0) {};
ExtcapArgument(argument), treeView(0), viewModel(0) {}
ExtArgMultiSelect::~ExtArgMultiSelect()
{
@ -187,6 +190,31 @@ void ExtArgMultiSelect::selectionChanged(const QItemSelection &, const QItemSele
emit valueChanged();
}
bool ExtArgMultiSelect::isValid()
{
bool valid = true;
if ( isRequired() )
{
if ( viewModel == 0 )
valid = false;
else
{
QStringList result;
QModelIndexList selected = treeView->selectionModel()->selectedIndexes();
if ( selected.size() <= 0 )
valid = false;
}
}
QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
QString txtStyle("QTreeView { background-color: %1; } ");
treeView->setStyleSheet( txtStyle.arg(valid ? QString("") : lblInvalidColor) );
return valid;
}
/*
* Editor modelines

View File

@ -41,6 +41,7 @@ public:
virtual QString value();
virtual QString defaultValue();
virtual bool isValid();
protected:
virtual QList<QStandardItem *> valueWalker(ExtcapValueList list, QStringList &defaults);

View File

@ -56,6 +56,7 @@
#include <ui/qt/extcap_argument.h>
#include <ui/qt/extcap_argument_file.h>
#include <ui/qt/extcap_argument_multiselect.h>
ExtcapOptionsDialog::ExtcapOptionsDialog(QWidget *parent) :
QDialog(parent),
@ -104,6 +105,9 @@ ExtcapOptionsDialog * ExtcapOptionsDialog::createForDevice(QString &dev_name, QW
resultDialog->updateWidgets();
/* mark required fields */
resultDialog->anyValueChanged();
return resultDialog;
}
@ -122,17 +126,54 @@ void ExtcapOptionsDialog::on_buttonBox_accepted()
void ExtcapOptionsDialog::anyValueChanged()
{
/* Guard, that only extcap arguments are given, which should be the case anyway */
if ( dynamic_cast<ExtcapArgument *>(QObject::sender()) == NULL )
return;
bool allowStart = true;
ExtcapArgumentList::const_iterator iter;
for(iter = extcapArguments.constBegin(); iter != extcapArguments.constEnd() && allowStart; ++iter)
/* All arguments are being iterated, to ensure, that any error handling catches all arguments */
for(iter = extcapArguments.constBegin(); iter != extcapArguments.constEnd(); ++iter)
{
if ( (*iter)->isRequired() && ! (*iter)->isValid() )
/* The dynamic casts are necessary, because we come here using the Signal/Slot system
* of Qt, and -in short- Q_OBJECT classes cannot be multiple inherited. Another possibility
* would be to use Q_INTERFACE, but this causes way more nightmares, and we really just
* need here an explicit cast for the check functionality */
if ( dynamic_cast<ExtArgBool *>((*iter)) != NULL)
{
if ( ! ((ExtArgBool *)*iter)->isValid() )
allowStart = false;
}
else if ( dynamic_cast<ExtArgRadio *>((*iter)) != NULL)
{
if ( ! ((ExtArgRadio *)*iter)->isValid() )
allowStart = false;
}
else if ( dynamic_cast<ExtArgSelector *>((*iter)) != NULL)
{
if ( ! ((ExtArgSelector *)*iter)->isValid() )
allowStart = false;
}
else if ( dynamic_cast<ExtArgMultiSelect *>((*iter)) != NULL)
{
if ( ! ((ExtArgMultiSelect *)*iter)->isValid() )
allowStart = false;
}
else if ( dynamic_cast<ExtcapArgumentFileSelection *>((*iter)) != NULL)
{
if ( ! ((ExtcapArgumentFileSelection *)*iter)->isValid() )
allowStart = false;
}
else if ( dynamic_cast<ExtArgNumber *>((*iter)) != NULL)
{
if ( ! ((ExtArgNumber *)*iter)->isValid() )
allowStart = false;
}
else if ( dynamic_cast<ExtArgText *>((*iter)) != NULL)
{
if ( ! ((ExtArgText *)*iter)->isValid() )
allowStart = false;
}
else
if ( ! (*iter)->isValid() )
allowStart = false;
}
@ -156,6 +197,9 @@ void ExtcapOptionsDialog::updateWidgets()
QGridLayout * layout = new QGridLayout();
ExtcapArgumentList required;
ExtcapArgumentList optional;
while ( walker != NULL )
{
item = g_list_first((GList *)(walker->data));
@ -164,34 +208,50 @@ void ExtcapOptionsDialog::updateWidgets()
argument = ExtcapArgument::create((extcap_arg *)(item->data), device_defaults);
if ( argument != NULL )
{
extcapArguments << argument;
if ( argument->isRequired() )
required << argument;
else
optional << argument;
lblWidget = argument->createLabel((QWidget *)this);
if ( lblWidget != NULL )
{
layout->addWidget(lblWidget, counter, 0, Qt::AlignVCenter);
editWidget = argument->createEditor((QWidget *) this);
if ( editWidget != NULL )
{
layout->addWidget(editWidget, counter, 1, Qt::AlignVCenter);
}
if ( argument->isRequired() && ! argument->isValid() )
allowStart = false;
connect(argument, SIGNAL(valueChanged()), this, SLOT(anyValueChanged()));
counter++;
}
}
item = item->next;
}
walker = walker->next;
}
if ( required.length() > 0 )
extcapArguments << required;
if ( optional.length() > 0 )
extcapArguments << optional;
ExtcapArgumentList::iterator iter = extcapArguments.begin();
while ( iter != extcapArguments.end() )
{
lblWidget = (*iter)->createLabel((QWidget *)this);
if ( lblWidget != NULL )
{
layout->addWidget(lblWidget, counter, 0, Qt::AlignVCenter);
editWidget = (*iter)->createEditor((QWidget *) this);
if ( editWidget != NULL )
{
layout->addWidget(editWidget, counter, 1, Qt::AlignVCenter);
}
if ( (*iter)->isRequired() && ! (*iter)->isValid() )
allowStart = false;
connect((*iter), SIGNAL(valueChanged()), this, SLOT(anyValueChanged()));
counter++;
}
++iter;
}
if ( counter > 0 )
{
setStyleSheet ( "QLabel[isRequired=\"true\"] { font-weight: bold; } ");
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowStart);
ui->verticalLayout->addLayout(layout);

View File

@ -189,7 +189,7 @@ void InterfaceTree::display()
#if HAVE_EXTCAP
if ( device.if_info.type == IF_EXTCAP )
{
if ( extcap_has_configuration((const char *)(device.name)) )
if ( extcap_has_configuration((const char *)(device.name), FALSE) )
{
ti->setIcon(IFTREE_COL_EXTCAP, extcap_icon);
ti->setData(IFTREE_COL_EXTCAP, Qt::UserRole, QString(device.if_info.extcap));

View File

@ -53,6 +53,10 @@
#define VERSION_FLAVOR ""
#endif
#if HAVE_EXTCAP
#include <extcap.h>
#endif
MainWelcome::MainWelcome(QWidget *parent) :
QFrame(parent),
welcome_ui_(new Ui::MainWelcome),
@ -230,6 +234,19 @@ void MainWelcome::appInitialized()
void MainWelcome::interfaceDoubleClicked(QTreeWidgetItem *item, int)
{
if (item) {
#if HAVE_EXTCAP
QString extcap_string = QVariant(item->data(IFTREE_COL_EXTCAP, Qt::UserRole)).toString();
/* We trust the string here. If this interface is really extcap, the string is
* being checked immediatly before the dialog is being generated */
if ( extcap_string.length() > 0 ) {
QString device_name = QVariant(item->data(IFTREE_COL_NAME, Qt::UserRole)).toString();
/* this checks if configuration is required and not yet provided or saved via prefs */
if ( extcap_has_configuration((const char *)(device_name.toStdString().c_str()), TRUE ) ) {
emit showExtcapOptions(device_name);
return;
}
}
#endif
emit startCapture();
}
}