PageRenderTime 63ms CodeModel.GetById 18ms app.highlight 41ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 19#include "ndasmodel.h"
 20#include "ndasdevice.h"
 21#include "ndasslot.h"
 22
 23Kandas::Client::NdasModel::NdasModel(QObject *parent)
 24    : QAbstractItemModel(parent)
 25{
 26}
 27
 28Kandas::Client::NdasModel::~NdasModel()
 29{
 30    qDeleteAll(m_devices);
 31}
 32
 33int Kandas::Client::NdasModel::columnCount(const QModelIndex &parent) const
 34{
 35    Q_UNUSED(parent)
 36    return 1;
 37}
 38
 39int Kandas::Client::NdasModel::rowCount(const QModelIndex &parent) const
 40{
 41    //root level = device level
 42    if (!parent.isValid())
 43        return m_devices.count();
 44    //slot level
 45    Kandas::Client::NdasDevice* device = ndasdata_cast<Kandas::Client::NdasDevice*>(parent.internalPointer());
 46    if (device)
 47        return device->slotList().count();
 48    //no structure below slot level
 49    return 0;
 50}
 51
 52QVariant Kandas::Client::NdasModel::data(const QModelIndex &index, int role) const
 53{
 54    //dataItem may be a Kandas::Client::NdasDevice or Kandas::Client::NdasSlot instance
 55    Kandas::Client::NdasData* dataItem = ndasdata_cast<Kandas::Client::NdasData *>(index.internalPointer());
 56    if (dataItem)
 57        return dataItem->data(role);
 58    else
 59        return QVariant();
 60}
 61
 62QVariant Kandas::Client::NdasModel::headerData(int section, Qt::Orientation orientation, int role) const
 63{
 64    Q_UNUSED(section)
 65    Q_UNUSED(orientation)
 66    Q_UNUSED(role)
 67    return QVariant();
 68}
 69
 70QModelIndex Kandas::Client::NdasModel::index(int row, int column, const QModelIndex &parent) const
 71{
 72    //structure on X axis
 73    if (column != 0)
 74        return QModelIndex();
 75    //root level = device level
 76    if (!parent.isValid())
 77    {
 78        if (m_devices.value(row) == 0) //bounds checking!
 79            return QModelIndex();
 80        else
 81            return createIndex(row, 0, (void*) m_devices[row]);
 82    }
 83    //slot level
 84    Kandas::Client::NdasDevice* device = ndasdata_cast<Kandas::Client::NdasDevice*>(parent.internalPointer());
 85    if (device)
 86    {
 87        QList<Kandas::Client::NdasSlot*> slotList = device->slotList();
 88        if (slotList.value(row) == 0) //bounds checking!
 89            return QModelIndex();
 90        else
 91            return createIndex(row, 0, (void*) slotList[row]);
 92    }
 93    //no structure below slot level
 94    else
 95        return QModelIndex();
 96}
 97
 98QModelIndex Kandas::Client::NdasModel::parent(const QModelIndex &index) const
 99{
100    //root level = device level
101    Kandas::Client::NdasDevice* device = ndasdata_cast<Kandas::Client::NdasDevice*>(index.internalPointer());
102    if (device)
103        return QModelIndex();
104    //slot level -> find device for slot
105    Kandas::Client::NdasSlot* slot = ndasdata_cast<Kandas::Client::NdasSlot*>(index.internalPointer());
106    if (slot)
107    {
108        for (int row = 0; row < m_devices.count(); ++row)
109            if (m_devices[row]->name() == slot->deviceName())
110                return createIndex(row, 0, (void*) m_devices[row]);
111    }
112    return QModelIndex();
113}
114
115void Kandas::Client::NdasModel::updateDevice(const QString &deviceName, const QString &serial, Kandas::DeviceState state, bool hasWriteKey)
116{
117    //check if device exists
118    for (int d = 0; d < m_devices.count(); ++d)
119    {
120        Kandas::Client::NdasDevice* device = m_devices[d];
121        if (device->name() == deviceName)
122        {
123            device->update(serial, state, hasWriteKey);
124            const QModelIndex index = createIndex(d, 0, (void*) device);
125            emit dataChanged(index, index);
126            //if device is not available, set slots to unavailable state
127            if (state != Kandas::DeviceOnline)
128                foreach (Kandas::Client::NdasSlot* slot, device->slotList())
129                    updateSlot(slot->number(), slot->deviceName(), slot->blockDeviceName(), Kandas::SlotOffline);
130            return;
131        }
132    }
133    //device not found -> insert new device entry
134    Kandas::Client::NdasDevice* device = new Kandas::Client::NdasDevice(deviceName, serial, state, hasWriteKey);
135    int pos = m_devices.count();
136    beginInsertRows(QModelIndex(), pos, pos);
137    m_devices << device;
138    endInsertRows();
139}
140
141void Kandas::Client::NdasModel::updateSlot(int slotNumber, const QString &deviceName, const QString &blockDeviceName, Kandas::SlotState state)
142{
143    //check if slot exists at the correct device
144    for (int d = 0; d < m_devices.count(); ++d)
145    {
146        Kandas::Client::NdasDevice* device = m_devices[d];
147        if (device->name() == deviceName)
148        {
149            int slotCount = device->slotList().count();
150            for (int s = 0; s < slotCount; ++s)
151            {
152                Kandas::Client::NdasSlot* slot = device->slotList()[s];
153                if (slot->number() == slotNumber)
154                {
155                    //slot cannot be online if device is offline
156                    if (device->state() != Kandas::DeviceOnline)
157                        state = Kandas::SlotOffline;
158                    //update data
159                    slot->update(deviceName, blockDeviceName, state);
160                    const QModelIndex index = createIndex(s, 0, (void*) slot);
161                    emit dataChanged(index, index);
162                    //data update for device necessary
163                    const QModelIndex parent = createIndex(d, 0, (void*) device);
164                    emit dataChanged(parent, parent);
165                    return;
166                }
167            }
168        }
169    }
170    //check if slot exists at another device
171    Kandas::Client::NdasSlot* slot = 0;
172    for (int d = 0; d < m_devices.count(); ++d)
173    {
174        Kandas::Client::NdasDevice* device = m_devices[d];
175        if (device->name() != deviceName)
176        {
177            int slotCount = device->slotList().count();
178            for (int s = 0; s < slotCount; ++s)
179            {
180                slot = device->slotList()[s];
181                if (slot->number() == slotNumber)
182                {
183                    //remove from this device
184                    QModelIndex parent = createIndex(d, 0, (void*) device);
185                    beginRemoveRows(parent, s, s);
186                    device->removeSlot(slot);
187                    endRemoveRows();
188                    //data update for device necessary
189                    emit dataChanged(parent, parent);
190                    return;
191                }
192            }
193        }
194    }
195    if (slot)
196    {
197        //slot has to be repositioned
198        slot->update(deviceName, blockDeviceName, state);
199        for (int d = 0; d < m_devices.count(); ++d)
200        {
201            Kandas::Client::NdasDevice* device = m_devices[d];
202            if (device->name() == deviceName)
203            {
204                //slot cannot be online if device is offline
205                if (device->state() != Kandas::DeviceOnline)
206                    slot->update(deviceName, blockDeviceName, Kandas::SlotOffline);
207                //insert slot here
208                QModelIndex parent = createIndex(d, 0, (void*) device);
209                int d = device->slotList().count();
210                beginInsertRows(parent, d, d);
211                device->addSlot(slot);
212                endInsertRows();
213                //data update for device necessary
214                emit dataChanged(parent, parent);
215                return;
216            }
217        }
218        //could not insert slot -> remove slot
219        delete slot;
220    }
221    else
222    {
223        //create new slot and insert it
224        Kandas::Client::NdasSlot* slot = new Kandas::Client::NdasSlot(slotNumber, deviceName, blockDeviceName, state);
225        for (int d = 0; d < m_devices.count(); ++d)
226        {
227            Kandas::Client::NdasDevice* device = m_devices[d];
228            if (device->name() == deviceName)
229            {
230                //slot cannot be online if device is offline
231                if (device->state() != Kandas::DeviceOnline)
232                    slot->update(deviceName, blockDeviceName, Kandas::SlotOffline);
233                //insert slot here
234                QModelIndex parent = createIndex(d, 0, (void*) device);
235                int d = device->slotList().count();
236                beginInsertRows(parent, d, d);
237                device->addSlot(slot);
238                endInsertRows();
239                //data update for device necessary
240                emit dataChanged(parent, parent);
241                return;
242            }
243        }
244    }
245}
246
247void Kandas::Client::NdasModel::removeDevice(const QString &deviceName)
248{
249    //find device to remove
250    for (int d = 0; d < m_devices.count(); ++d)
251    {
252        Kandas::Client::NdasDevice* device = m_devices[d];
253        if (device->name() == deviceName)
254        {
255            //workaround for a problem in KWidgetItemDelegate: explicitly remove all slots in this device
256            QModelIndex parent = createIndex(d, 0, (void*) device);
257            int slotCount = device->slotList().count();
258            beginRemoveRows(parent, 0, slotCount - 1);
259            QList<Kandas::Client::NdasSlot*> slotList = device->slotList();
260            foreach (Kandas::Client::NdasSlot* slot, slotList)
261            {
262                device->removeSlot(slot);
263                delete slot;
264            }
265            endRemoveRows();
266            //remove device from model
267            beginRemoveRows(QModelIndex(), d, d);
268            m_devices.removeAt(d);
269            endRemoveRows();
270            //delete data item
271            delete device;
272        }
273    }
274}
275
276void Kandas::Client::NdasModel::removeSlot(int slotNumber)
277{
278    //find slot to remove
279    for (int d = 0; d < m_devices.count(); ++d)
280    {
281        Kandas::Client::NdasDevice* device = m_devices[d];
282        int slotCount = device->slotList().count();
283        for (int s = 0; s < slotCount; ++s)
284        {
285            Kandas::Client::NdasSlot* slot = device->slotList()[s];
286            if (slot->number() == slotNumber)
287            {
288                //remove from model
289                QModelIndex parent = createIndex(d, 0, (void*) device);
290                beginRemoveRows(parent, s, s);
291                device->removeSlot(slot);
292                endRemoveRows();
293                //delete data item
294                delete slot;
295            }
296        }
297    }
298}