You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
4.9 KiB
193 lines
4.9 KiB
15 years ago
|
/***************************************************************************
|
||
|
* Copyright (C) 2001 by Matthias Hoelzer-Kluepfel <mhk@caldera.de> *
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or modify *
|
||
|
* it under the terms of the GNU General Public License as published by *
|
||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||
|
* (at your option) any later version. *
|
||
|
* *
|
||
|
***************************************************************************/
|
||
|
|
||
|
#include <qgroupbox.h>
|
||
|
#include <qheader.h>
|
||
|
#include <qlayout.h>
|
||
|
#include <qlistview.h>
|
||
|
#include <qsplitter.h>
|
||
|
#include <qtextview.h>
|
||
|
#include <qtimer.h>
|
||
|
|
||
|
#include <kaboutdata.h>
|
||
|
#include <kdialog.h>
|
||
|
#include <kgenericfactory.h>
|
||
|
|
||
|
#include "usbdevices.h"
|
||
|
#include "kcmusb.moc"
|
||
|
|
||
|
typedef KGenericFactory<USBViewer, QWidget > USBFactory;
|
||
|
K_EXPORT_COMPONENT_FACTORY (kcm_usb, USBFactory("kcmusb") )
|
||
|
|
||
|
USBViewer::USBViewer(QWidget *parent, const char *name, const QStringList &)
|
||
|
: KCModule(USBFactory::instance(), parent, name)
|
||
|
{
|
||
|
setButtons(Help);
|
||
|
|
||
|
setQuickHelp( i18n("<h1>USB Devices</h1> This module allows you to see"
|
||
|
" the devices attached to your USB bus(es)."));
|
||
|
|
||
|
QVBoxLayout *vbox = new QVBoxLayout(this, 0, KDialog::spacingHint());
|
||
|
QGroupBox *gbox = new QGroupBox(i18n("USB Devices"), this);
|
||
|
gbox->setColumnLayout( 0, Qt::Horizontal );
|
||
|
vbox->addWidget(gbox);
|
||
|
|
||
|
QVBoxLayout *vvbox = new QVBoxLayout(gbox->layout(), KDialog::spacingHint());
|
||
|
|
||
|
QSplitter *splitter = new QSplitter(gbox);
|
||
|
vvbox->addWidget(splitter);
|
||
|
|
||
|
_devices = new QListView(splitter);
|
||
|
_devices->addColumn(i18n("Device"));
|
||
|
_devices->setRootIsDecorated(true);
|
||
|
_devices->header()->hide();
|
||
|
_devices->setMinimumWidth(200);
|
||
|
_devices->setColumnWidthMode(0, QListView::Maximum);
|
||
|
|
||
|
QValueList<int> sizes;
|
||
|
sizes.append(200);
|
||
|
splitter->setSizes(sizes);
|
||
|
|
||
|
_details = new QTextView(splitter);
|
||
|
|
||
|
splitter->setResizeMode(_devices, QSplitter::KeepSize);
|
||
|
|
||
|
QTimer *refreshTimer = new QTimer(this);
|
||
|
// 1 sec seems to be a good compromise between latency and polling load.
|
||
|
refreshTimer->start(1000);
|
||
|
|
||
|
connect(refreshTimer, SIGNAL(timeout()), SLOT(refresh()));
|
||
|
connect(_devices, SIGNAL(selectionChanged(QListViewItem*)),
|
||
|
this, SLOT(selectionChanged(QListViewItem*)));
|
||
|
|
||
|
KAboutData *about =
|
||
|
new KAboutData(I18N_NOOP("kcmusb"), I18N_NOOP("KDE USB Viewer"),
|
||
|
0, 0, KAboutData::License_GPL,
|
||
|
I18N_NOOP("(c) 2001 Matthias Hoelzer-Kluepfel"));
|
||
|
|
||
|
about->addAuthor("Matthias Hoelzer-Kluepfel", 0, "mhk@kde.org");
|
||
|
about->addCredit("Leo Savernik", "Live Monitoring of USB Bus", "l.savernik@aon.at");
|
||
|
setAboutData( about );
|
||
|
|
||
|
load();
|
||
|
}
|
||
|
|
||
|
void USBViewer::load()
|
||
|
{
|
||
|
_items.clear();
|
||
|
_devices->clear();
|
||
|
|
||
|
refresh();
|
||
|
}
|
||
|
|
||
|
static Q_UINT32 key( USBDevice &dev )
|
||
|
{
|
||
|
return dev.bus()*256 + dev.device();
|
||
|
}
|
||
|
|
||
|
static Q_UINT32 key_parent( USBDevice &dev )
|
||
|
{
|
||
|
return dev.bus()*256 + dev.parent();
|
||
|
}
|
||
|
|
||
|
static void delete_recursive( QListViewItem *item, const QIntDict<QListViewItem> &new_items )
|
||
|
{
|
||
|
if (!item)
|
||
|
return;
|
||
|
|
||
|
QListViewItemIterator it( item );
|
||
|
while ( it.current() ) {
|
||
|
if (!new_items.find(it.current()->text(1).toUInt())) {
|
||
|
delete_recursive( it.current()->firstChild(), new_items);
|
||
|
delete it.current();
|
||
|
}
|
||
|
++it;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void USBViewer::refresh()
|
||
|
{
|
||
|
QIntDict<QListViewItem> new_items;
|
||
|
|
||
|
if (!USBDevice::parse("/proc/bus/usb/devices"))
|
||
|
USBDevice::parseSys("/sys/bus/usb/devices");
|
||
|
|
||
|
int level = 0;
|
||
|
bool found = true;
|
||
|
|
||
|
while (found)
|
||
|
{
|
||
|
found = false;
|
||
|
|
||
|
QPtrListIterator<USBDevice> it(USBDevice::devices());
|
||
|
for ( ; it.current(); ++it)
|
||
|
if (it.current()->level() == level)
|
||
|
{
|
||
|
Q_UINT32 k = key(*it.current());
|
||
|
if (level == 0)
|
||
|
{
|
||
|
QListViewItem *item = _items.find(k);
|
||
|
if (!item) {
|
||
|
item = new QListViewItem(_devices,
|
||
|
it.current()->product(),
|
||
|
QString::number(k));
|
||
|
}
|
||
|
new_items.insert(k, item);
|
||
|
found = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
QListViewItem *parent = new_items.find(key_parent(*it.current()));
|
||
|
if (parent)
|
||
|
{
|
||
|
QListViewItem *item = _items.find(k);
|
||
|
|
||
|
if (!item) {
|
||
|
item = new QListViewItem(parent,
|
||
|
it.current()->product(),
|
||
|
QString::number(k) );
|
||
|
}
|
||
|
new_items.insert(k, item);
|
||
|
parent->setOpen(true);
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
++level;
|
||
|
}
|
||
|
|
||
|
// recursive delete all items not in new_items
|
||
|
delete_recursive( _devices->firstChild(), new_items );
|
||
|
|
||
|
_items = new_items;
|
||
|
|
||
|
if (!_devices->selectedItem())
|
||
|
selectionChanged(_devices->firstChild());
|
||
|
}
|
||
|
|
||
|
|
||
|
void USBViewer::selectionChanged(QListViewItem *item)
|
||
|
{
|
||
|
if (item)
|
||
|
{
|
||
|
Q_UINT32 busdev = item->text(1).toUInt();
|
||
|
USBDevice *dev = USBDevice::find(busdev>>8, busdev&255);
|
||
|
if (dev)
|
||
|
{
|
||
|
_details->setText(dev->dump());
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
_details->clear();
|
||
|
}
|
||
|
|
||
|
|