24 #include <Solid/DeviceNotifier>
25 #include <Solid/Device>
26 #include <Solid/DeviceInterface>
27 #include <Solid/StorageDrive>
28 #include <Solid/StorageVolume>
29 #include <Solid/StorageAccess>
30 #include <Solid/OpticalDrive>
31 #include <Solid/OpticalDisc>
32 #include <Solid/PortableMediaPlayer>
33 #include <Solid/Predicate>
35 #include <QDBusConnection>
36 #include <QDBusConnectionInterface>
37 #include <QDBusServiceWatcher>
48 m_dbusServiceExists(false)
50 Solid::Predicate p(Solid::DeviceInterface::StorageAccess);
51 p |= Solid::Predicate(Solid::DeviceInterface::OpticalDrive);
52 p |= Solid::Predicate(Solid::DeviceInterface::PortableMediaPlayer);
53 QList<Solid::Device> devices = Solid::Device::listFromQuery(p);
54 foreach (
const Solid::Device &dev, devices)
56 m_devices.insert(dev.udi(), dev);
57 connectSignals(&m_devices[dev.udi()]);
60 connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(
const QString &)),
62 connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(
const QString &)),
66 QDBusConnectionInterface*
interface = QDBusConnection::sessionBus().interface();
69 if( m_dbusServiceExists )
73 QDBusServiceWatcher *watcher =
new QDBusServiceWatcher(
this);
74 watcher->setConnection(QDBusConnection::sessionBus());
75 watcher->setWatchMode(QDBusServiceWatcher::WatchForOwnerChange);
77 connect(watcher, SIGNAL(serviceOwnerChanged(
const QString&,
const QString&,
const QString&)),
78 SLOT(slotServiceOwnerChanged(
const QString&,
const QString&,
const QString&)));
83 Solid::Device device(udi);
84 m_devices.insert(udi, device);
85 connectSignals(&m_devices[udi]);
90 if (m_devices[udi].is<Solid::StorageVolume>())
92 Solid::StorageAccess *access = m_devices[udi].as<Solid::StorageAccess>();
94 disconnect(access, 0,
this, 0);
96 m_devices.remove(udi);
99 bool KSolidNotify::isSafelyRemovable(
const QString &udi)
101 Solid::Device parent = m_devices[udi].parent();
102 if (parent.is<Solid::StorageDrive>())
104 Solid::StorageDrive *drive = parent.as<Solid::StorageDrive>();
105 return (!drive->isInUse() && (drive->isHotpluggable() || drive->isRemovable()));
107 Solid::StorageAccess* access = m_devices[udi].as<Solid::StorageAccess>();
109 return !m_devices[udi].as<Solid::StorageAccess>()->isAccessible();
117 void KSolidNotify::connectSignals(Solid::Device* device)
119 Solid::StorageAccess *access = device->as<Solid::StorageAccess>();
122 connect(access, SIGNAL(teardownDone(Solid::ErrorType, QVariant,
const QString &)),
123 this, SLOT(storageTeardownDone(Solid::ErrorType, QVariant ,
const QString &)));
124 connect(access, SIGNAL(setupDone(Solid::ErrorType, QVariant,
const QString &)),
125 this, SLOT(storageSetupDone(Solid::ErrorType, QVariant ,
const QString &)));
127 if (device->is<Solid::OpticalDisc>())
129 Solid::OpticalDrive *drive = device->parent().as<Solid::OpticalDrive>();
130 connect(drive, SIGNAL(ejectDone(Solid::ErrorType, QVariant,
const QString &)),
131 this, SLOT(storageEjectDone(Solid::ErrorType, QVariant ,
const QString &)));
135 void KSolidNotify::notifySolidEvent(QString event, Solid::ErrorType error, QVariant errorData,
const QString & udi,
const QString & errorMessage)
138 if (m_dbusServiceExists)
141 if (mountConfig.readEntry(
"Action").split(
'|').contains(
"Popup"))
144 m << error << errorMessage << errorData.toString().simplified() << udi;
145 QDBusConnection::sessionBus().call(m);
147 context << QPair<QString, QString>(
"devnotifier",
"present");
150 m_kNotify->
event(event,
"hardwarenotifications", context, i18n(
"Devices notification"), errorMessage,
KNotifyImage(), QStringList(), -1);
154 void KSolidNotify::storageSetupDone(Solid::ErrorType error, QVariant errorData,
const QString &udi)
158 Solid::Device device(udi);
159 QString errorMessage = i18n(
"Could not mount the following device: %1", device.description());
160 notifySolidEvent(
"mounterror", error, errorData, udi, errorMessage);
164 void KSolidNotify::storageTeardownDone(Solid::ErrorType error, QVariant errorData,
const QString &udi)
168 Solid::Device device(udi);
169 QString errorMessage = i18n(
"Could not unmount the following device: %1\nOne or more files on this device are open within an application ", device.description());
170 notifySolidEvent(
"mounterror", error, errorData, udi, errorMessage);
171 }
else if (isSafelyRemovable(udi))
173 Solid::Device device(udi);
174 notifySolidEvent(
"safetoremove", error, errorData, udi, i18nc(
"The term \"remove\" here means \"physically disconnect the device from the computer\", whereas \"safely\" means \"without risk of data loss\"",
"The following device can now be safely removed: %1", device.description()));
178 void KSolidNotify::storageEjectDone(Solid::ErrorType error, QVariant errorData,
const QString &udi)
183 foreach (Solid::Device device, m_devices) {
184 if (device.parentUdi() == udi) {
185 discUdi = device.udi();
189 if (discUdi.isNull()) {
194 Solid::Device discDevice(discUdi);
195 QString errorMessage = i18n(
"Could not eject the following device: %1\nOne or more files on this device are open within an application ", discDevice.description());
196 notifySolidEvent(
"mounterror", error, errorData, udi, errorMessage);
197 }
else if (isSafelyRemovable(udi))
199 Solid::Device device(udi);
200 notifySolidEvent(
"safetoremove", error, errorData, udi, i18n(
"The following device can now be safely removed: %1", device.description()));
204 void KSolidNotify::slotServiceOwnerChanged(
const QString & serviceName,
const QString & oldOwner,
const QString & newOwner )
206 Q_UNUSED(serviceName);
207 if (newOwner.isEmpty())
208 m_dbusServiceExists =
false;
209 else if (oldOwner.isEmpty())
210 m_dbusServiceExists =
true;
214 #include "ksolidnotify.moc"
void onDeviceAdded(const QString &udi)
KSolidNotify(KNotify *parent)
static const char dbusDeviceNotificationsPath[]
static const char dbusDeviceNotificationsName[]
An image with lazy loading from the byte array.
QList< QPair< QString, QString > > ContextList
void onDeviceRemoved(const QString &udi)
Represent the configuration for an event.
int event(const QString &event, const QString &fromApp, const ContextList &contexts, const QString &title, const QString &text, const KNotifyImage &image, const QStringList &actions, int timeout, WId winId=0)