fixed setProperty for discoverable timeout
[profile/ivi/bluetooth-qt.git] / bluetooth-qt / bluetoothdevicemodel.cpp
1 /*  -*- Mode: C++ -*-
2  *
3  * meego handset bluetooth
4  * Copyright © 2010, Intel Corporation.
5  *
6  * This program is licensed under the terms and conditions of the
7  * Apache License, version 2.0.  The full text of the Apache License is at
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  */
11
12 #include "bluetoothdevicemodel.h"
13
14 BluetoothDevicesModel::BluetoothDevicesModel(QObject *parent) :
15         QAbstractListModel(parent), m_connected(false), adapter(NULL)
16 {
17         manager = new OrgBluezManagerInterface(
18                         "org.bluez",
19                         "/", QDBusConnection::systemBus(), this);
20
21         connect(manager,SIGNAL(AdapterAdded(QDBusObjectPath)),this,SLOT(adapterAdded(QDBusObjectPath)));
22         connect(manager,SIGNAL(AdapterRemoved(QDBusObjectPath)),this,SLOT(adapterRemoved(QDBusObjectPath)));
23         adapterAdded(QDBusObjectPath());
24
25         QHash<int, QByteArray> roles;
26
27         QMetaObject properties = BluetoothDevice::staticMetaObject;
28
29         for(int i=0; i<properties.propertyCount();i++)
30         {
31                 roles[i]=properties.property(i).name();
32         }
33
34         setRoleNames(roles);
35 }
36
37 int BluetoothDevicesModel::rowCount(const QModelIndex &) const
38 {
39         return m_devices.size();
40 }
41
42 QVariant BluetoothDevicesModel::data(const QModelIndex &index, int role) const
43 {
44         qDebug()<<"requested role: "<<roleNames()[role];
45
46         if(!index.isValid() || index.row() < 0)
47         {
48                 qDebug()<<"index is not valid: "<<index.row()<<","<<index.column();
49                 return QVariant(); ///this is retarded but it has to be done.
50         }
51
52         QString roleName = roleNames()[role];
53         QMetaObject object = BluetoothDevice::staticMetaObject;
54
55         for(int i=0; i<object.propertyCount(); i++)
56         {
57                 if(object.property(i).name() == roleName)
58                 {
59
60                         return object.property(i).read(m_devices[index.row()]);
61                 }
62         }
63         return QVariant();
64 }
65
66 QString BluetoothDevicesModel::devicePath(QString devicename)
67 {
68         foreach(BluetoothDevice* device, m_devices)
69         {
70                 if(device->name() == devicename)
71                         return device->path();
72         }
73         return "";
74 }
75
76 BluetoothDevice* BluetoothDevicesModel::device(QString path)
77 {
78         foreach(BluetoothDevice* device, m_devices)
79         {
80                 if(device->path() == path)
81                         return device;
82         }
83         qDebug()<<"Device not found for path: "<<path;
84         return NULL;
85 }
86
87 void BluetoothDevicesModel::makePowered(bool poweredValue)
88 {
89         if(adapter) adapter->SetProperty("Powered", QDBusVariant(poweredValue));
90 }
91
92 bool BluetoothDevicesModel::powered()
93 {
94         if(adapter)
95         {
96                 QVariantMap props = adapter->GetProperties();
97                 return props["Powered"].toBool();
98         }
99
100         return false;
101 }
102
103 void BluetoothDevicesModel::makeDiscoverable(bool discoverableValue)
104 {
105         if(adapter) adapter->SetProperty("Discoverable", QDBusVariant(discoverableValue));
106 }
107
108 bool BluetoothDevicesModel::discoverable()
109 {
110         if(adapter)
111         {
112                 QVariantMap props = adapter->GetProperties();
113                 return props["Discoverable"].toBool();
114         }
115
116         return false;
117 }
118
119 int BluetoothDevicesModel::discoverableTimeout()
120 {
121         if(adapter)
122         {
123                 QVariantMap props = adapter->GetProperties();
124                 return props["DiscoverableTimeout"].toInt();
125         }
126
127         return -1;
128 }
129
130 void BluetoothDevicesModel::setDiscoverableTimeout(int timeout)
131 {
132         if(adapter)
133         {
134                 QDBusReply<void> reply = adapter->SetProperty("DiscoverableTimeout", QDBusVariant(timeout));
135                 if(!reply.isValid())
136                 {
137                         qDebug()<<"error setting discoverable timeout: "<<reply.error().message();
138                 }
139                 else
140                 {
141                         qDebug()<<"Setting discoverable timeout to "<<timeout;
142                 }
143         }
144 }
145
146 void BluetoothDevicesModel::adapterAdded(QDBusObjectPath path)
147 {
148         if(adapter && adapter->path() == path.path()) return;
149
150         QDBusObjectPath adapterpath = manager->DefaultAdapter();
151
152         if(adapterpath.path() == "")
153         {
154                 ///we actually shouldn't ever get here.
155                 return;
156         }
157
158         adapter = new OrgBluezAdapterInterface(
159                         "org.bluez",
160                         adapterpath.path(),
161                         QDBusConnection::systemBus(), this);
162
163         connect(adapter,
164                         SIGNAL(PropertyChanged(QString,QDBusVariant)),
165                         this,
166                         SLOT(adapterPropertyChanged(QString,QDBusVariant)));
167
168         connect(adapter,
169                 SIGNAL(DeviceRemoved(QDBusObjectPath)),
170                 this,
171                 SLOT(deviceRemoved(QDBusObjectPath)));
172
173         connect(adapter,
174                 SIGNAL(DeviceCreated(QDBusObjectPath)),
175                 this,
176                 SLOT(deviceCreated(QDBusObjectPath)));
177
178         adapterChanged(true);
179
180         QList<QDBusObjectPath> list = adapter->ListDevices();
181         foreach(QDBusObjectPath item, list)
182         {
183                 deviceCreated(item);
184         }
185 }
186
187 void BluetoothDevicesModel::adapterRemoved(QDBusObjectPath)
188 {
189         QDBusObjectPath adapterpath = manager->DefaultAdapter();
190
191         if(adapterpath.path() == "")
192         {
193                 beginRemoveRows(QModelIndex(), 0, m_devices.size()-1);
194                 foreach(BluetoothDevice* device, m_devices)
195                 {
196                         updateConnected(device->connected());
197                         device->deleteLater();
198                 }
199                 m_devices.clear();
200                 endRemoveRows();
201
202                 if(adapter) delete adapter;
203                 adapter = NULL;
204                 adapterChanged(false);
205                 return;
206         }
207 }
208
209 void BluetoothDevicesModel::deviceCreated(QDBusObjectPath devicepath)
210 {
211         BluetoothDevice* device = new BluetoothDevice(devicepath,this);
212
213         updateConnected(device->connected());
214         connect(device,SIGNAL(propertyChanged(QString,QVariant)),this,SLOT(devicePropertyChanged(QString,QVariant)));
215
216         beginInsertRows(QModelIndex(),m_devices.size(),m_devices.size());
217         m_devices.append(device);
218         endInsertRows();
219 }
220
221 void BluetoothDevicesModel::deviceRemoved(QDBusObjectPath devicepath)
222 {
223         for(int i=0; i<m_devices.size(); i++)
224         {
225
226                 if(m_devices[i]->path() == devicepath.path())
227                 {
228                         beginRemoveRows(QModelIndex(), i, i);
229                         m_devices[i]->deleteLater();
230                         m_devices.removeAt(i);
231                         endRemoveRows();
232                 }
233         }
234 }
235
236 void BluetoothDevicesModel::devicePropertyChanged(QString name, QVariant value)
237 {
238         BluetoothDevice* device = qobject_cast<BluetoothDevice*>(sender());
239
240         qDebug()<<"device property changed for "<<device->address()<<": "<<name<<" "<<value;
241
242         if(name == "Paired" && value.toBool() == true)
243         {
244                 emit devicePaired(device);
245         }
246
247         else if(name == "Connected")
248         {
249                 updateConnected(value.toBool());
250         }
251         int row = m_devices.indexOf(device);
252         if(row == -1) return; ///device doesn't exist.
253
254         dataChanged(createIndex(row, 0),createIndex(row, 0));
255 }
256
257 void BluetoothDevicesModel::adapterPropertyChanged(QString name, QDBusVariant value)
258 {
259         qDebug()<<"adapter property changed: "<<name<<" "<<value.variant();
260
261         if(name == "Powered")
262         {
263                 poweredChanged(value.variant().toBool());
264         }
265         else if(name == "Discoverable")
266         {
267                 discoverableChanged(value.variant().toBool());
268         }
269         else if(name == "DiscoverableTimeout")
270         {
271                 discoverableTimeoutChanged(value.variant().toInt());
272         }
273 }
274
275 void BluetoothDevicesModel::updateConnected(bool deviceconnectedStatus)
276 {
277         if(deviceconnectedStatus)
278         {
279                 if(!m_connected)
280                 {
281                         m_connected = true;
282                         connectedChanged(m_connected);
283                 }
284         }
285         else
286         {
287                 bool temp = false;
288                 foreach(BluetoothDevice* device, devices())
289                 {
290                         temp |= device->connected();
291                 }
292
293                 if(temp != m_connected)
294                 {
295                         m_connected = temp;
296                         connectedChanged(m_connected);
297                 }
298         }
299 }