diff options
Diffstat (limited to 'qt-ui/btdeviceselectiondialog.cpp')
-rw-r--r-- | qt-ui/btdeviceselectiondialog.cpp | 214 |
1 files changed, 156 insertions, 58 deletions
diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp index 9b97da3a9..007fe940e 100644 --- a/qt-ui/btdeviceselectiondialog.cpp +++ b/qt-ui/btdeviceselectiondialog.cpp @@ -11,14 +11,6 @@ BtDeviceSelectionDialog::BtDeviceSelectionDialog(QWidget *parent) : localDevice(new QBluetoothLocalDevice), ui(new Ui::BtDeviceSelectionDialog) { - // Check if Bluetooth is available on this device - if (!localDevice->isValid()) { - QMessageBox::warning(this, tr("Warning"), - "This should never happen, please contact the Subsurface developers " - "and tell them that the Bluetooth download mode doesn't work."); - return; - } - ui->setupUi(this); // Quit button callbacks @@ -29,36 +21,41 @@ BtDeviceSelectionDialog::BtDeviceSelectionDialog(QWidget *parent) : // Disable the save button because there is no device selected ui->save->setEnabled(false); - connect(ui->discoveredDevicesList, SIGNAL(itemActivated(QListWidgetItem*)), - this, SLOT(itemActivated(QListWidgetItem*))); + connect(ui->discoveredDevicesList, SIGNAL(itemClicked(QListWidgetItem*)), + this, SLOT(itemClicked(QListWidgetItem*))); - // Set UI information about the local device - ui->deviceAddress->setText(localDevice->address().toString()); - ui->deviceName->setText(localDevice->name()); + // Populate the list with local bluetooth devices + QList<QBluetoothHostInfo> localAvailableDevices = localDevice->allDevices(); + int availableDevicesSize = localAvailableDevices.size(); - connect(localDevice, SIGNAL(hostModeStateChanged(QBluetoothLocalDevice::HostMode)), - this, SLOT(hostModeStateChanged(QBluetoothLocalDevice::HostMode))); + if (availableDevicesSize > 1) { + int defaultDeviceIndex = -1; - // Initialize the state of the local device and activate/deactive the scan button - hostModeStateChanged(localDevice->hostMode()); + for (int it = 0; it < availableDevicesSize; it++) { + QBluetoothHostInfo localAvailableDevice = localAvailableDevices.at(it); + ui->localSelectedDevice->addItem(localAvailableDevice.name(), + QVariant::fromValue(localAvailableDevice.address())); - // Intialize the discovery agent - remoteDeviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(); + if (localDevice->address() == localAvailableDevice.address()) + defaultDeviceIndex = it; + } - connect(remoteDeviceDiscoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)), - this, SLOT(addRemoteDevice(QBluetoothDeviceInfo))); - connect(remoteDeviceDiscoveryAgent, SIGNAL(finished()), - this, SLOT(remoteDeviceScanFinished())); + // Positionate the current index to the default device and register to index changes events + ui->localSelectedDevice->setCurrentIndex(defaultDeviceIndex); + connect(ui->localSelectedDevice, SIGNAL(currentIndexChanged(int)), + this, SLOT(localDeviceChanged(int))); + } else { + // If there is only one local Bluetooth adapter hide the combobox and the label + ui->selectDeviceLabel->hide(); + ui->localSelectedDevice->hide(); + } - // Add context menu for devices to be able to pair them - ui->discoveredDevicesList->setContextMenuPolicy(Qt::CustomContextMenu); - connect(ui->discoveredDevicesList, SIGNAL(customContextMenuRequested(QPoint)), - this, SLOT(displayPairingMenu(QPoint))); - connect(localDevice, SIGNAL(pairingFinished(QBluetoothAddress, QBluetoothLocalDevice::Pairing)), - this, SLOT(pairingFinished(QBluetoothAddress, QBluetoothLocalDevice::Pairing))); + // Update the UI information about the local device + updateLocalDeviceInformation(); - connect(localDevice, SIGNAL(error(QBluetoothLocalDevice::Error)), - this, SLOT(error(QBluetoothLocalDevice::Error))); + // Initialize the device discovery agent + if (localDevice->isValid()) + initializeDeviceDiscoveryAgent(); } BtDeviceSelectionDialog::~BtDeviceSelectionDialog() @@ -86,6 +83,12 @@ void BtDeviceSelectionDialog::on_save_clicked() // Save the selected device selectedRemoteDeviceInfo = QSharedPointer<QBluetoothDeviceInfo>(new QBluetoothDeviceInfo(remoteDeviceInfo)); + if (remoteDeviceDiscoveryAgent->isActive()) { + // Stop the SDP agent if the clear button is pressed and enable the Scan button + remoteDeviceDiscoveryAgent->stop(); + ui->scan->setEnabled(true); + } + // Close the device selection dialog and set the result code to Accepted accept(); } @@ -95,6 +98,12 @@ void BtDeviceSelectionDialog::on_clear_clicked() ui->dialogStatus->setText("Remote devices list was cleaned."); ui->discoveredDevicesList->clear(); ui->save->setEnabled(false); + + if (remoteDeviceDiscoveryAgent->isActive()) { + // Stop the SDP agent if the clear button is pressed and enable the Scan button + remoteDeviceDiscoveryAgent->stop(); + ui->scan->setEnabled(true); + } } void BtDeviceSelectionDialog::on_scan_clicked() @@ -108,21 +117,6 @@ void BtDeviceSelectionDialog::remoteDeviceScanFinished() { ui->dialogStatus->setText("Scanning finished."); ui->scan->setEnabled(true); - -#if defined(Q_OS_ANDROID) - // Check if there is a selected device and activate the Save button if it is paired - QListWidgetItem *currentItem = ui->discoveredDevicesList->currentItem(); - - if (currentItem != NULL) { - QBluetoothDeviceInfo remoteDeviceInfo = currentItem->data(Qt::UserRole).value<QBluetoothDeviceInfo>(); - QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(remoteDeviceInfo.address()); - - if (pairingStatus != QBluetoothLocalDevice::Unpaired) { - ui->save->setEnabled(true); - ui->dialogStatus->setText("Scanning finished. You can press the Save button and start the download."); - } - } -#endif } void BtDeviceSelectionDialog::hostModeStateChanged(QBluetoothLocalDevice::HostMode mode) @@ -137,12 +131,12 @@ void BtDeviceSelectionDialog::hostModeStateChanged(QBluetoothLocalDevice::HostMo void BtDeviceSelectionDialog::addRemoteDevice(const QBluetoothDeviceInfo &remoteDeviceInfo) { - QString deviceLable = QString("%1 (%2)").arg(remoteDeviceInfo.name()).arg(remoteDeviceInfo.address().toString()); - QList<QListWidgetItem *> itemsWithSameSignature = ui->discoveredDevicesList->findItems(deviceLable, Qt::MatchStartsWith); + QString deviceLabel = QString("%1 (%2)").arg(remoteDeviceInfo.name()).arg(remoteDeviceInfo.address().toString()); + QList<QListWidgetItem *> itemsWithSameSignature = ui->discoveredDevicesList->findItems(deviceLabel, Qt::MatchStartsWith); // Check if the remote device is already in the list if (itemsWithSameSignature.empty()) { - QListWidgetItem *item = new QListWidgetItem(deviceLable); + QListWidgetItem *item = new QListWidgetItem(deviceLabel); QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(remoteDeviceInfo.address()); item->setData(Qt::UserRole, QVariant::fromValue(remoteDeviceInfo)); @@ -161,7 +155,7 @@ void BtDeviceSelectionDialog::addRemoteDevice(const QBluetoothDeviceInfo &remote } } -void BtDeviceSelectionDialog::itemActivated(QListWidgetItem *item) +void BtDeviceSelectionDialog::itemClicked(QListWidgetItem *item) { QBluetoothDeviceInfo remoteDeviceInfo = item->data(Qt::UserRole).value<QBluetoothDeviceInfo>(); QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(remoteDeviceInfo.address()); @@ -171,19 +165,36 @@ void BtDeviceSelectionDialog::itemActivated(QListWidgetItem *item) .arg(remoteDeviceInfo.address().toString())); ui->save->setEnabled(false); } else { -#if defined(Q_OS_ANDROID) - if (remoteDeviceDiscoveryAgent->isActive()) { - ui->dialogStatus->setText(QString("The device %1 can be used for connection. Wait until the device scanning is done and press the Save button.") - .arg(remoteDeviceInfo.address().toString())); - return; - } -#endif ui->dialogStatus->setText(QString("The device %1 can be used for connection. You can press the Save button.") .arg(remoteDeviceInfo.address().toString())); ui->save->setEnabled(true); } } +void BtDeviceSelectionDialog::localDeviceChanged(int index) +{ + QBluetoothAddress localDeviceSelectedAddress = ui->localSelectedDevice->itemData(index, Qt::UserRole).value<QBluetoothAddress>(); + + // Delete the old localDevice + if (localDevice) + delete localDevice; + + // Create a new local device using the selected address + localDevice = new QBluetoothLocalDevice(localDeviceSelectedAddress); + + ui->dialogStatus->setText(QString("The local device was changed.")); + + // Clear the discovered devices list + on_clear_clicked(); + + // Update the UI information about the local device + updateLocalDeviceInformation(); + + // Initialize the device discovery agent + if (localDevice->isValid()) + initializeDeviceDiscoveryAgent(); +} + void BtDeviceSelectionDialog::displayPairingMenu(const QPoint &pos) { QMenu menu(this); @@ -261,7 +272,28 @@ void BtDeviceSelectionDialog::pairingFinished(const QBluetoothAddress &address, void BtDeviceSelectionDialog::error(QBluetoothLocalDevice::Error error) { ui->dialogStatus->setText(QString("Local device error: %1.") - .arg((error == QBluetoothLocalDevice::PairingError)? "Pairing error" : "Unknown error")); + .arg((error == QBluetoothLocalDevice::PairingError)? "Pairing error. If the remote device requires a custom PIN code, " + "please try to pair the devices using your operating system. " + : "Unknown error")); +} + +void BtDeviceSelectionDialog::deviceDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error error) +{ + QString errorDescription; + + switch (error) { + case QBluetoothDeviceDiscoveryAgent::PoweredOffError: + errorDescription = QString("The Bluetooth adaptor is powered off, power it on before doing discovery."); + break; + case QBluetoothDeviceDiscoveryAgent::InputOutputError: + errorDescription = QString("Writing or reading from the device resulted in an error."); + break; + default: + errorDescription = QString("An unknown error has occurred."); + break; + } + + ui->dialogStatus->setText(QString("Device discovery error: %1.").arg(errorDescription)); } QString BtDeviceSelectionDialog::getSelectedDeviceAddress() @@ -281,3 +313,69 @@ QString BtDeviceSelectionDialog::getSelectedDeviceName() return QString(); } + +void BtDeviceSelectionDialog::updateLocalDeviceInformation() +{ + // Check if the selected Bluetooth device can be accessed + if (!localDevice->isValid()) { + QString na = QString("Not available"); + + // Update the UI information + ui->deviceAddress->setText(na); + ui->deviceName->setText(na); + + // Announce the user that there is a problem with the selected local Bluetooth adapter + ui->dialogStatus->setText(QString("The local Bluetooth adapter cannot be accessed.")); + + // Disable the buttons + ui->save->setEnabled(false); + ui->scan->setEnabled(false); + ui->clear->setEnabled(false); + ui->changeDeviceState->setEnabled(false); + + return; + } + + // Set UI information about the local device + ui->deviceAddress->setText(localDevice->address().toString()); + ui->deviceName->setText(localDevice->name()); + + connect(localDevice, SIGNAL(hostModeStateChanged(QBluetoothLocalDevice::HostMode)), + this, SLOT(hostModeStateChanged(QBluetoothLocalDevice::HostMode))); + + // Initialize the state of the local device and activate/deactive the scan button + hostModeStateChanged(localDevice->hostMode()); + + // Add context menu for devices to be able to pair them + ui->discoveredDevicesList->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->discoveredDevicesList, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(displayPairingMenu(QPoint))); + connect(localDevice, SIGNAL(pairingFinished(QBluetoothAddress, QBluetoothLocalDevice::Pairing)), + this, SLOT(pairingFinished(QBluetoothAddress, QBluetoothLocalDevice::Pairing))); + + connect(localDevice, SIGNAL(error(QBluetoothLocalDevice::Error)), + this, SLOT(error(QBluetoothLocalDevice::Error))); +} + +void BtDeviceSelectionDialog::initializeDeviceDiscoveryAgent() +{ + // Intialize the discovery agent + remoteDeviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(localDevice->address()); + + // Test if the discovery agent was successfully created + if (remoteDeviceDiscoveryAgent->error() == QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError) { + ui->dialogStatus->setText(QString("The device discovery agent was not created because the %1 address does not " + "match the physical adapter address of any local Bluetooth device.") + .arg(localDevice->address().toString())); + ui->scan->setEnabled(false); + ui->clear->setEnabled(false); + return; + } + + connect(remoteDeviceDiscoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)), + this, SLOT(addRemoteDevice(QBluetoothDeviceInfo))); + connect(remoteDeviceDiscoveryAgent, SIGNAL(finished()), + this, SLOT(remoteDeviceScanFinished())); + connect(remoteDeviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), + this, SLOT(deviceDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error))); +} |