diff options
Diffstat (limited to 'examples/btfiletransfer/remoteselector.cpp')
-rw-r--r-- | examples/btfiletransfer/remoteselector.cpp | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/examples/btfiletransfer/remoteselector.cpp b/examples/btfiletransfer/remoteselector.cpp new file mode 100644 index 00000000..ca49d9c3 --- /dev/null +++ b/examples/btfiletransfer/remoteselector.cpp @@ -0,0 +1,372 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "remoteselector.h" +#include "ui_remoteselector.h" + +#include <qbluetoothdeviceinfo.h> +#include <qbluetoothaddress.h> +#include <qbluetoothtransferrequest.h> +#include <qbluetoothtransferreply.h> +#include <qbluetoothlocaldevice.h> + +#include <QMovie> +#include <QMessageBox> +#include <QFileDialog> +#include <QCheckBox> + +#include "progress.h" +#include "pindisplay.h" + +QTBLUETOOTH_USE_NAMESPACE + +RemoteSelector::RemoteSelector(QWidget *parent) +: QDialog(parent), ui(new Ui::RemoteSelector), + m_discoveryAgent(new QBluetoothServiceDiscoveryAgent), m_localDevice(new QBluetoothLocalDevice), m_pindisplay(0) +{ + ui->setupUi(this); + + connect(m_discoveryAgent, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)), + this, SLOT(serviceDiscovered(QBluetoothServiceInfo))); + connect(m_discoveryAgent, SIGNAL(finished()), this, SLOT(discoveryFinished())); + + ui->remoteDevices->setColumnWidth(3, 75); + ui->remoteDevices->setColumnWidth(4, 100); + + connect(m_localDevice, SIGNAL(pairingDisplayPinCode(const QBluetoothAddress &,QString)), this, SLOT(displayPin(const QBluetoothAddress &, QString))); + connect(m_localDevice, SIGNAL(pairingDisplayConfirmation(QBluetoothAddress,QString)), this, SLOT(displayConfirmation(QBluetoothAddress,QString))); + connect(m_localDevice, SIGNAL(pairingFinished(QBluetoothAddress,QBluetoothLocalDevice::Pairing)), this, SLOT(pairingFinished(QBluetoothAddress,QBluetoothLocalDevice::Pairing))); + + ui->busyWidget->setMovie(new QMovie(":/icons/busy.gif")); + ui->busyWidget->movie()->start(); + + ui->pairingBusy->setMovie(new QMovie(":/icons/pairing.gif")); + ui->pairingBusy->hide(); + + ui->remoteDevices->clearContents(); + ui->remoteDevices->setRowCount(0); + + +} + +RemoteSelector::~RemoteSelector() +{ + delete ui; + delete m_discoveryAgent; + delete m_localDevice; +} + +void RemoteSelector::startDiscovery(const QBluetoothUuid &uuid) +{ + ui->stopButton->setDisabled(false); + if (m_discoveryAgent->isActive()) + m_discoveryAgent->stop(); + + m_discoveryAgent->setUuidFilter(uuid); + m_discoveryAgent->start(); + + ui->status->setText(tr("Scanning...")); + ui->busyWidget->show(); + ui->busyWidget->movie()->start(); +} + +QBluetoothServiceInfo RemoteSelector::service() const +{ + return m_service; +} + +void RemoteSelector::serviceDiscovered(const QBluetoothServiceInfo &serviceInfo) +{ +#if 0 + qDebug() << "Discovered service on" + << serviceInfo.device().name() << serviceInfo.device().address().toString(); + qDebug() << "\tService name:" << serviceInfo.serviceName(); + qDebug() << "\tDescription:" + << serviceInfo.attribute(QBluetoothServiceInfo::ServiceDescription).toString(); + qDebug() << "\tProvider:" + << serviceInfo.attribute(QBluetoothServiceInfo::ServiceProvider).toString(); + qDebug() << "\tL2CAP protocol service multiplexer:" + << serviceInfo.protocolServiceMultiplexer(); + qDebug() << "\tRFCOMM server channel:" << serviceInfo.serverChannel(); +#endif + + QString remoteName; + if (serviceInfo.device().name().isEmpty()) + remoteName = serviceInfo.device().address().toString(); + else + remoteName = serviceInfo.device().name(); + +// QListWidgetItem *item = +// new QListWidgetItem(QString::fromLatin1("%1\t%2\t%3").arg(serviceInfo.device().address().toString(), +// serviceInfo.device().name(), serviceInfo.serviceName())); + + QMutableMapIterator<int, QBluetoothServiceInfo> i(m_discoveredServices); + while (i.hasNext()){ + i.next(); + if (serviceInfo.device().address() == i.value().device().address()){ + i.setValue(serviceInfo); + return; + } + } + + int row = ui->remoteDevices->rowCount(); + ui->remoteDevices->insertRow(row); + QTableWidgetItem *item = new QTableWidgetItem(serviceInfo.device().address().toString()); + ui->remoteDevices->setItem(row, 0, item); + item = new QTableWidgetItem(serviceInfo.device().name()); + ui->remoteDevices->setItem(row, 1, item); + item = new QTableWidgetItem(serviceInfo.serviceName()); + + ui->remoteDevices->setItem(row, 2, item); + + QBluetoothLocalDevice::Pairing p; + + p = m_localDevice->pairingStatus(serviceInfo.device().address()); + + ui->remoteDevices->blockSignals(true); + + item = new QTableWidgetItem(); + if ((p&QBluetoothLocalDevice::Paired) || (p&QBluetoothLocalDevice::AuthorizedPaired)) + item->setCheckState(Qt::Checked); + else + item->setCheckState(Qt::Unchecked); + ui->remoteDevices->setItem(row, 3, item); + + item = new QTableWidgetItem(); + if (p&QBluetoothLocalDevice::AuthorizedPaired) + item->setCheckState(Qt::Checked); + else + item->setCheckState(Qt::Unchecked); + + ui->remoteDevices->setItem(row, 4, item); + + ui->remoteDevices->blockSignals(false); + + + m_discoveredServices.insert(row, serviceInfo); +} + +void RemoteSelector::discoveryFinished() +{ + ui->status->setText(tr("Select the device to send to.")); + ui->stopButton->setDisabled(true); + ui->busyWidget->movie()->stop(); + ui->busyWidget->hide(); +} + +void RemoteSelector::startDiscovery() +{ + startDiscovery(QBluetoothUuid(QBluetoothUuid::ObexObjectPush)); +} + +void RemoteSelector::on_refreshPB_clicked() +{ + startDiscovery(); + ui->stopButton->setDisabled(false); +} + +void RemoteSelector::on_fileSelectPB_clicked() +{ + ui->fileName->setText(QFileDialog::getOpenFileName()); + if (m_service.isValid()) + ui->sendButton->setDisabled(false); +} + +void RemoteSelector::on_sendButton_clicked() +{ + QBluetoothTransferManager mgr; + QBluetoothTransferRequest req(m_service.device().address()); + + m_file = new QFile(ui->fileName->text()); + + Progress *p = new Progress; + p->setStatus("Sending to: " + m_service.device().name(), "Waiting for start"); + p->show(); + + QBluetoothTransferReply *reply = mgr.put(req, m_file); + if (reply->error()){ + qDebug() << "Failed to send file"; + delete reply; + p->finished(reply); + return; + } + + connect(reply, SIGNAL(uploadProgress(qint64,qint64)), p, SLOT(uploadProgress(qint64,qint64))); + connect(reply, SIGNAL(finished(QBluetoothTransferReply*)), p, SLOT(finished(QBluetoothTransferReply*))); + connect(p, SIGNAL(rejected()), reply, SLOT(abort())); +} + +void RemoteSelector::on_stopButton_clicked() +{ + m_discoveryAgent->stop(); +} + +QString RemoteSelector::addressToName(const QBluetoothAddress &address) +{ + QMapIterator<int, QBluetoothServiceInfo> i(m_discoveredServices); + while (i.hasNext()){ + i.next(); + if (i.value().device().address() == address) + return i.value().device().name(); + } + return address.toString(); +} + +void RemoteSelector::displayPin(const QBluetoothAddress &address, QString pin) +{ + if (m_pindisplay) + m_pindisplay->deleteLater(); + m_pindisplay = new pinDisplay(QString("Enter pairing pin on: %1").arg(addressToName(address)), pin, this); + m_pindisplay->show(); +} + +void RemoteSelector::displayConfirmation(const QBluetoothAddress &address, QString pin) +{ + Q_UNUSED(address); + + if (m_pindisplay) + m_pindisplay->deleteLater(); + m_pindisplay = new pinDisplay(QString("Confirm this pin is the same"), pin, this); + connect(m_pindisplay, SIGNAL(accepted()), this, SLOT(displayConfAccepted())); + connect(m_pindisplay, SIGNAL(rejected()), this, SLOT(displayConfReject())); + m_pindisplay->setOkCancel(); + m_pindisplay->show(); +} + +void RemoteSelector::displayConfAccepted() +{ + m_localDevice->pairingConfirmation(true); +} +void RemoteSelector::displayConfReject() +{ + m_localDevice->pairingConfirmation(false); +} + +void RemoteSelector::pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing status) +{ + QBluetoothServiceInfo service; + int row = 0; + + ui->pairingBusy->hide(); + ui->pairingBusy->movie()->stop(); + + ui->remoteDevices->blockSignals(true); + + for (int i = 0; i < m_discoveredServices.count(); i++){ + if (m_discoveredServices.value(i).device().address() == address){ + service = m_discoveredServices.value(i); + row = i; + break; + } + } + + if (m_pindisplay) + delete m_pindisplay; + + QMessageBox msgBox; + if (status == QBluetoothLocalDevice::Paired || + status == QBluetoothLocalDevice::AuthorizedPaired){ + msgBox.setText("Paired successfully with" + address.toString()); + } + else { + msgBox.setText("Pairing failed with " + address.toString()); + } + + if (service.isValid()){ + if (status == QBluetoothLocalDevice::AuthorizedPaired){ + ui->remoteDevices->item(row, 3)->setCheckState(Qt::Checked); + ui->remoteDevices->item(row, 4)->setCheckState(Qt::Checked); + } + else if (status == QBluetoothLocalDevice::Paired){ + ui->remoteDevices->item(row, 3)->setCheckState(Qt::Checked); + ui->remoteDevices->item(row, 4)->setCheckState(Qt::Unchecked); + } + else { + ui->remoteDevices->item(row, 3)->setCheckState(Qt::Unchecked); + ui->remoteDevices->item(row, 4)->setCheckState(Qt::Unchecked); + } + } + + msgBox.exec(); + + ui->remoteDevices->blockSignals(false); + + +} + +void RemoteSelector::on_remoteDevices_cellClicked(int row, int column) +{ + Q_UNUSED(column); + + m_service = m_discoveredServices.value(row); + if (!ui->fileName->text().isEmpty()) { + ui->sendButton->setDisabled(false); + } +} + +void RemoteSelector::on_remoteDevices_itemChanged(QTableWidgetItem* item) +{ + int row = item->row(); + int column = item->column(); + m_service = m_discoveredServices.value(row); + + if (column < 3) + return; + + if (item->checkState() == Qt::Unchecked && column == 3){ + m_localDevice->requestPairing(m_service.device().address(), QBluetoothLocalDevice::Unpaired); + return; // don't continue and start movie + } + else if ((item->checkState() == Qt::Checked && column == 3) || + (item->checkState() == Qt::Unchecked && column == 4)){ + m_localDevice->requestPairing(m_service.device().address(), QBluetoothLocalDevice::Paired); + ui->remoteDevices->blockSignals(true); + ui->remoteDevices->item(row, column)->setCheckState(Qt::PartiallyChecked); + ui->remoteDevices->blockSignals(false); + } + else if (item->checkState() == Qt::Checked && column == 4){ + m_localDevice->requestPairing(m_service.device().address(), QBluetoothLocalDevice::AuthorizedPaired); + ui->remoteDevices->blockSignals(true); + ui->remoteDevices->item(row, column)->setCheckState(Qt::PartiallyChecked); + ui->remoteDevices->blockSignals(false); + } + ui->pairingBusy->show(); + ui->pairingBusy->movie()->start(); +} |