diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 4aed2c8219774f5d797760606b8489a92ddc5163 (patch) | |
tree | 3f8c130f7d269626bf6a9447407ef6c35954426a /ksysguard/gui/SensorBrowser.cc | |
download | tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.tar.gz tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'ksysguard/gui/SensorBrowser.cc')
-rw-r--r-- | ksysguard/gui/SensorBrowser.cc | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/ksysguard/gui/SensorBrowser.cc b/ksysguard/gui/SensorBrowser.cc new file mode 100644 index 000000000..969978947 --- /dev/null +++ b/ksysguard/gui/SensorBrowser.cc @@ -0,0 +1,412 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999, 2000 Chris Schlaeger <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger <[email protected]>. Please do + not commit any changes without consulting me first. Thanks! + +*/ + +#include <qdragobject.h> +#include <qtooltip.h> +#include <qwhatsthis.h> + +#include <kdebug.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <ksgrd/SensorManager.h> + +#include "SensorBrowser.h" + +class HostItem : public QListViewItem +{ + public: + HostItem( SensorBrowser *parent, const QString &text, int id, + KSGRD::SensorAgent *host) + : QListViewItem( parent, text ), mInited( false ), mId( id ), + mHost( host ), mParent( parent ) + { + setExpandable( true ); + } + + void setOpen( bool open ) + { + if ( open && !mInited ) { + mInited = true; + // request sensor list from host + mHost->sendRequest( "monitors", mParent, mId ); + } + + QListViewItem::setOpen( open ); + } + + private: + bool mInited; + int mId; + KSGRD::SensorAgent* mHost; + SensorBrowser* mParent; +}; + +SensorBrowser::SensorBrowser( QWidget* parent, KSGRD::SensorManager* sm, + const char* name) + : KListView( parent, name ), mSensorManager( sm ) +{ + mHostInfoList.setAutoDelete(true); + + connect( mSensorManager, SIGNAL( update() ), SLOT( update() ) ); + connect( this, SIGNAL( clicked( QListViewItem* ) ), + SLOT( newItemSelected( QListViewItem* ) ) ); + connect( this, SIGNAL( returnPressed( QListViewItem* ) ), + SLOT( newItemSelected( QListViewItem* ) ) ); + + addColumn( i18n( "Sensor Browser" ) ); + addColumn( i18n( "Sensor Type" ) ); + setFullWidth( true ); + + QToolTip::add( this, i18n( "Drag sensors to empty cells of a worksheet " + "or the panel applet." ) ); + setRootIsDecorated( true ); + + // The sensor browser can be completely hidden. + setMinimumWidth( 1 ); + + QWhatsThis::add( this, i18n( "The sensor browser lists the connected hosts and the sensors " + "that they provide. Click and drag sensors into drop zones " + "of a worksheet or the panel applet. A display will appear " + "that visualizes the " + "values provided by the sensor. Some sensor displays can " + "display values of multiple sensors. Simply drag other " + "sensors on to the display to add more sensors." ) ); +} + +SensorBrowser::~SensorBrowser() +{ +} + +void SensorBrowser::disconnect() +{ + QPtrListIterator<HostInfo> it( mHostInfoList ); + + for ( ; it.current(); ++it ) + if ( (*it)->listViewItem()->isSelected() ) { + kdDebug(1215) << "Disconnecting " << (*it)->hostName() << endl; + KSGRD::SensorMgr->requestDisengage( (*it)->sensorAgent() ); + } +} + +void SensorBrowser::hostReconfigured( const QString& ) +{ + // TODO: not yet implemented. +} + +void SensorBrowser::update() +{ + static int id = 0; + + KSGRD::SensorManagerIterator it( mSensorManager ); + + mHostInfoList.clear(); + clear(); + + KSGRD::SensorAgent* host; + for ( int i = 0 ; ( host = it.current() ); ++it, ++i ) { + QString hostName = mSensorManager->hostName( host ); + HostItem* lvi = new HostItem( this, hostName, id, host ); + + QPixmap pix = KGlobal::iconLoader()->loadIcon( "computer", KIcon::Desktop, KIcon::SizeSmall ); + lvi->setPixmap( 0, pix ); + + HostInfo* hostInfo = new HostInfo( id, host, hostName, lvi ); + mHostInfoList.append( hostInfo ); + ++id; + } + + setMouseTracking( false ); +} + +void SensorBrowser::newItemSelected( QListViewItem *item ) +{ + static bool showAnnoyingPopup = true; + if ( item && item->pixmap( 0 ) && showAnnoyingPopup) + { + showAnnoyingPopup = false; + KMessageBox::information( this, i18n( "Drag sensors to empty fields in a worksheet." ), + QString::null, "ShowSBUseInfo" ); + } +} + +void SensorBrowser::answerReceived( int id, const QString &answer ) +{ + /* An answer has the following format: + + cpu/idle integer + cpu/sys integer + cpu/nice integer + cpu/user integer + ps table + */ + + QPtrListIterator<HostInfo> it( mHostInfoList ); + + /* Check if id is still valid. It can get obsolete by rapid calls + * of update() or when the sensor died. */ + for ( ; it.current(); ++it ) + if ( (*it)->id() == id ) + break; + + if ( !it.current() ) + return; + + KSGRD::SensorTokenizer lines( answer, '\n' ); + + for ( uint i = 0; i < lines.count(); ++i ) { + if ( lines[ i ].isEmpty() ) + break; + + KSGRD::SensorTokenizer words( lines[ i ], '\t' ); + QString sensorName = words[ 0 ]; + QString sensorType = words[ 1 ]; + + /* Calling update() a rapid sequence will create pending + * requests that do not get erased by calling + * clear(). Subsequent updates will receive the old pending + * answers so we need to make sure that we register each + * sensor only once. */ + if ( (*it)->isRegistered( sensorName ) ) + return; + + /* The sensor browser can display sensors in a hierachical order. + * Sensors can be grouped into nodes by seperating the hierachical + * nodes through slashes in the sensor name. E. g. cpu/user is + * the sensor user in the cpu node. There is no limit for the + * depth of nodes. */ + KSGRD::SensorTokenizer absolutePath( sensorName, '/' ); + + QListViewItem* parent = (*it)->listViewItem(); + for ( uint j = 0; j < absolutePath.count(); ++j ) { + // Localize the sensor name part by part. + QString name = KSGRD::SensorMgr->translateSensorPath( absolutePath[ j ] ); + + bool found = false; + QListViewItem* sibling = parent->firstChild(); + while ( sibling && !found ) { + if (sibling->text( 0 ) == name ) { + // The node or sensor is already known. + found = true; + } else + sibling = sibling->nextSibling(); + } + if ( !found ) { + QListViewItem* lvi = new QListViewItem( parent, name ); + if ( j == absolutePath.count() - 1 ) { + QPixmap pix = KGlobal::iconLoader()->loadIcon( "ksysguardd", KIcon::Desktop, + KIcon::SizeSmall ); + lvi->setPixmap( 0, pix ); + lvi->setText( 1, KSGRD::SensorMgr->translateSensorType( sensorType ) ); + + // add sensor info to internal data structure + (*it)->addSensor( lvi, sensorName, name, sensorType ); + } else + parent = lvi; + + // The child indicator might need to be updated. + repaintItem( parent ); + } else + parent = sibling; + } + } + + repaintItem( (*it)->listViewItem() ); +} + +void SensorBrowser::viewportMouseMoveEvent( QMouseEvent *e ) +{ + /* setMouseTracking(false) seems to be broken. With current Qt + * mouse tracking cannot be turned off. So we have to check each event + * whether the LMB is really pressed. */ + + if ( !( e->state() & LeftButton ) ) + return; + + QListViewItem* item = itemAt( e->pos() ); + if ( !item ) // no item under cursor + return; + + // Make sure that a sensor and not a node or hostname has been picked. + QPtrListIterator<HostInfo> it( mHostInfoList ); + for ( ; it.current() && !(*it)->isRegistered( item ); ++it ); + if ( !it.current() ) + return; + + // Create text drag object as + // "<hostname> <sensorname> <sensortype> <sensordescription>". + // Only the description may contain blanks. + mDragText = (*it)->hostName() + " " + + (*it)->sensorName( item ) + " " + + (*it)->sensorType( item ) + " " + + (*it)->sensorDescription( item ); + + QDragObject* dragObject = new QTextDrag( mDragText, this ); + dragObject->dragCopy(); +} + +QStringList SensorBrowser::listHosts() +{ + QStringList hostList; + + QPtrListIterator<HostInfo> it( mHostInfoList ); + for ( ; it.current(); ++it ) + hostList.append( (*it)->hostName() ); + + return hostList; +} + +QStringList SensorBrowser::listSensors( const QString &hostName ) +{ + QPtrListIterator<HostInfo> it( mHostInfoList ); + for ( ; it.current(); ++it ) { + if ( (*it)->hostName() == hostName ) { + return (*it)->allSensorNames(); + } + } + + return QStringList(); +} + +/** + Helper classes + */ +SensorInfo::SensorInfo( QListViewItem *lvi, const QString &name, + const QString &desc, const QString &type ) + : mLvi( lvi ), mName( name ), mDesc( desc ), mType( type ) +{ +} + +QListViewItem* SensorInfo::listViewItem() const +{ + return mLvi; +} + +const QString& SensorInfo::name() const +{ + return mName; +} + +const QString& SensorInfo::type() const +{ + return mType; +} + +const QString& SensorInfo::description() const +{ + return mDesc; +} + +HostInfo::HostInfo( int id, const KSGRD::SensorAgent *agent, + const QString &name, QListViewItem *lvi ) + : mId( id ), mSensorAgent( agent ), mHostName( name ), mLvi( lvi ) +{ + mSensorList.setAutoDelete( true ); +} + +int HostInfo::id() const +{ + return ( mId ); +} + +const KSGRD::SensorAgent* HostInfo::sensorAgent() const +{ + return mSensorAgent; +} + +const QString& HostInfo::hostName() const +{ + return mHostName; +} + +QListViewItem* HostInfo::listViewItem() const +{ + return mLvi; +} + +const QString& HostInfo::sensorName( const QListViewItem *lvi ) const +{ + QPtrListIterator<SensorInfo> it( mSensorList ); + for ( ; it.current() && (*it)->listViewItem() != lvi; ++it ); + + Q_ASSERT( it.current() ); + return ( (*it)->name() ); +} + +QStringList HostInfo::allSensorNames() const +{ + QStringList list; + + QPtrListIterator<SensorInfo> it( mSensorList ); + for ( ; it.current(); ++it ) + list.append( it.current()->name() ); + + return list; +} + +const QString& HostInfo::sensorType( const QListViewItem *lvi ) const +{ + QPtrListIterator<SensorInfo> it( mSensorList ); + for ( ; it.current() && (*it)->listViewItem() != lvi; ++it ); + + Q_ASSERT( it.current() ); + return ( (*it)->type() ); +} + +const QString& HostInfo::sensorDescription( const QListViewItem *lvi ) const +{ + QPtrListIterator<SensorInfo> it( mSensorList ); + for ( ; it.current() && (*it)->listViewItem() != lvi; ++it ); + + Q_ASSERT( it.current() ); + return ( (*it)->description() ); +} + +void HostInfo::addSensor( QListViewItem *lvi, const QString& name, + const QString& desc, const QString& type ) +{ + SensorInfo* info = new SensorInfo( lvi, name, desc, type ); + mSensorList.append( info ); +} + +bool HostInfo::isRegistered( const QString& name ) const +{ + QPtrListIterator<SensorInfo> it( mSensorList ); + for ( ; it.current(); ++it ) + if ( (*it)->name() == name ) + return true; + + return false; +} + +bool HostInfo::isRegistered( QListViewItem *lvi ) const +{ + QPtrListIterator<SensorInfo> it( mSensorList ); + for ( ; it.current(); ++it ) + if ( (*it)->listViewItem() == lvi ) + return true; + + return false; +} + +#include "SensorBrowser.moc" |