diff options
author | Fabian Bumberger <fbumberger@rim.com> | 2013-09-16 18:01:13 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-18 17:24:18 +0200 |
commit | 8e86bc19f4be7d2d01181ab45a8cadd4320887ec (patch) | |
tree | 06ef4b435f0dd6b5b518d4f784bbe4e64ad450db | |
parent | 2d8378e49807ef3bf6e6662fbfcec96e95ee328f (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.qml | 79 | ||||
-rw-r--r-- | examples/bluetooth/scanner/scanner.pro | 3 | ||||
-rw-r--r-- | examples/bluetooth/scanner/scanner.qml | 82 | ||||
-rw-r--r-- | examples/bluetooth/scanner/scanner.qrc | 1 | ||||
-rw-r--r-- | src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp | 342 | ||||
-rw-r--r-- | src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h | 56 |
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; |