File indexing completed on 2024-05-19 16:31:59
0001 /* 0002 * SPDX-FileCopyrightText: 2001 Matthias Hoelzer-Kluepfel <mhk@caldera.de> 0003 * SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 #include "kcmusb.h" 0006 0007 #include <QHBoxLayout> 0008 #include <QHeaderView> 0009 #include <QList> 0010 #include <QSplitter> 0011 #include <QTextEdit> 0012 #include <QTimer> 0013 #include <QTreeWidget> 0014 0015 #include <KAboutData> 0016 0017 #include <KLocalizedString> 0018 #include <KPluginFactory> 0019 0020 #include "usbdevices.h" 0021 0022 K_PLUGIN_CLASS_WITH_JSON(USBViewer, "kcmusb.json") 0023 0024 USBViewer::USBViewer(QWidget *parent, const QVariantList &) 0025 : KCModule(parent) 0026 { 0027 setQuickHelp( 0028 i18n("This module allows you to see" 0029 " the devices attached to your USB bus(es).")); 0030 0031 QHBoxLayout *mainLayout = new QHBoxLayout(this); 0032 mainLayout->setContentsMargins(0, 0, 0, 0); 0033 mainLayout->setSpacing(0); 0034 0035 QSplitter *splitter = new QSplitter(this); 0036 splitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); 0037 mainLayout->addWidget(splitter); 0038 0039 _devices = new QTreeWidget(splitter); 0040 0041 QStringList headers; 0042 headers << i18n("Device"); 0043 _devices->setHeaderLabels(headers); 0044 _devices->setRootIsDecorated(true); 0045 _devices->header()->hide(); 0046 //_devices->setColumnWidthMode(0, Q3ListView::Maximum); 0047 0048 QList<int> sizes; 0049 sizes.append(200); 0050 splitter->setSizes(sizes); 0051 0052 _details = new QTextEdit(splitter); 0053 _details->setReadOnly(true); 0054 0055 QTimer *refreshTimer = new QTimer(this); 0056 // 1 sec seems to be a good compromise between latency and polling load. 0057 refreshTimer->start(1000); 0058 0059 connect(refreshTimer, &QTimer::timeout, this, &USBViewer::refresh); 0060 connect(_devices, &QTreeWidget::currentItemChanged, this, &USBViewer::selectionChanged); 0061 0062 KAboutData *about = 0063 new KAboutData(i18n("kcmusb"), i18n("USB Devices"), QString(), QString(), KAboutLicense::GPL, i18n("(c) 2001 Matthias Hoelzer-Kluepfel")); 0064 0065 about->addAuthor(i18n("Matthias Hoelzer-Kluepfel"), QString(), QStringLiteral("mhk@kde.org")); 0066 about->addCredit(i18n("Leo Savernik"), i18n("Live Monitoring of USB Bus"), QStringLiteral("l.savernik@aon.at")); 0067 setAboutData(about); 0068 } 0069 0070 USBViewer::~USBViewer() 0071 { 0072 USBDevice::clear(); 0073 } 0074 0075 void USBViewer::load() 0076 { 0077 _items.clear(); 0078 _devices->clear(); 0079 0080 refresh(); 0081 } 0082 0083 static quint32 key(USBDevice &dev) 0084 { 0085 return dev.bus() * 256 + dev.device(); 0086 } 0087 0088 static quint32 key_parent(USBDevice &dev) 0089 { 0090 return dev.bus() * 256 + dev.parent(); 0091 } 0092 0093 static void delete_recursive(QTreeWidgetItem *item, const QMap<int, QTreeWidgetItem *> &new_items) 0094 { 0095 if (!item) 0096 return; 0097 0098 QTreeWidgetItemIterator it(item, QTreeWidgetItemIterator::All); 0099 while (*it != nullptr) { 0100 QTreeWidgetItem *currentItem = *it; 0101 if (new_items.contains(currentItem->text(1).toUInt()) == false) { 0102 delete_recursive(currentItem->child(0), new_items); 0103 delete currentItem; 0104 } 0105 ++it; 0106 } 0107 } 0108 0109 void USBViewer::refresh() 0110 { 0111 QMap<int, QTreeWidgetItem *> new_items; 0112 0113 if (!USBDevice::load()) 0114 return; 0115 0116 int level = 0; 0117 bool found = true; 0118 0119 while (found) { 0120 found = false; 0121 0122 foreach (USBDevice *usbDevice, USBDevice::devices()) { 0123 if (usbDevice->level() == level) { 0124 quint32 k = key(*usbDevice); 0125 if (level == 0) { 0126 QTreeWidgetItem *item = _items.value(k); 0127 if (!item) { 0128 QStringList itemContent; 0129 itemContent << usbDevice->product() << QString::number(k); 0130 item = new QTreeWidgetItem(_devices, itemContent); 0131 } 0132 new_items.insert(k, item); 0133 found = true; 0134 } else { 0135 QTreeWidgetItem *parent = new_items.value(key_parent(*usbDevice)); 0136 if (parent) { 0137 QTreeWidgetItem *item = _items.value(k); 0138 0139 if (!item) { 0140 QStringList itemContent; 0141 itemContent << usbDevice->product() << QString::number(k); 0142 item = new QTreeWidgetItem(parent, itemContent); 0143 } 0144 new_items.insert(k, item); 0145 parent->setExpanded(true); 0146 found = true; 0147 } 0148 } 0149 } 0150 } 0151 0152 ++level; 0153 } 0154 0155 // recursive delete all items not in new_items 0156 delete_recursive(_devices->topLevelItem(0), new_items); 0157 0158 _items = new_items; 0159 0160 if (_devices->selectedItems().isEmpty() == true) 0161 selectionChanged(_devices->topLevelItem(0)); 0162 } 0163 0164 void USBViewer::selectionChanged(QTreeWidgetItem *item) 0165 { 0166 if (item) { 0167 quint32 busdev = item->text(1).toUInt(); 0168 USBDevice *dev = USBDevice::find(busdev >> 8, busdev & 255); 0169 if (dev) { 0170 _details->setHtml(dev->dump()); 0171 return; 0172 } 0173 } 0174 _details->clear(); 0175 } 0176 0177 #include "kcmusb.moc"