Solid
devicemanager.cpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2005-2007 Kevin Ottens <ervin@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Lesser General Public 00006 License as published by the Free Software Foundation; either 00007 version 2.1 of the License, or (at your option) version 3, or any 00008 later version accepted by the membership of KDE e.V. (or its 00009 successor approved by the membership of KDE e.V.), which shall 00010 act as a proxy defined in Section 6 of version 3 of the license. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 #include "devicenotifier.h" 00022 #include "devicemanager_p.h" //krazy:exclude=includes (devicenotifier.h is the header file for this class) 00023 00024 #include "device.h" 00025 #include "device_p.h" 00026 #include "predicate.h" 00027 00028 #include "ifaces/devicemanager.h" 00029 #include "ifaces/device.h" 00030 00031 #include "soliddefs_p.h" 00032 00033 SOLID_GLOBAL_STATIC(Solid::DeviceManagerStorage, globalDeviceStorage) 00034 00035 Solid::DeviceManagerPrivate::DeviceManagerPrivate() 00036 : m_nullDevice(new DevicePrivate(QString())) 00037 { 00038 loadBackends(); 00039 00040 QList<QObject*> backends = managerBackends(); 00041 foreach (QObject *backend, backends) { 00042 connect(backend, SIGNAL(deviceAdded(QString)), 00043 this, SLOT(_k_deviceAdded(QString))); 00044 connect(backend, SIGNAL(deviceRemoved(QString)), 00045 this, SLOT(_k_deviceRemoved(QString))); 00046 } 00047 } 00048 00049 Solid::DeviceManagerPrivate::~DeviceManagerPrivate() 00050 { 00051 QList<QObject*> backends = managerBackends(); 00052 foreach (QObject *backend, backends) { 00053 disconnect(backend, 0, this, 0); 00054 } 00055 00056 foreach (QWeakPointer<DevicePrivate> dev, m_devicesMap) { 00057 if (!dev.data()->ref.deref()) { 00058 delete dev.data(); 00059 } 00060 } 00061 00062 m_devicesMap.clear(); 00063 } 00064 00065 QList<Solid::Device> Solid::Device::allDevices() 00066 { 00067 QList<Device> list; 00068 QList<QObject*> backends = globalDeviceStorage->managerBackends(); 00069 00070 foreach (QObject *backendObj, backends) { 00071 Ifaces::DeviceManager *backend = qobject_cast<Ifaces::DeviceManager *>(backendObj); 00072 00073 if (backend == 0) continue; 00074 00075 QStringList udis = backend->allDevices(); 00076 00077 foreach (const QString &udi, udis) { 00078 list.append(Device(udi)); 00079 } 00080 } 00081 00082 return list; 00083 } 00084 00085 QList<Solid::Device> Solid::Device::listFromQuery(const QString &predicate, 00086 const QString &parentUdi) 00087 { 00088 Predicate p = Predicate::fromString(predicate); 00089 00090 if (p.isValid()) 00091 { 00092 return listFromQuery(p, parentUdi); 00093 } 00094 else 00095 { 00096 return QList<Device>(); 00097 } 00098 } 00099 00100 QList<Solid::Device> Solid::Device::listFromType(const DeviceInterface::Type &type, 00101 const QString &parentUdi) 00102 { 00103 QList<Device> list; 00104 QList<QObject*> backends = globalDeviceStorage->managerBackends(); 00105 00106 foreach (QObject *backendObj, backends) { 00107 Ifaces::DeviceManager *backend = qobject_cast<Ifaces::DeviceManager *>(backendObj); 00108 00109 if (backend == 0) continue; 00110 if (!backend->supportedInterfaces().contains(type)) continue; 00111 00112 QStringList udis = backend->devicesFromQuery(parentUdi, type); 00113 00114 foreach (const QString &udi, udis) { 00115 list.append(Device(udi)); 00116 } 00117 } 00118 00119 return list; 00120 } 00121 00122 QList<Solid::Device> Solid::Device::listFromQuery(const Predicate &predicate, 00123 const QString &parentUdi) 00124 { 00125 QList<Device> list; 00126 QList<QObject*> backends = globalDeviceStorage->managerBackends(); 00127 QSet<DeviceInterface::Type> usedTypes = predicate.usedTypes(); 00128 00129 foreach (QObject *backendObj, backends) { 00130 Ifaces::DeviceManager *backend = qobject_cast<Ifaces::DeviceManager *>(backendObj); 00131 00132 if (backend == 0) continue; 00133 00134 QSet<QString> udis; 00135 if (predicate.isValid()) { 00136 QSet<DeviceInterface::Type> supportedTypes = backend->supportedInterfaces(); 00137 if (supportedTypes.intersect(usedTypes).isEmpty()) { 00138 continue; 00139 } 00140 00141 foreach (DeviceInterface::Type type, supportedTypes) { 00142 udis+= QSet<QString>::fromList(backend->devicesFromQuery(parentUdi, type)); 00143 } 00144 } else { 00145 udis+= QSet<QString>::fromList(backend->allDevices()); 00146 } 00147 00148 foreach (const QString &udi, udis) 00149 { 00150 Device dev(udi); 00151 00152 bool matches = false; 00153 00154 if(!predicate.isValid()) { 00155 matches = true; 00156 } else { 00157 matches = predicate.matches(dev); 00158 } 00159 00160 if (matches) 00161 { 00162 list.append(dev); 00163 } 00164 } 00165 } 00166 00167 return list; 00168 } 00169 00170 Solid::DeviceNotifier *Solid::DeviceNotifier::instance() 00171 { 00172 return globalDeviceStorage->notifier(); 00173 } 00174 00175 void Solid::DeviceManagerPrivate::_k_deviceAdded(const QString &udi) 00176 { 00177 if (m_devicesMap.contains(udi)) { 00178 DevicePrivate *dev = m_devicesMap[udi].data(); 00179 00180 // Ok, this one was requested somewhere was invalid 00181 // and now becomes magically valid! 00182 00183 if (dev && dev->backendObject() == 0) { 00184 dev->setBackendObject(createBackendObject(udi)); 00185 Q_ASSERT(dev->backendObject()!=0); 00186 } 00187 } 00188 00189 emit deviceAdded(udi); 00190 } 00191 00192 void Solid::DeviceManagerPrivate::_k_deviceRemoved(const QString &udi) 00193 { 00194 if (m_devicesMap.contains(udi)) { 00195 DevicePrivate *dev = m_devicesMap[udi].data(); 00196 00197 // Ok, this one was requested somewhere was valid 00198 // and now becomes magically invalid! 00199 00200 if (dev) { 00201 Q_ASSERT(dev->backendObject()!=0); 00202 dev->setBackendObject(0); 00203 Q_ASSERT(dev->backendObject()==0); 00204 } 00205 } 00206 00207 emit deviceRemoved(udi); 00208 } 00209 00210 void Solid::DeviceManagerPrivate::_k_destroyed(QObject *object) 00211 { 00212 QString udi = m_reverseMap.take(object); 00213 00214 if (!udi.isEmpty()) { 00215 m_devicesMap.remove(udi); 00216 } 00217 } 00218 00219 Solid::DevicePrivate *Solid::DeviceManagerPrivate::findRegisteredDevice(const QString &udi) 00220 { 00221 if (udi.isEmpty()) { 00222 return m_nullDevice.data(); 00223 } else if (m_devicesMap.contains(udi)) { 00224 return m_devicesMap[udi].data(); 00225 } else { 00226 Ifaces::Device *iface = createBackendObject(udi); 00227 00228 DevicePrivate *devData = new DevicePrivate(udi); 00229 devData->setBackendObject(iface); 00230 00231 QWeakPointer<DevicePrivate> ptr(devData); 00232 m_devicesMap[udi] = ptr; 00233 m_reverseMap[devData] = udi; 00234 00235 connect(devData, SIGNAL(destroyed(QObject *)), 00236 this, SLOT(_k_destroyed(QObject *))); 00237 00238 return devData; 00239 } 00240 } 00241 00242 Solid::Ifaces::Device *Solid::DeviceManagerPrivate::createBackendObject(const QString &udi) 00243 { 00244 QList<QObject*> backends = globalDeviceStorage->managerBackends(); 00245 00246 foreach (QObject *backendObj, backends) { 00247 Ifaces::DeviceManager *backend = qobject_cast<Ifaces::DeviceManager *>(backendObj); 00248 00249 if (backend == 0) continue; 00250 if (!udi.startsWith(backend->udiPrefix())) continue; 00251 00252 Ifaces::Device *iface = 0; 00253 00254 QObject *object = backend->createDevice(udi); 00255 iface = qobject_cast<Ifaces::Device *>(object); 00256 00257 if (iface==0) { 00258 delete object; 00259 } 00260 00261 return iface; 00262 } 00263 00264 return 0; 00265 } 00266 00267 Solid::DeviceManagerStorage::DeviceManagerStorage() 00268 { 00269 00270 } 00271 00272 QList<QObject*> Solid::DeviceManagerStorage::managerBackends() 00273 { 00274 ensureManagerCreated(); 00275 return m_storage.localData()->managerBackends(); 00276 } 00277 00278 Solid::DeviceNotifier *Solid::DeviceManagerStorage::notifier() 00279 { 00280 ensureManagerCreated(); 00281 return m_storage.localData(); 00282 } 00283 00284 void Solid::DeviceManagerStorage::ensureManagerCreated() 00285 { 00286 if (!m_storage.hasLocalData()) { 00287 m_storage.setLocalData(new DeviceManagerPrivate()); 00288 } 00289 } 00290 00291 #include "devicenotifier.moc" 00292 #include "devicemanager_p.moc" 00293
KDE 4.6 API Reference