Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / kinfocenter / usbview / kcmusb.cpp
blob3ea7d9e15cf69f0f2f98a0e7ca2ed9538ba89e29
1 /***************************************************************************
2 * Copyright (C) 2001 by Matthias Hoelzer-Kluepfel <mhk@caldera.de> *
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 of the License, or *
7 * (at your option) any later version. *
8 * *
9 ***************************************************************************/
11 #include <QGroupBox>
12 #include <QLayout>
13 #include <QSplitter>
14 #include <QtGui/QTextEdit>
15 #include <QTimer>
16 #include <QHBoxLayout>
17 #include <QList>
18 #include <QTreeWidget>
19 #include <QHeaderView>
21 #include <kaboutdata.h>
22 #include <kdialog.h>
24 #include <KPluginFactory>
25 #include <KPluginLoader>
27 #include "usbdevices.h"
29 #include "kcmusb.moc"
31 K_PLUGIN_FACTORY(USBFactory,
32 registerPlugin<USBViewer>();
34 K_EXPORT_PLUGIN(USBFactory("kcmusb"))
36 USBViewer::USBViewer(QWidget *parent, const QVariantList &) :
37 KCModule(USBFactory::componentData(), parent) {
39 setQuickHelp(i18n("This module allows you to see"
40 " the devices attached to your USB bus(es)."));
42 QHBoxLayout *mainLayout = new QHBoxLayout(this);
43 mainLayout->setMargin(0);
44 mainLayout->setSpacing(0);
46 QSplitter *splitter = new QSplitter(this);
47 splitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
48 mainLayout->addWidget(splitter);
50 _devices = new QTreeWidget(splitter);
52 QStringList headers;
53 headers << i18n("Device");
54 _devices->setHeaderLabels(headers);
55 _devices->setRootIsDecorated(true);
56 _devices->header()->hide();
57 //_devices->setColumnWidthMode(0, Q3ListView::Maximum);
59 QList<int> sizes;
60 sizes.append(200);
61 splitter->setSizes(sizes);
63 _details = new QTextEdit(splitter);
64 _details->setReadOnly(true);
66 QTimer *refreshTimer = new QTimer(this);
67 // 1 sec seems to be a good compromise between latency and polling load.
68 refreshTimer->start(1000);
70 connect(refreshTimer, SIGNAL(timeout()), SLOT(refresh()));
71 connect(_devices, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(selectionChanged(QTreeWidgetItem*)));
73 KAboutData *about = new KAboutData(I18N_NOOP("kcmusb"), 0, ki18n("KDE USB Viewer"),
74 0, KLocalizedString(), KAboutData::License_GPL,
75 ki18n("(c) 2001 Matthias Hoelzer-Kluepfel"));
77 about->addAuthor(ki18n("Matthias Hoelzer-Kluepfel"), KLocalizedString(), "mhk@kde.org");
78 about->addCredit(ki18n("Leo Savernik"), ki18n("Live Monitoring of USB Bus"), "l.savernik@aon.at");
79 setAboutData(about);
83 void USBViewer::load() {
84 _items.clear();
85 _devices->clear();
87 refresh();
90 static quint32 key(USBDevice &dev) {
91 return dev.bus()*256 + dev.device();
94 static quint32 key_parent(USBDevice &dev) {
95 return dev.bus()*256 + dev.parent();
98 static void delete_recursive(QTreeWidgetItem *item, const QMap<int, QTreeWidgetItem*> &new_items) {
99 if (!item)
100 return;
102 QTreeWidgetItemIterator it(item, QTreeWidgetItemIterator::All);
103 while ( *it != NULL ) {
104 QTreeWidgetItem* currentItem = *it;
105 if (new_items.contains(currentItem->text(1).toUInt()) == false) {
106 delete_recursive(currentItem->child(0), new_items);
107 delete currentItem;
109 ++it;
113 void USBViewer::refresh() {
114 QMap<int, QTreeWidgetItem*> new_items;
116 if (!USBDevice::parse("/proc/bus/usb/devices"))
117 USBDevice::parseSys("/sys/bus/usb/devices");
119 int level = 0;
120 bool found = true;
122 while (found) {
123 found = false;
125 foreach(USBDevice* usbDevice, USBDevice::devices()) {
126 if (usbDevice->level() == level) {
127 quint32 k = key(*usbDevice);
128 if (level == 0) {
129 QTreeWidgetItem* item = _items.value(k);
130 if (!item) {
131 QStringList itemContent;
132 itemContent << usbDevice->product() << QString::number(k);
133 item = new QTreeWidgetItem(_devices, itemContent);
135 new_items.insert(k, item);
136 found = true;
137 } else {
138 QTreeWidgetItem *parent = new_items.value(key_parent(*usbDevice));
139 if (parent) {
140 QTreeWidgetItem *item = _items.value(k);
142 if (!item) {
143 QStringList itemContent;
144 itemContent << usbDevice->product() << QString::number(k);
145 item = new QTreeWidgetItem(parent, itemContent);
147 new_items.insert(k, item);
148 parent->setExpanded(true);
149 found = true;
155 ++level;
158 // recursive delete all items not in new_items
159 delete_recursive(_devices->topLevelItem(0), new_items);
161 _items = new_items;
163 if (_devices->selectedItems().isEmpty() == true)
164 selectionChanged(_devices->topLevelItem(0));
167 void USBViewer::selectionChanged(QTreeWidgetItem *item) {
168 if (item) {
169 quint32 busdev = item->text(1).toUInt();
170 USBDevice *dev = USBDevice::find(busdev>>8, busdev&255);
171 if (dev) {
172 _details->setHtml(dev->dump());
173 return;
176 _details->clear();