summaryrefslogtreecommitdiffstats
path: root/src/imports
diff options
context:
space:
mode:
authorFabian Bumberger <fbumberger@rim.com>2013-09-16 18:01:13 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-18 17:24:18 +0200
commit8e86bc19f4be7d2d01181ab45a8cadd4320887ec (patch)
tree06ef4b435f0dd6b5b518d4f784bbe4e64ad450db /src/imports
parent2d8378e49807ef3bf6e6662fbfcec96e95ee328f (diff)
Refactor QBluetoothDiscoveryModel
- Add the option to discover devices - Clear the model when a new discovery is started. In the previous implementation the model was only cleared if new data was available. This can lead to some funny results. - Change some property types to enums - Enhance the qmlscanner example Change-Id: I94f33e3eabd7440b5c0c6c83f3e8158009bd2dbd Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
Diffstat (limited to 'src/imports')
-rw-r--r--src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp342
-rw-r--r--src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h56
2 files changed, 268 insertions, 130 deletions
diff --git a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp
index 0bcdd46c..b3077073 100644
--- a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp
+++ b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
@@ -61,8 +62,9 @@
contents of the model can be filtered by UUID allowing discovery to be
limited to a single service such as a game.
- The model roles provided by BluetoothDiscoveryModel are display, decoration and \c Service.
- Through the \c Service role the BluetoothService can be accessed for more details.
+ The model roles provided by BluetoothDiscoveryModel are
+ \c service, \c name, \c remoteAddress and \c deviceName.
+ Through the \c service role the BluetoothService can be accessed for more details.
\sa QBluetoothServiceDiscoveryAgent
@@ -72,32 +74,37 @@ class QDeclarativeBluetoothDiscoveryModelPrivate
{
public:
QDeclarativeBluetoothDiscoveryModelPrivate()
- :m_agent(0),
- m_error(QBluetoothServiceDiscoveryAgent::NoError),
- m_minimal(true),
- m_componentCompleted(false),
- m_discovery(false),
- m_modelDataNeedsReset(false)
+ : m_serviceAgent(0),
+ m_deviceAgent(0),
+ m_error(QDeclarativeBluetoothDiscoveryModel::NoError),
+ m_discoveryMode(QDeclarativeBluetoothDiscoveryModel::MinimalServiceDiscovery),
+ m_running(false),
+ m_runningRequested(true),
+ m_componentCompleted(false)
{
}
~QDeclarativeBluetoothDiscoveryModelPrivate()
{
- if (m_agent)
- delete m_agent;
+ if (m_deviceAgent)
+ delete m_deviceAgent;
+
+ if (m_serviceAgent)
+ delete m_serviceAgent;
qDeleteAll(m_services);
}
- QBluetoothServiceDiscoveryAgent *m_agent;
+ QBluetoothServiceDiscoveryAgent *m_serviceAgent;
+ QBluetoothDeviceDiscoveryAgent *m_deviceAgent;
- QBluetoothServiceDiscoveryAgent::Error m_error;
-// QList<QBluetoothServiceInfo> m_services;
+ QDeclarativeBluetoothDiscoveryModel::Error m_error;
QList<QDeclarativeBluetoothService *> m_services;
- bool m_minimal;
- bool m_componentCompleted;
+ QList<QBluetoothDeviceInfo> m_devices;
+ QDeclarativeBluetoothDiscoveryModel::DiscoveryMode m_discoveryMode;
QString m_uuid;
- bool m_discovery;
- bool m_modelDataNeedsReset;
+ bool m_running;
+ bool m_runningRequested;
+ bool m_componentCompleted;
};
QDeclarativeBluetoothDiscoveryModel::QDeclarativeBluetoothDiscoveryModel(QObject *parent) :
@@ -107,16 +114,11 @@ QDeclarativeBluetoothDiscoveryModel::QDeclarativeBluetoothDiscoveryModel(QObject
QHash<int, QByteArray> roleNames;
roleNames = QAbstractItemModel::roleNames();
- roleNames.insert(Qt::DisplayRole, "name");
- roleNames.insert(Qt::DecorationRole, "icon");
+ roleNames.insert(Name, "name");
roleNames.insert(ServiceRole, "service");
+ roleNames.insert(RemoteAddress, "remoteAddress");
+ roleNames.insert(DeviceName, "deviceName");
setRoleNames(roleNames);
-
- d->m_agent = new QBluetoothServiceDiscoveryAgent(this);
- connect(d->m_agent, SIGNAL(serviceDiscovered(const QBluetoothServiceInfo&)), this, SLOT(serviceDiscovered(const QBluetoothServiceInfo&)));
- connect(d->m_agent, SIGNAL(finished()), this, SLOT(finishedDiscovery()));
- connect(d->m_agent, SIGNAL(canceled()), this, SLOT(finishedDiscovery()));
- connect(d->m_agent, SIGNAL(error(QBluetoothServiceDiscoveryAgent::Error)), this, SLOT(errorDiscovery(QBluetoothServiceDiscoveryAgent::Error)));
}
QDeclarativeBluetoothDiscoveryModel::~QDeclarativeBluetoothDiscoveryModel()
@@ -126,107 +128,138 @@ QDeclarativeBluetoothDiscoveryModel::~QDeclarativeBluetoothDiscoveryModel()
void QDeclarativeBluetoothDiscoveryModel::componentComplete()
{
d->m_componentCompleted = true;
- setDiscovery(true);
+ if (d->m_runningRequested)
+ setRunning(true);
}
-/*!
- \qmlproperty bool BluetoothDiscoveryModel::discovery
-
- This property starts or stops discovery. A restart of the discovery process
- requires setting this property to \c false and subsequemtly to \c true again.
-
-*/
-void QDeclarativeBluetoothDiscoveryModel::setDiscovery(bool discovery_)
+void QDeclarativeBluetoothDiscoveryModel::errorDiscovery(QBluetoothServiceDiscoveryAgent::Error error)
{
- if (!d->m_componentCompleted)
- return;
-
- if (d->m_discovery == discovery_)
- return;
-
- d->m_discovery = discovery_;
-
- if (!discovery_) {
- d->m_agent->stop();
- } else {
- if (!d->m_uuid.isEmpty())
- d->m_agent->setUuidFilter(QBluetoothUuid(d->m_uuid));
-
- if (d->m_minimal)
- d->m_agent->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
- else
- d->m_agent->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
-
- d->m_modelDataNeedsReset = true;
+ switch (error) {
+ case QBluetoothServiceDiscoveryAgent::DeviceDiscoveryError:
+ d->m_error = DeviceDiscoveryError;
+ break;
+ case QBluetoothServiceDiscoveryAgent::UnknownError:
+ d->m_error = UnknownError;
+ break;
+ default:
+ d->m_error = UnknownError;
+ break;
}
-
- emit discoveryChanged();
+ emit errorChanged();
}
-void QDeclarativeBluetoothDiscoveryModel::errorDiscovery(QBluetoothServiceDiscoveryAgent::Error error)
+void QDeclarativeBluetoothDiscoveryModel::errorDeviceDiscovery(QBluetoothDeviceDiscoveryAgent::Error error)
{
- d->m_error = error;
+ switch (error) {
+ case QBluetoothDeviceDiscoveryAgent::IOFailure:
+ d->m_error = IOFailure;
+ break;
+ case QBluetoothDeviceDiscoveryAgent::PoweredOff:
+ d->m_error = PoweredOffFailure;
+ break;
+ case QBluetoothDeviceDiscoveryAgent::UnknownError:
+ d->m_error = UnknownError;
+ break;
+ default:
+ d->m_error = UnknownError;
+ break;
+ }
emit errorChanged();
}
-void QDeclarativeBluetoothDiscoveryModel::clearModelIfRequired()
+void QDeclarativeBluetoothDiscoveryModel::clearModel()
{
- if (d->m_modelDataNeedsReset) {
- d->m_modelDataNeedsReset = false;
-
- beginResetModel();
- qDeleteAll(d->m_services);
- d->m_services.clear();
- endResetModel();
- }
+ beginResetModel();
+ qDeleteAll(d->m_services);
+ d->m_services.clear();
+ d->m_devices.clear();
+ endResetModel();
}
/*!
- \qmlproperty string BluetoothDiscoveryModel::error
-
- This property holds the last error reported during discovery.
+ \qmlproperty enumeration BluetoothDiscoveryModel::error
+
+ This property holds the last error reported during discovery.
+ \table
+ \header \li Property \li Description
+ \row \li \c BluetoothDiscoveryModel.NoError
+ \li No error occurred.
+ \row \li \c BluetoothDiscoveryModel.IOFailure
+ \li An IO failure occurred during device discovery
+ \row \li \c BluetoothDiscoveryModel.PoweredOffFailure
+ \li The bluetooth device is not powered on.
+ \row \li \c BluetoothDiscoveryModel.DeviceDiscoveryError
+ \li In order to be able to discover services a device discovery is started first.
+ This error indicates that a problem detected there.
+ \row \li \c BluetoothDiscoveryModel.UnknownError
+ \li An unknown error occurred.
+ \endtable
This property is read-only.
*/
-QString QDeclarativeBluetoothDiscoveryModel::error() const
+QDeclarativeBluetoothDiscoveryModel::Error QDeclarativeBluetoothDiscoveryModel::error() const
{
- switch (d->m_error){
- case QBluetoothServiceDiscoveryAgent::NoError:
- break;
- default:
- return QLatin1String("UnknownError");
- }
- return QLatin1String("NoError");
-
+ return d->m_error;
}
int QDeclarativeBluetoothDiscoveryModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
- return d->m_services.count();
+ if (discoveryMode() == DeviceDiscovery)
+ return d->m_devices.count();
+ else
+ return d->m_services.count();
}
QVariant QDeclarativeBluetoothDiscoveryModel::data(const QModelIndex &index, int role) const
{
- if (!index.isValid())
+ if (!index.isValid() || index.row() < 0)
return QVariant();
- QDeclarativeBluetoothService *service = d->m_services.value(index.row());
-
- switch (role) {
- case Qt::DisplayRole:
- {
- QString label = service->deviceName();
- if (label.isEmpty())
- label += service->deviceAddress();
- else
- label+= QStringLiteral(":");
- label += QStringLiteral(" ") + service->serviceName();
- return label;
+ if (discoveryMode() != DeviceDiscovery) {
+ if (index.row() >= d->m_services.count()){
+ qWarning() << "index out of bounds";
+ return QVariant();
+ }
+
+ QDeclarativeBluetoothService *service = d->m_services.value(index.row());
+
+ switch (role) {
+ case Name: {
+ QString label = service->deviceName();
+ if (label.isEmpty())
+ label += service->deviceAddress();
+ else
+ label+= QStringLiteral(":");
+ label += QStringLiteral(" ") + service->serviceName();
+ return label;
+ }
+ case ServiceRole:
+ return QVariant::fromValue(service);
+ case DeviceName:
+ return service->deviceName();
+ case RemoteAddress:
+ return service->deviceAddress();
+ }
+ } else {
+ if (index.row() >= d->m_devices.count()) {
+ qWarning() << "index out of bounds";
+ return QVariant();
+ }
+
+ QBluetoothDeviceInfo device = d->m_devices.value(index.row());
+ switch (role) {
+ case Name:
+ return (device.name() + QStringLiteral(" (") + device.address().toString() + QStringLiteral(")"));
+ case ServiceRole:
+ break;
+ case DeviceName:
+ return device.name();
+ case RemoteAddress:
+ return device.address().toString();
}
- case ServiceRole:
- return QVariant::fromValue(service);
}
+
return QVariant();
}
@@ -238,7 +271,7 @@ QVariant QDeclarativeBluetoothDiscoveryModel::data(const QModelIndex &index, int
void QDeclarativeBluetoothDiscoveryModel::serviceDiscovered(const QBluetoothServiceInfo &service)
{
- clearModelIfRequired();
+ //qDebug() << "service discovered";
QDeclarativeBluetoothService *bs = new QDeclarativeBluetoothService(service, this);
QDeclarativeBluetoothService *current = 0;
@@ -258,6 +291,22 @@ void QDeclarativeBluetoothDiscoveryModel::serviceDiscovered(const QBluetoothServ
}
/*!
+ \qmlsignal BluetoothDiscoveryModel::newDeviceDiscovered()
+
+ This handler is called when a new device is discovered.
+ */
+
+void QDeclarativeBluetoothDiscoveryModel::deviceDiscovered(const QBluetoothDeviceInfo &device)
+{
+ //qDebug() << "Device discovered" << device.address().toString() << device.name();
+
+ beginInsertRows(QModelIndex(),d->m_devices.count(), d->m_devices.count());
+ d->m_devices.append(device);
+ endInsertRows();
+ emit newDeviceDiscovered();
+}
+
+/*!
\qmlsignal BluetoothDiscoveryModel::discoveryChanged()
This handler is called when discovery has completed and no
@@ -266,35 +315,102 @@ void QDeclarativeBluetoothDiscoveryModel::serviceDiscovered(const QBluetoothServ
void QDeclarativeBluetoothDiscoveryModel::finishedDiscovery()
{
- clearModelIfRequired();
- if (d->m_discovery) {
- d->m_discovery = false;
- emit discoveryChanged();
- }
+ setRunning(false);
}
/*!
- \qmlproperty bool BluetoothDiscoveryModel::minimalDiscovery
-
- This property controls minimalDiscovery, which is faster than full discocvery but it
- only guarantees the device and UUID information to be correct.
+ \qmlproperty enumeration BluetoothDiscoveryModel::discoveryMode
+
+ Sets the discovery mode. The discovery mode has to be set before the discovery is started
+ \table
+ \header \li Property \li Description
+ \row \li \c BluetoothDiscoveryModel.FullServiceDiscovery
+ \li Starts a full discovery of all services of all devices in range.
+ \row \li \c BluetoothDiscoveryModel.MinimalServiceDiscovery
+ \li (Default) Starts a minimal discovery of all services of all devices in range. A minimal discovery is
+ faster but only guarantees the device and UUID information to be correct.
+ \row \li \c BluetoothDiscoveryModel.DeviceDiscovery
+ \li Discovers only devices in range. The service role will be 0 for any model item.
+ \endtable
+*/
- */
+QDeclarativeBluetoothDiscoveryModel::DiscoveryMode QDeclarativeBluetoothDiscoveryModel::discoveryMode() const
+{
+ return d->m_discoveryMode;
+}
-bool QDeclarativeBluetoothDiscoveryModel::minimalDiscovery() const
+void QDeclarativeBluetoothDiscoveryModel::setDiscoveryMode(DiscoveryMode discovery)
{
- return d->m_minimal;
+ d->m_discoveryMode = discovery;
+ emit discoveryModeChanged();
}
-void QDeclarativeBluetoothDiscoveryModel::setMinimalDiscovery(bool minimalDiscovery_)
+/*!
+ \qmlproperty bool BluetoothDiscoveryModel::running
+
+ This property starts or stops discovery. A restart of the discovery process
+ requires setting this property to \c false and subsequemtly to \c true again.
+
+*/
+
+bool QDeclarativeBluetoothDiscoveryModel::running() const
{
- d->m_minimal = minimalDiscovery_;
- emit minimalDiscoveryChanged();
+ return d->m_running;
}
-bool QDeclarativeBluetoothDiscoveryModel::discovery() const
+void QDeclarativeBluetoothDiscoveryModel::setRunning(bool running)
{
- return d->m_discovery;
+ if (!d->m_componentCompleted) {
+ d->m_runningRequested = running;
+ return;
+ }
+
+ if (d->m_running == running)
+ return;
+
+ d->m_running = running;
+
+ if (!running) {
+ if (d->m_deviceAgent) {
+ d->m_deviceAgent->stop();
+ } else if (d->m_serviceAgent) {
+ d->m_serviceAgent->stop();
+ }
+ } else {
+ clearModel();
+ d->m_error = NoError;
+ if (d->m_discoveryMode == DeviceDiscovery) {
+ if (!d->m_deviceAgent) {
+ d->m_deviceAgent = new QBluetoothDeviceDiscoveryAgent(this);
+ connect(d->m_deviceAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)), this, SLOT(deviceDiscovered(QBluetoothDeviceInfo)));
+ connect(d->m_deviceAgent, SIGNAL(finished()), this, SLOT(finishedDiscovery()));
+ connect(d->m_deviceAgent, SIGNAL(canceled()), this, SLOT(finishedDiscovery()));
+ connect(d->m_deviceAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), this, SLOT(errorDeviceDiscovery(QBluetoothDeviceDiscoveryAgent::Error)));
+ }
+ d->m_deviceAgent->start();
+ } else {
+ if (!d->m_serviceAgent) {
+ d->m_serviceAgent = new QBluetoothServiceDiscoveryAgent(this);
+ connect(d->m_serviceAgent, SIGNAL(serviceDiscovered(const QBluetoothServiceInfo&)), this, SLOT(serviceDiscovered(const QBluetoothServiceInfo&)));
+ connect(d->m_serviceAgent, SIGNAL(finished()), this, SLOT(finishedDiscovery()));
+ connect(d->m_serviceAgent, SIGNAL(canceled()), this, SLOT(finishedDiscovery()));
+ connect(d->m_serviceAgent, SIGNAL(error(QBluetoothServiceDiscoveryAgent::Error)), this, SLOT(errorDiscovery(QBluetoothServiceDiscoveryAgent::Error)));
+ }
+
+ if (!d->m_uuid.isEmpty())
+ d->m_serviceAgent->setUuidFilter(QBluetoothUuid(d->m_uuid));
+
+ if (discoveryMode() == FullServiceDiscovery) {
+ //qDebug() << "Full Discovery";
+ d->m_serviceAgent->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
+ } else {
+ //qDebug() << "Minimal Discovery";
+ d->m_serviceAgent->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
+ }
+ }
+ }
+
+ Q_EMIT runningChanged();
}
/*!
diff --git a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h
index 8cc76817..725f98bf 100644
--- a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h
+++ b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
@@ -48,6 +49,7 @@
#include <qbluetoothserviceinfo.h>
#include <qbluetoothservicediscoveryagent.h>
+#include <qbluetoothdevicediscoveryagent.h>
#include <qbluetoothglobal.h>
@@ -59,9 +61,11 @@ class QDeclarativeBluetoothDiscoveryModelPrivate;
class QDeclarativeBluetoothDiscoveryModel : public QAbstractListModel, public QQmlParserStatus
{
Q_OBJECT
- Q_PROPERTY(QString error READ error NOTIFY errorChanged)
- Q_PROPERTY(bool minimalDiscovery READ minimalDiscovery WRITE setMinimalDiscovery NOTIFY minimalDiscoveryChanged)
- Q_PROPERTY(bool discovery READ discovery WRITE setDiscovery NOTIFY discoveryChanged)
+ Q_ENUMS(DiscoveryMode)
+ Q_ENUMS(Error)
+ Q_PROPERTY(Error error READ error NOTIFY errorChanged)
+ Q_PROPERTY(DiscoveryMode discoveryMode READ discoveryMode WRITE setDiscoveryMode NOTIFY discoveryModeChanged)
+ Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged)
Q_PROPERTY(QString uuidFilter READ uuidFilter WRITE setUuidFilter NOTIFY uuidFilterChanged)
Q_INTERFACES(QQmlParserStatus)
public:
@@ -69,45 +73,63 @@ public:
virtual ~QDeclarativeBluetoothDiscoveryModel();
enum {
- ServiceRole = Qt::UserRole + 500,
- AddressRole,
- NameRole
+ Name = Qt::UserRole + 1,
+ ServiceRole,
+ DeviceName,
+ RemoteAddress
};
- QString error() const;
+ enum DiscoveryMode {
+ MinimalServiceDiscovery,
+ FullServiceDiscovery,
+ DeviceDiscovery
+ };
+
+ enum Error
+ {
+ NoError,
+ IOFailure,
+ PoweredOffFailure,
+ DeviceDiscoveryError,
+ UnknownError
+ };
+
+ Error error() const;
- // From QDeclarativeParserStatus
- virtual void classBegin() {}
+ void componentComplete();
- virtual void componentComplete();
+ void classBegin() { }
// From QAbstractListModel
int rowCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
- bool minimalDiscovery() const;
- void setMinimalDiscovery(bool minimalDiscovery_);
+ DiscoveryMode discoveryMode() const;
+ void setDiscoveryMode(DiscoveryMode discovery);
- bool discovery() const;
- void setDiscovery(bool discovery_);
+ bool running() const;
+ void setRunning(bool running);
QString uuidFilter() const;
void setUuidFilter(QString uuid);
signals:
void errorChanged();
- void minimalDiscoveryChanged();
+ void discoveryModeChanged();
void newServiceDiscovered(QDeclarativeBluetoothService *service);
- void discoveryChanged();
+ void newDeviceDiscovered();
+ void runningChanged();
void uuidFilterChanged();
private slots:
void serviceDiscovered(const QBluetoothServiceInfo &service);
+ void deviceDiscovered(const QBluetoothDeviceInfo &device);
void finishedDiscovery();
void errorDiscovery(QBluetoothServiceDiscoveryAgent::Error error);
+ void errorDeviceDiscovery(QBluetoothDeviceDiscoveryAgent::Error);
private:
- void clearModelIfRequired();
+ void clearModel();
private:
QDeclarativeBluetoothDiscoveryModelPrivate* d;