Kerberos: add kerberos_inject_longterm_key() helper function
[wireshark-sm.git] / ui / qt / manuf_dialog.cpp
blob074e6b9b9a0bbbc9bb8f26bf155df6c477966951
1 /*
2 * manuf_dialog.c
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include <config.h>
12 #include "manuf_dialog.h"
13 #include <ui_manuf_dialog.h>
15 #include <cstdio>
16 #include <cstdint>
17 #include <QComboBox>
18 #include <QStandardItemModel>
19 #include <QPushButton>
20 #include <QRegularExpression>
21 #include <QClipboard>
22 #include <QAction>
23 #include <QButtonGroup>
24 #include <QCheckBox>
26 #include "main_application.h"
27 #include <epan/manuf.h>
28 #include <epan/strutil.h>
29 #include <wsutil/regex.h>
30 #include <utils/qt_ui_utils.h>
32 #define PLACEHOLDER_SEARCH_ADDR "Search address"
33 #define PLACEHOLDER_SEARCH_NAME "Search name"
35 ManufDialog::ManufDialog(QWidget &parent, CaptureFile &cf) :
36 WiresharkDialog(parent, cf),
37 ui(new Ui::ManufDialog)
39 ui->setupUi(this);
40 loadGeometry();
42 model_ = new ManufTableModel(this);
43 proxy_model_ = new ManufSortFilterProxyModel(this);
44 proxy_model_->setSourceModel(model_);
46 ui->manufTableView->setModel(proxy_model_);
47 ui->manufTableView->setContextMenuPolicy(Qt::ActionsContextMenu);
48 ui->manufTableView->setColumnHidden(ManufTableModel::COL_SHORT_NAME, true);
50 QAction *select_action = new QAction(tr("Select all"), ui->manufTableView);
51 ui->manufTableView->addAction(select_action);
52 connect(select_action, &QAction::triggered, ui->manufTableView, &QTableView::selectAll);
54 QAction *copy_action = new QAction(tr("Copy"), ui->manufTableView);
55 ui->manufTableView->addAction(copy_action);
56 connect(copy_action, &QAction::triggered, this, &ManufDialog::copyToClipboard);
58 QPushButton *find_button = ui->buttonBox->addButton(tr("Find"), QDialogButtonBox::ActionRole);
59 find_button->setDefault(true);
60 connect(find_button, &QPushButton::clicked, this, &ManufDialog::on_editingFinished);
62 QPushButton *clear_button = ui->buttonBox->addButton(tr("Clear"), QDialogButtonBox::ActionRole);
63 connect(clear_button, &QPushButton::clicked, this, &ManufDialog::clearFilter);
65 QPushButton *copy_button = ui->buttonBox->addButton(tr("Copy"), QDialogButtonBox::ApplyRole);
66 connect(copy_button, &QPushButton::clicked, this, &ManufDialog::copyToClipboard);
68 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
69 connect(ui->radioButtonGroup, &QButtonGroup::buttonClicked, this, &ManufDialog::on_searchToggled);
70 connect(ui->radioButtonGroup, &QButtonGroup::buttonClicked, this, &ManufDialog::on_editingFinished);
71 #else
72 connect(ui->radioButtonGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), this, &ManufDialog::on_searchToggled);
73 connect(ui->radioButtonGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), this, &ManufDialog::on_editingFinished);
74 #endif
75 #if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
76 connect(ui->checkShortNameButton, &QCheckBox::checkStateChanged, this, &ManufDialog::shortNameStateChanged);
77 #else
78 connect(ui->checkShortNameButton, &QCheckBox::stateChanged, this, &ManufDialog::shortNameStateChanged);
79 #endif
81 ui->manufLineEdit->setPlaceholderText(tr(PLACEHOLDER_SEARCH_ADDR));
83 ui->hintLabel->clear();
86 ManufDialog::~ManufDialog()
88 delete ui;
91 void ManufDialog::searchVendor(QString &text)
93 QRegularExpression name_re;
95 name_re = QRegularExpression(text, QRegularExpression::CaseInsensitiveOption);
96 if (!name_re.isValid()) {
97 ui->hintLabel->setText(QStringLiteral("<small><i>Invalid regular expression: %1</i></small>").arg(name_re.errorString()));
98 return;
101 proxy_model_->setFilterName(name_re);
102 ui->hintLabel->setText(QStringLiteral("<small><i>Found %1 matches for \"%2\"</i></small>").arg(proxy_model_->rowCount()).arg(text));
105 static QByteArray convertMacAddressToByteArray(const QString &bytesString)
107 GByteArray *bytes = g_byte_array_new();
109 if (!hex_str_to_bytes(qUtf8Printable(bytesString), bytes, false)
110 || bytes->len == 0 || bytes->len > 6) {
111 g_byte_array_free(bytes, true);
112 return QByteArray();
115 /* Mask out multicast/locally administered flags. */
116 bytes->data[0] &= 0xFC;
118 return gbytearray_free_to_qbytearray(bytes);
121 QString convertToMacAddress(const QByteArray& byteArray) {
122 QString macAddress;
123 for (int i = 0; i < byteArray.size(); ++i) {
124 macAddress += QStringLiteral("%1").arg(static_cast<quint8>(byteArray[i]), 2, 16, QChar('0'));
125 if (i != byteArray.size() - 1) {
126 macAddress += ":";
129 return macAddress.toUpper();
132 void ManufDialog::searchPrefix(QString &text)
134 QByteArray addr;
136 addr = convertMacAddressToByteArray(text);
137 if (addr.isEmpty()) {
138 ui->hintLabel->setText(QStringLiteral("<small><i>\"%1\" is not a valid MAC address</i></small>").arg(text));
139 return;
142 proxy_model_->setFilterAddress(addr);
143 ui->hintLabel->setText(QStringLiteral("<small><i>Found %1 matches for \"%2\"</i></small>").arg(proxy_model_->rowCount()).arg(convertToMacAddress(addr)));
146 void ManufDialog::on_searchToggled(void)
148 if (ui->ouiRadioButton->isChecked())
149 ui->manufLineEdit->setPlaceholderText(tr(PLACEHOLDER_SEARCH_ADDR));
150 else if (ui->vendorRadioButton->isChecked())
151 ui->manufLineEdit->setPlaceholderText(tr(PLACEHOLDER_SEARCH_NAME));
152 else
153 ws_assert_not_reached();
156 void ManufDialog::on_editingFinished(void)
158 QString text = ui->manufLineEdit->text();
160 if (text.isEmpty())
161 return;
163 if (ui->ouiRadioButton->isChecked())
164 searchPrefix(text);
165 else if (ui->vendorRadioButton->isChecked())
166 searchVendor(text);
167 else
168 ws_assert_not_reached();
171 #if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
172 void ManufDialog::shortNameStateChanged(Qt::CheckState state)
173 #else
174 void ManufDialog::shortNameStateChanged(int state)
175 #endif
177 ui->manufTableView->setColumnHidden(ManufTableModel::COL_SHORT_NAME, state == Qt::Checked ? false : true);
180 void ManufDialog::clearFilter()
182 proxy_model_->clearFilter();
183 ui->manufLineEdit->clear();
184 ui->hintLabel->clear();
187 void ManufDialog::copyToClipboard() {
188 QModelIndexList selectedIndexes = ui->manufTableView->selectionModel()->selectedIndexes();
190 std::sort(selectedIndexes.begin(), selectedIndexes.end(), [](const QModelIndex &a, const QModelIndex &b) {
191 return a.row() < b.row() || (a.row() == b.row() && a.column() < b.column());
194 QAbstractItemModel *model = ui->manufTableView->model();
195 QString copiedData;
197 int previousRow = -1;
199 for (const QModelIndex& selectedIndex : selectedIndexes) {
200 // If the row changed, add a newline character
201 if (selectedIndex.row() != previousRow) {
202 if (!copiedData.isEmpty()) {
203 copiedData += "\n";
205 previousRow = selectedIndex.row();
207 else {
208 // If not the first column in the row, add a tab character
209 copiedData += "\t";
212 // Add the cell data to the string
213 copiedData += model->data(selectedIndex).toString();
216 QClipboard *clipboard = QApplication::clipboard();
217 clipboard->setText(copiedData);