extcap: Reload values on request

Allow certaing elements to be reloaded upon request. The way
this works is, certain elements can be configured to be reloadable.

By doing so, the extcap is asked once more just for the values
list of this item, together with all already set options, and
reloads the available options depending on the response.

Only supported for selector. Radio and Multiselect will need
additional patches, also moving those parts outside of extcap_argument.cpp
might make sense before hand.

Change-Id: I2e9e3d109b334bf878835a7cc9354f468bc22dee
Reviewed-on: https://code.wireshark.org/review/26223
Petri-Dish: Roland Knall <rknall@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Roland Knall <rknall@gmail.com>
This commit is contained in:
Roland Knall 2018-03-02 15:41:00 +01:00 committed by Roland Knall
parent c2422d7828
commit 6124ee2a1c
13 changed files with 419 additions and 106 deletions

View File

@ -108,14 +108,14 @@ This method prints the extcap configuration, which will be picked up by the
interface in Wireshark to present a interface specific configuration for interface in Wireshark to present a interface specific configuration for
this extcap plugin this extcap plugin
""" """
def extcap_config(interface): def extcap_config(interface, option):
args = [] args = []
values = [] values = []
args.append ( (0, '--delay', 'Time delay', 'Time delay between packages', 'integer', '{range=1,15}{default=5}') ) args.append ( (0, '--delay', 'Time delay', 'Time delay between packages', 'integer', '{range=1,15}{default=5}') )
args.append ( (1, '--message', 'Message', 'Package message content', 'string', '{required=true}{placeholder=Please enter a message here ...}') ) args.append ( (1, '--message', 'Message', 'Package message content', 'string', '{required=true}{placeholder=Please enter a message here ...}') )
args.append ( (2, '--verify', 'Verify', 'Verify package content', 'boolflag', '{default=yes}') ) args.append ( (2, '--verify', 'Verify', 'Verify package content', 'boolflag', '{default=yes}') )
args.append ( (3, '--remote', 'Remote Channel', 'Remote Channel Selector', 'selector', '')) args.append ( (3, '--remote', 'Remote Channel', 'Remote Channel Selector', 'selector', '{reload=true}{placeholder=Load interfaces ...}'))
args.append ( (4, '--fake_ip', 'Fake IP Address', 'Use this ip address as sender', 'string', '{save=false}{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}')) args.append ( (4, '--fake_ip', 'Fake IP Address', 'Use this ip address as sender', 'string', '{save=false}{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}'))
args.append ( (5, '--ltest', 'Long Test', 'Long Test Value', 'long', '{default=123123123123123123}')) args.append ( (5, '--ltest', 'Long Test', 'Long Test Value', 'long', '{default=123123123123123123}'))
args.append ( (6, '--d1test', 'Double 1 Test', 'Long Test Value', 'double', '{default=123.456}')) args.append ( (6, '--d1test', 'Double 1 Test', 'Long Test Value', 'double', '{default=123.456}'))
@ -126,17 +126,30 @@ def extcap_config(interface):
args.append ( (11, '--radio', 'Radio Test', 'Radio Test Value', 'radio', '') ) args.append ( (11, '--radio', 'Radio Test', 'Radio Test Value', 'radio', '') )
args.append ( (12, '--multi', 'MultiCheck Test', 'MultiCheck Test Value', 'multicheck', '') ) args.append ( (12, '--multi', 'MultiCheck Test', 'MultiCheck Test Value', 'multicheck', '') )
values.append ( (3, "if1", "Remote1", "true" ) ) if ( option == "remote" ):
values.append ( (3, "if2", "Remote2", "false" ) ) values.append ( (3, "if1", "Remote Interface 1", "false" ) )
values.append ( (3, "if2", "Remote Interface 2", "true" ) )
values.append ( (3, "if3", "Remote Interface 3", "false" ) )
values.append ( (3, "if4", "Remote Interface 4", "false" ) )
values.append ( (11, "r1", "Radio1", "false" ) ) if ( option == "radio" ):
values.append ( (11, "r2", "Radio2", "true" ) ) values.append ( (11, "r1", "Radio Option 1", "false" ) )
values.append ( (11, "r2", "Radio Option 2", "false" ) )
values.append ( (11, "r3", "Radio Option 3", "true" ) )
values.append ( (12, "m1", "MultiCheck1", "false" ) )
values.append ( (12, "m2", "MultiCheck2", "false" ) )
for arg in args: if ( len(option) <= 0 ):
print ("arg {number=%d}{call=%s}{display=%s}{tooltip=%s}{type=%s}%s" % arg) for arg in args:
print ("arg {number=%d}{call=%s}{display=%s}{tooltip=%s}{type=%s}%s" % arg)
values.append ( (3, "if1", "Remote1", "true" ) )
values.append ( (3, "if2", "Remote2", "false" ) )
values.append ( (11, "r1", "Radio1", "false" ) )
values.append ( (11, "r2", "Radio2", "true" ) )
values.append ( (12, "m1", "MultiCheck1", "false" ) )
values.append ( (12, "m2", "MultiCheck2", "false" ) )
for value in values: for value in values:
print ("value {arg=%d}{value=%s}{display=%s}{default=%s}" % value) print ("value {arg=%d}{value=%s}{display=%s}{default=%s}" % value)
@ -385,6 +398,7 @@ def usage():
if __name__ == '__main__': if __name__ == '__main__':
interface = "" interface = ""
option = ""
# Capture options # Capture options
delay = 0 delay = 0
@ -408,11 +422,12 @@ if __name__ == '__main__':
parser.add_argument("--extcap-control-in", help="Used to get control messages from toolbar") parser.add_argument("--extcap-control-in", help="Used to get control messages from toolbar")
parser.add_argument("--extcap-control-out", help="Used to send control messages to toolbar") parser.add_argument("--extcap-control-out", help="Used to send control messages to toolbar")
parser.add_argument("--extcap-version", help="Shows the version of this utility", action="store_true") parser.add_argument("--extcap-version", help="Shows the version of this utility", action="store_true")
parser.add_argument("--extcap-reload-option", help="Reload elements for the given option")
# Interface Arguments # Interface Arguments
parser.add_argument("--verify", help="Demonstrates a verification bool flag", action="store_true" ) parser.add_argument("--verify", help="Demonstrates a verification bool flag", action="store_true" )
parser.add_argument("--delay", help="Demonstrates an integer variable", type=int, default=0, choices=[0, 1, 2, 3, 4, 5, 6] ) parser.add_argument("--delay", help="Demonstrates an integer variable", type=int, default=0, choices=[0, 1, 2, 3, 4, 5, 6] )
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", "if3", "if4"] )
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" ) parser.add_argument("--fake_ip", help="Add a fake sender IP adress", nargs='?', default="127.0.0.1" )
parser.add_argument("--ts", help="Capture start time", action="store_true" ) parser.add_argument("--ts", help="Capture start time", action="store_true" )
@ -467,8 +482,11 @@ if __name__ == '__main__':
ts = args.ts ts = args.ts
if ( args.extcap_reload_option and len(args.extcap_reload_option) > 0 ):
option = args.extcap_reload_option
if args.extcap_config: if args.extcap_config:
extcap_config(interface) extcap_config(interface, option)
elif args.extcap_dlts: elif args.extcap_dlts:
extcap_dlts(interface) extcap_dlts(interface)
elif args.capture: elif args.capture:

