1 /* extcap_argument.cpp
2 *
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include <extcap_argument.h>
11
12 #include <QObject>
13 #include <QWidget>
14 #include <QLabel>
15 #include <QLineEdit>
16 #include <QDateTimeEdit>
17 #include <QIntValidator>
18 #include <QDoubleValidator>
19 #include <QCheckBox>
20 #include <QButtonGroup>
21 #include <QBoxLayout>
22 #include <QRadioButton>
23 #include <QComboBox>
24 #include <QPushButton>
25 #include <QMargins>
26 #include <QVariant>
27 #include <QAbstractItemModel>
28 #include <QStringList>
29 #include <QStandardItem>
30 #include <QStandardItemModel>
31 #include <QItemSelectionModel>
32 #include <QRegExp>
33
34 #include <glib.h>
35
36 #include <extcap.h>
37 #include <epan/prefs.h>
38 #include <epan/prefs-int.h>
39 #include <wsutil/wslog.h>
40 #include <ui/qt/utils/color_utils.h>
41
42 #include <extcap_parser.h>
43 #include <extcap_argument_file.h>
44 #include <extcap_argument_multiselect.h>
45
46 #include <ui/qt/extcap_options_dialog.h>
47
ExtArgTimestamp(extcap_arg * argument,QObject * parent)48 ExtArgTimestamp::ExtArgTimestamp(extcap_arg * argument, QObject * parent) :
49 ExtcapArgument(argument, parent) {}
50
createEditor(QWidget * parent)51 QWidget * ExtArgTimestamp::createEditor(QWidget * parent)
52 {
53 QDateTimeEdit * tsBox;
54 QString text = defaultValue();
55
56 if (_argument->pref_valptr && *_argument->pref_valptr)
57 {
58 QString storeValue(*_argument->pref_valptr);
59
60 if (storeValue.length() > 0 && storeValue.compare(text) != 0)
61 text = storeValue.trimmed();
62 }
63
64 #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
65 ts = QDateTime::fromSecsSinceEpoch(text.toInt());
66 #else
67 ts = QDateTime::fromTime_t(text.toInt());
68 #endif
69 tsBox = new QDateTimeEdit(ts, parent);
70 tsBox->setDisplayFormat(QLocale::system().dateTimeFormat());
71 tsBox->setCalendarPopup(true);
72 tsBox->setAutoFillBackground(true);
73
74 if (_argument->tooltip != NULL)
75 tsBox->setToolTip(QString().fromUtf8(_argument->tooltip));
76
77 connect(tsBox, SIGNAL(dateTimeChanged(QDateTime)), SLOT(onDateTimeChanged(QDateTime)));
78
79 return tsBox;
80 }
81
onDateTimeChanged(QDateTime t)82 void ExtArgTimestamp::onDateTimeChanged(QDateTime t)
83 {
84 ts = t;
85 emit valueChanged();
86 }
87
defaultValue()88 QString ExtArgTimestamp::defaultValue()
89 {
90 #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
91 return QString::number(QDateTime::currentDateTime().toSecsSinceEpoch());
92 #else
93 return QString::number(QDateTime::currentDateTime().toTime_t());
94 #endif
95 }
96
isValid()97 bool ExtArgTimestamp::isValid()
98 {
99 bool valid = true;
100
101 if (value().length() == 0 && isRequired())
102 valid = false;
103
104 return valid;
105 }
106
value()107 QString ExtArgTimestamp::value()
108 {
109 #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
110 return QString::number(ts.toSecsSinceEpoch());
111 #else
112 return QString::number(ts.toTime_t());
113 #endif
114 }
115
prefValue()116 QString ExtArgTimestamp::prefValue()
117 {
118 return value();
119 }
120
ExtArgSelector(extcap_arg * argument,QObject * parent)121 ExtArgSelector::ExtArgSelector(extcap_arg * argument, QObject * parent) :
122 ExtcapArgument(argument, parent), boxSelection(0) {}
123
createEditor(QWidget * parent)124 QWidget * ExtArgSelector::createEditor(QWidget * parent)
125 {
126 int counter = 0;
127 int selected = -1;
128 const char *prefval = _argument->pref_valptr ? *_argument->pref_valptr : NULL;
129 QString stored(prefval ? prefval : "");
130
131 QWidget * editor = new QWidget(parent);
132 QHBoxLayout * layout = new QHBoxLayout();
133 QMargins margins = layout->contentsMargins();
134 layout->setContentsMargins(0, margins.top(), 0, margins.bottom());
135
136 boxSelection = new QComboBox(parent);
137 layout->addWidget(boxSelection);
138
139 if (values.length() > 0)
140 {
141 ExtcapValueList::const_iterator iter = values.constBegin();
142
143 while (iter != values.constEnd())
144 {
145 boxSelection->addItem((*iter).value(), (*iter).call());
146
147 if (!prefval && (*iter).isDefault())
148 selected = counter;
149 else if (prefval && stored.compare((*iter).call()) == 0)
150 selected = counter;
151
152 counter++;
153 ++iter;
154 }
155
156 if (selected > -1 && selected < boxSelection->count())
157 boxSelection->setCurrentIndex(selected);
158 }
159
160 if (reload())
161 {
162 QString btnText(tr("Reload data"));
163 if (_argument->placeholder)
164 btnText = QString(_argument->placeholder);
165
166 QPushButton * reloadButton = new QPushButton(btnText, editor);
167 layout->addWidget(reloadButton);
168 reloadButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
169 boxSelection->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
170
171 connect(reloadButton, SIGNAL(clicked()), this, SLOT(onReloadTriggered()));
172 }
173
174 connect (boxSelection, SIGNAL(currentIndexChanged(int)), SLOT(onIntChanged(int)));
175
176 editor->setLayout(layout);
177
178 return editor;
179 }
180
onReloadTriggered()181 void ExtArgSelector::onReloadTriggered()
182 {
183 int counter = 0;
184 int selected = -1;
185
186 QString call = boxSelection->currentData().toString();
187 const char *prefval = _argument->pref_valptr ? *_argument->pref_valptr : NULL;
188 QString stored(prefval ? prefval : "");
189 if (call != stored)
190 stored = call;
191
192 if (reloadValues() && values.length() > 0)
193 {
194 boxSelection->clear();
195
196 ExtcapValueList::const_iterator iter = values.constBegin();
197
198 while (iter != values.constEnd())
199 {
200 boxSelection->addItem((*iter).value(), (*iter).call());
201
202 if (stored.compare((*iter).call()) == 0)
203 selected = counter;
204 else if ((*iter).isDefault() && selected == -1)
205 selected = counter;
206
207 counter++;
208 ++iter;
209 }
210
211 if (selected > -1 && selected < boxSelection->count())
212 boxSelection->setCurrentIndex(selected);
213 }
214 }
215
isValid()216 bool ExtArgSelector::isValid()
217 {
218 bool valid = true;
219
220 if (value().length() == 0 && isRequired())
221 valid = false;
222
223 if (boxSelection)
224 {
225 QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
226 QString cmbBoxStyle("QComboBox { background-color: %1; } ");
227 boxSelection->setStyleSheet(cmbBoxStyle.arg(valid ? QString("") : lblInvalidColor));
228 }
229
230 return valid;
231 }
232
value()233 QString ExtArgSelector::value()
234 {
235 if (boxSelection == 0)
236 return QString();
237
238 QVariant data = boxSelection->currentData();
239
240 return data.toString();
241 }
242
ExtArgRadio(extcap_arg * argument,QObject * parent)243 ExtArgRadio::ExtArgRadio(extcap_arg * argument, QObject * parent) :
244 ExtcapArgument(argument, parent), selectorGroup(0), callStrings(0) {}
245
createEditor(QWidget * parent)246 QWidget * ExtArgRadio::createEditor(QWidget * parent)
247 {
248
249 int count = 0;
250 bool anyChecked = false;
251
252 selectorGroup = new QButtonGroup(parent);
253 QWidget * radioButtons = new QWidget;
254 QVBoxLayout * vrLayout = new QVBoxLayout();
255 QMargins margins = vrLayout->contentsMargins();
256 vrLayout->setContentsMargins(0, 0, 0, margins.bottom());
257 if (callStrings != 0)
258 delete callStrings;
259
260 callStrings = new QList<QString>();
261
262 if (values.length() > 0 )
263 {
264 ExtcapValueList::const_iterator iter = values.constBegin();
265
266 while (iter != values.constEnd())
267 {
268 QRadioButton * radio = new QRadioButton((*iter).value());
269 QString callString = (*iter).call();
270 callStrings->append(callString);
271
272 if ((*iter).isDefault())
273 {
274 radio->setChecked(true);
275 anyChecked = true;
276 }
277
278 connect(radio, SIGNAL(clicked(bool)), SLOT(onBoolChanged(bool)));
279 selectorGroup->addButton(radio, count);
280
281 vrLayout->addWidget(radio);
282 count++;
283
284 ++iter;
285 }
286 }
287
288 /* No default was provided, and not saved value exists */
289 if (anyChecked == false && count > 0)
290 ((QRadioButton*)(selectorGroup->button(0)))->setChecked(true);
291
292 radioButtons->setLayout(vrLayout);
293
294 return radioButtons;
295 }
296
value()297 QString ExtArgRadio::value()
298 {
299 int idx = 0;
300 if (selectorGroup == 0 || callStrings == 0)
301 return QString();
302
303 idx = selectorGroup->checkedId();
304 if (idx > -1 && callStrings->length() > idx)
305 return callStrings->takeAt(idx);
306
307 return QString();
308 }
309
isValid()310 bool ExtArgRadio::isValid()
311 {
312 bool valid = true;
313 int idx = 0;
314
315 if (isRequired())
316 {
317 if (selectorGroup == 0 || callStrings == 0)
318 valid = false;
319 else
320 {
321 idx = selectorGroup->checkedId();
322 if (idx == -1 || callStrings->length() <= idx)
323 valid = false;
324 }
325 }
326
327 /* If nothing is selected, but a selection is required, the only thing that
328 * can be marked is the label */
329 QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
330 _label->setStyleSheet (label_style.arg(valid ? QString("") : lblInvalidColor));
331
332 return valid;
333 }
334
ExtArgBool(extcap_arg * argument,QObject * parent)335 ExtArgBool::ExtArgBool(extcap_arg * argument, QObject * parent) :
336 ExtcapArgument(argument, parent), boolBox(0) {}
337
createLabel(QWidget * parent)338 QWidget * ExtArgBool::createLabel(QWidget * parent)
339 {
340 return new QWidget(parent);
341 }
342
createEditor(QWidget * parent)343 QWidget * ExtArgBool::createEditor(QWidget * parent)
344 {
345 bool state = defaultBool();
346
347 boolBox = new QCheckBox(QString().fromUtf8(_argument->display), parent);
348 if (_argument->tooltip != NULL)
349 boolBox->setToolTip(QString().fromUtf8(_argument->tooltip));
350
351 const char *prefval = _argument->pref_valptr ? *_argument->pref_valptr : NULL;
352 if (prefval)
353 {
354 QRegExp regexp(EXTCAP_BOOLEAN_REGEX);
355
356 bool savedstate = (regexp.indexIn(QString(prefval[0]), 0) != -1);
357 if (savedstate != state)
358 state = savedstate;
359 }
360
361 boolBox->setCheckState(state ? Qt::Checked : Qt::Unchecked);
362
363 connect (boolBox, SIGNAL(stateChanged(int)), SLOT(onIntChanged(int)));
364
365 return boolBox;
366 }
367
call()368 QString ExtArgBool::call()
369 {
370 if (boolBox == NULL)
371 return QString("");
372
373 if (_argument->arg_type == EXTCAP_ARG_BOOLEAN)
374 return ExtcapArgument::call();
375
376 return QString(boolBox->checkState() == Qt::Checked ? _argument->call : "");
377 }
378
value()379 QString ExtArgBool::value()
380 {
381 if (boolBox == NULL || _argument->arg_type == EXTCAP_ARG_BOOLFLAG)
382 return QString();
383 return QString(boolBox->checkState() == Qt::Checked ? "true" : "false");
384 }
385
prefValue()386 QString ExtArgBool::prefValue()
387 {
388 if (boolBox == NULL)
389 return QString("false");
390 return QString(boolBox->checkState() == Qt::Checked ? "true" : "false");
391 }
392
isValid()393 bool ExtArgBool::isValid()
394 {
395 /* A bool is allways valid, but the base function checks on string length,
396 * which will fail with boolflags */
397 return true;
398 }
399
defaultBool()400 bool ExtArgBool::defaultBool()
401 {
402 bool result = false;
403
404 if (_argument)
405 {
406 if (extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE)
407 result = true;
408 }
409
410 return result;
411 }
412
defaultValue()413 QString ExtArgBool::defaultValue()
414 {
415 return defaultBool() ? QString("true") : QString("false");
416 }
417
ExtArgText(extcap_arg * argument,QObject * parent)418 ExtArgText::ExtArgText(extcap_arg * argument, QObject * parent) :
419 ExtcapArgument(argument, parent), textBox(0)
420 {
421 }
422
createEditor(QWidget * parent)423 QWidget * ExtArgText::createEditor(QWidget * parent)
424 {
425 QString text = defaultValue();
426
427 if (_argument->pref_valptr && *_argument->pref_valptr)
428 {
429 QString storeValue(*_argument->pref_valptr);
430
431 if (storeValue.length() > 0 && storeValue.compare(text) != 0)
432 text = storeValue.trimmed();
433 }
434
435 textBox = new QLineEdit(text, parent);
436
437 if (_argument->tooltip != NULL)
438 textBox->setToolTip(QString().fromUtf8(_argument->tooltip));
439
440 if (_argument->placeholder != NULL)
441 textBox->setPlaceholderText(QString().fromUtf8(_argument->placeholder));
442
443 if (_argument->arg_type == EXTCAP_ARG_PASSWORD)
444 textBox->setEchoMode(QLineEdit::Password);
445
446 connect(textBox , SIGNAL(textChanged(QString)), SLOT(onStringChanged(QString)));
447
448 return textBox;
449 }
450
value()451 QString ExtArgText::value()
452 {
453 if (textBox == 0)
454 return QString();
455
456 return textBox->text();
457 }
458
isValid()459 bool ExtArgText::isValid()
460 {
461 bool valid = true;
462
463 if (isRequired() && value().length() == 0)
464 valid = false;
465
466 /* Does the validator, if any, consider the value valid?
467 *
468 * If it considers it an "intermediate" value, rather than an "invalid"
469 * value, the user will be able to transfer the input focus to another
470 * widget, and, as long as all widgets have values for which isValid()
471 * is true, they wil be able to click the "Start" button.
472 *
473 * For QIntValidator(), used for integral fields with minimum and
474 * maximum values, a value that's larger than the maximum but has
475 * the same number of digits as the maximum is "intermediate" rather
476 * than "invalid", so the user will be able to cause that value to
477 * be passed to the extcap module; see bug 16510.
478 *
479 * So we explicitly call the hasAcceptableInput() method on the
480 * text box; that returns false if the value is not "valid", and
481 * that includes "intermediate" values.
482 *
483 * This way, 1) non-colorblind users are informed that the value
484 * is invalid by the text box background being red (perhaps the
485 * user isn't fully colorblind, or perhaps the background is a
486 * noticeably different grayscale), and 2) the user won't be able
487 * to start the capture until they fix the problem.
488 *
489 * XXX - it might be nice to have some way of indicating to the
490 * user what the problem is with the value - alert box? Tooltip? */
491 if (!textBox->hasAcceptableInput())
492 valid = false;
493
494 /* validation should only be checked if there is a value. if the argument
495 * must be present (isRequired) the check above will handle that */
496 if (valid && _argument->regexp != NULL && value().length() > 0)
497 {
498 QString regexp = QString().fromUtf8(_argument->regexp);
499 if (regexp.length() > 0)
500 {
501 QRegExp expr(regexp);
502 if (! expr.isValid() || expr.indexIn(value(), 0) == -1)
503 valid = false;
504 }
505 }
506
507 QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
508 QString txtStyle("QLineEdit { background-color: %1; } ");
509 textBox->setStyleSheet(txtStyle.arg(valid ? QString("") : lblInvalidColor));
510
511 return valid;
512 }
513
ExtArgNumber(extcap_arg * argument,QObject * parent)514 ExtArgNumber::ExtArgNumber(extcap_arg * argument, QObject * parent) :
515 ExtArgText(argument, parent) {}
516
createEditor(QWidget * parent)517 QWidget * ExtArgNumber::createEditor(QWidget * parent)
518 {
519 QString text = defaultValue();
520
521 if (_argument->pref_valptr && *_argument->pref_valptr)
522 {
523 QString storeValue(*_argument->pref_valptr);
524
525 if (storeValue.length() > 0 && storeValue.compare(text) != 0)
526 text = storeValue;
527 }
528
529 textBox = (QLineEdit *)ExtArgText::createEditor(parent);
530 textBox->disconnect(SIGNAL(textChanged(QString)));
531
532 if (_argument->arg_type == EXTCAP_ARG_INTEGER || _argument->arg_type == EXTCAP_ARG_UNSIGNED)
533 {
534 QIntValidator * textValidator = new QIntValidator(parent);
535 if (_argument->range_start != NULL)
536 {
537 int val = 0;
538 if (_argument->arg_type == EXTCAP_ARG_INTEGER)
539 val = extcap_complex_get_int(_argument->range_start);
540 else if (_argument->arg_type == EXTCAP_ARG_UNSIGNED)
541 {
542 guint tmp = extcap_complex_get_uint(_argument->range_start);
543 if (tmp > G_MAXINT)
544 {
545 ws_log(LOG_DOMAIN_CAPTURE, LOG_LEVEL_DEBUG, "Defined value for range_start of %s exceeds valid integer range", _argument->call);
546 val = G_MAXINT;
547 }
548 else
549 val = (gint)tmp;
550 }
551
552 textValidator->setBottom(val);
553 }
554 if (_argument->arg_type == EXTCAP_ARG_UNSIGNED && textValidator->bottom() < 0)
555 {
556 ws_log(LOG_DOMAIN_CAPTURE, LOG_LEVEL_DEBUG, "%s sets negative bottom range for unsigned value, setting to 0", _argument->call);
557 textValidator->setBottom(0);
558 }
559
560 if (_argument->range_end != NULL)
561 {
562 int val = 0;
563 if (_argument->arg_type == EXTCAP_ARG_INTEGER)
564 val = extcap_complex_get_int(_argument->range_end);
565 else if (_argument->arg_type == EXTCAP_ARG_UNSIGNED)
566 {
567 guint tmp = extcap_complex_get_uint(_argument->range_end);
568 if (tmp > G_MAXINT)
569 {
570 ws_log(LOG_DOMAIN_CAPTURE, LOG_LEVEL_DEBUG, "Defined value for range_end of %s exceeds valid integer range", _argument->call);
571 val = G_MAXINT;
572 }
573 else
574 val = (gint)tmp;
575 }
576
577 textValidator->setTop(val);
578 }
579 textBox->setValidator(textValidator);
580 }
581 else if (_argument->arg_type == EXTCAP_ARG_DOUBLE)
582 {
583 QDoubleValidator * textValidator = new QDoubleValidator(parent);
584 if (_argument->range_start != NULL)
585 textValidator->setBottom(extcap_complex_get_double(_argument->range_start));
586 if (_argument->range_end != NULL)
587 textValidator->setTop(extcap_complex_get_double(_argument->range_end));
588
589 textBox->setValidator(textValidator);
590 }
591
592 textBox->setText(text.trimmed());
593
594 connect(textBox, SIGNAL(textChanged(QString)), SLOT(onStringChanged(QString)));
595
596 return textBox;
597 }
598
defaultValue()599 QString ExtArgNumber::defaultValue()
600 {
601 QString result;
602
603 if (_argument != 0)
604 {
605 if (_argument->arg_type == EXTCAP_ARG_DOUBLE)
606 result = QString::number(extcap_complex_get_double(_argument->default_complex));
607 else if (_argument->arg_type == EXTCAP_ARG_INTEGER)
608 result = QString::number(extcap_complex_get_int(_argument->default_complex));
609 else if (_argument->arg_type == EXTCAP_ARG_UNSIGNED)
610 result = QString::number(extcap_complex_get_uint(_argument->default_complex));
611 else if (_argument->arg_type == EXTCAP_ARG_LONG)
612 result = QString::number(extcap_complex_get_long(_argument->default_complex));
613 else
614 {
615 QString defValue = ExtcapArgument::defaultValue();
616 result = defValue.length() > 0 ? defValue : QString();
617 }
618 }
619
620 return result;
621 }
622
~ExtcapValue()623 ExtcapValue::~ExtcapValue() {}
624
setChildren(ExtcapValueList children)625 void ExtcapValue::setChildren(ExtcapValueList children)
626 {
627 ExtcapValueList::iterator iter = children.begin();
628 while (iter != children.end())
629 {
630 (*iter)._depth = _depth + 1;
631 ++iter;
632 }
633
634 _children.append(children);
635 }
636
ExtcapArgument(QObject * parent)637 ExtcapArgument::ExtcapArgument(QObject *parent) :
638 QObject(parent), _argument(0), _label(0), _number(0),
639 label_style(QString("QLabel { color: %1; }"))
640 {
641 }
642
ExtcapArgument(extcap_arg * argument,QObject * parent)643 ExtcapArgument::ExtcapArgument(extcap_arg * argument, QObject *parent) :
644 QObject(parent), _argument(argument), _label(0),
645 label_style(QString("QLabel { color: %1; }"))
646 {
647 _number = argument->arg_num;
648
649 if (_argument->values != 0)
650 {
651 ExtcapValueList elements = loadValues(QString(""));
652 if (elements.length() > 0)
653 values.append(elements);
654 }
655 }
656
ExtcapArgument(const ExtcapArgument & obj)657 ExtcapArgument::ExtcapArgument(const ExtcapArgument &obj) :
658 QObject(obj.parent()), _argument(obj._argument), _label(0),
659 label_style(QString("QLabel { color: %1; }"))
660 {
661 _number = obj._argument->arg_num;
662
663 if (_argument->values != 0)
664 {
665 ExtcapValueList elements = loadValues(QString(""));
666 if (elements.length() > 0)
667 values.append(elements);
668 }
669 }
670
loadValues(QString parent)671 ExtcapValueList ExtcapArgument::loadValues(QString parent)
672 {
673 if (_argument == 0 || _argument->values == 0)
674 return ExtcapValueList();
675
676 GList * walker = 0;
677 extcap_value * v;
678 ExtcapValueList elements;
679
680 for (walker = g_list_first((GList *)(_argument->values)); walker != NULL ; walker = walker->next)
681 {
682 v = (extcap_value *) walker->data;
683 if (v == NULL || v->display == NULL || v->call == NULL)
684 break;
685
686 QString valParent = QString().fromUtf8(v->parent);
687
688 if (parent.compare(valParent) == 0)
689 {
690
691 QString display = QString().fromUtf8(v->display);
692 QString call = QString().fromUtf8(v->call);
693
694 ExtcapValue element = ExtcapValue(display, call,
695 v->enabled == (gboolean)TRUE, v->is_default == (gboolean)TRUE);
696
697 if (!call.isEmpty())
698 element.setChildren(this->loadValues(call));
699
700 elements.append(element);
701 }
702 }
703
704 return elements;
705 }
706
reloadValues()707 bool ExtcapArgument::reloadValues()
708 {
709 if (! qobject_cast<ExtcapOptionsDialog*> (parent()) )
710 return false;
711
712 ExtcapOptionsDialog * dialog = qobject_cast<ExtcapOptionsDialog*>(parent());
713 ExtcapValueList list = dialog->loadValuesFor(_argument->arg_num, _argument->call);
714
715 if (list.size() > 0)
716 {
717 values.clear();
718 values << list;
719
720 return true;
721 }
722
723 return false;
724 }
725
~ExtcapArgument()726 ExtcapArgument::~ExtcapArgument() {
727 }
728
createLabel(QWidget * parent)729 QWidget * ExtcapArgument::createLabel(QWidget * parent)
730 {
731 if (_argument == 0 || _argument->display == 0)
732 return 0;
733
734 QString lblInvalidColor = ColorUtils::fromColorT(prefs.gui_text_invalid).name();
735
736 QString text = QString().fromUtf8(_argument->display);
737
738 if (_label == 0)
739 _label = new QLabel(text, parent);
740 else
741 _label->setText(text);
742
743 _label->setProperty("isRequired", QString(isRequired() ? "true" : "false"));
744
745 _label->setStyleSheet (label_style.arg(QString("")));
746
747 if (_argument->tooltip != 0)
748 _label->setToolTip(QString().fromUtf8(_argument->tooltip));
749
750 return (QWidget *)_label;
751 }
752
createEditor(QWidget *)753 QWidget * ExtcapArgument::createEditor(QWidget *)
754 {
755 return 0;
756 }
757
call()758 QString ExtcapArgument::call()
759 {
760 return QString(_argument->call);
761 }
762
value()763 QString ExtcapArgument::value()
764 {
765 return QString();
766 }
767
prefValue()768 QString ExtcapArgument::prefValue()
769 {
770 return value();
771 }
772
resetValue()773 void ExtcapArgument::resetValue()
774 {
775 if (_argument->pref_valptr) {
776 g_free(*_argument->pref_valptr);
777 *_argument->pref_valptr = g_strdup("");
778 }
779 }
780
isValid()781 bool ExtcapArgument::isValid()
782 {
783 /* Unrequired arguments are always valid, except if validity checks fail,
784 * which must be checked in an derived class, not here */
785 if (! isRequired())
786 return true;
787
788 return value().length() > 0;
789 }
790
defaultValue()791 QString ExtcapArgument::defaultValue()
792 {
793 if (_argument != 0 && _argument->default_complex != 0)
794 {
795 gchar * str = extcap_get_complex_as_string(_argument->default_complex);
796 if (str != 0)
797 return QString(str);
798 }
799 return QString();
800 }
801
group() const802 QString ExtcapArgument::group() const
803 {
804 if (_argument != 0 && _argument->group != 0)
805 return QString(_argument->group);
806
807 return QString();
808 }
809
argNr() const810 int ExtcapArgument::argNr() const
811 {
812 return _number;
813 }
814
prefKey(const QString & device_name)815 QString ExtcapArgument::prefKey(const QString & device_name)
816 {
817 struct preference * pref = NULL;
818
819 if (_argument == 0 || ! _argument->save)
820 return QString();
821
822 pref = extcap_pref_for_argument(device_name.toStdString().c_str(), _argument);
823 if (pref != NULL)
824 return QString(prefs_get_name(pref));
825
826 return QString();
827 }
828
isRequired()829 bool ExtcapArgument::isRequired()
830 {
831 if (_argument != NULL)
832 return _argument->is_required;
833
834 return FALSE;
835 }
836
reload()837 bool ExtcapArgument::reload()
838 {
839 if (_argument != NULL)
840 return _argument->reload;
841
842 return false;
843 }
844
fileExists()845 bool ExtcapArgument::fileExists()
846 {
847 if (_argument != NULL)
848 return _argument->fileexists;
849
850 return FALSE;
851 }
852
isDefault()853 bool ExtcapArgument::isDefault()
854 {
855 if (value().compare(defaultValue()) == 0)
856 return true;
857
858 return false;
859 }
860
create(extcap_arg * argument,QObject * parent)861 ExtcapArgument * ExtcapArgument::create(extcap_arg * argument, QObject *parent)
862 {
863 if (argument == 0 || argument->display == 0)
864 return 0;
865
866 ExtcapArgument * result = 0;
867
868 if (argument->arg_type == EXTCAP_ARG_STRING || argument->arg_type == EXTCAP_ARG_PASSWORD)
869 result = new ExtArgText(argument, parent);
870 else if (argument->arg_type == EXTCAP_ARG_INTEGER || argument->arg_type == EXTCAP_ARG_LONG ||
871 argument->arg_type == EXTCAP_ARG_UNSIGNED || argument->arg_type == EXTCAP_ARG_DOUBLE)
872 result = new ExtArgNumber(argument, parent);
873 else if (argument->arg_type == EXTCAP_ARG_BOOLEAN || argument->arg_type == EXTCAP_ARG_BOOLFLAG)
874 result = new ExtArgBool(argument, parent);
875 else if (argument->arg_type == EXTCAP_ARG_SELECTOR)
876 result = new ExtArgSelector(argument, parent);
877 else if (argument->arg_type == EXTCAP_ARG_RADIO)
878 result = new ExtArgRadio(argument, parent);
879 else if (argument->arg_type == EXTCAP_ARG_FILESELECT)
880 result = new ExtcapArgumentFileSelection(argument, parent);
881 else if (argument->arg_type == EXTCAP_ARG_MULTICHECK)
882 result = new ExtArgMultiSelect(argument, parent);
883 else if (argument->arg_type == EXTCAP_ARG_TIMESTAMP)
884 result = new ExtArgTimestamp(argument, parent);
885 else
886 {
887 /* For everything else, we just print the label */
888 result = new ExtcapArgument(argument, parent);
889 }
890
891 return result;
892 }
893
894 /* The following is a necessity, because Q_Object does not do well with multiple inheritances */
onStringChanged(QString)895 void ExtcapArgument::onStringChanged(QString)
896 {
897 emit valueChanged();
898 }
899
onIntChanged(int)900 void ExtcapArgument::onIntChanged(int)
901 {
902 if (isValid())
903 emit valueChanged();
904 }
905
onBoolChanged(bool)906 void ExtcapArgument::onBoolChanged(bool)
907 {
908 emit valueChanged();
909 }
910