clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name extcap_argument_multiselect.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/build/ui/qt -isystem /builds/wireshark/wireshark/ui/qt -isystem /builds/wireshark/wireshark/ui/qt/lua_debugger -isystem /usr/include/x86_64-linux-gnu/qt6/QtConcurrent -isystem /usr/include/x86_64-linux-gnu/qt6 -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt6/mkspecs/linux-g++ -isystem /usr/include/x86_64-linux-gnu/qt6/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt6/QtPrintSupport -isystem /usr/include/x86_64-linux-gnu/qt6/QtGui -isystem /usr/include/x86_64-linux-gnu/qt6/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt6/QtSvg -isystem /usr/include/x86_64-linux-gnu/qt6/QtMultimedia -isystem /usr/include/x86_64-linux-gnu/qt6/QtDBus -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D QT_CONCURRENT_LIB -D QT_CORE_LIB -D QT_DBUS_LIB -D QT_GUI_LIB -D QT_MULTIMEDIA_LIB -D QT_NETWORK_LIB -D QT_PRINTSUPPORT_LIB -D QT_SVG_LIB -D QT_WIDGETS_LIB -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build/ui/qt/qtui_autogen/include -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=c++17 -fdeprecated-macro -ferror-limit 19 -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-09-19-100317-3660-1 -x c++ /builds/wireshark/wireshark/ui/qt/extcap_argument_multiselect.cpp
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | #include <extcap_argument.h> |
| 11 | #include <extcap_argument_file.h> |
| 12 | |
| 13 | #include <wsutil/utf8_entities.h> |
| 14 | |
| 15 | #include <QLabel> |
| 16 | #include <QLineEdit> |
| 17 | #include <QBoxLayout> |
| 18 | #include <QVariant> |
| 19 | #include <QPushButton> |
| 20 | #include <QMenu> |
| 21 | #include <QHeaderView> |
| 22 | #include <QInputDialog> |
| 23 | |
| 24 | #include <ui/qt/widgets/stock_icon_tool_button.h> |
| 25 | #include <ui/qt/utils/theme_manager.h> |
| 26 | |
| 27 | #include <extcap.h> |
| 28 | #include <extcap_parser.h> |
| 29 | #include <extcap_argument_multiselect.h> |
| 30 | #include "ui/capture_globals.h" |
| 31 | |
| 32 | ExtArgMultiSelect::ExtArgMultiSelect(extcap_arg * argument, QObject *parent) : |
| 33 | ExtcapArgument(argument, parent), viewModel(0), treeView(0) {} |
| 34 | |
| 35 | ExtArgMultiSelect::~ExtArgMultiSelect() |
| 36 | { |
| 37 | } |
| 38 | |
| 39 | |
| 40 | QList<QStandardItem *> ExtArgMultiSelect::valueWalker(ExtcapValueList list, QStringList &defaults) |
| 41 | { |
| 42 | ExtcapValueList::iterator iter = list.begin(); |
| 43 | QList<QStandardItem *> items; |
| 44 | |
| 45 | while (iter != list.end()) |
| 46 | { |
| 47 | QStandardItem * item = new QStandardItem((*iter).value()); |
| 48 | if ((*iter).enabled() == false) |
| 49 | { |
| 50 | item->setCheckable(false); |
| 51 | } |
| 52 | else |
| 53 | { |
| 54 | item->setCheckable(true); |
| 55 | } |
| 56 | |
| 57 | item->setData((*iter).call(), Qt::UserRole); |
| 58 | if ((*iter).isDefault()) |
| 59 | defaults << (*iter).call(); |
| 60 | |
| 61 | displayNames[(*iter).call()] = (*iter).value(); |
| 62 | |
| 63 | item->setSelectable(false); |
| 64 | item->setEditable(false); |
| 65 | |
| 66 | QList<QStandardItem *> childs = valueWalker((*iter).children(), defaults); |
| 67 | if (childs.length() > 0) |
| 68 | item->appendRows(childs); |
| 69 | |
| 70 | items << item; |
| 71 | ++iter; |
| 72 | } |
| 73 | |
| 74 | return items; |
| 75 | } |
| 76 | |
| 77 | |
| 78 | void ExtArgMultiSelect::checkItemsWalker(QStandardItem * item, QStringList defaults) |
| 79 | { |
| 80 | QModelIndex index; |
| 81 | |
| 82 | if (item->hasChildren()) |
| 83 | { |
| 84 | for (int row = 0; row < item->rowCount(); row++) |
| 85 | { |
| 86 | QStandardItem * child = item->child(row); |
| 87 | if (child != 0) |
| 88 | { |
| 89 | |
| 90 | checkItemsWalker(child, defaults); |
| 91 | } |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | QString data = item->data(Qt::UserRole).toString(); |
| 96 | |
| 97 | if (defaults.contains(data)) |
| 98 | { |
| 99 | item->setCheckState(Qt::Checked); |
| 100 | index = item->index(); |
| 101 | while (index.isValid()) |
| 102 | { |
| 103 | treeView->setExpanded(index, true); |
| 104 | index = index.parent(); |
| 105 | } |
| 106 | } else if (item->isCheckable()) { |
| 107 | item->setCheckState(Qt::Unchecked); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | QWidget * ExtArgMultiSelect::createEditor(QWidget * parent) |
| 112 | { |
| 113 | QStringList checked; |
| 114 | QLineEdit* searchBox; |
| 115 | QVBoxLayout* layout; |
| 116 | TreeSortFilterProxyModel* tableProxyModel; |
| 117 | QWidget* pane = new QWidget(parent); |
| |
| 118 | |
| 119 | QList<QStandardItem *> items = valueWalker(values, checked); |
| 120 | if (items.length() == 0) |
| 3 | | Assuming the condition is true | |
|
| |
| 121 | return new QWidget(); |
| 5 | | Potential leak of memory pointed to by 'pane' |
|
| 122 | |
| 123 | |
| 124 | if (_argument->pref_valptr && (*_argument->pref_valptr)) |
| 125 | { |
| 126 | checked = QString(*_argument->pref_valptr).split(",", Qt::SkipEmptyParts); |
| 127 | } |
| 128 | |
| 129 | |
| 130 | viewModel = new QStandardItemModel(this); |
| 131 | QList<QStandardItem *>::const_iterator iter = items.constBegin(); |
| 132 | while (iter != items.constEnd()) |
| 133 | { |
| 134 | viewModel->appendRow((*iter)); |
| 135 | ++iter; |
| 136 | } |
| 137 | |
| 138 | |
| 139 | tableProxyModel = new TreeSortFilterProxyModel(this); |
| 140 | tableProxyModel->setSourceModel(viewModel); |
| 141 | |
| 142 | searchBox = new QLineEdit(); |
| 143 | searchBox->setClearButtonEnabled(true); |
| 144 | searchBox->setPlaceholderText("Search"); |
| 145 | |
| 146 | treeView = new QTreeView(); |
| 147 | treeView->setModel(tableProxyModel); |
| 148 | |
| 149 | |
| 150 | treeView->setMinimumHeight(100); |
| 151 | treeView->setHeaderHidden(true); |
| 152 | treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); |
| 153 | treeView->setEditTriggers(QAbstractItemView::NoEditTriggers); |
| 154 | treeView->expandAll(); |
| 155 | |
| 156 | for (int row = 0; row < viewModel->rowCount(); row++) |
| 157 | checkItemsWalker(((QStandardItemModel*)viewModel)->item(row), checked); |
| 158 | |
| 159 | connect(viewModel, &QStandardItemModel::itemChanged, this, &ExtArgMultiSelect::valueChanged); |
| 160 | connect(searchBox, &QLineEdit::textChanged, this, [tableProxyModel](const QString& text) { |
| 161 | tableProxyModel->setFilterRegularExpression(QRegularExpression(text, QRegularExpression::PatternOption::CaseInsensitiveOption)); |
| 162 | }); |
| 163 | |
| 164 | layout = new QVBoxLayout(pane); |
| 165 | layout->addWidget(searchBox); |
| 166 | layout->addWidget(treeView); |
| 167 | pane->setLayout(layout); |
| 168 | |
| 169 | return pane; |
| 170 | } |
| 171 | |
| 172 | bool TreeSortFilterProxyModel::filterAcceptsRow(int sourceRow, |
| 173 | const QModelIndex& sourceParent) const |
| 174 | { |
| 175 | |
| 176 | if (sourceModel()->hasChildren(sourceModel()->index(sourceRow, 0, sourceParent))) |
| 177 | return true; |
| 178 | |
| 179 | return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); |
| 180 | } |
| 181 | |
| 182 | QStringList ExtArgMultiSelect::checkedValues() |
| 183 | { |
| 184 | if (viewModel == 0) |
| 185 | return QStringList(); |
| 186 | |
| 187 | QStringList result; |
| 188 | QModelIndexList checked = viewModel->match(viewModel->index(0, 0), Qt::CheckStateRole, Qt::Checked, -1, Qt::MatchExactly | Qt::MatchRecursive); |
| 189 | if (checked.size() <= 0) |
| 190 | return QStringList(); |
| 191 | |
| 192 | QModelIndexList::const_iterator iter = checked.constBegin(); |
| 193 | while (iter != checked.constEnd()) |
| 194 | { |
| 195 | QModelIndex index = (QModelIndex)(*iter); |
| 196 | |
| 197 | result << viewModel->data(index, Qt::UserRole).toString(); |
| 198 | |
| 199 | ++iter; |
| 200 | } |
| 201 | |
| 202 | return result; |
| 203 | } |
| 204 | |
| 205 | QString ExtArgMultiSelect::value() |
| 206 | { |
| 207 | return checkedValues().join(QString(',')); |
| 208 | } |
| 209 | |
| 210 | bool ExtArgMultiSelect::isValid() |
| 211 | { |
| 212 | bool valid = true; |
| 213 | |
| 214 | if (isRequired()) |
| 215 | { |
| 216 | if (viewModel == 0) |
| 217 | valid = false; |
| 218 | else |
| 219 | { |
| 220 | QModelIndexList checked = viewModel->match(viewModel->index(0, 0), Qt::CheckStateRole, Qt::Checked, -1, Qt::MatchExactly | Qt::MatchRecursive); |
| 221 | if (checked.size() <= 0) |
| 222 | valid = false; |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | if (viewModel != 0) |
| 227 | ThemeManager::setValidationState(treeView, valid ? QString() : QStringLiteral("invalid")); |
| 228 | |
| 229 | return valid; |
| 230 | } |
| 231 | |
| 232 | QString ExtArgMultiSelect::defaultValue() |
| 233 | { |
| 234 | QStringList checked; |
| 235 | |
| 236 | QList<QStandardItem *> items = valueWalker(values, checked); |
| 237 | qDeleteAll(items); |
| 238 | |
| 239 | return checked.join(QString(',')); |
| 240 | } |
| 241 | |
| 242 | bool ExtArgMultiSelect::isSetDefaultValueSupported() |
| 243 | { |
| 244 | return true; |
| 245 | } |
| 246 | |
| 247 | void ExtArgMultiSelect::setDefaultValue() |
| 248 | { |
| 249 | QStringList checked; |
| 250 | |
| 251 | if (viewModel == 0) |
| 252 | return; |
| 253 | |
| 254 | checked = defaultValue().split(",", Qt::SkipEmptyParts); |
| 255 | for (int row = 0; row < viewModel->rowCount(); row++) |
| 256 | checkItemsWalker(((QStandardItemModel*)viewModel)->item(row), checked); |
| 257 | } |
| 258 | |
| 259 | ExtArgTable::ExtArgTable(extcap_arg* argument, QObject* parent) : |
| 260 | ExtArgMultiSelect(argument, parent), extcap_options_dialog(0), addDialog(0), tableViewModel(0), tableView(0), paneLayout(0), toolbar(0) {} |
| 261 | |
| 262 | ExtArgTable::~ExtArgTable() |
| 263 | { |
| 264 | |
| 265 | if (tableView != 0) |
| 266 | delete tableView; |
| 267 | if (tableViewModel != 0) |
| 268 | delete tableViewModel; |
| 269 | if (toolbar != 0) |
| 270 | delete toolbar; |
| 271 | if (paneLayout != 0) |
| 272 | delete paneLayout; |
| 273 | } |
| 274 | |
| 275 | ExtArgTableAddDialog::ExtArgTableAddDialog(QWidget* parent, QWidget* selector) : QDialog(parent) |
| 276 | { |
| 277 | setWindowTitle("Add element"); |
| 278 | setMinimumWidth(400); |
| 279 | |
| 280 | QVBoxLayout* layout = new QVBoxLayout(this); |
| 281 | QPushButton* okButton = new QPushButton("OK", this); |
| 282 | QPushButton* cancelButton = new QPushButton("Cancel", this); |
| 283 | |
| 284 | layout->addWidget(selector); |
| 285 | layout->addWidget(okButton); |
| 286 | layout->addWidget(cancelButton); |
| 287 | |
| 288 | connect(okButton, &QPushButton::clicked, this, &QDialog::accept); |
| 289 | connect(cancelButton, &QPushButton::clicked, this, &QDialog::reject); |
| 290 | } |
| 291 | |
| 292 | QWidget* ExtArgTable::createEditor(QWidget* parent) |
| 293 | { |
| 294 | |
| 295 | QWidget* pane = new QWidget(parent); |
| 296 | paneLayout = new QVBoxLayout(pane); |
| 297 | |
| 298 | |
| 299 | QWidget* treeViewWidget = ExtArgMultiSelect::createEditor(addDialog); |
| 1 | Calling 'ExtArgMultiSelect::createEditor' | |
|
| 300 | addDialog = new ExtArgTableAddDialog(parent, treeViewWidget); |
| 301 | |
| 302 | |
| 303 | toolbar = new QToolBar(pane); |
| 304 | toolbar->setStyleSheet("QToolBar { border: 1px solid gray; border-radius: 3px; }"); |
| 305 | QAction* addAction = toolbar->addAction("Add"); |
| 306 | QAction* addActionCustom = toolbar->addAction("Add custom"); |
| 307 | QAction* removeAction = toolbar->addAction("Remove"); |
| 308 | paneLayout->addWidget(toolbar); |
| 309 | |
| 310 | |
| 311 | tableView = new QTableView(pane); |
| 312 | tableView->setMinimumHeight(200); |
| 313 | tableView->setSelectionMode(QAbstractItemView::ExtendedSelection); |
| 314 | tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); |
| 315 | tableView->verticalHeader()->hide(); |
| 316 | tableView->horizontalHeader()->hide(); |
| 317 | |
| 318 | tableViewModel = new QStandardItemModel(pane); |
| 319 | tableView->setModel(tableViewModel); |
| 320 | paneLayout->addWidget(tableView); |
| 321 | |
| 322 | |
| 323 | if (_argument->pref_valptr && (*_argument->pref_valptr)) |
| 324 | { |
| 325 | QStringList checked; |
| 326 | QStringList options; |
| 327 | |
| 328 | if (_argument->prefix) |
| 329 | { |
| 330 | QStringList splitted = QString(*_argument->pref_valptr).split(_argument->prefix, Qt::SkipEmptyParts); |
| 331 | QStringList parts; |
| 332 | for (QString item : splitted) |
| 333 | { |
| 334 | parts = item.split(" ", Qt::SkipEmptyParts); |
| 335 | checked << parts.takeFirst(); |
| 336 | options << parts.join(" "); |
| 337 | } |
| 338 | } |
| 339 | else |
| 340 | { |
| 341 | checked = QString(*_argument->pref_valptr).split(" ", Qt::SkipEmptyParts); |
| 342 | } |
| 343 | addChecked(checked, options); |
| 344 | } |
| 345 | |
| 346 | |
| 347 | connect(addAction, &QAction::triggered, this, &ExtArgTable::addKnown); |
| 348 | connect(addActionCustom, &QAction::triggered, this, &ExtArgTable::addCustom); |
| 349 | connect(removeAction, &QAction::triggered, this, &ExtArgTable::removeSelected); |
| 350 | return pane; |
| 351 | } |
| 352 | |
| 353 | QString ExtArgTable::value() |
| 354 | { |
| 355 | QStringList results; |
| 356 | for (int row = 0; row < tableViewModel->rowCount(); row++) { |
| 357 | QString s = ((QStandardItemModel*)tableViewModel)->item(row)->data(Qt::UserRole).toString(); |
| 358 | QString config = ((QStandardItemModel*)tableViewModel)->item(row)->data(Qt::UserRole + 1).toString(); |
| 359 | if (_argument->prefix != NULL) |
| 360 | { |
| 361 | s.prepend(" "); |
| 362 | s.prepend(_argument->prefix); |
| 363 | } |
| 364 | if (!config.isEmpty()) |
| 365 | { |
| 366 | s.append(" "); |
| 367 | s.append(config); |
| 368 | } |
| 369 | results << s; |
| 370 | } |
| 371 | return results.join(" "); |
| 372 | } |
| 373 | |
| 374 | void ExtArgTable::addChecked(QStringList checked, QStringList options) |
| 375 | { |
| 376 | for (int i = 0; i < checked.size(); ++i) { |
| 377 | QStandardItem* item = new QStandardItem(checked[i]); |
| 378 | item->setData(checked[i], Qt::UserRole); |
| 379 | if (displayNames.contains(checked[i])) |
| 380 | { |
| 381 | item->setText(displayNames[checked[i]]); |
| 382 | } |
| 383 | |
| 384 | if (_argument->configurable) |
| 385 | { |
| 386 | if (options.size() > i) |
| 387 | { |
| 388 | item->setData(QString(options[i]), Qt::UserRole + 1); |
| 389 | } |
| 390 | else |
| 391 | { |
| 392 | item->setData(QString(), Qt::UserRole + 1); |
| 393 | } |
| 394 | |
| 395 | QStandardItem* btnItem = new QStandardItem(); |
| 396 | tableViewModel->appendRow({ item, btnItem }); |
| 397 | |
| 398 | |
| 399 | StockIconToolButton* settingsButton = new StockIconToolButton(tableView, "x-capture-options"); |
| 400 | settingsButton->setFixedWidth(30); |
| 401 | tableView->setIndexWidget(tableViewModel->indexFromItem(btnItem), settingsButton); |
| 402 | |
| 403 | connect(settingsButton, &StockIconToolButton::clicked, this, [=]() { |
| 404 | QString optionValue = checked[i]; |
| 405 | this->showExtcapOptionsDialogForOptionValue(item, optionValue); |
| 406 | }); |
| 407 | } |
| 408 | else |
| 409 | { |
| 410 | tableViewModel->appendRow(item); |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | if (tableView->horizontalHeader()->count() > 0) |
| 415 | { |
| 416 | |
| 417 | |
| 418 | tableView->resizeColumnToContents(1); |
| 419 | tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); |
| 420 | if (_argument->configurable) |
| 421 | tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); |
| 422 | } |
| 423 | } |
| 424 | |
| 425 | void ExtArgTable::setDefaultValue() |
| 426 | { |
| 427 | QStringList checked; |
| 428 | |
| 429 | if (tableViewModel == 0) |
| 430 | return; |
| 431 | |
| 432 | tableViewModel->clear(); |
| 433 | checked = defaultValue().split(",", Qt::SkipEmptyParts); |
| 434 | addChecked(checked, QStringList()); |
| 435 | } |
| 436 | |
| 437 | void ExtArgTable::addKnown() |
| 438 | { |
| 439 | |
| 440 | QStringList checked; |
| 441 | for (int row = 0; row < viewModel->rowCount(); row++) |
| 442 | checkItemsWalker(((QStandardItemModel*)viewModel)->item(row), checked); |
| 443 | |
| 444 | |
| 445 | if (addDialog->exec() == QDialog::Accepted) |
| 446 | { |
| 447 | checked = ExtArgMultiSelect::checkedValues(); |
| 448 | addChecked(checked, QStringList()); |
| 449 | } |
| 450 | } |
| 451 | |
| 452 | void ExtArgTable::addCustom() |
| 453 | { |
| 454 | |
| 455 | bool ok; |
| 456 | QString text = QInputDialog::getText( |
| 457 | tableView, |
| 458 | tr("Add custom data"), |
| 459 | tr("Custom:"), |
| 460 | QLineEdit::Normal, |
| 461 | "", |
| 462 | &ok |
| 463 | ); |
| 464 | if (ok && !text.isEmpty()) |
| 465 | { |
| 466 | addChecked({ text }, QStringList()); |
| 467 | } |
| 468 | } |
| 469 | |
| 470 | void ExtArgTable::removeSelected() |
| 471 | { |
| 472 | |
| 473 | QModelIndexList selected = tableView->selectionModel()->selectedIndexes(); |
| 474 | |
| 475 | |
| 476 | for (int row = 0; row < selected.size(); row++) |
| 477 | tableViewModel->removeRow(selected[row].row()); |
| 478 | } |
| 479 | |
| 480 | void ExtArgTable::showExtcapOptionsDialogForOptionValue(QStandardItem* item, QString& option_value) |
| 481 | { |
| 482 | QString device_name(_argument->device_name); |
| 483 | QString option_name(_argument->call + 2); |
| 484 | extcap_options_dialog = ExtcapOptionsDialog::createForDevice(device_name, false, tableView->parentWidget(), |
| 485 | &option_name, &option_value); |
| 486 | |
| 487 | if (extcap_options_dialog) { |
| 488 | extcap_options_dialog->setModal(true); |
| 489 | extcap_options_dialog->setAttribute(Qt::WA_DeleteOnClose); |
| 490 | connect(extcap_options_dialog, &ExtcapOptionsDialog::accepted, this, [=]() { |
| 491 | this->extcap_suboptions_accepted(item); |
| 492 | }); |
| 493 | extcap_options_dialog->show(); |
| 494 | } |
| 495 | } |
| 496 | |
| 497 | QString |
| 498 | extcap_format_external_arguments(GHashTable* extcap_args) |
| 499 | { |
| 500 | QString command_line; |
| 501 | |
| 502 | GHashTableIter iter; |
| 503 | void *key, *value; |
| 504 | g_hash_table_iter_init(&iter, extcap_args); |
| 505 | while (g_hash_table_iter_next(&iter, &key, &value)) { |
| 506 | if (key != NULL) |
| 507 | { |
| 508 | command_line.append(g_strdup((char*)key)); |
| 509 | command_line.append(" "); |
| 510 | } |
| 511 | if (value != NULL) |
| 512 | { |
| 513 | command_line.append(g_strdup((char*)value)); |
| 514 | command_line.append(" "); |
| 515 | } |
| 516 | } |
| 517 | |
| 518 | return command_line; |
| 519 | } |
| 520 | |
| 521 | void ExtArgTable::extcap_suboptions_accepted(QStandardItem* item) |
| 522 | { |
| 523 | QString arguments = extcap_format_external_arguments(extcap_options_dialog->getExtcapArgumentSettings()); |
| 524 | item->setData(arguments, Qt::UserRole + 1); |
| 525 | } |