/src/kandas-client/ndasmodel.cpp

http://kandas.googlecode.com/ · C++ · 298 lines · 232 code · 13 blank · 53 comment · 53 complexity · 9efd4fadd714ea1174a1e3301bf2e923 MD5 · raw file

  1. /***************************************************************************
  2. * Copyright 2009 Stefan Majewsky <majewsky@gmx.net>
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. ***************************************************************************/
  18. #include "ndasmodel.h"
  19. #include "ndasdevice.h"
  20. #include "ndasslot.h"
  21. Kandas::Client::NdasModel::NdasModel(QObject *parent)
  22. : QAbstractItemModel(parent)
  23. {
  24. }
  25. Kandas::Client::NdasModel::~NdasModel()
  26. {
  27. qDeleteAll(m_devices);
  28. }
  29. int Kandas::Client::NdasModel::columnCount(const QModelIndex &parent) const
  30. {
  31. Q_UNUSED(parent)
  32. return 1;
  33. }
  34. int Kandas::Client::NdasModel::rowCount(const QModelIndex &parent) const
  35. {
  36. //root level = device level
  37. if (!parent.isValid())
  38. return m_devices.count();
  39. //slot level
  40. Kandas::Client::NdasDevice* device = ndasdata_cast<Kandas::Client::NdasDevice*>(parent.internalPointer());
  41. if (device)
  42. return device->slotList().count();
  43. //no structure below slot level
  44. return 0;
  45. }
  46. QVariant Kandas::Client::NdasModel::data(const QModelIndex &index, int role) const
  47. {
  48. //dataItem may be a Kandas::Client::NdasDevice or Kandas::Client::NdasSlot instance
  49. Kandas::Client::NdasData* dataItem = ndasdata_cast<Kandas::Client::NdasData *>(index.internalPointer());
  50. if (dataItem)
  51. return dataItem->data(role);
  52. else
  53. return QVariant();
  54. }
  55. QVariant Kandas::Client::NdasModel::headerData(int section, Qt::Orientation orientation, int role) const
  56. {
  57. Q_UNUSED(section)
  58. Q_UNUSED(orientation)
  59. Q_UNUSED(role)
  60. return QVariant();
  61. }
  62. QModelIndex Kandas::Client::NdasModel::index(int row, int column, const QModelIndex &parent) const
  63. {
  64. //structure on X axis
  65. if (column != 0)
  66. return QModelIndex();
  67. //root level = device level
  68. if (!parent.isValid())
  69. {
  70. if (m_devices.value(row) == 0) //bounds checking!
  71. return QModelIndex();
  72. else
  73. return createIndex(row, 0, (void*) m_devices[row]);
  74. }
  75. //slot level
  76. Kandas::Client::NdasDevice* device = ndasdata_cast<Kandas::Client::NdasDevice*>(parent.internalPointer());
  77. if (device)
  78. {
  79. QList<Kandas::Client::NdasSlot*> slotList = device->slotList();
  80. if (slotList.value(row) == 0) //bounds checking!
  81. return QModelIndex();
  82. else
  83. return createIndex(row, 0, (void*) slotList[row]);
  84. }
  85. //no structure below slot level
  86. else
  87. return QModelIndex();
  88. }
  89. QModelIndex Kandas::Client::NdasModel::parent(const QModelIndex &index) const
  90. {
  91. //root level = device level
  92. Kandas::Client::NdasDevice* device = ndasdata_cast<Kandas::Client::NdasDevice*>(index.internalPointer());
  93. if (device)
  94. return QModelIndex();
  95. //slot level -> find device for slot
  96. Kandas::Client::NdasSlot* slot = ndasdata_cast<Kandas::Client::NdasSlot*>(index.internalPointer());
  97. if (slot)
  98. {
  99. for (int row = 0; row < m_devices.count(); ++row)
  100. if (m_devices[row]->name() == slot->deviceName())
  101. return createIndex(row, 0, (void*) m_devices[row]);
  102. }
  103. return QModelIndex();
  104. }
  105. void Kandas::Client::NdasModel::updateDevice(const QString &deviceName, const QString &serial, Kandas::DeviceState state, bool hasWriteKey)
  106. {
  107. //check if device exists
  108. for (int d = 0; d < m_devices.count(); ++d)
  109. {
  110. Kandas::Client::NdasDevice* device = m_devices[d];
  111. if (device->name() == deviceName)
  112. {
  113. device->update(serial, state, hasWriteKey);
  114. const QModelIndex index = createIndex(d, 0, (void*) device);
  115. emit dataChanged(index, index);
  116. //if device is not available, set slots to unavailable state
  117. if (state != Kandas::DeviceOnline)
  118. foreach (Kandas::Client::NdasSlot* slot, device->slotList())
  119. updateSlot(slot->number(), slot->deviceName(), slot->blockDeviceName(), Kandas::SlotOffline);
  120. return;
  121. }
  122. }
  123. //device not found -> insert new device entry
  124. Kandas::Client::NdasDevice* device = new Kandas::Client::NdasDevice(deviceName, serial, state, hasWriteKey);
  125. int pos = m_devices.count();
  126. beginInsertRows(QModelIndex(), pos, pos);
  127. m_devices << device;
  128. endInsertRows();
  129. }
  130. void Kandas::Client::NdasModel::updateSlot(int slotNumber, const QString &deviceName, const QString &blockDeviceName, Kandas::SlotState state)
  131. {
  132. //check if slot exists at the correct device
  133. for (int d = 0; d < m_devices.count(); ++d)
  134. {
  135. Kandas::Client::NdasDevice* device = m_devices[d];
  136. if (device->name() == deviceName)
  137. {
  138. int slotCount = device->slotList().count();
  139. for (int s = 0; s < slotCount; ++s)
  140. {
  141. Kandas::Client::NdasSlot* slot = device->slotList()[s];
  142. if (slot->number() == slotNumber)
  143. {
  144. //slot cannot be online if device is offline
  145. if (device->state() != Kandas::DeviceOnline)
  146. state = Kandas::SlotOffline;
  147. //update data
  148. slot->update(deviceName, blockDeviceName, state);
  149. const QModelIndex index = createIndex(s, 0, (void*) slot);
  150. emit dataChanged(index, index);
  151. //data update for device necessary
  152. const QModelIndex parent = createIndex(d, 0, (void*) device);
  153. emit dataChanged(parent, parent);
  154. return;
  155. }
  156. }
  157. }
  158. }
  159. //check if slot exists at another device
  160. Kandas::Client::NdasSlot* slot = 0;
  161. for (int d = 0; d < m_devices.count(); ++d)
  162. {
  163. Kandas::Client::NdasDevice* device = m_devices[d];
  164. if (device->name() != deviceName)
  165. {
  166. int slotCount = device->slotList().count();
  167. for (int s = 0; s < slotCount; ++s)
  168. {
  169. slot = device->slotList()[s];
  170. if (slot->number() == slotNumber)
  171. {
  172. //remove from this device
  173. QModelIndex parent = createIndex(d, 0, (void*) device);
  174. beginRemoveRows(parent, s, s);
  175. device->removeSlot(slot);
  176. endRemoveRows();
  177. //data update for device necessary
  178. emit dataChanged(parent, parent);
  179. return;
  180. }
  181. }
  182. }
  183. }
  184. if (slot)
  185. {
  186. //slot has to be repositioned
  187. slot->update(deviceName, blockDeviceName, state);
  188. for (int d = 0; d < m_devices.count(); ++d)
  189. {
  190. Kandas::Client::NdasDevice* device = m_devices[d];
  191. if (device->name() == deviceName)
  192. {
  193. //slot cannot be online if device is offline
  194. if (device->state() != Kandas::DeviceOnline)
  195. slot->update(deviceName, blockDeviceName, Kandas::SlotOffline);
  196. //insert slot here
  197. QModelIndex parent = createIndex(d, 0, (void*) device);
  198. int d = device->slotList().count();
  199. beginInsertRows(parent, d, d);
  200. device->addSlot(slot);
  201. endInsertRows();
  202. //data update for device necessary
  203. emit dataChanged(parent, parent);
  204. return;
  205. }
  206. }
  207. //could not insert slot -> remove slot
  208. delete slot;
  209. }
  210. else
  211. {
  212. //create new slot and insert it
  213. Kandas::Client::NdasSlot* slot = new Kandas::Client::NdasSlot(slotNumber, deviceName, blockDeviceName, state);
  214. for (int d = 0; d < m_devices.count(); ++d)
  215. {
  216. Kandas::Client::NdasDevice* device = m_devices[d];
  217. if (device->name() == deviceName)
  218. {
  219. //slot cannot be online if device is offline
  220. if (device->state() != Kandas::DeviceOnline)
  221. slot->update(deviceName, blockDeviceName, Kandas::SlotOffline);
  222. //insert slot here
  223. QModelIndex parent = createIndex(d, 0, (void*) device);
  224. int d = device->slotList().count();
  225. beginInsertRows(parent, d, d);
  226. device->addSlot(slot);
  227. endInsertRows();
  228. //data update for device necessary
  229. emit dataChanged(parent, parent);
  230. return;
  231. }
  232. }
  233. }
  234. }
  235. void Kandas::Client::NdasModel::removeDevice(const QString &deviceName)
  236. {
  237. //find device to remove
  238. for (int d = 0; d < m_devices.count(); ++d)
  239. {
  240. Kandas::Client::NdasDevice* device = m_devices[d];
  241. if (device->name() == deviceName)
  242. {
  243. //workaround for a problem in KWidgetItemDelegate: explicitly remove all slots in this device
  244. QModelIndex parent = createIndex(d, 0, (void*) device);
  245. int slotCount = device->slotList().count();
  246. beginRemoveRows(parent, 0, slotCount - 1);
  247. QList<Kandas::Client::NdasSlot*> slotList = device->slotList();
  248. foreach (Kandas::Client::NdasSlot* slot, slotList)
  249. {
  250. device->removeSlot(slot);
  251. delete slot;
  252. }
  253. endRemoveRows();
  254. //remove device from model
  255. beginRemoveRows(QModelIndex(), d, d);
  256. m_devices.removeAt(d);
  257. endRemoveRows();
  258. //delete data item
  259. delete device;
  260. }
  261. }
  262. }
  263. void Kandas::Client::NdasModel::removeSlot(int slotNumber)
  264. {
  265. //find slot to remove
  266. for (int d = 0; d < m_devices.count(); ++d)
  267. {
  268. Kandas::Client::NdasDevice* device = m_devices[d];
  269. int slotCount = device->slotList().count();
  270. for (int s = 0; s < slotCount; ++s)
  271. {
  272. Kandas::Client::NdasSlot* slot = device->slotList()[s];
  273. if (slot->number() == slotNumber)
  274. {
  275. //remove from model
  276. QModelIndex parent = createIndex(d, 0, (void*) device);
  277. beginRemoveRows(parent, s, s);
  278. device->removeSlot(slot);
  279. endRemoveRows();
  280. //delete data item
  281. delete slot;
  282. }
  283. }
  284. }
  285. }