not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / plasma / dataengines / soliddevice / soliddeviceengine.cpp
blob13f001594b6565cd776e210bd611fb569448a727
1 /*
2 * Copyright (C) 2007 Christopher Blauvelt <cblauvelt@gmail.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License version 2 as
6 * published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details
13 * You should have received a copy of the GNU Library General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "soliddeviceengine.h"
21 #include <config-workspace.h>
23 #include <KDebug>
24 #include <KLocale>
26 #include <Plasma/DataContainer>
28 // The pattern here is:
29 // FreeBSD: param + mount
30 // Linux: stat + vfs
31 #ifdef HAVE_SYS_PARAM_H
32 #include <sys/param.h>
33 #endif
35 #ifdef HAVE_SYS_MOUNT_H
36 #include <sys/mount.h>
37 #endif
39 #include <sys/stat.h>
40 #ifdef HAVE_SYS_STATFS_H
41 #include <sys/statfs.h>
42 #endif
43 #ifdef HAVE_SYS_STATVFS_H
44 #include <sys/statvfs.h>
45 #endif
47 #ifdef HAVE_SYS_VFS_H
48 #include <sys/vfs.h>
49 #endif
51 SolidDeviceEngine::SolidDeviceEngine(QObject* parent, const QVariantList& args)
52 : Plasma::DataEngine(parent, args),
53 temperature(0),
54 notifier(0)
56 Q_UNUSED(args)
57 signalmanager = new DeviceSignalMapManager(this);
59 listenForNewDevices();
60 temperature = new HddTemp(this);
61 setMinimumPollingInterval(1000);
62 connect(this, SIGNAL(sourceRemoved(const QString&)),
63 this, SLOT(sourceRemoved(const QString&)));
66 SolidDeviceEngine::~SolidDeviceEngine()
70 void SolidDeviceEngine::listenForNewDevices()
72 if(notifier) {
73 return;
75 //detect when new devices are added
76 notifier = Solid::DeviceNotifier::instance();
77 connect(notifier, SIGNAL(deviceAdded(const QString&)),
78 this, SLOT(deviceAdded(const QString&)));
79 connect(notifier, SIGNAL(deviceRemoved(const QString&)),
80 this, SLOT(deviceRemoved(const QString&)));
83 bool SolidDeviceEngine::sourceRequestEvent(const QString &name)
86 //create a predicate to check for validity
87 Solid::Predicate predicate = Solid::Predicate::fromString(name);
88 Solid::Device device(name);
89 if(predicate.isValid() && !predicatemap.contains(name)) {
90 foreach (const Solid::Device &device, Solid::Device::listFromQuery(predicate)) {
91 predicatemap[name] << device.udi();
93 setData(name, predicatemap[name]);
94 return true;
95 } else if (device.isValid()) {
96 if (devicemap.contains(name) ) {
97 return true;
98 } else {
99 devicemap[name] = device;
100 return populateDeviceData(name);
104 kDebug() << "Source is not a predicate or a device.";
105 return false;
108 void SolidDeviceEngine::sourceRemoved(const QString &source)
110 devicemap.remove(source);
111 predicatemap.remove(source);
114 bool SolidDeviceEngine::populateDeviceData(const QString &name)
116 Solid::Device device = devicemap.value(name);
117 if (!device.isValid()) {
118 return false;
121 QStringList devicetypes;
122 setData(name, I18N_NOOP("Parent UDI"), device.parentUdi());
123 setData(name, I18N_NOOP("Vendor"), device.vendor());
124 setData(name, I18N_NOOP("Product"), device.product());
125 setData(name, I18N_NOOP("Icon"), device.icon());
127 if (device.is<Solid::Processor>()) {
128 Solid::Processor *processor = device.as<Solid::Processor>();
129 if (processor == 0) {
130 return false;
133 devicetypes << I18N_NOOP("Processor");
134 setData(name, I18N_NOOP("Number"), processor->number());
135 setData(name, I18N_NOOP("Max Speed"), processor->maxSpeed());
136 setData(name, I18N_NOOP("Can Change Frequency"), processor->canChangeFrequency());
138 if (device.is<Solid::Block>()) {
139 Solid::Block *block = device.as<Solid::Block>();
140 if (block == 0) {
141 return false;
144 devicetypes << I18N_NOOP("Block");
145 setData(name, I18N_NOOP("Major"), block->deviceMajor());
146 setData(name, I18N_NOOP("Minor"), block->deviceMajor());
147 setData(name, I18N_NOOP("Device"), block->device());
149 if (device.is<Solid::StorageAccess>()) {
150 Solid::StorageAccess *storageaccess = device.as<Solid::StorageAccess>();
151 if (storageaccess == 0) return false;
153 devicetypes << I18N_NOOP("Storage Access");
154 setData(name, I18N_NOOP("Accessible"), storageaccess->isAccessible());
155 setData(name, I18N_NOOP("File Path"), storageaccess->filePath());
156 QVariant freeDiskVar;
157 qlonglong freeDisk = freeDiskSpace(storageaccess->filePath());
158 if ( freeDisk != -1 ) {
159 freeDiskVar.setValue( freeDisk );
161 setData(name, I18N_NOOP("Free Space"), freeDiskVar );
163 signalmanager->mapDevice(storageaccess, device.udi());
165 if (device.is<Solid::StorageDrive>()) {
166 Solid::StorageDrive *storagedrive = device.as<Solid::StorageDrive>();
167 if (storagedrive == 0) {
168 return false;
171 devicetypes << I18N_NOOP("Storage Drive");
173 QStringList bus;
174 bus << I18N_NOOP("Ide") << I18N_NOOP("Usb") << I18N_NOOP("Ieee1394") << I18N_NOOP("Scsi") << I18N_NOOP("Sata") << I18N_NOOP("Platform");
175 QStringList drivetype;
176 drivetype << I18N_NOOP("Hard Disk") << I18N_NOOP("Cdrom Drive") << I18N_NOOP("Floppy") << I18N_NOOP("Tape") << I18N_NOOP("Compact Flash") << I18N_NOOP("Memory Stick") << I18N_NOOP("Smart Media") << I18N_NOOP("SdMmc") << I18N_NOOP("Xd");
178 setData(name, I18N_NOOP("Bus"), bus.at((int)storagedrive->bus()));
179 setData(name, I18N_NOOP("Drive Type"), drivetype.at((int)storagedrive->driveType()));
180 setData(name, I18N_NOOP("Removable"), storagedrive->isRemovable());
181 setData(name, I18N_NOOP("Hotpluggable"), storagedrive->isHotpluggable());
183 updateHardDiskTemperature(name);
185 if (device.is<Solid::OpticalDrive>()) {
186 Solid::OpticalDrive *opticaldrive = device.as<Solid::OpticalDrive>();
187 if (opticaldrive == 0) {
188 return false;
191 devicetypes << I18N_NOOP("Optical Drive");
193 QStringList supportedtypes;
194 Solid::OpticalDrive::MediumTypes mediatypes = opticaldrive->supportedMedia();
195 if (mediatypes & Solid::OpticalDrive::Cdr) {
196 supportedtypes << I18N_NOOP("Cdr");
198 if (mediatypes & Solid::OpticalDrive::Cdrw) {
199 supportedtypes << I18N_NOOP("Cdrw");
201 if (mediatypes & Solid::OpticalDrive::Dvd) {
202 supportedtypes << I18N_NOOP("Dvd");
204 if (mediatypes & Solid::OpticalDrive::Dvdr) {
205 supportedtypes << I18N_NOOP("Dvdr");
207 if (mediatypes & Solid::OpticalDrive::Dvdrw) {
208 supportedtypes << I18N_NOOP("Dvdrw");
210 if (mediatypes & Solid::OpticalDrive::Dvdram) {
211 supportedtypes << I18N_NOOP("Dvdram");
213 if (mediatypes & Solid::OpticalDrive::Dvdplusr) {
214 supportedtypes << I18N_NOOP("Dvdplusr");
216 if (mediatypes & Solid::OpticalDrive::Dvdplusrw) {
217 supportedtypes << I18N_NOOP("Dvdplusrw");
219 if (mediatypes & Solid::OpticalDrive::Dvdplusdl) {
220 supportedtypes << I18N_NOOP("Dvdplusdl");
222 if (mediatypes & Solid::OpticalDrive::Dvdplusdlrw) {
223 supportedtypes << I18N_NOOP("Dvdplusdlrw");
225 if (mediatypes & Solid::OpticalDrive::Bd) {
226 supportedtypes << I18N_NOOP("Bd");
228 if (mediatypes & Solid::OpticalDrive::Bdr) {
229 supportedtypes << I18N_NOOP("Bdr");
231 if (mediatypes & Solid::OpticalDrive::Bdre) {
232 supportedtypes << I18N_NOOP("Bdre");
234 if (mediatypes & Solid::OpticalDrive::HdDvd) {
235 supportedtypes << I18N_NOOP("HdDvd");
237 if (mediatypes & Solid::OpticalDrive::HdDvdr) {
238 supportedtypes << I18N_NOOP("HdDvdr");
240 if (mediatypes & Solid::OpticalDrive::HdDvdrw) {
241 supportedtypes << I18N_NOOP("HdDvdrw");
243 setData(name, I18N_NOOP("Supported Media"), supportedtypes);
245 setData(name, I18N_NOOP("Read Speed"), opticaldrive->readSpeed());
246 setData(name, I18N_NOOP("Write Speed"), opticaldrive->writeSpeed());
248 //the following method return QList<int> so we need to convert it to QList<QVariant>
249 QList<int> writespeeds = opticaldrive->writeSpeeds();
250 QList<QVariant> variantlist = QList<QVariant>();
251 foreach(int num, writespeeds) {
252 variantlist << QVariant(num);
254 setData(name, I18N_NOOP("Write Speeds"), variantlist);
257 if (device.is<Solid::StorageVolume>()) {
258 Solid::StorageVolume *storagevolume = device.as<Solid::StorageVolume>();
259 if (storagevolume == 0) {
260 return false;
263 devicetypes << I18N_NOOP("Storage Volume");
265 QStringList usagetypes;
266 usagetypes << i18n("Other") << i18n("Unused") << i18n("File System")
267 << i18n("Partition Table") << i18n("Raid") << i18n("Encrypted");
269 if (usagetypes.count() > storagevolume->usage()) {
270 setData(name, I18N_NOOP("Usage"), usagetypes.at((int)storagevolume->usage()));
271 } else {
272 setData(name, I18N_NOOP("Usage"), i18n("Unknown"));
275 setData(name, I18N_NOOP("Ignored"), storagevolume->isIgnored());
276 setData(name, I18N_NOOP("File System Type"), storagevolume->fsType());
277 setData(name, I18N_NOOP("Label"), storagevolume->label());
278 setData(name, I18N_NOOP("Uuid"), storagevolume->uuid());
279 setData(name, I18N_NOOP("Size"), storagevolume->size());
281 if (device.is<Solid::OpticalDisc>()) {
282 Solid::OpticalDisc *opticaldisc = device.as<Solid::OpticalDisc>();
283 if (opticaldisc == 0) {
284 return false;
287 devicetypes << I18N_NOOP("OpticalDisc");
289 //get the content types
290 QStringList contenttypelist;
291 Solid::OpticalDisc::ContentTypes contenttypes = opticaldisc->availableContent();
292 if (contenttypes & Solid::OpticalDisc::Audio) {
293 contenttypelist << I18N_NOOP("Audio");
295 if (contenttypes & Solid::OpticalDisc::Audio) {
296 contenttypelist << I18N_NOOP("Data");
298 if (contenttypes & Solid::OpticalDisc::Audio) {
299 contenttypelist << I18N_NOOP("Video Cd");
301 if (contenttypes & Solid::OpticalDisc::Audio) {
302 contenttypelist << I18N_NOOP("Super Video Cd");
304 if (contenttypes & Solid::OpticalDisc::Audio) {
305 contenttypelist << I18N_NOOP("Video Dvd");
307 setData(name, I18N_NOOP("Available Content"), contenttypelist);
309 QStringList disctypes;
310 disctypes << I18N_NOOP("Unknown Disc Type") << I18N_NOOP("CD Rom") << I18N_NOOP("CD Recordable")
311 << I18N_NOOP("CD Rewritable") << I18N_NOOP("DVD Rom") << I18N_NOOP("DVD Ram")
312 << I18N_NOOP("DVD Recordable") << I18N_NOOP("DVD Rewritable") << I18N_NOOP("DVD Plus Recordable")
313 << I18N_NOOP("DVD Plus Rewritable") << I18N_NOOP("DVD Plus Recordable Duallayer")
314 << I18N_NOOP("DVD Plus Rewritable Duallayer") << I18N_NOOP("Blu Ray Rom") << I18N_NOOP("Blu Ray Recordable")
315 << I18N_NOOP("Blu Ray Rewritable") << I18N_NOOP("HD DVD Rom") << I18N_NOOP("HD DVD Recordable")
316 << I18N_NOOP("HD DVD Rewritable");
317 //+1 because the enum starts at -1
318 setData(name, I18N_NOOP("Disc Type"), disctypes.at((int)opticaldisc->discType() + 1));
319 setData(name, I18N_NOOP("Appendable"), opticaldisc->isAppendable());
320 setData(name, I18N_NOOP("Blank"), opticaldisc->isBlank());
321 setData(name, I18N_NOOP("Rewritable"), opticaldisc->isRewritable());
322 setData(name, I18N_NOOP("Capacity"), opticaldisc->capacity());
324 if (device.is<Solid::Camera>()) {
325 Solid::Camera *camera = device.as<Solid::Camera>();
326 if (camera == 0) {
327 return false;
330 devicetypes << I18N_NOOP("Camera");
332 setData(name, I18N_NOOP("Supported Protocols"), camera->supportedProtocols());
333 setData(name, I18N_NOOP("Supported Drivers"), camera->supportedDrivers());
335 if (device.is<Solid::PortableMediaPlayer>()) {
336 Solid::PortableMediaPlayer *mediaplayer = device.as<Solid::PortableMediaPlayer>();
337 if (mediaplayer == 0) {
338 return false;
341 devicetypes << I18N_NOOP("Portable Media Player");
343 setData(name, I18N_NOOP("Supported Protocols"), mediaplayer->supportedProtocols());
344 setData(name, I18N_NOOP("Supported Drivers"), mediaplayer->supportedDrivers());
346 if (device.is<Solid::NetworkInterface>()) {
347 Solid::NetworkInterface *networkinterface = device.as<Solid::NetworkInterface>();
348 if (networkinterface == 0) {
349 return false;
352 devicetypes << I18N_NOOP("Network Interface");
354 setData(name, I18N_NOOP("Interface Name"), networkinterface->ifaceName());
355 setData(name, I18N_NOOP("Wireless"), networkinterface->isWireless());
356 setData(name, I18N_NOOP("Hardware Address"), networkinterface->hwAddress());
357 setData(name, I18N_NOOP("Mac Address"), networkinterface->macAddress());
359 if (device.is<Solid::AcAdapter>()) {
360 Solid::AcAdapter *ac = device.as<Solid::AcAdapter>();
361 if (ac == 0) {
362 return false;
365 devicetypes << I18N_NOOP("AD Adapter");
367 setData(name, I18N_NOOP("Plugged In"), ac->isPlugged());
368 signalmanager->mapDevice(ac, device.udi());
370 if (device.is<Solid::Battery>()) {
371 Solid::Battery *battery = device.as<Solid::Battery>();
372 if (battery == 0) {
373 return false;
376 devicetypes << I18N_NOOP("Battery");
378 QStringList batterytype;
379 batterytype << I18N_NOOP("Unknown Battery") << I18N_NOOP("PDA Battery") << I18N_NOOP("UPS Battery")
380 << I18N_NOOP("Primary Battery") << I18N_NOOP("Mouse Battery") << I18N_NOOP("Keyboard Battery")
381 << I18N_NOOP("Keyboard Mouse Battery") << I18N_NOOP("Camera Battery");
383 QStringList chargestate;
384 chargestate << I18N_NOOP("Fully Charged") << I18N_NOOP("Charging") << I18N_NOOP("Discharging");
386 setData(name, I18N_NOOP("Plugged In"), battery->isPlugged());
387 setData(name, I18N_NOOP("Type"), batterytype.at((int)battery->type()));
388 setData(name, I18N_NOOP("Charge Percent"), battery->chargePercent());
389 setData(name, I18N_NOOP("Rechargeable"), battery->isRechargeable());
390 setData(name, I18N_NOOP("Charge State"), chargestate.at((int)battery->chargeState()));
392 signalmanager->mapDevice(battery, device.udi());
394 if (device.is<Solid::Button>()) {
395 Solid::Button *button = device.as<Solid::Button>();
396 if (button == 0) {
397 return false;
400 devicetypes << I18N_NOOP("Button");
402 QStringList buttontype;
403 buttontype << I18N_NOOP("Lid Button") << I18N_NOOP("Power Button") << I18N_NOOP("Sleep Button")
404 << I18N_NOOP("Unknown Button Type");
406 setData(name, I18N_NOOP("Type"), buttontype.at((int)button->type()));
407 setData(name, I18N_NOOP("Has State"), button->hasState());
408 setData(name, I18N_NOOP("State Value"), button->stateValue());
409 setData(name, I18N_NOOP("Pressed"), false); //this is an extra value that is tracked by the button signals
411 signalmanager->mapDevice(button, device.udi());
413 if (device.is<Solid::AudioInterface>()) {
414 Solid::AudioInterface *audiointerface = device.as<Solid::AudioInterface>();
415 if (audiointerface == 0) {
416 return false;
419 devicetypes << I18N_NOOP("Audio Interface");
421 QStringList audiodriver;
422 audiodriver << I18N_NOOP("ALSA") << I18N_NOOP("Open Sound System") << I18N_NOOP("Unknown Audio Driver");
424 setData(name, I18N_NOOP("Driver"), audiodriver.at((int)audiointerface->driver()));
425 setData(name, I18N_NOOP("Driver Handle"), audiointerface->driverHandle());
426 setData(name, I18N_NOOP("Name"), audiointerface->name());
428 //get AudioInterfaceTypes
429 QStringList audiointerfacetypes;
430 Solid::AudioInterface::AudioInterfaceTypes devicetypes = audiointerface->deviceType();
431 if (devicetypes & Solid::AudioInterface::UnknownAudioInterfaceType) {
432 audiointerfacetypes << I18N_NOOP("Unknown Audio Interface Type");
434 if (devicetypes & Solid::AudioInterface::AudioControl) {
435 audiointerfacetypes << I18N_NOOP("Audio Control");
437 if (devicetypes & Solid::AudioInterface::AudioInput) {
438 audiointerfacetypes << I18N_NOOP("Audio Input");
440 if (devicetypes & Solid::AudioInterface::AudioOutput) {
441 audiointerfacetypes << I18N_NOOP("Audio Output");
443 setData(name, I18N_NOOP("Audio Device Type"), audiointerfacetypes);
445 //get SoundCardTypes
446 QStringList soundcardtype;
447 soundcardtype << I18N_NOOP("Internal Soundcard") << I18N_NOOP("USB Soundcard") << I18N_NOOP("Firewire Soundcard")
448 << I18N_NOOP("Headset") << I18N_NOOP("Modem");
449 setData(name, I18N_NOOP("Soundcard Type"), soundcardtype.at((int)audiointerface->soundcardType()));
451 if (device.is<Solid::DvbInterface>()) {
452 Solid::DvbInterface *dvbinterface = device.as<Solid::DvbInterface>();
453 if (dvbinterface == 0) {
454 return false;
457 devicetypes << I18N_NOOP("DVB Interface");
459 setData(name, I18N_NOOP("Device"), dvbinterface->device());
460 setData(name, I18N_NOOP("Device Adapter"), dvbinterface->deviceAdapter());
462 //get devicetypes
463 QStringList dvbdevicetypes;
464 dvbdevicetypes << I18N_NOOP("DVB Unknown") << I18N_NOOP("DVB Audio") << I18N_NOOP("DVB Ca")
465 << I18N_NOOP("DVB Demux") << I18N_NOOP("DVB DVR") << I18N_NOOP("DVB Frontend")
466 << I18N_NOOP("DVB Net") << I18N_NOOP("DVB OSD") << I18N_NOOP("DVB Sec") << I18N_NOOP("DVB Video");
468 setData(name, I18N_NOOP("DVB Device Type"), dvbdevicetypes.at((int)dvbinterface->deviceType()));
469 setData(name, I18N_NOOP("Device Index"), dvbinterface->deviceIndex());
471 if (device.is<Solid::Video>()) {
472 Solid::Video *video = device.as<Solid::Video>();
473 if (video == 0) {
474 return false;
477 devicetypes << I18N_NOOP("Video");
479 setData(name, I18N_NOOP("Supported Protocols"), video->supportedProtocols());
480 setData(name, I18N_NOOP("Supported Drivers"), video->supportedDrivers());
482 QStringList handles;
483 foreach (const QString &driver, video->supportedDrivers()) {
484 handles << video->driverHandle(driver).toString();
486 setData(name, I18N_NOOP("Driver Handles"), handles);
489 setData(name, I18N_NOOP("Device Types"), devicetypes);
490 return true;
493 void SolidDeviceEngine::deviceAdded(const QString& udi)
495 Solid::Device device(udi);
497 foreach (const QString &query, predicatemap.keys()) {
498 Solid::Predicate predicate = Solid::Predicate::fromString(query);
499 if (predicate.matches(device)) {
500 predicatemap[query] << udi;
501 setData(query, predicatemap[query]);
505 scheduleSourcesUpdated();
508 qlonglong SolidDeviceEngine::freeDiskSpace(const QString &mountPoint)
510 //determine the free space available on the device
511 const QByteArray pathBa=mountPoint.toAscii();
512 // path is only valid as long as pathBa exists
513 const char *path=pathBa.constData();
515 #ifdef HAVE_STATVFS
516 struct statvfs fs_obj;
517 if (statvfs(path,&fs_obj) < 0) {
518 return -1;
519 } else {
520 return (qlonglong)fs_obj.f_bfree*(qlonglong)fs_obj.f_frsize;
522 #elif defined(HAVE_STATFS) && !defined(USE_SOLARIS)
523 struct statfs fs_obj;
524 if (statfs(path,&fs_obj) < 0){
525 return -1;
527 else{
528 return (qlonglong)fs_obj.f_bfree*(qlonglong)fs_obj.f_bsize;
530 #else
531 #ifdef __GNUC__
532 #warning "This system does not support statfs or statvfs - freeDiskSpace() will return -1"
533 #endif
534 #endif
535 return -1;
538 bool SolidDeviceEngine::updateFreeSpace(const QString &udi)
540 Solid::Device device = devicemap.value(udi);
541 if (!device.is<Solid::StorageAccess>()) {
542 return false;
545 Solid::StorageAccess *storageaccess = device.as<Solid::StorageAccess>();
546 if (storageaccess == 0) return false;
548 QVariant freeSpaceVar;
549 qlonglong freeSpace = freeDiskSpace(storageaccess->filePath());
550 if ( freeSpace != -1 ) {
551 freeSpaceVar.setValue( freeSpace );
553 setData(udi, I18N_NOOP("Free Space"), freeSpaceVar );
554 return true;
557 bool SolidDeviceEngine::updateHardDiskTemperature(const QString &udi)
559 Solid::Device device = devicemap.value(udi);
560 Solid::Block *block = device.as<Solid::Block>();
561 if (block != 0 && temperature->sources().contains(block->device())) {
562 setData(udi, I18N_NOOP("Temperature"), temperature->data(block->device(), HddTemp::Temperature));
563 setData(udi, I18N_NOOP("Temperature Unit"), temperature->data(block->device(), HddTemp::Unit));
564 return true;
566 return false;
569 bool SolidDeviceEngine::updateSourceEvent(const QString& source)
571 bool update1 = updateFreeSpace(source);
572 bool update2 = updateHardDiskTemperature(source);
574 return (update1 || update2);
577 void SolidDeviceEngine::deviceRemoved(const QString& udi)
579 foreach (const QString &query, predicatemap.keys()) {
580 predicatemap[query].removeAll(udi);
581 setData(query, predicatemap[query]);
584 devicemap.remove(udi);
585 removeSource(udi);
586 scheduleSourcesUpdated();
589 void SolidDeviceEngine::deviceChanged(const QString& udi, const QString &property, const QVariant &value)
591 setData(udi, property, value);
592 scheduleSourcesUpdated();
595 #include "soliddeviceengine.moc"