summaryrefslogtreecommitdiffstats
path: root/ksysguard/gui/SensorBrowser.cc
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit4aed2c8219774f5d797760606b8489a92ddc5163 (patch)
tree3f8c130f7d269626bf6a9447407ef6c35954426a /ksysguard/gui/SensorBrowser.cc
downloadtdebase-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.cc412
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 <cs@kde.org>
+
+ 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 <cs@kde.org>. 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"