summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--examples/bluetooth/scanner/Button.qml79
-rw-r--r--examples/bluetooth/scanner/scanner.pro3
-rw-r--r--examples/bluetooth/scanner/scanner.qml82
-rw-r--r--examples/bluetooth/scanner/scanner.qrc1
-rw-r--r--src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp342
-rw-r--r--src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h56
6 files changed, 390 insertions, 173 deletions
diff --git a/examples/bluetooth/scanner/Button.qml b/examples/bluetooth/scanner/Button.qml
new file mode 100644
index 00000000..a3debfca
--- /dev/null
+++ b/examples/bluetooth/scanner/Button.qml
@@ -0,0 +1,79 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module.
+**
+** $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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: button
+
+ property bool active: buttonGroup.activeButton == button
+ property bool fullDiscovery: false
+ property alias text: label.text
+
+ signal clicked()
+
+ height: 60
+ width: 105
+
+ color: active ? "#1c56f3" : "white"
+
+ radius: 5
+ border.width: 2
+
+ Text {
+ id: label
+ text: "Full Discovery"
+ font.bold: true
+ anchors.fill: parent
+ wrapMode: Text.WordWrap
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ button.clicked()
+ //Reset the model
+ btModel.running = false
+ btModel.running = true
+ buttonGroup.activeButton = button
+ }
+ }
+}
diff --git a/examples/bluetooth/scanner/scanner.pro b/examples/bluetooth/scanner/scanner.pro
index 0d9b1e99..7e5c00f7 100644
--- a/examples/bluetooth/scanner/scanner.pro
+++ b/examples/bluetooth/scanner/scanner.pro
@@ -11,3 +11,6 @@ OTHER_FILES += \
scanner.qml
#DEFINES += QMLJSDEBUGGER
+
+OTHER_FILES += \
+ Button.qml
diff --git a/examples/bluetooth/scanner/scanner.qml b/examples/bluetooth/scanner/scanner.qml
index 86d1477b..52182362 100644
--- a/examples/bluetooth/scanner/scanner.qml
+++ b/examples/bluetooth/scanner/scanner.qml
@@ -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 examples of the QtBluetooth module.
@@ -48,21 +49,22 @@ Item {
BluetoothDiscoveryModel {
id: btModel
- minimalDiscovery: true
- onDiscoveryChanged: console.log("Discovery mode: " + discovery)
+ running: true
+ discoveryMode: BluetoothDiscoveryModel.DeviceDiscovery
+ onDiscoveryModeChanged: console.log("Discovery mode: " + discoveryMode)
onNewServiceDiscovered: console.log("Found new service " + service.deviceAddress + " " + service.deviceName + " " + service.serviceName);
}
Rectangle {
id: busy
- width: top.width * 0.8;
+ width: top.width * 0.7;
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: top.top;
- height: 20;
+ height: 30;
radius: 5
color: "#1c56f3"
- visible: btModel.discovery
+ visible: btModel.running
Text {
id: text
@@ -83,7 +85,7 @@ Item {
id: mainList
width: top.width
anchors.top: busy.bottom
- anchors.bottom: fullDiscoveryButton.top
+ anchors.bottom: buttonGroup.top
model: btModel
delegate: Rectangle {
@@ -117,12 +119,18 @@ Item {
Text {
id: details
function get_details(s) {
- var str = "Address: " + s.deviceAddress;
- if (s.serviceName) { str += "<br>Service: " + s.serviceName; }
- if (s.serviceDescription) { str += "<br>Description: " + s.serviceDescription; }
- if (s.serviceProtocol) { str += "<br>Protocol: " + s.serviceProtocol; }
- if (s.servicePort) { str += "<br>Port: " + s.servicePort; }
- return str;
+ if (btModel.discoveryMode == BluetoothDiscoveryModel.DeviceDiscovery) {
+ //We are doing a device discovery
+ var str = "Address: " + remoteAddress;
+ return str;
+ } else {
+ var str = "Address: " + s.deviceAddress;
+ if (s.serviceName) { str += "<br>Service: " + s.serviceName; }
+ if (s.serviceDescription) { str += "<br>Description: " + s.serviceDescription; }
+ if (s.serviceProtocol) { str += "<br>Protocol: " + s.serviceProtocol; }
+ if (s.servicePort) { str += "<br>Port: " + s.servicePort; }
+ return str;
+ }
}
visible: opacity !== 0
opacity: btDelegate.expended ? 1 : 0.0
@@ -143,41 +151,29 @@ Item {
focus: true
}
- Rectangle {
- id: fullDiscoveryButton
-
- property bool fullDiscovery: false
-
- onFullDiscoveryChanged: {
- btModel.minimalDiscovery = !fullDiscovery;
- //reset discovery since we changed the discovery mode
- btModel.discovery = false;
- btModel.discovery = true;
- }
+ Row {
+ id: buttonGroup
+ property var activeButton: devButton
- anchors.bottom: top.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: 3
-
- height: 20
-
- color: fullDiscovery ? "#1c56f3" : "white"
-
- radius: 5
- border.width: 1
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 20
- Text {
- id: label
+ Button {
+ id: fdButton
text: "Full Discovery"
- anchors.centerIn: parent
+ onClicked: btModel.discoveryMode = BluetoothDiscoveryModel.FullServiceDiscovery
}
-
- MouseArea {
- anchors.fill: parent
- onClicked: parent.fullDiscovery = !parent.fullDiscovery
+ Button {
+ id: mdButton
+ text: "Minimal Discovery"
+ onClicked: btModel.discoveryMode = BluetoothDiscoveryModel.MinimalServiceDiscovery
+ }
+ Button {
+ id: devButton
+ text: "Device Discovery"
+ onClicked: btModel.discoveryMode = BluetoothDiscoveryModel.DeviceDiscovery
}
-
- Behavior on color { ColorAnimation { duration: 200 } }
}
+
}
diff --git a/examples/bluetooth/scanner/scanner.qrc b/examples/bluetooth/scanner/scanner.qrc
index 9543f065..46232c8a 100644
--- a/examples/bluetooth/scanner/scanner.qrc
+++ b/examples/bluetooth/scanner/scanner.qrc
@@ -2,5 +2,6 @@
<qresource prefix="/">
<file>scanner.qml</file>
<file>default.png</file>
+ <file>Button.qml</file>
</qresource>
</RCC>
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;