1 | /* This file is part of the KDE Project |
2 | Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> |
3 | Copyright (c) 2005-2007 Kevin Ottens <ervin@kde.org> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License version 2 as published by the Free Software Foundation. |
8 | |
9 | This library 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 GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #include "deviceserviceaction.h" |
21 | |
22 | #include <kdesktopfile.h> |
23 | #include <klocale.h> |
24 | #include <kmacroexpander.h> |
25 | #include <krun.h> |
26 | #include <kdebug.h> |
27 | #include <solid/storageaccess.h> |
28 | #include <solid/block.h> |
29 | |
30 | |
31 | class MacroExpander : public KMacroExpanderBase |
32 | { |
33 | public: |
34 | MacroExpander(const Solid::Device &device) |
35 | : KMacroExpanderBase('%'), m_device(device) {} |
36 | |
37 | protected: |
38 | virtual int expandEscapedMacro(const QString &str, int pos, QStringList &ret); |
39 | |
40 | private: |
41 | Solid::Device m_device; |
42 | }; |
43 | |
44 | class DelayedExecutor : public QObject |
45 | { |
46 | Q_OBJECT |
47 | public: |
48 | DelayedExecutor(const KServiceAction &service, Solid::Device &device); |
49 | |
50 | private slots: |
51 | void _k_storageSetupDone(Solid::ErrorType error, QVariant errorData, const QString &udi); |
52 | |
53 | private: |
54 | void delayedExecute(const QString &udi); |
55 | |
56 | KServiceAction m_service; |
57 | }; |
58 | |
59 | DeviceServiceAction::DeviceServiceAction() |
60 | : DeviceAction() |
61 | { |
62 | DeviceAction::setIconName("dialog-cancel" ); |
63 | DeviceAction::setLabel(i18nc("A default name for an action without proper label" , "Unknown" )); |
64 | } |
65 | |
66 | QString DeviceServiceAction::id() const |
67 | { |
68 | if (m_service.name().isEmpty() && m_service.exec().isEmpty()) { |
69 | return QString(); |
70 | } else { |
71 | return "#Service:" +m_service.name()+m_service.exec(); |
72 | } |
73 | } |
74 | |
75 | void DeviceServiceAction::execute(Solid::Device &device) |
76 | { |
77 | new DelayedExecutor(m_service, device); |
78 | } |
79 | |
80 | void DelayedExecutor::_k_storageSetupDone(Solid::ErrorType error, QVariant errorData, |
81 | const QString &udi) |
82 | { |
83 | Q_UNUSED(errorData); |
84 | |
85 | if (!error) { |
86 | delayedExecute(udi); |
87 | } |
88 | } |
89 | |
90 | void DeviceServiceAction::setService(const KServiceAction& service) |
91 | { |
92 | DeviceAction::setIconName(service.icon()); |
93 | DeviceAction::setLabel(service.text()); |
94 | |
95 | m_service = service; |
96 | } |
97 | |
98 | KServiceAction DeviceServiceAction::service() const |
99 | { |
100 | return m_service; |
101 | } |
102 | |
103 | int MacroExpander::expandEscapedMacro(const QString &str, int pos, QStringList &ret) |
104 | { |
105 | uint option = str[pos+1].unicode(); |
106 | |
107 | switch (option) { |
108 | |
109 | case 'f': // Filepath |
110 | case 'F': // case insensitive |
111 | if (m_device.is<Solid::StorageAccess>()) { |
112 | ret << m_device.as<Solid::StorageAccess>()->filePath(); |
113 | } else { |
114 | kWarning() << "DeviceServiceAction::execute: " << m_device.udi() |
115 | << " is not a StorageAccess device" << endl; |
116 | } |
117 | break; |
118 | case 'd': // Device node |
119 | case 'D': // case insensitive |
120 | if (m_device.is<Solid::Block>()) { |
121 | ret << m_device.as<Solid::Block>()->device(); |
122 | } else { |
123 | kWarning() << "DeviceServiceAction::execute: " << m_device.udi() |
124 | << " is not a Block device" << endl; |
125 | } |
126 | break; |
127 | case 'i': // UDI |
128 | case 'I': // case insensitive |
129 | ret << m_device.udi(); |
130 | break; |
131 | case '%': |
132 | ret = QStringList(QLatin1String("%" )); |
133 | break; |
134 | default: |
135 | return -2; // subst with same and skip |
136 | } |
137 | return 2; |
138 | } |
139 | |
140 | DelayedExecutor::DelayedExecutor(const KServiceAction &service, Solid::Device &device) |
141 | : m_service(service) |
142 | { |
143 | if (device.is<Solid::StorageAccess>() |
144 | && !device.as<Solid::StorageAccess>()->isAccessible()) { |
145 | Solid::StorageAccess *access = device.as<Solid::StorageAccess>(); |
146 | |
147 | connect(access, SIGNAL(setupDone(Solid::ErrorType, QVariant, const QString &)), |
148 | this, SLOT(_k_storageSetupDone(Solid::ErrorType, QVariant, const QString &))); |
149 | |
150 | access->setup(); |
151 | |
152 | } else { |
153 | delayedExecute(device.udi()); |
154 | } |
155 | } |
156 | |
157 | void DelayedExecutor::delayedExecute(const QString &udi) |
158 | { |
159 | Solid::Device device(udi); |
160 | |
161 | QString exec = m_service.exec(); |
162 | MacroExpander mx(device); |
163 | |
164 | if (!mx.expandMacrosShellQuote(exec)) { |
165 | kWarning() << ", Syntax error:" << m_service.exec(); |
166 | return; |
167 | } |
168 | |
169 | KRun::runCommand(exec, QString(), m_service.icon(), 0); |
170 | deleteLater(); |
171 | } |
172 | |
173 | #include "deviceserviceaction.moc" |
174 | |