summaryrefslogtreecommitdiffstats
path: root/tests/manual/examples/btscanner/device.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/examples/btscanner/device.cpp')
-rw-r--r--tests/manual/examples/btscanner/device.cpp182
1 files changed, 182 insertions, 0 deletions
diff --git a/tests/manual/examples/btscanner/device.cpp b/tests/manual/examples/btscanner/device.cpp
new file mode 100644
index 00000000..6d1f775f
--- /dev/null
+++ b/tests/manual/examples/btscanner/device.cpp
@@ -0,0 +1,182 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "device.h"
+#include "service.h"
+#include "ui_device.h"
+
+#include <QtBluetooth/qbluetoothaddress.h>
+#include <QtBluetooth/qbluetoothdevicediscoveryagent.h>
+#include <QtBluetooth/qbluetoothlocaldevice.h>
+
+#include <QtWidgets/qmenu.h>
+
+#if QT_CONFIG(permissions)
+#include <QtCore/qpermissions.h>
+#include <QtWidgets/qmessagebox.h>
+#include <QtWidgets/qapplication.h>
+#endif // QT_CONFIG(permissions)
+
+static QColor colorForPairing(QBluetoothLocalDevice::Pairing pairing)
+{
+ return pairing == QBluetoothLocalDevice::Paired
+ || pairing == QBluetoothLocalDevice::AuthorizedPaired
+ ? QColor(Qt::green) : QColor(Qt::red);
+}
+
+DeviceDiscoveryDialog::DeviceDiscoveryDialog(QWidget *parent) :
+ QDialog(parent),
+ localDevice(new QBluetoothLocalDevice(this)),
+ ui(new Ui::DeviceDiscovery)
+{
+#ifdef Q_OS_ANDROID
+ this->setWindowState(Qt::WindowMaximized);
+#endif
+ ui->setupUi(this);
+ ui->stopScan->setVisible(false);
+
+ // In case of multiple Bluetooth adapters it is possible to set the adapter
+ // to be used. Example code:
+ //
+ // QBluetoothAddress address("XX:XX:XX:XX:XX:XX");
+ // discoveryAgent = new QBluetoothDeviceDiscoveryAgent(address, this);
+
+ discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
+
+ connect(ui->scan, &QAbstractButton::clicked, this, &DeviceDiscoveryDialog::startScan);
+ connect(ui->stopScan, &QAbstractButton::clicked, this, &DeviceDiscoveryDialog::stopScan);
+
+ connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered,
+ this, &DeviceDiscoveryDialog::addDevice);
+ connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished,
+ this, &DeviceDiscoveryDialog::scanFinished);
+
+ connect(ui->list, &QListWidget::itemActivated,
+ this, &DeviceDiscoveryDialog::itemActivated);
+
+ connect(localDevice, &QBluetoothLocalDevice::hostModeStateChanged,
+ this, &DeviceDiscoveryDialog::hostModeStateChanged);
+
+ hostModeStateChanged(localDevice->hostMode());
+ // add context menu for devices to be able to pair device
+ ui->list->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(ui->list, &QWidget::customContextMenuRequested,
+ this, &DeviceDiscoveryDialog::displayPairingMenu);
+ connect(localDevice, &QBluetoothLocalDevice::pairingFinished,
+ this, &DeviceDiscoveryDialog::pairingDone);
+}
+
+DeviceDiscoveryDialog::~DeviceDiscoveryDialog()
+{
+ delete ui;
+}
+
+void DeviceDiscoveryDialog::addDevice(const QBluetoothDeviceInfo &info)
+{
+ const QString label = info.address().toString() + u' ' + info.name();
+ const auto items = ui->list->findItems(label, Qt::MatchExactly);
+ if (items.isEmpty()) {
+ QListWidgetItem *item = new QListWidgetItem(label);
+ QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(info.address());
+ item->setForeground(colorForPairing(pairingStatus));
+ ui->list->addItem(item);
+ }
+}
+
+void DeviceDiscoveryDialog::startScan()
+{
+#if QT_CONFIG(permissions)
+ if (qApp->checkPermission(QBluetoothPermission{}) != Qt::PermissionStatus::Granted) {
+ QMessageBox::warning(this, tr("Missing permission"),
+ tr("Permission is needed to use Bluetooth. "\
+ "Please grant the permission to this "\
+ "application in the system settings."));
+ return;
+ }
+#endif // QT_CONFIG(permissions)
+ discoveryAgent->start();
+ ui->scan->setVisible(false);
+ ui->stopScan->setVisible(true);
+}
+
+void DeviceDiscoveryDialog::stopScan()
+{
+ discoveryAgent->stop();
+ scanFinished();
+}
+
+void DeviceDiscoveryDialog::scanFinished()
+{
+ ui->scan->setVisible(true);
+ ui->stopScan->setVisible(false);
+}
+
+void DeviceDiscoveryDialog::itemActivated(QListWidgetItem *item)
+{
+ const QString text = item->text();
+ const auto index = text.indexOf(' ');
+ if (index == -1)
+ return;
+
+ QBluetoothAddress address(text.left(index));
+ QString name(text.mid(index + 1));
+
+ ServiceDiscoveryDialog d(name, address);
+ d.exec();
+}
+
+void DeviceDiscoveryDialog::on_discoverable_clicked(bool clicked)
+{
+ if (clicked)
+ localDevice->setHostMode(QBluetoothLocalDevice::HostDiscoverable);
+ else
+ localDevice->setHostMode(QBluetoothLocalDevice::HostConnectable);
+}
+
+void DeviceDiscoveryDialog::on_power_clicked(bool clicked)
+{
+ if (clicked)
+ localDevice->powerOn();
+ else
+ localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff);
+}
+
+void DeviceDiscoveryDialog::hostModeStateChanged(QBluetoothLocalDevice::HostMode mode)
+{
+ ui->power->setChecked(mode != QBluetoothLocalDevice::HostPoweredOff);
+ ui->discoverable->setChecked(mode == QBluetoothLocalDevice::HostDiscoverable);
+
+ const bool on = mode != QBluetoothLocalDevice::HostPoweredOff;
+ ui->scan->setEnabled(on);
+ ui->discoverable->setEnabled(on);
+}
+void DeviceDiscoveryDialog::displayPairingMenu(const QPoint &pos)
+{
+ if (ui->list->count() == 0)
+ return;
+ QMenu menu(this);
+ QAction *pairAction = menu.addAction("Pair");
+ QAction *removePairAction = menu.addAction("Remove Pairing");
+ QAction *chosenAction = menu.exec(ui->list->viewport()->mapToGlobal(pos));
+ QListWidgetItem *currentItem = ui->list->currentItem();
+
+ QString text = currentItem->text();
+ const auto index = text.indexOf(' ');
+ if (index == -1)
+ return;
+
+ QBluetoothAddress address (text.left(index));
+ if (chosenAction == pairAction) {
+ localDevice->requestPairing(address, QBluetoothLocalDevice::Paired);
+ } else if (chosenAction == removePairAction) {
+ localDevice->requestPairing(address, QBluetoothLocalDevice::Unpaired);
+ }
+}
+void DeviceDiscoveryDialog::pairingDone(const QBluetoothAddress &address,
+ QBluetoothLocalDevice::Pairing pairing)
+{
+ const auto items = ui->list->findItems(address.toString(), Qt::MatchContains);
+ const QColor color = colorForPairing(pairing);
+ for (auto *item : items)
+ item->setForeground(color);
+}