summaryrefslogtreecommitdiffstats
path: root/examples/btfiletransfer/remoteselector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/btfiletransfer/remoteselector.cpp')
-rw-r--r--examples/btfiletransfer/remoteselector.cpp372
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();
+}