• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kde-runtime API Reference
  • KDE Home
  • Contact Us
 

KNotify

  • sources
  • kde-4.14
  • kde-runtime
  • knotify
ksolidnotify.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 by Jacopo De Simoi <wilderkde@gmail.com>
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2, or (at your option)
7  any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 
18  */
19 
20 #include "ksolidnotify.h"
21 #include "knotify.h"
22 
23 //solid specific includes
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>
34 
35 #include <QDBusConnection>
36 #include <QDBusConnectionInterface>
37 #include <QDBusServiceWatcher>
38 
39 #include <KLocale>
40 
41 static const char dbusDeviceNotificationsName[] = "org.kde.DeviceNotifications";
42 static const char dbusDeviceNotificationsPath[] = "/org/kde/DeviceNotifications";
43 
44 
45 KSolidNotify::KSolidNotify(KNotify* parent):
46  QObject(parent),
47  m_kNotify(parent),
48  m_dbusServiceExists(false)
49 {
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)
55  {
56  m_devices.insert(dev.udi(), dev);
57  connectSignals(&m_devices[dev.udi()]);
58  }
59 
60  connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(const QString &)),
61  this, SLOT(onDeviceAdded(const QString &)));
62  connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(const QString &)),
63  this, SLOT(onDeviceRemoved(const QString &)));
64 
65  // check if service already exists on plugin instantiation
66  QDBusConnectionInterface* interface = QDBusConnection::sessionBus().interface();
67  m_dbusServiceExists = interface && interface->isServiceRegistered(dbusDeviceNotificationsName);
68 
69  if( m_dbusServiceExists )
70  slotServiceOwnerChanged(dbusDeviceNotificationsName, QString(), "_"); //connect signals
71 
72  // to catch register/unregister events from service in runtime
73  QDBusServiceWatcher *watcher = new QDBusServiceWatcher(this);
74  watcher->setConnection(QDBusConnection::sessionBus());
75  watcher->setWatchMode(QDBusServiceWatcher::WatchForOwnerChange);
76  watcher->addWatchedService(dbusDeviceNotificationsName);
77  connect(watcher, SIGNAL(serviceOwnerChanged(const QString&, const QString&, const QString&)),
78  SLOT(slotServiceOwnerChanged(const QString&, const QString&, const QString&)));
79 }
80 
81 void KSolidNotify::onDeviceAdded(const QString &udi)
82 {
83  Solid::Device device(udi);
84  m_devices.insert(udi, device);
85  connectSignals(&m_devices[udi]);
86 }
87 
88 void KSolidNotify::onDeviceRemoved(const QString &udi)
89 {
90  if (m_devices[udi].is<Solid::StorageVolume>())
91  {
92  Solid::StorageAccess *access = m_devices[udi].as<Solid::StorageAccess>();
93  if (access)
94  disconnect(access, 0, this, 0);
95  }
96  m_devices.remove(udi);
97 }
98 
99 bool KSolidNotify::isSafelyRemovable(const QString &udi)
100 {
101  Solid::Device parent = m_devices[udi].parent();
102  if (parent.is<Solid::StorageDrive>())
103  {
104  Solid::StorageDrive *drive = parent.as<Solid::StorageDrive>();
105  return (!drive->isInUse() && (drive->isHotpluggable() || drive->isRemovable()));
106  }
107  Solid::StorageAccess* access = m_devices[udi].as<Solid::StorageAccess>();
108  if (access) {
109  return !m_devices[udi].as<Solid::StorageAccess>()->isAccessible();
110  } else {
111  // If this check fails, the device has been already physically
112  // ejected, so no need to say that it is safe to remove it
113  return false;
114  }
115 }
116 
117 void KSolidNotify::connectSignals(Solid::Device* device)
118 {
119  Solid::StorageAccess *access = device->as<Solid::StorageAccess>();
120  if (access)
121  {
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 &)));
126  }
127  if (device->is<Solid::OpticalDisc>())
128  {
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 &)));
132  }
133 }
134 
135 void KSolidNotify::notifySolidEvent(QString event, Solid::ErrorType error, QVariant errorData, const QString & udi, const QString & errorMessage)
136 {
137  ContextList context;
138  if (m_dbusServiceExists)
139  {
140  KNotifyConfig mountConfig("hardwarenotifications", ContextList(), event);
141  if (mountConfig.readEntry("Action").split('|').contains("Popup"))
142  {
143  QDBusMessage m = QDBusMessage::createMethodCall( dbusDeviceNotificationsName, dbusDeviceNotificationsPath, dbusDeviceNotificationsName, "notify" );
144  m << error << errorMessage << errorData.toString().simplified() << udi;
145  QDBusConnection::sessionBus().call(m);
146  }
147  context << QPair<QString, QString>("devnotifier", "present");
148  }
149 
150  m_kNotify->event(event, "hardwarenotifications", context, i18n("Devices notification"), errorMessage, KNotifyImage(), QStringList(), -1);
151 
152 }
153 
154 void KSolidNotify::storageSetupDone(Solid::ErrorType error, QVariant errorData, const QString &udi)
155 {
156  if (error)
157  {
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);
161  }
162 }
163 
164 void KSolidNotify::storageTeardownDone(Solid::ErrorType error, QVariant errorData, const QString &udi)
165 {
166  if (error)
167  {
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))
172  {
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()));
175  }
176 }
177 
178 void KSolidNotify::storageEjectDone(Solid::ErrorType error, QVariant errorData, const QString &udi)
179 {
180  if (error)
181  {
182  QString discUdi;
183  foreach (Solid::Device device, m_devices) {
184  if (device.parentUdi() == udi) {
185  discUdi = device.udi();
186  }
187  }
188 
189  if (discUdi.isNull()) {
190  //This should not happen, bail out
191  return;
192  }
193 
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))
198  {
199  Solid::Device device(udi);
200  notifySolidEvent("safetoremove", error, errorData, udi, i18n("The following device can now be safely removed: %1", device.description()));
201  }
202 }
203 
204 void KSolidNotify::slotServiceOwnerChanged( const QString & serviceName, const QString & oldOwner, const QString & newOwner )
205 {
206  Q_UNUSED(serviceName);
207  if (newOwner.isEmpty())
208  m_dbusServiceExists = false;
209  else if (oldOwner.isEmpty())
210  m_dbusServiceExists = true;
211 }
212 
213 
214 #include "ksolidnotify.moc"
QHash::insert
iterator insert(const Key &key, const T &value)
KSolidNotify::onDeviceAdded
void onDeviceAdded(const QString &udi)
Definition: ksolidnotify.cpp:81
KSolidNotify::KSolidNotify
KSolidNotify(KNotify *parent)
Definition: ksolidnotify.cpp:45
QDBusConnection::call
QDBusMessage call(const QDBusMessage &message, QDBus::CallMode mode, int timeout) const
dbusDeviceNotificationsPath
static const char dbusDeviceNotificationsPath[]
Definition: ksolidnotify.cpp:42
QString::simplified
QString simplified() const
QDBusConnection::sessionBus
QDBusConnection sessionBus()
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QString::isNull
bool isNull() const
dbusDeviceNotificationsName
static const char dbusDeviceNotificationsName[]
Definition: ksolidnotify.cpp:41
KNotifyImage
An image with lazy loading from the byte array.
Definition: knotifyconfig.h:37
QDBusServiceWatcher::setConnection
void setConnection(const QDBusConnection &connection)
knotify.h
QObject
QDBusConnectionInterface
QString::isEmpty
bool isEmpty() const
QString
QList
QHash::remove
int remove(const Key &key)
QStringList
ContextList
QList< QPair< QString, QString > > ContextList
Definition: knotifyconfig.h:32
KNotify
Definition: knotify.h:40
ksolidnotify.h
QDBusMessage
KSolidNotify::onDeviceRemoved
void onDeviceRemoved(const QString &udi)
Definition: ksolidnotify.cpp:88
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QDBusServiceWatcher::setWatchMode
void setWatchMode(QFlags< QDBusServiceWatcher::WatchModeFlag > mode)
QObject::parent
QObject * parent() const
KNotifyConfig
Represent the configuration for an event.
Definition: knotifyconfig.h:60
QVariant::toString
QString toString() const
QDBusMessage::createMethodCall
QDBusMessage createMethodCall(const QString &service, const QString &path, const QString &interface, const QString &method)
QDBusServiceWatcher::addWatchedService
void addWatchedService(const QString &newService)
KNotify::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)
Definition: knotify.cpp:134
QDBusServiceWatcher
QVariant
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:08:23 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KNotify

Skip menu "KNotify"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kde-runtime API Reference

Skip menu "kde-runtime API Reference"
  • KCMShell
  • KNotify
  • Plasma Runtime
  •     PlasmaCore
  •     DragAndDrop
  •     PlasmaComponents
  •     PlasmaExtraComponents
  •     QtExtraComponents

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal