1 /***************************************************************************
2 * Copyright (C) 2007 by Alexis Ménard <darktears31@gmail.com> *
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 of the License, or *
7 * (at your option) any later version. *
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. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
18 ***************************************************************************/
21 #include "devicenotifier.h"
22 #include "notifierview.h"
23 #include "notifierdialog.h"
26 #include <QGraphicsLinearLayout>
27 #include <QGraphicsProxyWidget>
32 #include <KConfigDialog>
33 #include <KStandardDirs>
34 #include <KDesktopFile>
35 #include <kdesktopfileactions.h>
36 #include <KIconLoader>
39 #include <Plasma/Dialog>
40 //use for desktop view
41 #include <Plasma/IconWidget>
42 #include <Plasma/Theme>
45 #include <solid/device.h>
46 #include <solid/storagedrive.h>
49 using namespace Plasma
;
50 using namespace Notifier
;
52 K_EXPORT_PLASMA_APPLET(devicenotifier
, DeviceNotifier
)
54 DeviceNotifier::DeviceNotifier(QObject
*parent
, const QVariantList
&args
)
55 : Plasma::PopupApplet(parent
, args
),
57 m_solidDeviceEngine(0),
64 setBackgroundHints(StandardBackground
);
65 setAspectRatioMode(IgnoreAspectRatio
);
67 // let's initialize the widget
70 resize(widget()->sizeHint());
73 DeviceNotifier::~DeviceNotifier()
79 void DeviceNotifier::init()
81 KConfigGroup cg
= config();
82 m_numberItems
= cg
.readEntry("NumberItems", 4);
83 m_itemsValidity
= cg
.readEntry("ItemsValidity", 5);
85 m_solidEngine
= dataEngine("hotplug");
86 m_solidDeviceEngine
= dataEngine("soliddevice");
88 m_icon
= new Plasma::IconWidget(KIcon("device-notifier",NULL
), QString());
89 m_iconName
= QString("device-notifier");
91 Plasma::ToolTipManager::self()->registerWidget(this);
93 setPopupIcon(m_icon
->icon());
95 //feed the list with what is already reported by the engine
97 //connect to engine when a device is plug
98 connect(m_solidEngine
, SIGNAL(sourceAdded(const QString
&)),
99 this, SLOT(onSourceAdded(const QString
&)));
100 connect(m_solidEngine
, SIGNAL(sourceRemoved(const QString
&)),
101 this, SLOT(onSourceRemoved(const QString
&)));
103 fillPreviousDevices();
106 QWidget
*DeviceNotifier::widget()
109 m_dialog
= new NotifierDialog(this);
112 return m_dialog
->dialog();
115 void DeviceNotifier::fillPreviousDevices()
117 m_fillingPreviousDevices
= true;
118 foreach (const QString
&source
, m_solidEngine
->sources()) {
119 Solid::Device device
= Solid::Device(source
);
120 Solid::Device parentDevice
= device
.parent();
121 Solid::StorageDrive
*drive
= parentDevice
.as
<Solid::StorageDrive
>();
122 if (drive
&& (drive
->isHotpluggable() || drive
->isRemovable())) {
123 onSourceAdded(source
);
126 m_fillingPreviousDevices
= false;
129 void DeviceNotifier::changeNotifierIcon(const QString
& name
)
131 if (m_icon
&& name
.isNull()) {
132 m_icon
->setIcon(m_iconName
);
134 m_icon
->setIcon(name
);
137 setPopupIcon(m_icon
->icon());
140 void DeviceNotifier::popupEvent(bool show
)
143 Plasma::ToolTipManager::self()->clearContent(this);
147 void DeviceNotifier::dataUpdated(const QString
&source
, Plasma::DataEngine::Data data
)
149 if (data
.size() > 0) {
150 //data from hotplug engine
151 if (!data
["predicateFiles"].isNull()) {
153 QString lastActionLabel
;
154 foreach (const QString
&desktop
, data
["predicateFiles"].toStringList()) {
155 QString filePath
= KStandardDirs::locate("data", "solid/actions/" + desktop
);
156 QList
<KServiceAction
> services
= KDesktopFileActions::userDefinedServices(filePath
, true);
157 nb_actions
+= services
.size();
158 if (services
.size() > 0) {
159 lastActionLabel
= QString(services
[0].text());
162 m_dialog
->setDeviceData(source
,data
["predicateFiles"],NotifierDialog::PredicateFilesRole
);
163 m_dialog
->setDeviceData(source
,data
["text"], Qt::DisplayRole
);
166 m_dialog
->setDeviceData(source
,data
["icon"], NotifierDialog::IconNameRole
);
168 m_dialog
->setDeviceData(source
,KIcon(data
["icon"].toString()), Qt::DecorationRole
);
170 if (nb_actions
> 1) {
171 QString s
= i18np("1 action for this device",
172 "%1 actions for this device",
174 m_dialog
->setDeviceData(source
, s
, NotifierDialog::ActionRole
);
176 m_dialog
->setDeviceData(source
, lastActionLabel
, NotifierDialog::ActionRole
);
179 //data from soliddevice engine
181 kDebug() << "DeviceNotifier::solidDeviceEngine updated" << source
;
182 if (data
["Device Types"].toStringList().contains("Storage Access")) {
183 if (data
["Accessible"].toBool() == true) {
184 m_dialog
->setUnMount(true,source
);
186 //set icon to mounted device
187 QStringList overlays
;
188 overlays
<< "emblem-mounted";
189 m_dialog
->setDeviceData(source
, KIcon(m_dialog
->getDeviceData(source
,NotifierDialog::IconNameRole
).toString(), NULL
, overlays
), Qt::DecorationRole
);
190 } else if (data
["Device Types"].toStringList().contains("OpticalDisc")) {
191 //Unmounted optical drive
192 m_dialog
->setDeviceData(source
, KIcon("media-eject"), Qt::DecorationRole
);
193 //set icon to unmounted device
194 m_dialog
->setUnMount(true,source
);
195 m_dialog
->setDeviceData(source
, KIcon(m_dialog
->getDeviceData(source
,NotifierDialog::IconNameRole
).toString()), Qt::DecorationRole
);
197 m_dialog
->setUnMount(false,source
);
199 //set icon to unmounted device
200 m_dialog
->setDeviceData(source
, KIcon(m_dialog
->getDeviceData(source
,NotifierDialog::IconNameRole
).toString()), Qt::DecorationRole
);
203 // actions specific for other types of devices will go here
208 void DeviceNotifier::notifyDevice(const QString
&name
)
212 if (!m_fillingPreviousDevices
) {
217 void DeviceNotifier::toolTipAboutToShow()
219 Plasma::ToolTipContent toolTip
;
220 if (!m_lastPlugged
.isEmpty()) {
221 Solid::Device
device(m_lastPlugged
.last());
223 toolTip
.setSubText(i18n("Last plugged in device: %1", device
.product()));
224 toolTip
.setImage(KIcon(device
.icon()));
226 toolTip
.setSubText(i18n("No devices plugged in"));
227 toolTip
.setImage(KIcon("device-notifier"));
230 Plasma::ToolTipManager::self()->setContent(this, toolTip
);
233 void DeviceNotifier::toolTipHidden()
235 Plasma::ToolTipManager::self()->clearContent(this);
238 void DeviceNotifier::removeLastDeviceNotification(const QString
&name
)
240 m_lastPlugged
.removeAll(name
);
243 void DeviceNotifier::onSourceAdded(const QString
&name
)
245 kDebug() << "DeviceNotifier:: source added" << name
;
246 if (m_dialog
->countDevices() == m_numberItems
&& m_numberItems
!= 0) {
247 QString itemUdi
= m_dialog
->getDeviceUdi(m_dialog
->countDevices() - 1);
248 //disconnect sources and after (important) remove the row
249 m_solidDeviceEngine
->disconnectSource(itemUdi
, this);
250 m_solidEngine
->disconnectSource(itemUdi
, this);
252 m_dialog
->removeDevice(m_dialog
->countDevices() - 1);
255 m_dialog
->insertDevice(name
);
258 m_solidEngine
->connectSource(name
, this);
259 m_solidDeviceEngine
->connectSource(name
, this);
262 void DeviceNotifier::onSourceRemoved(const QString
&name
)
264 m_solidEngine
->disconnectSource(name
, this);
265 m_solidDeviceEngine
->disconnectSource(name
, this);
267 m_dialog
->removeDevice(name
);
268 removeLastDeviceNotification(name
);
271 #include "devicenotifier.moc"