View File

@ -807,6 +807,69 @@ extcap_get_if_configuration(const char *ifname)
return ret; return ret;
} }
static gboolean cb_reload_preference(extcap_callback_info_t cb_info)
{
GList *arguments = NULL, * walker = NULL;
GList **il = (GList **) cb_info.data;
arguments = extcap_parse_values(cb_info.output);
walker = g_list_first((GList *)(arguments));
while (walker != NULL)
{
extcap_value * val = (extcap_value *)walker->data;
*il = g_list_append(*il, val);
walker = g_list_next(walker);
}
g_list_free(arguments);
/* By returning false, extcap_foreach will break on first found */
return FALSE;
}
GList *
extcap_get_if_configuration_values(const char * ifname, const char * argname, GHashTable *arguments)
{
GList * args = NULL;
GList *ret = NULL;
gchar **err_str = NULL;
if (extcap_if_exists(ifname))
{
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Extcap path %s",
get_extcap_dir());
args = g_list_append(args, g_strdup(EXTCAP_ARGUMENT_CONFIG) );
args = g_list_append(args, g_strdup(EXTCAP_ARGUMENT_INTERFACE) );
args = g_list_append(args, g_strdup(ifname) );
args = g_list_append(args, g_strdup(EXTCAP_ARGUMENT_RELOAD_OPTION) );
args = g_list_append(args, g_strdup(argname) );
if ( arguments )
{
GList * keys = g_hash_table_get_keys(arguments);
while ( keys )
{
const gchar * key_data = (const gchar *)keys->data;
args = g_list_append(args, g_strdup(key_data) );
args = g_list_append(args, g_strdup((const gchar *)g_hash_table_lookup(arguments, key_data)) );
keys = g_list_next(keys);
}
}
extcap_callback_info_t cb_info;
cb_info.data = &ret;
cb_info.err_str = err_str;
cb_info.ifname = ifname;
extcap_foreach(args, cb_reload_preference, cb_info);
g_list_free_full(args, g_free);
}
return ret;
}
/** /**
* If is_required is FALSE: returns TRUE if the extcap interface has * If is_required is FALSE: returns TRUE if the extcap interface has
* configurable options. * configurable options.

View File

@ -32,6 +32,7 @@
#define EXTCAP_CONTROL_OUT_PREFIX "wireshark_control_ws_to_ext" #define EXTCAP_CONTROL_OUT_PREFIX "wireshark_control_ws_to_ext"
#define EXTCAP_ARGUMENT_CONFIG "--extcap-config" #define EXTCAP_ARGUMENT_CONFIG "--extcap-config"
#define EXTCAP_ARGUMENT_RELOAD_OPTION "--extcap-reload-option"
#define EXTCAP_ARGUMENT_LIST_INTERFACES "--extcap-interfaces" #define EXTCAP_ARGUMENT_LIST_INTERFACES "--extcap-interfaces"
#define EXTCAP_ARGUMENT_INTERFACE "--extcap-interface" #define EXTCAP_ARGUMENT_INTERFACE "--extcap-interface"
#define EXTCAP_ARGUMENT_LIST_DLTS "--extcap-dlts" #define EXTCAP_ARGUMENT_LIST_DLTS "--extcap-dlts"
@ -99,10 +100,20 @@ void
extcap_clear_interfaces(void); extcap_clear_interfaces(void);
/* returns the configuration for the given interface name, or an /* returns the configuration for the given interface name, or an
* empty list, if no configuration has been found */ * empty list, if no configuration has been found
* @param ifname the interface name
*/
GList * GList *
extcap_get_if_configuration(const char * ifname); extcap_get_if_configuration(const char * ifname);
/* returns the configuration values for the given argument, or an
* empty list, if no values could been found
* @param ifname the interface name
* @param argname the name of the argument, for which the values should be retrieved
*/
GList *
extcap_get_if_configuration_values(const char * ifname, const char * argname, GHashTable * arguments);
/** /**
* Check if the capture filter for the given interface name is valid. * Check if the capture filter for the given interface name is valid.
* @param ifname Interface to check * @param ifname Interface to check

View File

@ -175,6 +175,8 @@ static extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) {
param_type = EXTCAP_PARAM_ENABLED; param_type = EXTCAP_PARAM_ENABLED;
} else if (g_ascii_strcasecmp(arg, "parent") == 0) { } else if (g_ascii_strcasecmp(arg, "parent") == 0) {
param_type = EXTCAP_PARAM_PARENT; param_type = EXTCAP_PARAM_PARENT;
} else if (g_ascii_strcasecmp(arg, "reload") == 0) {
param_type = EXTCAP_PARAM_RELOAD;
} else if (g_ascii_strcasecmp(arg, "required") == 0) { } else if (g_ascii_strcasecmp(arg, "required") == 0) {
param_type = EXTCAP_PARAM_REQUIRED; param_type = EXTCAP_PARAM_REQUIRED;
} else if (g_ascii_strcasecmp(arg, "save") == 0) { } else if (g_ascii_strcasecmp(arg, "save") == 0) {
@ -321,13 +323,74 @@ static void extcap_free_tokenized_sentences(GList *sentences) {
g_list_free(sentences); g_list_free(sentences);
} }
static extcap_value *extcap_parse_value_sentence(extcap_token_sentence *s) {
extcap_value *value = NULL;
gchar *param_value = NULL;
int tint = 0;
if (s == NULL)
return value;
if (g_ascii_strcasecmp(s->sentence, "value") == 0) {
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_ARG)))
== NULL) {
printf("no arg in VALUE sentence\n");
return NULL;
}
if (sscanf(param_value, "%d", &tint) != 1) {
printf("invalid arg in VALUE sentence\n");
return NULL;
}
value = g_new0(extcap_value, 1);
value->arg_num = tint;
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_VALUE)))
== NULL) {
/* printf("no value in VALUE sentence\n"); */
extcap_free_value(value);
return NULL;
}
value->call = g_strdup(param_value);
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_DISPLAY)))
== NULL) {
/* printf("no display in VALUE sentence\n"); */
extcap_free_value(value);
return NULL;
}
value->display = g_strdup(param_value);
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_PARENT)))
!= NULL) {
value->parent = g_strdup(param_value);
}
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_DEFAULT)))
!= NULL) {
/* printf("found default value\n"); */
value->is_default = g_regex_match_simple(EXTCAP_BOOLEAN_REGEX, param_value, G_REGEX_CASELESS, (GRegexMatchFlags)0);
}
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_ENABLED)))
!= NULL) {
value->enabled = g_regex_match_simple(EXTCAP_BOOLEAN_REGEX, param_value, G_REGEX_CASELESS, (GRegexMatchFlags)0);
}
}
return value;
}
static extcap_arg *extcap_parse_arg_sentence(GList *args, extcap_token_sentence *s) { static extcap_arg *extcap_parse_arg_sentence(GList *args, extcap_token_sentence *s) {
gchar *param_value = NULL; gchar *param_value = NULL;
extcap_arg *target_arg = NULL; extcap_arg *target_arg = NULL;
extcap_value *value = NULL; extcap_value *value = NULL;
GList *entry = NULL; GList *entry = NULL;
int tint;
extcap_sentence_type sent = EXTCAP_SENTENCE_UNKNOWN; extcap_sentence_type sent = EXTCAP_SENTENCE_UNKNOWN;
if (s == NULL) if (s == NULL)
@ -451,6 +514,11 @@ static extcap_arg *extcap_parse_arg_sentence(GList *args, extcap_token_sentence
target_arg->save = g_regex_match_simple(EXTCAP_BOOLEAN_REGEX, param_value, G_REGEX_CASELESS, (GRegexMatchFlags)0); target_arg->save = g_regex_match_simple(EXTCAP_BOOLEAN_REGEX, param_value, G_REGEX_CASELESS, (GRegexMatchFlags)0);
} }
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_RELOAD)))
!= NULL) {
target_arg->reload = g_regex_match_simple(EXTCAP_BOOLEAN_REGEX, param_value, G_REGEX_CASELESS, (GRegexMatchFlags)0);
}
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_RANGE))) if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_RANGE)))
!= NULL) { != NULL) {
gchar *cp = g_strstr_len(param_value, -1, ","); gchar *cp = g_strstr_len(param_value, -1, ",");
@ -491,58 +559,14 @@ static extcap_arg *extcap_parse_arg_sentence(GList *args, extcap_token_sentence
} }
} else if (sent == EXTCAP_SENTENCE_VALUE) { } else if (sent == EXTCAP_SENTENCE_VALUE) {
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_ARG))) value = extcap_parse_value_sentence(s);
if ((entry = g_list_find_custom(args, &value->arg_num, glist_find_numbered_arg))
== NULL) { == NULL) {
printf("no arg in VALUE sentence\n"); printf("couldn't find arg %d in list for VALUE sentence\n", value->arg_num);
return NULL; return NULL;
} }
if (sscanf(param_value, "%d", &tint) != 1) {
printf("invalid arg in VALUE sentence\n");
return NULL;
}
if ((entry = g_list_find_custom(args, &tint, glist_find_numbered_arg))
== NULL) {
printf("couldn't find arg %d in list for VALUE sentence\n", tint);
return NULL;
}
value = g_new0(extcap_value, 1);
value->arg_num = tint;
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_VALUE)))
== NULL) {
/* printf("no value in VALUE sentence\n"); */
extcap_free_value(value);
return NULL;
}
value->call = g_strdup(param_value);
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_DISPLAY)))
== NULL) {
/* printf("no display in VALUE sentence\n"); */
extcap_free_value(value);
return NULL;
}
value->display = g_strdup(param_value);
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_PARENT)))
!= NULL) {
value->parent = g_strdup(param_value);
}
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_DEFAULT)))
!= NULL) {
/* printf("found default value\n"); */
value->is_default = g_regex_match_simple(EXTCAP_BOOLEAN_REGEX, param_value, G_REGEX_CASELESS, (GRegexMatchFlags)0);
}
if ((param_value = (gchar *)g_hash_table_lookup(s->param_list, ENUM_KEY(EXTCAP_PARAM_ENABLED)))
!= NULL) {
value->enabled = g_regex_match_simple(EXTCAP_BOOLEAN_REGEX, param_value, G_REGEX_CASELESS, (GRegexMatchFlags)0);
}
((extcap_arg *) entry->data)->values = g_list_append( ((extcap_arg *) entry->data)->values = g_list_append(
((extcap_arg *) entry->data)->values, value); ((extcap_arg *) entry->data)->values, value);
@ -575,6 +599,29 @@ GList *extcap_parse_args(gchar *output) {
return result; return result;
} }
GList *extcap_parse_values(gchar *output) {
GList *result = NULL;
GList *walker = NULL;
GList *temp = NULL;
walker = extcap_tokenize_sentences(output);
temp = walker;
while (walker) {
extcap_value *ra = NULL;
extcap_token_sentence *sentence = (extcap_token_sentence *)walker->data;
if ((ra = extcap_parse_value_sentence(sentence)) != NULL)
result = g_list_append(result, (gpointer) ra);
walker = g_list_next(walker);
}
extcap_free_tokenized_sentences(temp);
return result;
}
static extcap_interface *extcap_parse_interface_sentence(extcap_token_sentence *s) { static extcap_interface *extcap_parse_interface_sentence(extcap_token_sentence *s) {
extcap_sentence_type sent = EXTCAP_SENTENCE_UNKNOWN; extcap_sentence_type sent = EXTCAP_SENTENCE_UNKNOWN;
gchar *param_value = NULL; gchar *param_value = NULL;

View File

@ -64,6 +64,7 @@ typedef enum {
EXTCAP_PARAM_FILE_EXTENSION, EXTCAP_PARAM_FILE_EXTENSION,
EXTCAP_PARAM_PARENT, EXTCAP_PARAM_PARENT,
EXTCAP_PARAM_REQUIRED, EXTCAP_PARAM_REQUIRED,
EXTCAP_PARAM_RELOAD,
EXTCAP_PARAM_SAVE, EXTCAP_PARAM_SAVE,
EXTCAP_PARAM_VALIDATION, EXTCAP_PARAM_VALIDATION,
EXTCAP_PARAM_VERSION, EXTCAP_PARAM_VERSION,
@ -108,6 +109,8 @@ typedef struct _extcap_arg {
gboolean is_required; gboolean is_required;
gboolean save; gboolean save;
gboolean reload;
gchar * regexp; gchar * regexp;
extcap_arg_type arg_type; extcap_arg_type arg_type;
@ -187,6 +190,9 @@ void extcap_free_arg_list(GList *a);
/* Parse all sentences for args and values */ /* Parse all sentences for args and values */
GList * extcap_parse_args(gchar *output); GList * extcap_parse_args(gchar *output);
/* Parse all sentences for values */
GList * extcap_parse_values(gchar *output);
/* Parse all sentences for interfaces */ /* Parse all sentences for interfaces */
GList * extcap_parse_interfaces(gchar *output, GList **control_items); GList * extcap_parse_interfaces(gchar *output, GList **control_items);

View File

@ -42,8 +42,10 @@
#include <extcap_argument_file.h> #include <extcap_argument_file.h>
#include <extcap_argument_multiselect.h> #include <extcap_argument_multiselect.h>
ExtArgTimestamp::ExtArgTimestamp(extcap_arg * argument) : #include <ui/qt/extcap_options_dialog.h>
ExtcapArgument(argument) {}
ExtArgTimestamp::ExtArgTimestamp(extcap_arg * argument, QObject * parent) :
ExtcapArgument(argument, parent) {}
QWidget * ExtArgTimestamp::createEditor(QWidget * parent) QWidget * ExtArgTimestamp::createEditor(QWidget * parent)
{ {
@ -102,8 +104,8 @@ QString ExtArgTimestamp::prefValue()
return value(); return value();
} }
ExtArgSelector::ExtArgSelector(extcap_arg * argument) : ExtArgSelector::ExtArgSelector(extcap_arg * argument, QObject * parent) :
ExtcapArgument(argument), boxSelection(0) {} ExtcapArgument(argument, parent), boxSelection(0) {}
QWidget * ExtArgSelector::createEditor(QWidget * parent) QWidget * ExtArgSelector::createEditor(QWidget * parent)
{ {
@ -112,7 +114,11 @@ QWidget * ExtArgSelector::createEditor(QWidget * parent)
const char *prefval = _argument->pref_valptr ? *_argument->pref_valptr : NULL; const char *prefval = _argument->pref_valptr ? *_argument->pref_valptr : NULL;
QString stored(prefval ? prefval : ""); QString stored(prefval ? prefval : "");
QWidget * editor = new QWidget(parent);
QHBoxLayout * layout = new QHBoxLayout();
boxSelection = new QComboBox(parent); boxSelection = new QComboBox(parent);
layout->addWidget(boxSelection);
if ( values.length() > 0 ) if ( values.length() > 0 )
{ {
@ -135,9 +141,64 @@ QWidget * ExtArgSelector::createEditor(QWidget * parent)
boxSelection->setCurrentIndex(selected); boxSelection->setCurrentIndex(selected);
} }
if ( reload() )
{
QString btnText(tr("Reload data"));
if ( _argument->placeholder )
btnText = QString(_argument->placeholder);
QPushButton * reloadButton = new QPushButton(btnText, editor);
layout->addWidget(reloadButton);
reloadButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
boxSelection->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
connect(reloadButton, SIGNAL(clicked()), this, SLOT(onReloadTriggered()));
}
connect ( boxSelection, SIGNAL(currentIndexChanged(int)), SLOT(onIntChanged(int)) ); connect ( boxSelection, SIGNAL(currentIndexChanged(int)), SLOT(onIntChanged(int)) );
return boxSelection; editor->setLayout(layout);
return editor;
}
void ExtArgSelector::onReloadTriggered()
{
int counter = 0;
int selected = -1;
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
QString call = boxSelection->currentData().toString();
#else
QString call = boxSelection->itemData(boxSelection->currentIndex()).toString();
#endif
const char *prefval = _argument->pref_valptr ? *_argument->pref_valptr : NULL;
QString stored(prefval ? prefval : "");
if ( call != stored )
stored = call;
if ( reloadValues() && values.length() > 0 )
{
boxSelection->clear();
ExtcapValueList::const_iterator iter = values.constBegin();
while ( iter != values.constEnd() )
{
boxSelection->addItem((*iter).value(), (*iter).call());
if ( stored.compare((*iter).call()) == 0 )
selected = counter;
else if ( (*iter).isDefault() && selected == -1 )
selected = counter;
counter++;
++iter;
}
if ( selected > -1 && selected < boxSelection->count() )
boxSelection->setCurrentIndex(selected);
}
} }
bool ExtArgSelector::isValid() bool ExtArgSelector::isValid()
@ -147,9 +208,12 @@ bool ExtArgSelector::isValid()
if ( value().length() == 0 && isRequired() ) if ( value().length() == 0 && isRequired() )
valid = false; valid = false;
QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name(); if ( boxSelection )
QString cmbBoxStyle("QComboBox { background-color: %1; } "); {
boxSelection->setStyleSheet( cmbBoxStyle.arg(valid ? QString("") : lblInvalidColor) ); QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
QString cmbBoxStyle("QComboBox { background-color: %1; } ");
boxSelection->setStyleSheet( cmbBoxStyle.arg(valid ? QString("") : lblInvalidColor) );
}
return valid; return valid;
} }
@ -168,8 +232,8 @@ QString ExtArgSelector::value()
return data.toString(); return data.toString();
} }
ExtArgRadio::ExtArgRadio(extcap_arg * argument) : ExtArgRadio::ExtArgRadio(extcap_arg * argument, QObject * parent) :
ExtcapArgument(argument), selectorGroup(0), callStrings(0) {} ExtcapArgument(argument, parent), selectorGroup(0), callStrings(0) {}
QWidget * ExtArgRadio::createEditor(QWidget * parent) QWidget * ExtArgRadio::createEditor(QWidget * parent)
{ {
@ -260,8 +324,8 @@ bool ExtArgRadio::isValid()
return valid; return valid;
} }
ExtArgBool::ExtArgBool(extcap_arg * argument) : ExtArgBool::ExtArgBool(extcap_arg * argument, QObject * parent) :
ExtcapArgument(argument), boolBox(0) {} ExtcapArgument(argument, parent), boolBox(0) {}
QWidget * ExtArgBool::createLabel(QWidget * parent) QWidget * ExtArgBool::createLabel(QWidget * parent)
{ {
@ -343,8 +407,8 @@ QString ExtArgBool::defaultValue()
return defaultBool() ? QString("true") : QString("false"); return defaultBool() ? QString("true") : QString("false");
} }
ExtArgText::ExtArgText(extcap_arg * argument) : ExtArgText::ExtArgText(extcap_arg * argument, QObject * parent) :
ExtcapArgument(argument), textBox(0) ExtcapArgument(argument, parent), textBox(0)
{ {
} }
@ -411,8 +475,8 @@ bool ExtArgText::isValid()
return valid; return valid;
} }
ExtArgNumber::ExtArgNumber(extcap_arg * argument) : ExtArgNumber::ExtArgNumber(extcap_arg * argument, QObject * parent) :
ExtArgText(argument) {} ExtArgText(argument, parent) {}
QWidget * ExtArgNumber::createEditor(QWidget * parent) QWidget * ExtArgNumber::createEditor(QWidget * parent)
{ {
@ -600,6 +664,25 @@ ExtcapValueList ExtcapArgument::loadValues(QString parent)
return elements; return elements;
} }
bool ExtcapArgument::reloadValues()
{
if ( ! qobject_cast<ExtcapOptionsDialog*> ( parent() ) )
return false;
ExtcapOptionsDialog * dialog = qobject_cast<ExtcapOptionsDialog*>(parent());
ExtcapValueList list = dialog->loadValuesFor(_argument->arg_num, _argument->call);
if ( list.size() > 0 )
{
values.clear();
values << list;
return true;
}
return false;
}
ExtcapArgument::~ExtcapArgument() { ExtcapArgument::~ExtcapArgument() {
} }
@ -698,6 +781,14 @@ bool ExtcapArgument::isRequired()
return FALSE; return FALSE;
} }
bool ExtcapArgument::reload()
{
if ( _argument != NULL )
return _argument->reload;
return false;
}
bool ExtcapArgument::fileExists() bool ExtcapArgument::fileExists()
{ {
if ( _argument != NULL ) if ( _argument != NULL )
@ -714,7 +805,7 @@ bool ExtcapArgument::isDefault()
return false; return false;
} }
ExtcapArgument * ExtcapArgument::create(extcap_arg * argument) ExtcapArgument * ExtcapArgument::create(extcap_arg * argument, QObject *parent)
{ {
if ( argument == 0 || argument->display == 0 ) if ( argument == 0 || argument->display == 0 )
return 0; return 0;
@ -722,26 +813,26 @@ ExtcapArgument * ExtcapArgument::create(extcap_arg * argument)
ExtcapArgument * result = 0; ExtcapArgument * result = 0;
if ( argument->arg_type == EXTCAP_ARG_STRING || argument->arg_type == EXTCAP_ARG_PASSWORD ) if ( argument->arg_type == EXTCAP_ARG_STRING || argument->arg_type == EXTCAP_ARG_PASSWORD )
result = new ExtArgText(argument); result = new ExtArgText(argument, parent);
else if ( argument->arg_type == EXTCAP_ARG_INTEGER || argument->arg_type == EXTCAP_ARG_LONG || else if ( argument->arg_type == EXTCAP_ARG_INTEGER || argument->arg_type == EXTCAP_ARG_LONG ||
argument->arg_type == EXTCAP_ARG_UNSIGNED || argument->arg_type == EXTCAP_ARG_DOUBLE ) argument->arg_type == EXTCAP_ARG_UNSIGNED || argument->arg_type == EXTCAP_ARG_DOUBLE )
result = new ExtArgNumber(argument); result = new ExtArgNumber(argument, parent);
else if ( argument->arg_type == EXTCAP_ARG_BOOLEAN || argument->arg_type == EXTCAP_ARG_BOOLFLAG ) else if ( argument->arg_type == EXTCAP_ARG_BOOLEAN || argument->arg_type == EXTCAP_ARG_BOOLFLAG )
result = new ExtArgBool(argument); result = new ExtArgBool(argument, parent);
else if ( argument->arg_type == EXTCAP_ARG_SELECTOR ) else if ( argument->arg_type == EXTCAP_ARG_SELECTOR )
result = new ExtArgSelector(argument); result = new ExtArgSelector(argument, parent);
else if ( argument->arg_type == EXTCAP_ARG_RADIO ) else if ( argument->arg_type == EXTCAP_ARG_RADIO )
result = new ExtArgRadio(argument); result = new ExtArgRadio(argument, parent);
else if ( argument->arg_type == EXTCAP_ARG_FILESELECT ) else if ( argument->arg_type == EXTCAP_ARG_FILESELECT )
result = new ExtcapArgumentFileSelection(argument); result = new ExtcapArgumentFileSelection(argument, parent);
else if ( argument->arg_type == EXTCAP_ARG_MULTICHECK ) else if ( argument->arg_type == EXTCAP_ARG_MULTICHECK )
result = new ExtArgMultiSelect(argument); result = new ExtArgMultiSelect(argument, parent);
else if ( argument->arg_type == EXTCAP_ARG_TIMESTAMP ) else if ( argument->arg_type == EXTCAP_ARG_TIMESTAMP )
result = new ExtArgTimestamp(argument); result = new ExtArgTimestamp(argument, parent);
else else
{ {
/* For everything else, we just print the label */ /* For everything else, we just print the label */
result = new ExtcapArgument(argument); result = new ExtcapArgument(argument, parent);
} }
return result; return result;

View File

@ -70,8 +70,8 @@ class ExtcapArgument: public QObject
Q_OBJECT Q_OBJECT
public: public:
ExtcapArgument(QObject *parent=0); ExtcapArgument(QObject *parent = Q_NULLPTR);
ExtcapArgument(extcap_arg * argument, QObject *parent=0); ExtcapArgument(extcap_arg * argument, QObject *parent = Q_NULLPTR);
ExtcapArgument(const ExtcapArgument &obj); ExtcapArgument(const ExtcapArgument &obj);
virtual ~ExtcapArgument(); virtual ~ExtcapArgument();
@ -86,13 +86,14 @@ public:
bool isDefault(); bool isDefault();
virtual bool isValid(); virtual bool isValid();
bool isRequired(); bool isRequired();
bool reload();
QString prefKey(const QString & device_name); QString prefKey(const QString & device_name);
virtual QString prefValue(); virtual QString prefValue();
void resetValue(); void resetValue();
static ExtcapArgument * create(extcap_arg * argument = 0); static ExtcapArgument * create(extcap_arg * argument = Q_NULLPTR, QObject * parent = Q_NULLPTR);
Q_SIGNALS: Q_SIGNALS:
void valueChanged(); void valueChanged();
@ -102,6 +103,7 @@ protected:
bool fileExists(); bool fileExists();
ExtcapValueList loadValues(QString parent); ExtcapValueList loadValues(QString parent);
bool reloadValues();
ExtcapValueList values; ExtcapValueList values;
@ -122,7 +124,7 @@ class ExtArgText : public ExtcapArgument
{ {
public: public:
ExtArgText(extcap_arg * argument); ExtArgText(extcap_arg * argument, QObject *parent = Q_NULLPTR);
virtual QWidget * createEditor(QWidget * parent); virtual QWidget * createEditor(QWidget * parent);
virtual QString value(); virtual QString value();
@ -136,7 +138,7 @@ protected:
class ExtArgNumber : public ExtArgText class ExtArgNumber : public ExtArgText
{ {
public: public:
ExtArgNumber(extcap_arg * argument); ExtArgNumber(extcap_arg * argument, QObject *parent = Q_NULLPTR);
virtual QWidget * createEditor(QWidget * parent); virtual QWidget * createEditor(QWidget * parent);
virtual QString defaultValue(); virtual QString defaultValue();
@ -144,8 +146,10 @@ public:
class ExtArgSelector : public ExtcapArgument class ExtArgSelector : public ExtcapArgument
{ {
Q_OBJECT
public: public:
ExtArgSelector(extcap_arg * argument); ExtArgSelector(extcap_arg * argument, QObject *parent = Q_NULLPTR);
virtual QWidget * createEditor(QWidget * parent); virtual QWidget * createEditor(QWidget * parent);
virtual QString value(); virtual QString value();
@ -154,12 +158,16 @@ public:
private: private:
QComboBox * boxSelection; QComboBox * boxSelection;
private Q_SLOTS:
void onReloadTriggered();
}; };
class ExtArgRadio : public ExtcapArgument class ExtArgRadio : public ExtcapArgument
{ {
public: public:
ExtArgRadio(extcap_arg * argument); ExtArgRadio(extcap_arg * argument, QObject *parent = Q_NULLPTR);
virtual QWidget * createEditor(QWidget * parent); virtual QWidget * createEditor(QWidget * parent);
virtual QString value(); virtual QString value();
@ -174,7 +182,7 @@ private:
class ExtArgBool : public ExtcapArgument class ExtArgBool : public ExtcapArgument
{ {
public: public:
ExtArgBool(extcap_arg * argument); ExtArgBool(extcap_arg * argument, QObject *parent = Q_NULLPTR);
virtual QWidget * createLabel(QWidget * parent); virtual QWidget * createLabel(QWidget * parent);
virtual QWidget * createEditor(QWidget * parent); virtual QWidget * createEditor(QWidget * parent);
@ -197,7 +205,7 @@ class ExtArgTimestamp : public ExtcapArgument
Q_OBJECT Q_OBJECT
public: public:
ExtArgTimestamp(extcap_arg * argument); ExtArgTimestamp(extcap_arg * argument, QObject *parent = Q_NULLPTR);
virtual QWidget * createEditor(QWidget * parent); virtual QWidget * createEditor(QWidget * parent);
virtual bool isValid(); virtual bool isValid();

View File

@ -29,8 +29,8 @@
#include <extcap_parser.h> #include <extcap_parser.h>
ExtcapArgumentFileSelection::ExtcapArgumentFileSelection (extcap_arg * argument) : ExtcapArgumentFileSelection::ExtcapArgumentFileSelection (extcap_arg * argument, QObject *parent) :
ExtcapArgument(argument), textBox(0) ExtcapArgument(argument, parent), textBox(0)
{ {
} }

View File

@ -21,7 +21,7 @@ class ExtcapArgumentFileSelection : public ExtcapArgument
Q_OBJECT Q_OBJECT
public: public:
ExtcapArgumentFileSelection(extcap_arg * argument); ExtcapArgumentFileSelection(extcap_arg * argument, QObject * parent = Q_NULLPTR);
virtual ~ExtcapArgumentFileSelection(); virtual ~ExtcapArgumentFileSelection();
virtual QWidget * createEditor(QWidget * parent); virtual QWidget * createEditor(QWidget * parent);

View File

@ -25,8 +25,8 @@
#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, QObject *parent) :
ExtcapArgument(argument), treeView(0), viewModel(0) {} ExtcapArgument(argument, parent), treeView(0), viewModel(0) {}
ExtArgMultiSelect::~ExtArgMultiSelect() ExtArgMultiSelect::~ExtArgMultiSelect()
{ {

View File

@ -23,7 +23,7 @@ class ExtArgMultiSelect : public ExtcapArgument
{ {
Q_OBJECT Q_OBJECT
public: public:
ExtArgMultiSelect(extcap_arg * argument); ExtArgMultiSelect(extcap_arg * argument, QObject *parent = Q_NULLPTR);
virtual ~ExtArgMultiSelect(); virtual ~ExtArgMultiSelect();
virtual QString value(); virtual QString value();

View File

@ -205,7 +205,7 @@ void ExtcapOptionsDialog::loadArguments()
item = g_list_first((GList *)(walker->data)); item = g_list_first((GList *)(walker->data));
while ( item != NULL ) while ( item != NULL )
{ {
argument = ExtcapArgument::create((extcap_arg *)(item->data)); argument = ExtcapArgument::create((extcap_arg *)(item->data), this);
if ( argument != NULL ) if ( argument != NULL )
{ {
if ( argument->isRequired() ) if ( argument->isRequired() )
@ -253,7 +253,6 @@ void ExtcapOptionsDialog::updateWidgets()
/* Load all extcap arguments */ /* Load all extcap arguments */
loadArguments(); loadArguments();
ExtcapArgumentList::iterator iter = extcapArguments.begin(); ExtcapArgumentList::iterator iter = extcapArguments.begin();
while ( iter != extcapArguments.end() ) while ( iter != extcapArguments.end() )
{ {
@ -424,7 +423,7 @@ void ExtcapOptionsDialog::resetValues()
} }
} }
void ExtcapOptionsDialog::storeValues() GHashTable *ExtcapOptionsDialog::getArgumentSettings(bool useCallsAsKey)
{ {
GHashTable * entries = g_hash_table_new(g_str_hash, g_str_equal); GHashTable * entries = g_hash_table_new(g_str_hash, g_str_equal);
ExtcapArgumentList::const_iterator iter; ExtcapArgumentList::const_iterator iter;
@ -476,6 +475,9 @@ void ExtcapOptionsDialog::storeValues()
value = (*iter)->prefValue(); value = (*iter)->prefValue();
QString key = argument->prefKey(device_name); QString key = argument->prefKey(device_name);
if ( useCallsAsKey )
key = argument->call();
if (key.length() > 0) if (key.length() > 0)
{ {
gchar * val = g_strdup(value.length() == 0 ? " " : value.toStdString().c_str()); gchar * val = g_strdup(value.length() == 0 ? " " : value.toStdString().c_str());
@ -484,6 +486,13 @@ void ExtcapOptionsDialog::storeValues()
} }
} }
return entries;
}
void ExtcapOptionsDialog::storeValues()
{
GHashTable * entries = getArgumentSettings();
if ( g_hash_table_size(entries) > 0 ) if ( g_hash_table_size(entries) > 0 )
{ {
if ( prefs_store_ext_multiple("extcap", entries) ) if ( prefs_store_ext_multiple("extcap", entries) )
@ -492,6 +501,62 @@ void ExtcapOptionsDialog::storeValues()
} }
} }
ExtcapValueList ExtcapOptionsDialog::loadValuesFor(int argNum, QString argumentName, QString parent)
{
ExtcapValueList elements;
GList * walker = 0, * values = 0;
extcap_value * v;
QList<QWidget *> children = findChildren<QWidget *>();
foreach ( QWidget * child, children )
child->setEnabled(false);
QString argcall = argumentName;
if ( argcall.startsWith("--") )
argcall = argcall.right(argcall.size()-2);
GHashTable * entries = getArgumentSettings(true);
values = extcap_get_if_configuration_values(this->device_name.toStdString().c_str(), argcall.toStdString().c_str(), entries);
for (walker = g_list_first((GList *)(values)); walker != NULL ; walker = walker->next)
{
v = (extcap_value *) walker->data;
if (v == NULL || v->display == NULL || v->call == NULL )
break;
/* Only accept values for this argument */
if ( v->arg_num != argNum )
break;
QString valParent = QString().fromUtf8(v->parent);
if ( parent.compare(valParent) == 0 )
{
QString display = QString().fromUtf8(v->display);
QString call = QString().fromUtf8(v->call);
ExtcapValue element = ExtcapValue(display, call,
v->enabled == (gboolean)TRUE, v->is_default == (gboolean)TRUE);
#if 0
/* TODO: Disabled due to wrong parent handling. It leads to an infinite loop for now. To implement this properly, other things
will be needed, like new arguments for setting the parent in the call to the extcap utility*/
if (!call.isEmpty())
element.setChildren(this->loadValuesFor(argumentName, call));
#endif
elements.append(element);
}
}
foreach ( QWidget * child, children )
child->setEnabled(true);
return elements;
}
/* /*
* Editor modelines * Editor modelines
* *

View File

@ -36,6 +36,8 @@ public:
~ExtcapOptionsDialog(); ~ExtcapOptionsDialog();
static ExtcapOptionsDialog * createForDevice(QString &device_name, QWidget *parent = 0); static ExtcapOptionsDialog * createForDevice(QString &device_name, QWidget *parent = 0);
ExtcapValueList loadValuesFor(int argNum, QString call, QString parent = "");
private Q_SLOTS: private Q_SLOTS:
void on_buttonBox_accepted(); void on_buttonBox_accepted();
void on_buttonBox_rejected(); void on_buttonBox_rejected();
@ -56,8 +58,10 @@ private:
void loadArguments(); void loadArguments();
bool saveOptionToCaptureInfo(); bool saveOptionToCaptureInfo();
GHashTable * getArgumentSettings(bool useCallsAsKey = false);
void storeValues(); void storeValues();
void resetValues(); void resetValues();
}; };
#endif // EXTCAP_OPTIONS_DIALOG_H #endif // EXTCAP_OPTIONS_DIALOG_H