1/**************************************************************************** 2** 3** Copyright (C) 2017 The Qt Company Ltd. 4** Copyright (C) 2013 BlackBerry Limited. All rights reserved. 5** Contact: https://www.qt.io/licensing/ 6** 7** This file is part of the examples of the QtBluetooth module. 8** 9** $QT_BEGIN_LICENSE:BSD$ 10** Commercial License Usage 11** Licensees holding valid commercial Qt licenses may use this file in 12** accordance with the commercial license agreement provided with the 13** Software or, alternatively, in accordance with the terms contained in 14** a written agreement between you and The Qt Company. For licensing terms 15** and conditions see https://www.qt.io/terms-conditions. For further 16** information use the contact form at https://www.qt.io/contact-us. 17** 18** BSD License Usage 19** Alternatively, you may use this file under the terms of the BSD license 20** as follows: 21** 22** "Redistribution and use in source and binary forms, with or without 23** modification, are permitted provided that the following conditions are 24** met: 25** * Redistributions of source code must retain the above copyright 26** notice, this list of conditions and the following disclaimer. 27** * Redistributions in binary form must reproduce the above copyright 28** notice, this list of conditions and the following disclaimer in 29** the documentation and/or other materials provided with the 30** distribution. 31** * Neither the name of The Qt Company Ltd nor the names of its 32** contributors may be used to endorse or promote products derived 33** from this software without specific prior written permission. 34** 35** 36** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 37** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 38** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 39** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 40** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 42** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 43** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 44** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 45** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 46** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 47** 48** $QT_END_LICENSE$ 49** 50****************************************************************************/ 51 52import QtQuick 2.0 53import QtBluetooth 5.2 54 55Item { 56 id: top 57 58 property BluetoothService currentService 59 60 BluetoothDiscoveryModel { 61 id: btModel 62 running: true 63 discoveryMode: BluetoothDiscoveryModel.DeviceDiscovery 64 onDiscoveryModeChanged: console.log("Discovery mode: " + discoveryMode) 65 onServiceDiscovered: console.log("Found new service " + service.deviceAddress + " " + service.deviceName + " " + service.serviceName); 66 onDeviceDiscovered: console.log("New device: " + device) 67 onErrorChanged: { 68 switch (btModel.error) { 69 case BluetoothDiscoveryModel.PoweredOffError: 70 console.log("Error: Bluetooth device not turned on"); break; 71 case BluetoothDiscoveryModel.InputOutputError: 72 console.log("Error: Bluetooth I/O Error"); break; 73 case BluetoothDiscoveryModel.InvalidBluetoothAdapterError: 74 console.log("Error: Invalid Bluetooth Adapter Error"); break; 75 case BluetoothDiscoveryModel.NoError: 76 break; 77 default: 78 console.log("Error: Unknown Error"); break; 79 } 80 } 81 } 82 83 Rectangle { 84 id: busy 85 86 width: top.width * 0.7; 87 anchors.horizontalCenter: parent.horizontalCenter 88 anchors.top: top.top; 89 height: text.height*1.2; 90 radius: 5 91 color: "#1c56f3" 92 visible: btModel.running 93 94 Text { 95 id: text 96 text: "Scanning" 97 font.bold: true 98 font.pointSize: 20 99 anchors.centerIn: parent 100 } 101 102 SequentialAnimation on color { 103 id: busyThrobber 104 ColorAnimation { easing.type: Easing.InOutSine; from: "#1c56f3"; to: "white"; duration: 1000; } 105 ColorAnimation { easing.type: Easing.InOutSine; to: "#1c56f3"; from: "white"; duration: 1000 } 106 loops: Animation.Infinite 107 } 108 } 109 110 ListView { 111 id: mainList 112 width: top.width 113 anchors.top: busy.bottom 114 anchors.bottom: buttonGroup.top 115 anchors.bottomMargin: 10 116 anchors.topMargin: 10 117 clip: true 118 119 model: btModel 120 delegate: Rectangle { 121 id: btDelegate 122 width: parent.width 123 height: column.height + 10 124 125 property bool expended: false; 126 clip: true 127 Image { 128 id: bticon 129 source: "qrc:/default.png"; 130 width: bttext.height; 131 height: bttext.height; 132 anchors.top: parent.top 133 anchors.left: parent.left 134 anchors.margins: 5 135 } 136 137 Column { 138 id: column 139 anchors.left: bticon.right 140 anchors.leftMargin: 5 141 Text { 142 id: bttext 143 text: deviceName ? deviceName : name 144 font.family: "FreeSerif" 145 font.pointSize: 16 146 } 147 148 Text { 149 id: details 150 function get_details(s) { 151 if (btModel.discoveryMode == BluetoothDiscoveryModel.DeviceDiscovery) { 152 //We are doing a device discovery 153 var str = "Address: " + remoteAddress; 154 return str; 155 } else { 156 var str = "Address: " + s.deviceAddress; 157 if (s.serviceName) { str += "<br>Service: " + s.serviceName; } 158 if (s.serviceDescription) { str += "<br>Description: " + s.serviceDescription; } 159 if (s.serviceProtocol) { str += "<br>Protocol: " + s.serviceProtocol; } 160 return str; 161 } 162 } 163 visible: opacity !== 0 164 opacity: btDelegate.expended ? 1 : 0.0 165 text: get_details(service) 166 font.family: "FreeSerif" 167 font.pointSize: 14 168 Behavior on opacity { 169 NumberAnimation { duration: 200} 170 } 171 } 172 } 173 Behavior on height { NumberAnimation { duration: 200} } 174 175 MouseArea { 176 anchors.fill: parent 177 onClicked: btDelegate.expended = !btDelegate.expended 178 } 179 } 180 focus: true 181 } 182 183 Row { 184 id: buttonGroup 185 property var activeButton: devButton 186 187 anchors.bottom: parent.bottom 188 anchors.horizontalCenter: parent.horizontalCenter 189 anchors.bottomMargin: 5 190 spacing: 10 191 192 Button { 193 id: fdButton 194 width: top.width/3*0.9 195 //mdButton has longest text 196 height: mdButton.height 197 text: "Full Discovery" 198 onClicked: btModel.discoveryMode = BluetoothDiscoveryModel.FullServiceDiscovery 199 } 200 Button { 201 id: mdButton 202 width: top.width/3*0.9 203 text: "Minimal Discovery" 204 onClicked: btModel.discoveryMode = BluetoothDiscoveryModel.MinimalServiceDiscovery 205 } 206 Button { 207 id: devButton 208 width: top.width/3*0.9 209 //mdButton has longest text 210 height: mdButton.height 211 text: "Device Discovery" 212 onClicked: btModel.discoveryMode = BluetoothDiscoveryModel.DeviceDiscovery 213 } 214 } 215 216} 217