KIO
kdevicelistmodel.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kdevicelistmodel.h"
00021 #include "kdevicelistitem_p.h"
00022
00023 #include <solid/devicenotifier.h>
00024 #include <solid/device.h>
00025 #include <solid/deviceinterface.h>
00026
00027 #include <QTimer>
00028
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 #include <kicon.h>
00032
00033 class KDeviceListModel::Private
00034 {
00035 public:
00036 Private(KDeviceListModel *self) : q(self), rootItem(new KDeviceListItem()) {}
00037 ~Private() { delete rootItem; }
00038
00039
00040 KDeviceListModel *q;
00041
00042 KDeviceListItem *rootItem;
00043 QMap<QString, KDeviceListItem*> deviceItems;
00044 Solid::Predicate predicate;
00045
00046
00047 void initialize(const Solid::Predicate &p);
00048 QModelIndex indexForItem(KDeviceListItem *item) const;
00049 void addDevice(const Solid::Device &device);
00050 void removeBranch(const QString &udi);
00051
00052
00053 void _k_initDeviceList();
00054 void _k_deviceAdded(const QString &udi);
00055 void _k_deviceRemoved(const QString &udi);
00056 };
00057
00058 KDeviceListModel::KDeviceListModel(QObject *parent)
00059 : QAbstractItemModel(parent), d(new Private(this))
00060 {
00061 d->initialize(Solid::Predicate());
00062 }
00063
00064 KDeviceListModel::KDeviceListModel(const QString &predicate, QObject *parent)
00065 : QAbstractItemModel(parent), d(new Private(this))
00066 {
00067 d->initialize(Solid::Predicate::fromString(predicate));
00068 }
00069
00070 KDeviceListModel::KDeviceListModel(const Solid::Predicate &predicate, QObject *parent)
00071 : QAbstractItemModel(parent), d(new Private(this))
00072 {
00073 d->initialize(predicate);
00074 }
00075
00076 KDeviceListModel::~KDeviceListModel()
00077 {
00078 delete d;
00079 }
00080
00081 void KDeviceListModel::Private::initialize(const Solid::Predicate &p)
00082 {
00083 predicate = p;
00084
00085
00086 QTimer::singleShot( 0, q, SLOT(_k_initDeviceList()) );
00087 }
00088
00089 QVariant KDeviceListModel::data(const QModelIndex &index, int role) const
00090 {
00091 if( !index.isValid() )
00092 return QVariant();
00093
00094 KDeviceListItem *deviceItem = static_cast<KDeviceListItem*>(index.internalPointer());
00095 Solid::Device device = deviceItem->device();
00096
00097 QVariant returnData;
00098 if (role == Qt::DisplayRole) {
00099 returnData = device.product();
00100 }
00101
00102 else if (role == Qt::DecorationRole && index.column() == 0) {
00103 returnData = KIcon(device.icon());
00104 }
00105
00106 return returnData;
00107 }
00108
00109 QVariant KDeviceListModel::headerData(int section, Qt::Orientation orientation, int role) const
00110 {
00111 Q_UNUSED(section)
00112
00113 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
00114 {
00115 return i18n("Device name");
00116 }
00117
00118 return QVariant();
00119 }
00120
00121 QModelIndex KDeviceListModel::index(int row, int column, const QModelIndex &parent) const
00122 {
00123 if (row<0 || column!=0)
00124 return QModelIndex();
00125
00126 if (!parent.isValid())
00127 return createIndex(row, column, d->rootItem);
00128
00129 KDeviceListItem *parentItem = static_cast<KDeviceListItem*>(parent.internalPointer());
00130 KDeviceListItem *childItem = parentItem->child(row);
00131
00132 if (childItem) {
00133 return createIndex(row, column, childItem);
00134 } else {
00135 return QModelIndex();
00136 }
00137 }
00138
00139 QModelIndex KDeviceListModel::rootIndex() const
00140 {
00141 return d->indexForItem(d->rootItem);
00142 }
00143
00144 QModelIndex KDeviceListModel::parent(const QModelIndex &child) const
00145 {
00146 if (!child.isValid())
00147 return QModelIndex();
00148
00149 KDeviceListItem *childItem = static_cast<KDeviceListItem*>(child.internalPointer());
00150 KDeviceListItem *parentItem = childItem->parent();
00151
00152 if (!parentItem)
00153 return QModelIndex();
00154 else
00155 return d->indexForItem(parentItem);
00156 }
00157
00158 int KDeviceListModel::rowCount(const QModelIndex &parent) const
00159 {
00160 if( !parent.isValid() )
00161 return 1;
00162
00163 KDeviceListItem *item = static_cast<KDeviceListItem*>(parent.internalPointer());
00164
00165 return item->childCount();
00166 }
00167
00168 int KDeviceListModel::columnCount(const QModelIndex &parent) const
00169 {
00170 Q_UNUSED(parent);
00171
00172 return 1;
00173 }
00174
00175 Solid::Device KDeviceListModel::deviceForIndex(const QModelIndex& index) const
00176 {
00177 KDeviceListItem *deviceItem = static_cast<KDeviceListItem*>(index.internalPointer());
00178 return deviceItem->device();
00179 }
00180
00181 void KDeviceListModel::Private::_k_initDeviceList()
00182 {
00183 Solid::DeviceNotifier *notifier = Solid::DeviceNotifier::instance();
00184
00185 connect(notifier, SIGNAL(deviceAdded(const QString&)),
00186 q, SLOT(_k_deviceAdded(const QString&)));
00187 connect(notifier, SIGNAL(deviceRemoved(const QString&)),
00188 q, SLOT(_k_deviceRemoved(const QString&)));
00189
00190
00191
00192 const QList<Solid::Device> &deviceList = predicate.isValid()?
00193 Solid::Device::listFromQuery(predicate)
00194 : Solid::Device::allDevices();
00195
00196 foreach(const Solid::Device &device, deviceList)
00197 {
00198 addDevice(device);
00199 }
00200
00201 emit q->modelInitialized();
00202 }
00203
00204 void KDeviceListModel::Private::addDevice(const Solid::Device &device)
00205 {
00206
00207 if (!device.isValid()) return;
00208
00209
00210
00211 if (!device.parentUdi().isEmpty()
00212 && predicate.isValid() && !predicate.matches(device)) {
00213 return;
00214 }
00215
00216 KDeviceListItem *item;
00217 if (deviceItems.contains(device.udi())) {
00218 item = deviceItems[device.udi()];
00219 } else {
00220 item = new KDeviceListItem();
00221 deviceItems[device.udi()] = item;
00222 }
00223 item->setDevice(device);
00224
00225 if (device.parentUdi().isEmpty()) {
00226 rootItem=item;
00227 emit q->dataChanged(q->rootIndex(), q->rootIndex());
00228 } else {
00229 KDeviceListItem *parent = rootItem;
00230
00231 if (!deviceItems.contains(device.parentUdi()) )
00232 addDevice( Solid::Device(device.parentUdi()) );
00233
00234 if (deviceItems.contains(device.parentUdi()))
00235 parent = deviceItems[device.parentUdi()];
00236
00237 if (item->parent()!=parent) {
00238 q->beginInsertRows(indexForItem(parent), parent->childCount(), parent->childCount());
00239 item->setParent(parent);
00240 q->endInsertRows();
00241 }
00242 }
00243 }
00244
00245 void KDeviceListModel::Private::removeBranch(const QString &udi)
00246 {
00247 if (!deviceItems.contains(udi)) return;
00248
00249 KDeviceListItem *item = deviceItems[udi];
00250 KDeviceListItem *parent = item->parent();
00251
00252 QList<KDeviceListItem*> children = item->children();
00253
00254 foreach(KDeviceListItem *child, children) {
00255 removeBranch(child->device().udi());
00256 }
00257
00258 q->beginRemoveRows(indexForItem(parent),
00259 item->row(), item->row());
00260
00261 item->setParent(0);
00262 deviceItems.remove(udi);
00263 delete item;
00264
00265 q->endRemoveRows();
00266 }
00267
00268 void KDeviceListModel::Private::_k_deviceAdded(const QString &udi)
00269 {
00270 Solid::Device device(udi);
00271 addDevice(device);
00272 }
00273
00274 void KDeviceListModel::Private::_k_deviceRemoved(const QString &udi)
00275 {
00276 removeBranch(udi);
00277 }
00278
00279 QModelIndex KDeviceListModel::Private::indexForItem(KDeviceListItem *item) const
00280 {
00281 return q->createIndex(item->row(), 0, item);
00282 }
00283
00284 #include "kdevicelistmodel.moc"