1 /* This file is part of the KDE project
2 Copyright (C) 2006 Kevin Ottens <ervin@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library 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 GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
20 #include "solid-hardware.h"
24 #include <QStringList>
25 #include <QMetaProperty>
29 #include <kcomponentdata.h>
30 #include <kcmdlineargs.h>
34 #include <k3socketaddress.h>
36 #include <solid/device.h>
37 #include <solid/genericinterface.h>
38 #include <solid/storageaccess.h>
39 #include <solid/opticaldrive.h>
44 static const char appName
[] = "solid-hardware";
45 static const char programName
[] = I18N_NOOP("solid-hardware");
47 static const char description
[] = I18N_NOOP("KDE tool for querying your hardware from the command line");
49 static const char version
[] = "0.1a";
51 std::ostream
&operator<<(std::ostream
&out
, const QString
&msg
)
53 return (out
<< msg
.toLocal8Bit().constData());
56 std::ostream
&operator<<(std::ostream
&out
, const QVariant
&value
)
60 case QVariant::StringList
:
64 const QStringList list
= value
.toStringList();
66 QStringList::ConstIterator it
= list
.constBegin();
67 QStringList::ConstIterator end
= list
.constEnd();
71 out
<< "'" << *it
<< "'";
79 out
<< "} (string list)";
83 out
<< (value
.toBool()?"true":"false") << " (bool)";
86 out
<< value
.toString()
87 << " (0x" << QString::number(value
.toInt(), 16) << ") (int)";
90 out
<< "'" << value
.toString() << "' (string)";
97 std::ostream
&operator<<(std::ostream
&out
, const Solid::Device
&device
)
99 out
<< " parent = " << QVariant(device
.parentUdi()) << endl
;
100 out
<< " vendor = " << QVariant(device
.vendor()) << endl
;
101 out
<< " product = " << QVariant(device
.product()) << endl
;
103 int index
= Solid::DeviceInterface::staticMetaObject
.indexOfEnumerator("Type");
104 QMetaEnum typeEnum
= Solid::DeviceInterface::staticMetaObject
.enumerator(index
);
106 for (int i
=0; i
<typeEnum
.keyCount(); i
++)
108 Solid::DeviceInterface::Type type
= (Solid::DeviceInterface::Type
)typeEnum
.value(i
);
109 const Solid::DeviceInterface
*interface
= device
.asDeviceInterface(type
);
113 const QMetaObject
*meta
= interface
->metaObject();
115 for (int i
=meta
->propertyOffset(); i
<meta
->propertyCount(); i
++)
117 QMetaProperty property
= meta
->property(i
);
118 out
<< " " << QString(meta
->className()).mid(7) << "." << property
.name()
121 QVariant value
= property
.read(interface
);
123 if (property
.isEnumType()) {
124 QMetaEnum metaEnum
= property
.enumerator();
125 out
<< "'" << metaEnum
.valueToKeys(value
.toInt()).constData() << "'"
126 << " (0x" << QString::number(value
.toInt(), 16) << ") ";
127 if (metaEnum
.isFlag()) {
134 out
<< value
<< endl
;
143 std::ostream
&operator<<(std::ostream
&out
, const QMap
<QString
,QVariant
> &properties
)
145 foreach (const QString
&key
, properties
.keys())
147 out
<< " " << key
<< " = " << properties
[key
] << endl
;
153 void checkArgumentCount(int min
, int max
)
155 int count
= KCmdLineArgs::parsedArgs()->count();
159 cerr
<< i18n("Syntax Error: Not enough arguments") << endl
;
163 if ((max
> 0) && (count
> max
))
165 cerr
<< i18n("Syntax Error: Too many arguments") << endl
;
170 int main(int argc
, char **argv
)
172 KCmdLineArgs::init(argc
, argv
, appName
, 0, ki18n(programName
), version
, ki18n(description
), false);
175 KCmdLineOptions options
;
177 options
.add("commands", ki18n("Show available commands"));
179 options
.add("+command", ki18n("Command (see --commands)"));
181 options
.add("+[arg(s)]", ki18n("Arguments for command"));
183 KCmdLineArgs::addCmdLineOptions(options
);
185 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
187 KComponentData
componentData(appName
);
189 if (args
->isSet("commands"))
191 KCmdLineArgs::enable_i18n();
193 cout
<< endl
<< i18n("Syntax:") << endl
<< endl
;
195 cout
<< " solid-hardware list [details|nonportableinfo]" << endl
;
196 cout
<< i18n(" # List the hardware available in the system.\n"
197 " # - If the 'nonportableinfo' option is specified, the device\n"
198 " # properties are listed (be careful, in this case property names\n"
199 " # are backend dependent),\n"
200 " # - If the 'details' option is specified, the device interfaces\n"
201 " # and the corresponding properties are listed in a platform\n"
202 " # neutral fashion,\n"
203 " # - Otherwise only device UDIs are listed.\n") << endl
;
205 cout
<< " solid-hardware details 'udi'" << endl
;
206 cout
<< i18n(" # Display all the interfaces and properties of the device\n"
207 " # corresponding to 'udi' in a platform neutral fashion.\n") << endl
;
209 cout
<< " solid-hardware nonportableinfo 'udi'" << endl
;
210 cout
<< i18n(" # Display all the properties of the device corresponding to 'udi'\n"
211 " # (be careful, in this case property names are backend dependent).\n") << endl
;
213 cout
<< " solid-hardware query 'predicate' ['parentUdi']" << endl
;
214 cout
<< i18n(" # List the UDI of devices corresponding to 'predicate'.\n"
215 " # - If 'parentUdi' is specified, the search is restricted to the\n"
216 " # branch of the corresponding device,\n"
217 " # - Otherwise the search is done on all the devices.\n") << endl
;
219 cout
<< " solid-hardware mount 'udi'" << endl
;
220 cout
<< i18n(" # If applicable, mount the device corresponding to 'udi'.\n") << endl
;
222 cout
<< " solid-hardware unmount 'udi'" << endl
;
223 cout
<< i18n(" # If applicable, unmount the device corresponding to 'udi'.\n") << endl
;
225 cout
<< " solid-hardware hardware eject 'udi'" << endl
;
226 cout
<< i18n(" # If applicable, eject the device corresponding to 'udi'.\n") << endl
;
231 return SolidHardware::doIt() ? 0 : 1;
234 bool SolidHardware::doIt()
236 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
237 checkArgumentCount(1, 0);
239 QString
command(args
->arg(0));
242 char **fake_argv
= 0;
243 SolidHardware
shell(fake_argc
, fake_argv
);
245 if (command
== "list")
247 checkArgumentCount(1, 2);
248 QByteArray
extra(args
->count()==2 ? args
->arg(1).toLocal8Bit() : "");
249 return shell
.hwList(extra
=="details", extra
=="nonportableinfo");
251 else if (command
== "details")
253 checkArgumentCount(2, 2);
254 QString
udi(args
->arg(1));
255 return shell
.hwCapabilities(udi
);
257 else if (command
== "nonportableinfo")
259 checkArgumentCount(2, 2);
260 QString
udi(args
->arg(1));
261 return shell
.hwProperties(udi
);
263 else if (command
== "query")
265 checkArgumentCount(2, 3);
267 QString query
= args
->arg(1);
270 if (args
->count() == 3)
272 parent
= args
->arg(2);
275 return shell
.hwQuery(parent
, query
);
277 else if (command
== "mount")
279 checkArgumentCount(2, 2);
280 QString
udi(args
->arg(1));
281 return shell
.hwVolumeCall(Mount
, udi
);
283 else if (command
== "unmount")
285 checkArgumentCount(2, 2);
286 QString
udi(args
->arg(1));
287 return shell
.hwVolumeCall(Unmount
, udi
);
289 else if (command
== "eject")
291 checkArgumentCount(2, 2);
292 QString
udi(args
->arg(1));
293 return shell
.hwVolumeCall(Eject
, udi
);
297 cerr
<< i18n("Syntax Error: Unknown command '%1'" ,command
) << endl
;
303 bool SolidHardware::hwList(bool interfaces
, bool system
)
305 const QList
<Solid::Device
> all
= Solid::Device::allDevices();
307 foreach (const Solid::Device
&device
, all
)
309 cout
<< "udi = '" << device
.udi() << "'" << endl
;
313 cout
<< device
<< endl
;
315 else if (system
&& device
.is
<Solid::GenericInterface
>())
317 QMap
<QString
,QVariant
> properties
= device
.as
<Solid::GenericInterface
>()->allProperties();
318 cout
<< properties
<< endl
;
325 bool SolidHardware::hwCapabilities(const QString
&udi
)
327 const Solid::Device
device(udi
);
329 cout
<< "udi = '" << device
.udi() << "'" << endl
;
330 cout
<< device
<< endl
;
335 bool SolidHardware::hwProperties(const QString
&udi
)
337 const Solid::Device
device(udi
);
339 cout
<< "udi = '" << device
.udi() << "'" << endl
;
340 if (device
.is
<Solid::GenericInterface
>()) {
341 QMap
<QString
,QVariant
> properties
= device
.as
<Solid::GenericInterface
>()->allProperties();
342 cout
<< properties
<< endl
;
348 bool SolidHardware::hwQuery(const QString
&parentUdi
, const QString
&query
)
350 const QList
<Solid::Device
> devices
351 = Solid::Device::listFromQuery(query
, parentUdi
);
353 foreach (const Solid::Device device
, devices
)
355 cout
<< "udi = '" << device
.udi() << "'" << endl
;
361 bool SolidHardware::hwVolumeCall(SolidHardware::VolumeCallType type
, const QString
&udi
)
363 Solid::Device
device(udi
);
365 if (!device
.is
<Solid::StorageAccess
>() && type
!=Eject
)
367 cerr
<< i18n("Error: %1 does not have the interface StorageAccess." , udi
) << endl
;
370 else if (!device
.is
<Solid::OpticalDrive
>() && type
==Eject
)
372 cerr
<< i18n("Error: %1 does not have the interface OpticalDrive." , udi
) << endl
;
379 connect(device
.as
<Solid::StorageAccess
>(),
380 SIGNAL(setupDone(Solid::ErrorType
, QVariant
, const QString
&)),
382 SLOT(slotStorageResult(Solid::ErrorType
, QVariant
)));
383 device
.as
<Solid::StorageAccess
>()->setup();
386 connect(device
.as
<Solid::StorageAccess
>(),
387 SIGNAL(teardownDone(Solid::ErrorType
, QVariant
, const QString
&)),
389 SLOT(slotStorageResult(Solid::ErrorType
, QVariant
)));
390 device
.as
<Solid::StorageAccess
>()->teardown();
393 connect(device
.as
<Solid::OpticalDrive
>(),
394 SIGNAL(ejectDone(Solid::ErrorType
, QVariant
, const QString
&)),
396 SLOT(slotStorageResult(Solid::ErrorType
, QVariant
)));
397 device
.as
<Solid::OpticalDrive
>()->eject();
405 cerr
<< i18n("Error: %1" , m_errorString
) << endl
;
412 void SolidHardware::connectJob(KJob
*job
)
414 connect(job
, SIGNAL(result(KJob
*)),
415 this, SLOT(slotResult(KJob
*)));
416 connect(job
, SIGNAL(percent(KJob
*, unsigned long)),
417 this, SLOT(slotPercent(KJob
*, unsigned long)));
418 connect(job
, SIGNAL(infoMessage(KJob
*, const QString
&, const QString
&)),
419 this, SLOT(slotInfoMessage(KJob
*, const QString
&)));
422 void SolidHardware::slotPercent(KJob */
*job */
, unsigned long percent
)
424 cout
<< i18n("Progress: %1%" , percent
) << endl
;
427 void SolidHardware::slotInfoMessage(KJob */
*job */
, const QString
&message
)
429 cout
<< i18n("Info: %1" , message
) << endl
;
432 void SolidHardware::slotResult(KJob
*job
)
438 m_error
= job
->error();
439 m_errorString
= job
->errorString();
445 void SolidHardware::slotStorageResult(Solid::ErrorType error
, const QVariant
&errorData
)
449 m_errorString
= errorData
.toString();
454 #include "solid-hardware.moc"