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