forked from osmocom/wireshark
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:
parent
a7e3ba03ce
commit
cfd5457ec0
|
@ -74,9 +74,10 @@ def extcap_config(interface):
|
||||||
values = []
|
values = []
|
||||||
|
|
||||||
args.append ( (0, '--delay', 'Time delay', 'Time delay between packages', 'integer', '{range=1,15}') )
|
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 ( (2, '--verify', 'Verify', 'Verify package content', 'boolflag', '') )
|
||||||
args.append ( (3, '--remote', 'Remote Channel', 'Remote Channel Selector', 'selector', ''))
|
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, "if1", "Remote1", "true" ) )
|
||||||
values.append ( (3, "if2", "Remote2", "false" ) )
|
values.append ( (3, "if2", "Remote2", "false" ) )
|
||||||
|
@ -140,7 +141,7 @@ def ip_checksum(iph):
|
||||||
csum = csum & 0xFFFF ^ 0xFFFF
|
csum = csum & 0xFFFF ^ 0xFFFF
|
||||||
return csum
|
return csum
|
||||||
|
|
||||||
def pcap_fake_package ( message ):
|
def pcap_fake_package ( message, fake_ip ):
|
||||||
|
|
||||||
pcap = bytearray()
|
pcap = bytearray()
|
||||||
#length = 14 bytes [ eth ] + 20 bytes [ ip ] + messagelength
|
#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', int ( '40', 16) ))
|
||||||
pcap = append_bytes(pcap, struct.pack('B', 0xFE )) # Protocol (2 = unspecified)
|
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('<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, struct.pack('>L', int ( '7F000001', 16) )) # Dest IP
|
||||||
|
|
||||||
pcap = append_bytes(pcap, message)
|
pcap = append_bytes(pcap, message)
|
||||||
return pcap
|
return pcap
|
||||||
|
|
||||||
def extcap_capture(interface, fifo, delay, verify, message, remote):
|
def extcap_capture(interface, fifo, delay, verify, message, remote, fake_ip):
|
||||||
global doExit
|
global doExit
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, signalHandler)
|
signal.signal(signal.SIGINT, signalHandler)
|
||||||
|
@ -198,7 +202,7 @@ def extcap_capture(interface, fifo, delay, verify, message, remote):
|
||||||
while doExit == False:
|
while doExit == False:
|
||||||
out = str( "%s|%04X%s|%s" % ( remote.strip(), len(message), message, verify ) )
|
out = str( "%s|%04X%s|%s" % ( remote.strip(), len(message), message, verify ) )
|
||||||
try:
|
try:
|
||||||
fh.write (pcap_fake_package(out))
|
fh.write (pcap_fake_package(out, fake_ip))
|
||||||
time.sleep(tdelay)
|
time.sleep(tdelay)
|
||||||
except IOError:
|
except IOError:
|
||||||
doExit = True
|
doExit = True
|
||||||
|
@ -216,6 +220,7 @@ if __name__ == '__main__':
|
||||||
# Capture options
|
# Capture options
|
||||||
delay = 0
|
delay = 0
|
||||||
message = ""
|
message = ""
|
||||||
|
fake_ip = ""
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
prog="Extcap Example",
|
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("--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("--remote", help="Demonstrates a selector choice", default="if1", choices=["if1", "if2"] )
|
||||||
parser.add_argument("--message", help="Demonstrates string variable", nargs='?', default="" )
|
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()
|
args, unknown = parser.parse_known_args()
|
||||||
if ( len(sys.argv) <= 1 ):
|
if ( len(sys.argv) <= 1 ):
|
||||||
|
@ -260,6 +266,10 @@ if __name__ == '__main__':
|
||||||
if ( args.message == None or len(args.message) == 0 ):
|
if ( args.message == None or len(args.message) == 0 ):
|
||||||
message = "Extcap Test"
|
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:
|
if args.extcap_config:
|
||||||
extcap_config(interface)
|
extcap_config(interface)
|
||||||
elif args.extcap_dlts:
|
elif args.extcap_dlts:
|
||||||
|
@ -267,7 +277,7 @@ if __name__ == '__main__':
|
||||||
elif args.capture:
|
elif args.capture:
|
||||||
if args.fifo is None:
|
if args.fifo is None:
|
||||||
sys.exit(ERROR_FIFO)
|
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:
|
else:
|
||||||
usage()
|
usage()
|
||||||
sys.exit(ERROR_USAGE)
|
sys.exit(ERROR_USAGE)
|
||||||
|
|
10
extcap.c
10
extcap.c
|
@ -440,7 +440,7 @@ extcap_get_if_configuration(const char * ifname) {
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
extcap_has_configuration(const char * ifname) {
|
extcap_has_configuration(const char * ifname, gboolean is_required) {
|
||||||
GList * arguments = 0;
|
GList * arguments = 0;
|
||||||
GList * walker = 0, * item = 0;
|
GList * walker = 0, * item = 0;
|
||||||
|
|
||||||
|
@ -455,7 +455,11 @@ extcap_has_configuration(const char * ifname) {
|
||||||
while ( item != NULL && ! found )
|
while ( item != NULL && ! found )
|
||||||
{
|
{
|
||||||
if ( (extcap_arg *)(item->data) != NULL )
|
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;
|
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 )
|
for ( walker = g_list_first ( arg_iter->value_list ); walker; walker = walker->next )
|
||||||
{
|
{
|
||||||
v = (extcap_value *)walker->data;
|
v = (extcap_value *)walker->data;
|
||||||
if (v->is_default == TRUE)
|
if (v->is_default)
|
||||||
printf("*");
|
printf("*");
|
||||||
printf("\tcall=\"%p\" display=\"%p\"\n", v->call, v->display);
|
printf("\tcall=\"%p\" display=\"%p\"\n", v->call, v->display);
|
||||||
printf("\tcall=\"%s\" display=\"%s\"\n", v->call, v->display);
|
printf("\tcall=\"%s\" display=\"%s\"\n", v->call, v->display);
|
||||||
|
|
2
extcap.h
2
extcap.h
|
@ -67,7 +67,7 @@ GList *
|
||||||
extcap_get_if_configuration(const char * ifname);
|
extcap_get_if_configuration(const char * ifname);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
extcap_has_configuration(const char * ifname);
|
extcap_has_configuration(const char * ifname, gboolean is_required);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
HANDLE
|
HANDLE
|
||||||
|
|
|
@ -300,6 +300,21 @@ extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) {
|
||||||
return NULL ;
|
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) {
|
if ((eq = g_strstr_len(b, -1, "=")) == NULL) {
|
||||||
/* printf("debug - tokenizer - invalid, missing =\n"); */
|
/* printf("debug - tokenizer - invalid, missing =\n"); */
|
||||||
extcap_free_tokenized_sentence(rs);
|
extcap_free_tokenized_sentence(rs);
|
||||||
|
@ -349,6 +364,8 @@ extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) {
|
||||||
tv->param_type = EXTCAP_PARAM_PARENT;
|
tv->param_type = EXTCAP_PARAM_PARENT;
|
||||||
} else if (g_ascii_strcasecmp(tv->arg, "required") == 0) {
|
} else if (g_ascii_strcasecmp(tv->arg, "required") == 0) {
|
||||||
tv->param_type = EXTCAP_PARAM_REQUIRED;
|
tv->param_type = EXTCAP_PARAM_REQUIRED;
|
||||||
|
} else if (g_ascii_strcasecmp(tv->arg, "validation") == 0) {
|
||||||
|
tv->param_type = EXTCAP_PARAM_VALIDATION;
|
||||||
} else {
|
} else {
|
||||||
tv->param_type = EXTCAP_PARAM_UNKNOWN;
|
tv->param_type = EXTCAP_PARAM_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
@ -480,6 +497,7 @@ extcap_arg *extcap_new_arg(void) {
|
||||||
r->default_complex = NULL;
|
r->default_complex = NULL;
|
||||||
r->fileexists = FALSE;
|
r->fileexists = FALSE;
|
||||||
r->fileextension = NULL;
|
r->fileextension = NULL;
|
||||||
|
r->regexp = NULL;
|
||||||
r->is_required = FALSE;
|
r->is_required = FALSE;
|
||||||
|
|
||||||
r->values = NULL;
|
r->values = NULL;
|
||||||
|
@ -509,6 +527,9 @@ void extcap_free_arg(extcap_arg *a) {
|
||||||
if (a->fileextension != NULL)
|
if (a->fileextension != NULL)
|
||||||
g_free(a->fileextension);
|
g_free(a->fileextension);
|
||||||
|
|
||||||
|
if (a->regexp != NULL)
|
||||||
|
g_free(a->regexp);
|
||||||
|
|
||||||
if (a->range_start != NULL)
|
if (a->range_start != NULL)
|
||||||
extcap_free_complex(a->range_start);
|
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);
|
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))
|
if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_REQUIRED))
|
||||||
!= NULL) {
|
!= NULL) {
|
||||||
target_arg->is_required = (v->value[0] == 't' || v->value[0] == 'T');
|
target_arg->is_required = (v->value[0] == 't' || v->value[0] == 'T');
|
||||||
|
|
|
@ -69,7 +69,8 @@ typedef enum {
|
||||||
EXTCAP_PARAM_FILE_MUSTEXIST,
|
EXTCAP_PARAM_FILE_MUSTEXIST,
|
||||||
EXTCAP_PARAM_FILE_EXTENSION,
|
EXTCAP_PARAM_FILE_EXTENSION,
|
||||||
EXTCAP_PARAM_PARENT,
|
EXTCAP_PARAM_PARENT,
|
||||||
EXTCAP_PARAM_REQUIRED
|
EXTCAP_PARAM_REQUIRED,
|
||||||
|
EXTCAP_PARAM_VALIDATION
|
||||||
} extcap_param_type;
|
} extcap_param_type;
|
||||||
|
|
||||||
/* Values for a given sentence; values are all stored as a call
|
/* Values for a given sentence; values are all stored as a call
|
||||||
|
@ -112,6 +113,8 @@ typedef struct _extcap_arg {
|
||||||
|
|
||||||
gboolean is_required;
|
gboolean is_required;
|
||||||
|
|
||||||
|
gchar * regexp;
|
||||||
|
|
||||||
extcap_arg_type arg_type;
|
extcap_arg_type arg_type;
|
||||||
|
|
||||||
extcap_complex *range_start;
|
extcap_complex *range_start;
|
||||||
|
|
|
@ -40,338 +40,364 @@
|
||||||
#include <QStandardItem>
|
#include <QStandardItem>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QItemSelectionModel>
|
#include <QItemSelectionModel>
|
||||||
#include <QTreeView>
|
|
||||||
|
#include <epan/prefs.h>
|
||||||
|
#include <color_utils.h>
|
||||||
|
|
||||||
#include <extcap_parser.h>
|
#include <extcap_parser.h>
|
||||||
#include <extcap_argument_file.h>
|
#include <extcap_argument_file.h>
|
||||||
#include <extcap_argument_multiselect.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:
|
int counter = 0;
|
||||||
ExtArgSelector(extcap_arg * argument) :
|
int selected = -1;
|
||||||
ExtcapArgument(argument), boxSelection(0) {};
|
|
||||||
|
|
||||||
virtual QWidget * createEditor(QWidget * parent)
|
boxSelection = new QComboBox(parent);
|
||||||
|
|
||||||
|
if ( values.length() > 0 )
|
||||||
{
|
{
|
||||||
int counter = 0;
|
ExtcapValueList::const_iterator iter = values.constBegin();
|
||||||
int selected = -1;
|
|
||||||
|
|
||||||
boxSelection = new QComboBox(parent);
|
while ( iter != values.constEnd() )
|
||||||
|
|
||||||
if ( values.length() > 0 )
|
|
||||||
{
|
{
|
||||||
ExtcapValueList::const_iterator iter = values.constBegin();
|
boxSelection->addItem((*iter).value(), (*iter).call());
|
||||||
|
if ( (*iter).isDefault() )
|
||||||
|
selected = counter;
|
||||||
|
|
||||||
while ( iter != values.constEnd() )
|
counter++;
|
||||||
{
|
++iter;
|
||||||
boxSelection->addItem((*iter).value(), (*iter).call());
|
|
||||||
if ( (*iter).isDefault() )
|
|
||||||
selected = counter;
|
|
||||||
|
|
||||||
counter++;
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( selected > -1 && selected < boxSelection->count() )
|
|
||||||
boxSelection->setCurrentIndex(selected);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connect ( boxSelection, SIGNAL(currentIndexChanged(int)), SLOT(onIntChanged(int)) );
|
if ( selected > -1 && selected < boxSelection->count() )
|
||||||
|
boxSelection->setCurrentIndex(selected);
|
||||||
return boxSelection;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual QString value()
|
connect ( boxSelection, SIGNAL(currentIndexChanged(int)), SLOT(onIntChanged(int)) );
|
||||||
{
|
|
||||||
if ( boxSelection == 0 )
|
return boxSelection;
|
||||||
return QString();
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
|
||||||
QVariant data = boxSelection->currentData();
|
QVariant data = boxSelection->currentData();
|
||||||
#else
|
#else
|
||||||
QVariant data = boxSelection->itemData(boxSelection->currentIndex());
|
QVariant data = boxSelection->itemData(boxSelection->currentIndex());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return data.toString();
|
return data.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
ExtArgRadio::ExtArgRadio(extcap_arg * argument) :
|
||||||
|
ExtcapArgument(argument), selectorGroup(0), callStrings(0) {}
|
||||||
|
|
||||||
QComboBox * boxSelection;
|
QWidget * ExtArgRadio::createEditor(QWidget * parent)
|
||||||
};
|
|
||||||
|
|
||||||
class ExtArgRadio : public ExtcapArgument
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
ExtArgRadio(extcap_arg * argument) :
|
int count = 0;
|
||||||
ExtcapArgument(argument), selectorGroup(0), callStrings(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;
|
||||||
|
|
||||||
|
callStrings = new QList<QString>();
|
||||||
|
|
||||||
|
if ( values.length() > 0 )
|
||||||
{
|
{
|
||||||
};
|
ExtcapValueList::const_iterator iter = values.constBegin();
|
||||||
|
|
||||||
virtual QWidget * createEditor(QWidget * parent)
|
while ( iter != values.constEnd() )
|
||||||
{
|
{
|
||||||
|
QRadioButton * radio = new QRadioButton((*iter).value());
|
||||||
|
QString callString = (*iter).call();
|
||||||
|
callStrings->append(callString);
|
||||||
|
|
||||||
int count = 0;
|
if ( _default != NULL && (*iter).isDefault() )
|
||||||
bool anyChecked = false;
|
{
|
||||||
|
radio->setChecked(true);
|
||||||
selectorGroup = new QButtonGroup(parent);
|
anyChecked = true;
|
||||||
QWidget * radioButtons = new QWidget;
|
}
|
||||||
QVBoxLayout * vrLayout = new QVBoxLayout();
|
else if (_default != NULL)
|
||||||
QMargins margins = vrLayout->contentsMargins();
|
{
|
||||||
vrLayout->setContentsMargins(0, 0, 0, margins.bottom());
|
if ( callString.compare(_default->toString()) == 0 )
|
||||||
if ( callStrings != 0 )
|
|
||||||
delete callStrings;
|
|
||||||
|
|
||||||
callStrings = new QList<QString>();
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if ( _default != NULL && (*iter).isDefault() )
|
|
||||||
{
|
{
|
||||||
radio->setChecked(true);
|
radio->setChecked(true);
|
||||||
anyChecked = 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
|
||||||
|
|
||||||
radioButtons->setLayout(vrLayout);
|
|
||||||
|
|
||||||
return radioButtons;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual QString value()
|
/* No default was provided, and not saved value exists */
|
||||||
|
if ( anyChecked == false && count > 0 )
|
||||||
|
((QRadioButton*)(selectorGroup->button(0)))->setChecked(true);
|
||||||
|
|
||||||
|
radioButtons->setLayout(vrLayout);
|
||||||
|
|
||||||
|
return radioButtons;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ExtArgRadio::value()
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
if ( selectorGroup == 0 || callStrings == 0 )
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
idx = selectorGroup->checkedId();
|
||||||
|
if ( idx > -1 && callStrings->length() > idx )
|
||||||
|
return callStrings->takeAt(idx);
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExtArgRadio::isValid()
|
||||||
|
{
|
||||||
|
bool valid = true;
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
if ( isRequired() )
|
||||||
{
|
{
|
||||||
int idx = 0;
|
|
||||||
if ( selectorGroup == 0 || callStrings == 0 )
|
if ( selectorGroup == 0 || callStrings == 0 )
|
||||||
return QString();
|
valid = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idx = selectorGroup->checkedId();
|
||||||
|
if ( idx == -1 || callStrings->length() <= idx )
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
idx = selectorGroup->checkedId();
|
/* If nothing is selected, but a selection is required, the only thing that
|
||||||
if ( idx > -1 && callStrings->length() > idx )
|
* can be marked is the label */
|
||||||
return callStrings->takeAt(idx);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if ( _default != NULL )
|
||||||
|
{
|
||||||
|
if ( _default->toString().compare("true") )
|
||||||
|
boolBox->setCheckState(Qt::Checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect (boolBox, SIGNAL(stateChanged(int)), SLOT(onIntChanged(int)));
|
||||||
|
|
||||||
|
return boolBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ExtArgBool::call()
|
||||||
|
{
|
||||||
|
if ( boolBox == NULL )
|
||||||
|
return QString("");
|
||||||
|
|
||||||
|
if ( _argument->arg_type == EXTCAP_ARG_BOOLEAN )
|
||||||
|
return ExtcapArgument::call();
|
||||||
|
|
||||||
|
return QString(boolBox->checkState() == Qt::Checked ? _argument->call : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ExtArgBool::value()
|
||||||
|
{
|
||||||
|
if ( boolBox == NULL || _argument->arg_type == EXTCAP_ARG_BOOLFLAG )
|
||||||
return QString();
|
return QString();
|
||||||
}
|
return QString(boolBox->checkState() == Qt::Checked ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
bool ExtArgBool::isValid()
|
||||||
|
|
||||||
QButtonGroup * selectorGroup;
|
|
||||||
QList<QString> * callStrings;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExtArgBool : public ExtcapArgument
|
|
||||||
{
|
{
|
||||||
public:
|
/* A bool is allways valid, but the base function checks on string length,
|
||||||
ExtArgBool(extcap_arg * argument) :
|
* which will fail with boolflags */
|
||||||
ExtcapArgument(argument), boolBox(0) {};
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
virtual QWidget * createLabel(QWidget * parent)
|
QString ExtArgBool::defaultValue()
|
||||||
{
|
|
||||||
return new QWidget(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual QWidget * 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);
|
|
||||||
|
|
||||||
if ( _default != NULL )
|
|
||||||
{
|
|
||||||
if ( _default->toString().compare("true") )
|
|
||||||
boolBox->setCheckState(Qt::Checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect (boolBox, SIGNAL(stateChanged(int)), SLOT(onIntChanged(int)));
|
|
||||||
|
|
||||||
return boolBox;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual QString call()
|
|
||||||
{
|
|
||||||
if ( boolBox == NULL )
|
|
||||||
return QString("");
|
|
||||||
|
|
||||||
if ( _argument->arg_type == EXTCAP_ARG_BOOLEAN )
|
|
||||||
return ExtcapArgument::call();
|
|
||||||
|
|
||||||
return QString(boolBox->checkState() == Qt::Checked ? _argument->call : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual QString value()
|
|
||||||
{
|
|
||||||
if ( boolBox == NULL || _argument->arg_type == EXTCAP_ARG_BOOLFLAG )
|
|
||||||
return QString();
|
|
||||||
return QString(boolBox->checkState() == Qt::Checked ? "true" : "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual QString defaultValue()
|
|
||||||
{
|
|
||||||
if ( _argument != 0 && _argument->default_complex != NULL )
|
|
||||||
if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
|
|
||||||
return QString("true");
|
|
||||||
|
|
||||||
return QString("false");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
QCheckBox * boolBox;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExtArgText : public ExtcapArgument
|
|
||||||
{
|
{
|
||||||
|
if ( _argument != 0 && _argument->default_complex != NULL )
|
||||||
|
if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
|
||||||
|
return QString("true");
|
||||||
|
|
||||||
public:
|
return QString("false");
|
||||||
ExtArgText(extcap_arg * argument) :
|
}
|
||||||
ExtcapArgument(argument), textBox(0)
|
|
||||||
{
|
|
||||||
_default = new QVariant(QString(""));
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual QWidget * createEditor(QWidget * parent)
|
ExtArgText::ExtArgText(extcap_arg * argument) :
|
||||||
{
|
ExtcapArgument(argument), textBox(0)
|
||||||
textBox = new QLineEdit(_default->toString(), parent);
|
{
|
||||||
|
_default = new QVariant(QString(""));
|
||||||
|
}
|
||||||
|
|
||||||
textBox->setText(defaultValue());
|
QWidget * ExtArgText::createEditor(QWidget * parent)
|
||||||
|
{
|
||||||
|
textBox = new QLineEdit(_default->toString(), parent);
|
||||||
|
|
||||||
if ( _argument->tooltip != NULL )
|
textBox->setText(defaultValue());
|
||||||
textBox->setToolTip(QString().fromUtf8(_argument->tooltip));
|
|
||||||
|
|
||||||
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()
|
return textBox;
|
||||||
{
|
}
|
||||||
if ( textBox == 0 )
|
|
||||||
return QString();
|
|
||||||
|
|
||||||
return textBox->text();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool isValid()
|
|
||||||
{
|
|
||||||
if ( isRequired() && value().length() == 0 )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual QString defaultValue()
|
|
||||||
{
|
|
||||||
if ( _argument != 0 && _argument->default_complex != 0)
|
|
||||||
{
|
|
||||||
gchar * str = extcap_get_complex_as_string(_argument->default_complex);
|
|
||||||
if ( str != 0 )
|
|
||||||
return QString(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
QString ExtArgText::value()
|
||||||
|
{
|
||||||
|
if ( textBox == 0 )
|
||||||
return QString();
|
return QString();
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
return textBox->text();
|
||||||
|
}
|
||||||
|
|
||||||
QLineEdit * textBox;
|
bool ExtArgText::isValid()
|
||||||
};
|
|
||||||
|
|
||||||
class ExtArgNumber : public ExtArgText
|
|
||||||
{
|
{
|
||||||
public:
|
bool valid = true;
|
||||||
ExtArgNumber(extcap_arg * argument) :
|
|
||||||
ExtArgText(argument) {};
|
|
||||||
|
|
||||||
virtual QWidget * createEditor(QWidget * parent)
|
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)
|
||||||
{
|
{
|
||||||
textBox = (QLineEdit *)ExtArgText::createEditor(parent);
|
QString regexp = QString().fromUtf8(_argument->regexp);
|
||||||
textBox->disconnect(SIGNAL(textChanged(QString)));
|
if ( regexp.length() > 0 )
|
||||||
|
|
||||||
if ( _argument->arg_type == EXTCAP_ARG_INTEGER || _argument->arg_type == EXTCAP_ARG_UNSIGNED )
|
|
||||||
{
|
{
|
||||||
QIntValidator * textValidator = new QIntValidator(parent);
|
QRegExp expr(regexp);
|
||||||
if ( _argument->range_start != NULL )
|
if ( ! expr.isValid() || expr.indexIn(value(), 0) == -1 )
|
||||||
textValidator->setBottom(extcap_complex_get_int(_argument->range_start));
|
valid = false;
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
textBox->setValidator(textValidator);
|
|
||||||
}
|
|
||||||
|
|
||||||
textBox->setText(defaultValue());
|
|
||||||
|
|
||||||
connect(textBox, SIGNAL(textChanged(QString)), SLOT(onStringChanged(QString)));
|
|
||||||
|
|
||||||
return textBox;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual QString defaultValue()
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtArgNumber::ExtArgNumber(extcap_arg * argument) :
|
||||||
|
ExtArgText(argument) {}
|
||||||
|
|
||||||
|
QWidget * ExtArgNumber::createEditor(QWidget * parent)
|
||||||
|
{
|
||||||
|
textBox = (QLineEdit *)ExtArgText::createEditor(parent);
|
||||||
|
textBox->disconnect(SIGNAL(textChanged(QString)));
|
||||||
|
|
||||||
|
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->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->setText(defaultValue());
|
||||||
|
|
||||||
|
connect(textBox, SIGNAL(textChanged(QString)), SLOT(onStringChanged(QString)));
|
||||||
|
|
||||||
|
return textBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ExtArgNumber::defaultValue()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
ExtcapValue::~ExtcapValue() {}
|
ExtcapValue::~ExtcapValue() {}
|
||||||
|
|
||||||
|
@ -388,7 +414,8 @@ void ExtcapValue::setChildren(ExtcapValueList children)
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtcapArgument::ExtcapArgument(extcap_arg * argument, QObject *parent) :
|
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 )
|
if ( _argument->values != 0 )
|
||||||
{
|
{
|
||||||
|
@ -441,13 +468,20 @@ QWidget * ExtcapArgument::createLabel(QWidget * parent)
|
||||||
if ( _argument == 0 || _argument->display == 0 )
|
if ( _argument == 0 || _argument->display == 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
|
||||||
|
|
||||||
QString text = QString().fromUtf8(_argument->display);
|
QString text = QString().fromUtf8(_argument->display);
|
||||||
|
|
||||||
QLabel * label = new QLabel(text, parent);
|
_label = new QLabel(text, parent);
|
||||||
if ( _argument->tooltip != 0 )
|
|
||||||
label->setToolTip(QString().fromUtf8(_argument->tooltip));
|
|
||||||
|
|
||||||
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 *)
|
QWidget * ExtcapArgument::createEditor(QWidget *)
|
||||||
|
@ -468,6 +502,11 @@ QString ExtcapArgument::value()
|
||||||
|
|
||||||
bool ExtcapArgument::isValid()
|
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;
|
return value().length() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,16 @@
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QButtonGroup>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
#include <extcap_parser.h>
|
#include <extcap_parser.h>
|
||||||
|
|
||||||
|
#define EXTCAP_GUI_BLANK_LABEL "QLabel { color : ; }"
|
||||||
|
#define EXTCAP_GUI_ERROR_LABEL "QLabel { color : red; }"
|
||||||
|
|
||||||
class ExtcapValue;
|
class ExtcapValue;
|
||||||
|
|
||||||
typedef QList<ExtcapValue> ExtcapValueList;
|
typedef QList<ExtcapValue> ExtcapValueList;
|
||||||
|
@ -108,6 +115,9 @@ protected:
|
||||||
|
|
||||||
extcap_arg * _argument;
|
extcap_arg * _argument;
|
||||||
QVariant * _default;
|
QVariant * _default;
|
||||||
|
QWidget * _label;
|
||||||
|
|
||||||
|
const QString label_style;
|
||||||
|
|
||||||
private Q_SLOTS:
|
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_ */
|
#endif /* UI_QT_EXTCAP_ARGUMENT_H_ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -35,8 +35,10 @@
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
#include <extcap_parser.h>
|
#include <epan/prefs.h>
|
||||||
|
#include <color_utils.h>
|
||||||
|
|
||||||
|
#include <extcap_parser.h>
|
||||||
|
|
||||||
ExtcapArgumentFileSelection::ExtcapArgumentFileSelection (extcap_arg * argument) :
|
ExtcapArgumentFileSelection::ExtcapArgumentFileSelection (extcap_arg * argument) :
|
||||||
ExtcapArgument(argument), textBox(0)
|
ExtcapArgument(argument), textBox(0)
|
||||||
|
@ -118,9 +120,16 @@ void ExtcapArgumentFileSelection::openFileDialog()
|
||||||
|
|
||||||
bool ExtcapArgumentFileSelection::isValid()
|
bool ExtcapArgumentFileSelection::isValid()
|
||||||
{
|
{
|
||||||
if ( textBox->text().length() > 0 )
|
bool valid = false;
|
||||||
return true;
|
|
||||||
return 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -32,11 +32,14 @@
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
|
#include <epan/prefs.h>
|
||||||
|
#include <color_utils.h>
|
||||||
|
|
||||||
#include <extcap_parser.h>
|
#include <extcap_parser.h>
|
||||||
#include <extcap_argument_multiselect.h>
|
#include <extcap_argument_multiselect.h>
|
||||||
|
|
||||||
ExtArgMultiSelect::ExtArgMultiSelect(extcap_arg * argument) :
|
ExtArgMultiSelect::ExtArgMultiSelect(extcap_arg * argument) :
|
||||||
ExtcapArgument(argument), treeView(0), viewModel(0) {};
|
ExtcapArgument(argument), treeView(0), viewModel(0) {}
|
||||||
|
|
||||||
ExtArgMultiSelect::~ExtArgMultiSelect()
|
ExtArgMultiSelect::~ExtArgMultiSelect()
|
||||||
{
|
{
|
||||||
|
@ -187,6 +190,31 @@ void ExtArgMultiSelect::selectionChanged(const QItemSelection &, const QItemSele
|
||||||
emit valueChanged();
|
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
|
* Editor modelines
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
|
|
||||||
virtual QString value();
|
virtual QString value();
|
||||||
virtual QString defaultValue();
|
virtual QString defaultValue();
|
||||||
|
virtual bool isValid();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QList<QStandardItem *> valueWalker(ExtcapValueList list, QStringList &defaults);
|
virtual QList<QStandardItem *> valueWalker(ExtcapValueList list, QStringList &defaults);
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
|
|
||||||
#include <ui/qt/extcap_argument.h>
|
#include <ui/qt/extcap_argument.h>
|
||||||
#include <ui/qt/extcap_argument_file.h>
|
#include <ui/qt/extcap_argument_file.h>
|
||||||
|
#include <ui/qt/extcap_argument_multiselect.h>
|
||||||
|
|
||||||
ExtcapOptionsDialog::ExtcapOptionsDialog(QWidget *parent) :
|
ExtcapOptionsDialog::ExtcapOptionsDialog(QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
|
@ -104,6 +105,9 @@ ExtcapOptionsDialog * ExtcapOptionsDialog::createForDevice(QString &dev_name, QW
|
||||||
|
|
||||||
resultDialog->updateWidgets();
|
resultDialog->updateWidgets();
|
||||||
|
|
||||||
|
/* mark required fields */
|
||||||
|
resultDialog->anyValueChanged();
|
||||||
|
|
||||||
return resultDialog;
|
return resultDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,18 +126,55 @@ void ExtcapOptionsDialog::on_buttonBox_accepted()
|
||||||
|
|
||||||
void ExtcapOptionsDialog::anyValueChanged()
|
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;
|
bool allowStart = true;
|
||||||
|
|
||||||
ExtcapArgumentList::const_iterator iter;
|
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
|
||||||
allowStart = false;
|
* 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);
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowStart);
|
||||||
|
@ -156,6 +197,9 @@ void ExtcapOptionsDialog::updateWidgets()
|
||||||
|
|
||||||
QGridLayout * layout = new QGridLayout();
|
QGridLayout * layout = new QGridLayout();
|
||||||
|
|
||||||
|
ExtcapArgumentList required;
|
||||||
|
ExtcapArgumentList optional;
|
||||||
|
|
||||||
while ( walker != NULL )
|
while ( walker != NULL )
|
||||||
{
|
{
|
||||||
item = g_list_first((GList *)(walker->data));
|
item = g_list_first((GList *)(walker->data));
|
||||||
|
@ -164,34 +208,50 @@ void ExtcapOptionsDialog::updateWidgets()
|
||||||
argument = ExtcapArgument::create((extcap_arg *)(item->data), device_defaults);
|
argument = ExtcapArgument::create((extcap_arg *)(item->data), device_defaults);
|
||||||
if ( argument != NULL )
|
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;
|
item = item->next;
|
||||||
}
|
}
|
||||||
walker = walker->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 )
|
if ( counter > 0 )
|
||||||
{
|
{
|
||||||
|
setStyleSheet ( "QLabel[isRequired=\"true\"] { font-weight: bold; } ");
|
||||||
|
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowStart);
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowStart);
|
||||||
|
|
||||||
ui->verticalLayout->addLayout(layout);
|
ui->verticalLayout->addLayout(layout);
|
||||||
|
|
|
@ -189,7 +189,7 @@ void InterfaceTree::display()
|
||||||
#if HAVE_EXTCAP
|
#if HAVE_EXTCAP
|
||||||
if ( device.if_info.type == IF_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->setIcon(IFTREE_COL_EXTCAP, extcap_icon);
|
||||||
ti->setData(IFTREE_COL_EXTCAP, Qt::UserRole, QString(device.if_info.extcap));
|
ti->setData(IFTREE_COL_EXTCAP, Qt::UserRole, QString(device.if_info.extcap));
|
||||||
|
|
|
@ -53,6 +53,10 @@
|
||||||
#define VERSION_FLAVOR ""
|
#define VERSION_FLAVOR ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_EXTCAP
|
||||||
|
#include <extcap.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
MainWelcome::MainWelcome(QWidget *parent) :
|
MainWelcome::MainWelcome(QWidget *parent) :
|
||||||
QFrame(parent),
|
QFrame(parent),
|
||||||
welcome_ui_(new Ui::MainWelcome),
|
welcome_ui_(new Ui::MainWelcome),
|
||||||
|
@ -230,6 +234,19 @@ void MainWelcome::appInitialized()
|
||||||
void MainWelcome::interfaceDoubleClicked(QTreeWidgetItem *item, int)
|
void MainWelcome::interfaceDoubleClicked(QTreeWidgetItem *item, int)
|
||||||
{
|
{
|
||||||
if (item) {
|
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();
|
emit startCapture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue