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>
26 #include <Plasma/DataContainer>
28 // The pattern here is:
29 // FreeBSD: param + mount
31 #ifdef HAVE_SYS_PARAM_H
32 #include <sys/param.h>
35 #ifdef HAVE_SYS_MOUNT_H
36 #include <sys/mount.h>
40 #ifdef HAVE_SYS_STATFS_H
41 #include <sys/statfs.h>
43 #ifdef HAVE_SYS_STATVFS_H
44 #include <sys/statvfs.h>
51 SolidDeviceEngine::SolidDeviceEngine(QObject
* parent
, const QVariantList
& args
)
52 : Plasma::DataEngine(parent
, 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()
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
]);
95 } else if (device
.isValid()) {
96 if (devicemap
.contains(name
) ) {
99 devicemap
[name
] = device
;
100 return populateDeviceData(name
);
104 kDebug() << "Source is not a predicate or a device.";
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()) {
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) {
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
>();
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) {
171 devicetypes
<< I18N_NOOP("Storage Drive");
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) {
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) {
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()));
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) {
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
>();
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) {
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) {
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
>();
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
>();
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
>();
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) {
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
);
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) {
457 devicetypes
<< I18N_NOOP("DVB Interface");
459 setData(name
, I18N_NOOP("Device"), dvbinterface
->device());
460 setData(name
, I18N_NOOP("Device Adapter"), dvbinterface
->deviceAdapter());
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
>();
477 devicetypes
<< I18N_NOOP("Video");
479 setData(name
, I18N_NOOP("Supported Protocols"), video
->supportedProtocols());
480 setData(name
, I18N_NOOP("Supported Drivers"), video
->supportedDrivers());
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
);
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();
516 struct statvfs fs_obj
;
517 if (statvfs(path
,&fs_obj
) < 0) {
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){
528 return (qlonglong
)fs_obj
.f_bfree
*(qlonglong
)fs_obj
.f_bsize
;
532 #warning "This system does not support statfs or statvfs - freeDiskSpace() will return -1"
538 bool SolidDeviceEngine::updateFreeSpace(const QString
&udi
)
540 Solid::Device device
= devicemap
.value(udi
);
541 if (!device
.is
<Solid::StorageAccess
>()) {
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
);
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
));
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
);
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"