delay a few things on startup, such as setting the visibility mode, which ensures...
[personal-kdebase.git] / runtime / solid-hardware / solid-hardware.cpp
blobb5d9ac3f1a38be02c5d15f5c296700838be4c872
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"
23 #include <QString>
24 #include <QStringList>
25 #include <QMetaProperty>
26 #include <QMetaEnum>
27 #include <QTimer>
29 #include <kcomponentdata.h>
30 #include <kcmdlineargs.h>
31 #include <kdebug.h>
32 #include <kjob.h>
33 #include <klocale.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>
41 #include <iostream>
42 using namespace std;
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)
58 switch (value.type())
60 case QVariant::StringList:
62 out << "{";
64 const QStringList list = value.toStringList();
66 QStringList::ConstIterator it = list.constBegin();
67 QStringList::ConstIterator end = list.constEnd();
69 for (; it!=end; ++it)
71 out << "'" << *it << "'";
73 if (it+1!=end)
75 out << ", ";
79 out << "} (string list)";
80 break;
82 case QVariant::Bool:
83 out << (value.toBool()?"true":"false") << " (bool)";
84 break;
85 case QVariant::Int:
86 out << value.toString()
87 << " (0x" << QString::number(value.toInt(), 16) << ") (int)";
88 break;
89 default:
90 out << "'" << value.toString() << "' (string)";
91 break;
94 return out;
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);
111 if (interface)
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()
119 << " = ";
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()) {
128 out << "(flag)";
129 } else {
130 out << "(enum)";
132 out << endl;
133 } else {
134 out << value << endl;
140 return out;
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;
150 return out;
153 void checkArgumentCount(int min, int max)
155 int count = KCmdLineArgs::parsedArgs()->count();
157 if (count < min)
159 cerr << i18n("Syntax Error: Not enough arguments") << endl;
160 ::exit(1);
163 if ((max > 0) && (count > max))
165 cerr << i18n("Syntax Error: Too many arguments") << endl;
166 ::exit(1);
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;
228 return 0;
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));
241 int fake_argc = 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);
268 QString parent;
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);
295 else
297 cerr << i18n("Syntax Error: Unknown command '%1'" ,command) << endl;
300 return false;
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;
311 if (interfaces)
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;
322 return true;
325 bool SolidHardware::hwCapabilities(const QString &udi)
327 const Solid::Device device(udi);
329 cout << "udi = '" << device.udi() << "'" << endl;
330 cout << device << endl;
332 return true;
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;
345 return true;
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;
358 return true;
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;
368 return false;
370 else if (!device.is<Solid::OpticalDrive>() && type==Eject)
372 cerr << i18n("Error: %1 does not have the interface OpticalDrive." , udi) << endl;
373 return false;
376 switch(type)
378 case Mount:
379 connect(device.as<Solid::StorageAccess>(),
380 SIGNAL(setupDone(Solid::ErrorType, QVariant, const QString &)),
381 this,
382 SLOT(slotStorageResult(Solid::ErrorType, QVariant)));
383 device.as<Solid::StorageAccess>()->setup();
384 break;
385 case Unmount:
386 connect(device.as<Solid::StorageAccess>(),
387 SIGNAL(teardownDone(Solid::ErrorType, QVariant, const QString &)),
388 this,
389 SLOT(slotStorageResult(Solid::ErrorType, QVariant)));
390 device.as<Solid::StorageAccess>()->teardown();
391 break;
392 case Eject:
393 connect(device.as<Solid::OpticalDrive>(),
394 SIGNAL(ejectDone(Solid::ErrorType, QVariant, const QString &)),
395 this,
396 SLOT(slotStorageResult(Solid::ErrorType, QVariant)));
397 device.as<Solid::OpticalDrive>()->eject();
398 break;
401 m_loop.exec();
403 if (m_error)
405 cerr << i18n("Error: %1" , m_errorString) << endl;
406 return false;
409 return true;
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)
434 m_error = 0;
436 if (job->error())
438 m_error = job->error();
439 m_errorString = job->errorString();
442 m_loop.exit();
445 void SolidHardware::slotStorageResult(Solid::ErrorType error, const QVariant &errorData)
447 if (error) {
448 m_error = 1;
449 m_errorString = errorData.toString();
451 m_loop.exit();
454 #include "solid-hardware.moc"