aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xdoc/extcap_example.py22
-rw-r--r--extcap.c10
-rw-r--r--extcap.h2
-rw-r--r--extcap_parser.c26
-rw-r--r--extcap_parser.h5
-rw-r--r--ui/qt/extcap_argument.cpp513
-rw-r--r--ui/qt/extcap_argument.h82
-rw-r--r--ui/qt/extcap_argument_file.cpp17
-rw-r--r--ui/qt/extcap_argument_multiselect.cpp30
-rw-r--r--ui/qt/extcap_argument_multiselect.h1
-rw-r--r--ui/qt/extcap_options_dialog.cpp108
-rw-r--r--ui/qt/interface_tree.cpp2
-rw-r--r--ui/qt/main_welcome.cpp17
13 files changed, 557 insertions, 278 deletions
diff --git a/doc/extcap_example.py b/doc/extcap_example.py
index 1eab8d39e4..13c079d0ec 100755
--- a/doc/extcap_example.py
+++ b/doc/extcap_example.py
@@ -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)
diff --git a/extcap.c b/extcap.c
index 0a5e19ba3c..6d66ad167c 100644
--- a/extcap.c
+++ b/extcap.c
@@ -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 )
- found = TRUE;
+ {
+ /* 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);
diff --git a/extcap.h b/extcap.h
index 47c6511dc5..813d4bd740 100644
--- a/extcap.h
+++ b/extcap.h
@@ -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
diff --git a/extcap_parser.c b/extcap_parser.c
index ef683f1a40..d884298a3a 100644
--- a/extcap_parser.c
+++ b/extcap_parser.c
@@ -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');
diff --git a/extcap_parser.h b/extcap_parser.h
index a730d200bc..158838c16f 100644
--- a/extcap_parser.h
+++ b/extcap_parser.h
@@ -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;
diff --git a/ui/qt/extcap_argument.cpp b/ui/qt/extcap_argument.cpp
index 0150446ae5..2ae543660f 100644
--- a/ui/qt/extcap_argument.cpp
+++ b/ui/qt/extcap_argument.cpp
@@ -40,338 +40,364 @@
#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
+ExtArgSelector::ExtArgSelector(extcap_arg * argument) :
+ ExtcapArgument(argument), boxSelection(0) {}
+
+QWidget * ExtArgSelector::createEditor(QWidget * parent)
{
-public:
- ExtArgSelector(extcap_arg * argument) :
- ExtcapArgument(argument), boxSelection(0) {};
+ int counter = 0;
+ int selected = -1;
- virtual QWidget * createEditor(QWidget * parent)
- {
- int counter = 0;
- int selected = -1;
+ boxSelection = new QComboBox(parent);
- boxSelection = new QComboBox(parent);
+ if ( values.length() > 0 )
+ {
+ ExtcapValueList::const_iterator iter = values.constBegin();
- if ( values.length() > 0 )
+ while ( iter != values.constEnd() )
{
- ExtcapValueList::const_iterator iter = values.constBegin();
+ boxSelection->addItem((*iter).value(), (*iter).call());
+ if ( (*iter).isDefault() )
+ selected = counter;
- while ( iter != values.constEnd() )
- {
- boxSelection->addItem((*iter).value(), (*iter).call());
- if ( (*iter).isDefault() )
- selected = counter;
+ counter++;
+ ++iter;
+ }
- counter++;
- ++iter;
- }
+ if ( selected > -1 && selected < boxSelection->count() )
+ boxSelection->setCurrentIndex(selected);
+ }
- if ( selected > -1 && selected < boxSelection->count() )
- boxSelection->setCurrentIndex(selected);
- }
+ connect ( boxSelection, SIGNAL(currentIndexChanged(int)), SLOT(onIntChanged(int)) );
- connect ( boxSelection, SIGNAL(currentIndexChanged(int)), SLOT(onIntChanged(int)) );
+ return boxSelection;
+}
- return boxSelection;
- }
+bool ExtArgSelector::isValid()
+{
+ bool valid = true;
- virtual QString value()
- {
- if ( boxSelection == 0 )
- return QString();
+ 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();
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
- QVariant data = boxSelection->currentData();
+ QVariant data = boxSelection->currentData();
#else
- QVariant data = boxSelection->itemData(boxSelection->currentIndex());
+ QVariant data = boxSelection->itemData(boxSelection->currentIndex());
#endif
- return data.toString();
- }
-
-private:
+ return data.toString();
+}
- QComboBox * boxSelection;
-};
+ExtArgRadio::ExtArgRadio(extcap_arg * argument) :
+ ExtcapArgument(argument), selectorGroup(0), callStrings(0) {}
-class ExtArgRadio : public ExtcapArgument
+QWidget * ExtArgRadio::createEditor(QWidget * parent)
{
-public:
- ExtArgRadio(extcap_arg * argument) :
- ExtcapArgument(argument), selectorGroup(0), callStrings(0)
- {
- };
- virtual QWidget * createEditor(QWidget * parent)
- {
-
- int count = 0;
- bool anyChecked = false;
+ int count = 0;
+ bool anyChecked = false;
- selectorGroup = new QButtonGroup(parent);
- QWidget * radioButtons = new QWidget;
- QVBoxLayout * vrLayout = new QVBoxLayout();
- QMargins margins = vrLayout->contentsMargins();
- vrLayout->setContentsMargins(0, 0, 0, margins.bottom());
- if ( callStrings != 0 )
- delete callStrings;
+ selectorGroup = new QButtonGroup(parent);
+ QWidget * radioButtons = new QWidget;
+ QVBoxLayout * vrLayout = new QVBoxLayout();
+ QMargins margins = vrLayout->contentsMargins();
+ vrLayout->setContentsMargins(0, 0, 0, margins.bottom());
+ if ( callStrings != 0 )
+ delete callStrings;
- callStrings = new QList<QString>();
+ callStrings = new QList<QString>();
- if ( values.length() > 0 )
- {
- ExtcapValueList::const_iterator iter = values.constBegin();
+ if ( values.length() > 0 )
+ {
+ ExtcapValueList::const_iterator iter = values.constBegin();
- while ( iter != values.constEnd() )
- {
- QRadioButton * radio = new QRadioButton((*iter).value());
- QString callString = (*iter).call();
- callStrings->append(callString);
+ while ( iter != values.constEnd() )
+ {
+ QRadioButton * radio = new QRadioButton((*iter).value());
+ QString callString = (*iter).call();
+ callStrings->append(callString);
- if ( _default != NULL && (*iter).isDefault() )
+ if ( _default != NULL && (*iter).isDefault() )
+ {
+ radio->setChecked(true);
+ anyChecked = true;
+ }
+ else if (_default != NULL)
+ {
+ if ( callString.compare(_default->toString()) == 0 )
{
radio->setChecked(true);
anyChecked = true;
}
- else if (_default != NULL)
- {
- if ( callString.compare(_default->toString()) == 0 )
- {
- radio->setChecked(true);
- anyChecked = true;
- }
- }
-
- connect(radio, SIGNAL(clicked(bool)), SLOT(onBoolChanged(bool)));
- selectorGroup->addButton(radio, count);
-
- vrLayout->addWidget(radio);
- count++;
-
- ++iter;
}
- }
- /* No default was provided, and not saved value exists */
- if ( anyChecked == false && count > 0 )
- ((QRadioButton*)(selectorGroup->button(0)))->setChecked(true);
+ connect(radio, SIGNAL(clicked(bool)), SLOT(onBoolChanged(bool)));
+ selectorGroup->addButton(radio, count);
- radioButtons->setLayout(vrLayout);
+ vrLayout->addWidget(radio);
+ count++;
- return radioButtons;
+ ++iter;
+ }
}
- virtual QString value()
- {
- int idx = 0;
- if ( selectorGroup == 0 || callStrings == 0 )
- return QString();
+ /* No default was provided, and not saved value exists */
+ if ( anyChecked == false && count > 0 )
+ ((QRadioButton*)(selectorGroup->button(0)))->setChecked(true);
+
+ radioButtons->setLayout(vrLayout);
- idx = selectorGroup->checkedId();
- if ( idx > -1 && callStrings->length() > idx )
- return callStrings->takeAt(idx);
+ return radioButtons;
+}
+QString ExtArgRadio::value()
+{
+ int idx = 0;
+ if ( selectorGroup == 0 || callStrings == 0 )
return QString();
- }
-private:
+ idx = selectorGroup->checkedId();
+ if ( idx > -1 && callStrings->length() > idx )
+ return callStrings->takeAt(idx);
- QButtonGroup * selectorGroup;
- QList<QString> * callStrings;
-};
+ return QString();
+}
-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() )
{
- return new QWidget(parent);
+ if ( selectorGroup == 0 || callStrings == 0 )
+ valid = false;
+ else
+ {
+ idx = selectorGroup->checkedId();
+ if ( idx == -1 || callStrings->length() <= idx )
+ valid = false;
+ }
}
- virtual QWidget * createEditor(QWidget * parent)
- {
- boolBox = new QCheckBox(QString().fromUtf8(_argument->display), parent);
- if ( _argument->tooltip != NULL )
- boolBox->setToolTip(QString().fromUtf8(_argument->tooltip));
+ /* 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) );
- if ( _argument->default_complex != NULL )
- if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
- boolBox->setCheckState(Qt::Checked);
+ return valid;
+}
- if ( _default != NULL )
- {
- if ( _default->toString().compare("true") )
- boolBox->setCheckState(Qt::Checked);
- }
+ExtArgBool::ExtArgBool(extcap_arg * argument) :
+ ExtcapArgument(argument), boolBox(0) {}
- connect (boolBox, SIGNAL(stateChanged(int)), SLOT(onIntChanged(int)));
+QWidget * ExtArgBool::createLabel(QWidget * parent)
+{
+ return new QWidget(parent);
+}
- return boolBox;
- }
+QWidget * ExtArgBool::createEditor(QWidget * parent)
+{
+ boolBox = new QCheckBox(QString().fromUtf8(_argument->display), parent);
+ if ( _argument->tooltip != NULL )
+ boolBox->setToolTip(QString().fromUtf8(_argument->tooltip));
+
+ if ( _argument->default_complex != NULL )
+ if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
+ boolBox->setCheckState(Qt::Checked);
- virtual QString call()
+ if ( _default != NULL )
{
- if ( boolBox == NULL )
- return QString("");
+ if ( _default->toString().compare("true") )
+ boolBox->setCheckState(Qt::Checked);
+ }
- if ( _argument->arg_type == EXTCAP_ARG_BOOLEAN )
- return ExtcapArgument::call();
+ connect (boolBox, SIGNAL(stateChanged(int)), SLOT(onIntChanged(int)));
- return QString(boolBox->checkState() == Qt::Checked ? _argument->call : "");
- }
+ return boolBox;
+}
- virtual QString value()
- {
- if ( boolBox == NULL || _argument->arg_type == EXTCAP_ARG_BOOLFLAG )
- return QString();
- return QString(boolBox->checkState() == Qt::Checked ? "true" : "false");
- }
+QString ExtArgBool::call()
+{
+ if ( boolBox == NULL )
+ return QString("");
- virtual QString defaultValue()
- {
- if ( _argument != 0 && _argument->default_complex != NULL )
- if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
- return QString("true");
+ if ( _argument->arg_type == EXTCAP_ARG_BOOLEAN )
+ return ExtcapArgument::call();
- return QString("false");
- }
+ return QString(boolBox->checkState() == Qt::Checked ? _argument->call : "");
+}
-private:
+QString ExtArgBool::value()
+{
+ if ( boolBox == NULL || _argument->arg_type == EXTCAP_ARG_BOOLFLAG )
+ return QString();
+ return QString(boolBox->checkState() == Qt::Checked ? "true" : "false");
+}
- QCheckBox * boolBox;
-};
+bool ExtArgBool::isValid()
+{
+ /* A bool is allways valid, but the base function checks on string length,
+ * which will fail with boolflags */
+ return true;
+}
-class ExtArgText : public ExtcapArgument
+QString ExtArgBool::defaultValue()
{
+ if ( _argument != 0 && _argument->default_complex != NULL )
+ if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
+ return QString("true");
-public:
- ExtArgText(extcap_arg * argument) :
- ExtcapArgument(argument), textBox(0)
- {
- _default = new QVariant(QString(""));
- };
+ return QString("false");
+}
- virtual QWidget * createEditor(QWidget * parent)
- {
- textBox = new QLineEdit(_default->toString(), parent);
+ExtArgText::ExtArgText(extcap_arg * argument) :
+ ExtcapArgument(argument), textBox(0)
+{
+ _default = new QVariant(QString(""));
+}
- textBox->setText(defaultValue());
+QWidget * ExtArgText::createEditor(QWidget * parent)
+{
+ textBox = new QLineEdit(_default->toString(), parent);
- if ( _argument->tooltip != NULL )
- textBox->setToolTip(QString().fromUtf8(_argument->tooltip));
+ textBox->setText(defaultValue());
- connect(textBox , SIGNAL(textChanged(QString)), SLOT(onStringChanged(QString)));
+ if ( _argument->tooltip != NULL )
+ textBox->setToolTip(QString().fromUtf8(_argument->tooltip));
- return textBox;
- }
+ connect(textBox , SIGNAL(textChanged(QString)), SLOT(onStringChanged(QString)));
- virtual QString value()
- {
- if ( textBox == 0 )
- return QString();
+ return textBox;
+}
- return textBox->text();
- }
+QString ExtArgText::value()
+{
+ if ( textBox == 0 )
+ return QString();
- virtual bool isValid()
- {
- if ( isRequired() && value().length() == 0 )
- return false;
+ return textBox->text();
+}
- return true;
- }
+bool ExtArgText::isValid()
+{
+ bool valid = true;
+
+ if ( isRequired() && value().length() == 0 )
+ valid = false;
- virtual QString defaultValue()
+ /* 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)
{
- if ( _argument != 0 && _argument->default_complex != 0)
+ QString regexp = QString().fromUtf8(_argument->regexp);
+ if ( regexp.length() > 0 )
{
- gchar * str = extcap_get_complex_as_string(_argument->default_complex);
- if ( str != 0 )
- return QString(str);
+ QRegExp expr(regexp);
+ if ( ! expr.isValid() || expr.indexIn(value(), 0) == -1 )
+ valid = false;
}
+ }
- return QString();
+ 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)
+ {
+ gchar * str = extcap_get_complex_as_string(_argument->default_complex);
+ if ( str != 0 )
+ return QString(str);
}
-protected:
+ return QString();
+}
- QLineEdit * textBox;
-};
+ExtArgNumber::ExtArgNumber(extcap_arg * argument) :
+ ExtArgText(argument) {}
-class ExtArgNumber : public ExtArgText
+QWidget * ExtArgNumber::createEditor(QWidget * parent)
{
-public:
- ExtArgNumber(extcap_arg * argument) :
- ExtArgText(argument) {};
+ textBox = (QLineEdit *)ExtArgText::createEditor(parent);
+ textBox->disconnect(SIGNAL(textChanged(QString)));
- virtual QWidget * createEditor(QWidget * parent)
+ if ( _argument->arg_type == EXTCAP_ARG_INTEGER || _argument->arg_type == EXTCAP_ARG_UNSIGNED )
{
- textBox = (QLineEdit *)ExtArgText::createEditor(parent);
- textBox->disconnect(SIGNAL(textChanged(QString)));
+ QIntValidator * textValidator = new QIntValidator(parent);
+ if ( _argument->range_start != NULL )
+ textValidator->setBottom(extcap_complex_get_int(_argument->range_start));
- if ( _argument->arg_type == EXTCAP_ARG_INTEGER || _argument->arg_type == EXTCAP_ARG_UNSIGNED )
- {
- QIntValidator * textValidator = new QIntValidator(parent);
- if ( _argument->range_start != NULL )
- textValidator->setBottom(extcap_complex_get_int(_argument->range_start));
+ if ( _argument->arg_type == EXTCAP_ARG_UNSIGNED && textValidator->bottom() < 0 )
+ textValidator->setBottom(0);
- if ( _argument->arg_type == EXTCAP_ARG_UNSIGNED && textValidator->bottom() < 0 )
- textValidator->setBottom(0);
+ if ( _argument->range_end != NULL )
+ textValidator->setTop(extcap_complex_get_int(_argument->range_end));
+ textBox->setValidator(textValidator);
+ }
+ else if ( _argument->arg_type == EXTCAP_ARG_DOUBLE )
+ {
+ QDoubleValidator * textValidator = new QDoubleValidator(parent);
+ if ( _argument->range_start != NULL )
+ textValidator->setBottom(extcap_complex_get_double(_argument->range_start));
+ if ( _argument->range_end != NULL )
+ textValidator->setTop(extcap_complex_get_double(_argument->range_end));
- if ( _argument->range_end != NULL )
- textValidator->setTop(extcap_complex_get_int(_argument->range_end));
- textBox->setValidator(textValidator);
- }
- else if ( _argument->arg_type == EXTCAP_ARG_DOUBLE )
- {
- QDoubleValidator * textValidator = new QDoubleValidator(parent);
- if ( _argument->range_start != NULL )
- textValidator->setBottom(extcap_complex_get_double(_argument->range_start));
- if ( _argument->range_end != NULL )
- textValidator->setTop(extcap_complex_get_double(_argument->range_end));
+ textBox->setValidator(textValidator);
+ }
- textBox->setValidator(textValidator);
- }
+ textBox->setText(defaultValue());
- textBox->setText(defaultValue());
+ connect(textBox, SIGNAL(textChanged(QString)), SLOT(onStringChanged(QString)));
- connect(textBox, SIGNAL(textChanged(QString)), SLOT(onStringChanged(QString)));
+ return textBox;
+}
- return textBox;
- };
+QString ExtArgNumber::defaultValue()
+{
+ QString result;
- virtual QString defaultValue()
+ if ( _argument != 0 && _argument->default_complex != NULL )
{
- QString result;
-
- if ( _argument != 0 && _argument->default_complex != NULL )
- {
- if ( _argument->arg_type == EXTCAP_ARG_DOUBLE )
- result = QString::number(extcap_complex_get_double(_argument->default_complex));
- else if ( _argument->arg_type == EXTCAP_ARG_INTEGER )
- result = QString::number(extcap_complex_get_int(_argument->default_complex));
- else if ( _argument->arg_type == EXTCAP_ARG_UNSIGNED )
- result = QString::number(extcap_complex_get_uint(_argument->default_complex));
- else if ( _argument->arg_type == EXTCAP_ARG_LONG )
- result = QString::number(extcap_complex_get_long(_argument->default_complex));
- else
- result = QString();
- }
-
- return result;
+ if ( _argument->arg_type == EXTCAP_ARG_DOUBLE )
+ result = QString::number(extcap_complex_get_double(_argument->default_complex));
+ else if ( _argument->arg_type == EXTCAP_ARG_INTEGER )
+ result = QString::number(extcap_complex_get_int(_argument->default_complex));
+ else if ( _argument->arg_type == EXTCAP_ARG_UNSIGNED )
+ result = QString::number(extcap_complex_get_uint(_argument->default_complex));
+ else if ( _argument->arg_type == EXTCAP_ARG_LONG )
+ result = QString::number(extcap_complex_get_long(_argument->default_complex));
+ else
+ result = QString();
}
-};
+ return result;
+}
ExtcapValue::~ExtcapValue() {}
@@ -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);
+ _label = new QLabel(text, parent);
+
+ _label->setProperty("isRequired", QString(isRequired() ? "true" : "false"));
+
+ _label->setStyleSheet ( label_style.arg(QString("")) );
+
if ( _argument->tooltip != 0 )
- label->setToolTip(QString().fromUtf8(_argument->tooltip));
+ _label->setToolTip(QString().fromUtf8(_argument->tooltip));
- return label;
+ 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;
}
diff --git a/ui/qt/extcap_argument.h b/ui/qt/extcap_argument.h
index 9287628a7c..017a163378 100644
--- a/ui/qt/extcap_argument.h
+++ b/ui/qt/extcap_argument.h
@@ -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_ */
/*
diff --git a/ui/qt/extcap_argument_file.cpp b/ui/qt/extcap_argument_file.cpp
index f0115ceda4..b93e889ef6 100644
--- a/ui/qt/extcap_argument_file.cpp
+++ b/ui/qt/extcap_argument_file.cpp
@@ -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;
}
/*
diff --git a/ui/qt/extcap_argument_multiselect.cpp b/ui/qt/extcap_argument_multiselect.cpp
index b99a75379d..fc01dfb351 100644
--- a/ui/qt/extcap_argument_multiselect.cpp
+++ b/ui/qt/extcap_argument_multiselect.cpp
@@ -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
diff --git a/ui/qt/extcap_argument_multiselect.h b/ui/qt/extcap_argument_multiselect.h
index 9b9dcd6480..9e72faeca2 100644
--- a/ui/qt/extcap_argument_multiselect.h
+++ b/ui/qt/extcap_argument_multiselect.h
@@ -41,6 +41,7 @@ public:
virtual QString value();
virtual QString defaultValue();
+ virtual bool isValid();
protected:
virtual QList<QStandardItem *> valueWalker(ExtcapValueList list, QStringList &defaults);
diff --git a/ui/qt/extcap_options_dialog.cpp b/ui/qt/extcap_options_dialog.cpp
index 229c5e5843..e2b5c165ca 100644
--- a/ui/qt/extcap_options_dialog.cpp
+++ b/ui/qt/extcap_options_dialog.cpp
@@ -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,18 +126,55 @@ 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() )
- allowStart = false;
+ /* 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;
}
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowStart);
@@ -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);
- }
+ }
+ item = item->next;
+ }
+ walker = walker->next;
+ }
- if ( argument->isRequired() && ! argument->isValid() )
- allowStart = false;
+ if ( required.length() > 0 )
+ extcapArguments << required;
- connect(argument, SIGNAL(valueChanged()), this, SLOT(anyValueChanged()));
+ if ( optional.length() > 0 )
+ extcapArguments << optional;
- counter++;
- }
+ 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);
}
- item = item->next;
+ if ( (*iter)->isRequired() && ! (*iter)->isValid() )
+ allowStart = false;
+
+ connect((*iter), SIGNAL(valueChanged()), this, SLOT(anyValueChanged()));
+
+ counter++;
}
- walker = walker->next;
+ ++iter;
}
if ( counter > 0 )
{
+ setStyleSheet ( "QLabel[isRequired=\"true\"] { font-weight: bold; } ");
+
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowStart);
ui->verticalLayout->addLayout(layout);
diff --git a/ui/qt/interface_tree.cpp b/ui/qt/interface_tree.cpp
index a506e13376..5d4839c80f 100644
--- a/ui/qt/interface_tree.cpp
+++ b/ui/qt/interface_tree.cpp
@@ -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));
diff --git a/ui/qt/main_welcome.cpp b/ui/qt/main_welcome.cpp
index 521c2aa6a9..667fbf582a 100644
--- a/ui/qt/main_welcome.cpp
+++ b/ui/qt/main_welcome.cpp
@@ -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();
}
}