summaryrefslogtreecommitdiffstats
path: root/ksysguard/gui/SensorBrowser.cc
diff options
context:
space:
mode:
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..801091d98
--- /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 <tqdragobject.h>
+#include <tqtooltip.h>
+#include <tqwhatsthis.h>
+
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <tdelocale.h>
+#include <tdemessagebox.h>
+#include <ksgrd/SensorManager.h>
+
+#include "SensorBrowser.h"
+
+class HostItem : public TQListViewItem
+{
+ public:
+ HostItem( SensorBrowser *parent, const TQString &text, int id,
+ KSGRD::SensorAgent *host)
+ : TQListViewItem( 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 );
+ }
+
+ TQListViewItem::setOpen( open );
+ }
+
+ private:
+ bool mInited;
+ int mId;
+ KSGRD::SensorAgent* mHost;
+ SensorBrowser* mParent;
+};
+
+SensorBrowser::SensorBrowser( TQWidget* parent, KSGRD::SensorManager* sm,
+ const char* name)
+ : TDEListView( parent, name ), mSensorManager( sm )
+{
+ mHostInfoList.setAutoDelete(true);
+
+ connect( mSensorManager, TQT_SIGNAL( update() ), TQT_SLOT( update() ) );
+ connect( this, TQT_SIGNAL( clicked( TQListViewItem* ) ),
+ TQT_SLOT( newItemSelected( TQListViewItem* ) ) );
+ connect( this, TQT_SIGNAL( returnPressed( TQListViewItem* ) ),
+ TQT_SLOT( newItemSelected( TQListViewItem* ) ) );
+
+ addColumn( i18n( "Sensor Browser" ) );
+ addColumn( i18n( "Sensor Type" ) );
+ setFullWidth( true );
+
+ TQToolTip::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 );
+
+ TQWhatsThis::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()
+{
+ TQPtrListIterator<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 TQString& )
+{
+ // 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 ) {
+ TQString hostName = mSensorManager->hostName( host );
+ HostItem* lvi = new HostItem( this, hostName, id, host );
+
+ TQPixmap pix = TDEGlobal::iconLoader()->loadIcon( "computer", TDEIcon::Desktop, TDEIcon::SizeSmall );
+ lvi->setPixmap( 0, pix );
+
+ HostInfo* hostInfo = new HostInfo( id, host, hostName, lvi );
+ mHostInfoList.append( hostInfo );
+ ++id;
+ }
+
+ setMouseTracking( false );
+}
+
+void SensorBrowser::newItemSelected( TQListViewItem *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." ),
+ TQString::null, "ShowSBUseInfo" );
+ }
+}
+
+void SensorBrowser::answerReceived( int id, const TQString &answer )
+{
+ /* An answer has the following format:
+
+ cpu/idle integer
+ cpu/sys integer
+ cpu/nice integer
+ cpu/user integer
+ ps table
+ */
+
+ TQPtrListIterator<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' );
+ TQString sensorName = words[ 0 ];
+ TQString 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, '/' );
+
+ TQListViewItem* parent = (*it)->listViewItem();
+ for ( uint j = 0; j < absolutePath.count(); ++j ) {
+ // Localize the sensor name part by part.
+ TQString name = KSGRD::SensorMgr->translateSensorPath( absolutePath[ j ] );
+
+ bool found = false;
+ TQListViewItem* 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 ) {
+ TQListViewItem* lvi = new TQListViewItem( parent, name );
+ if ( j == absolutePath.count() - 1 ) {
+ TQPixmap pix = TDEGlobal::iconLoader()->loadIcon( "ksysguardd", TDEIcon::Desktop,
+ TDEIcon::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( TQMouseEvent *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() & Qt::LeftButton ) )
+ return;
+
+ TQListViewItem* 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.
+ TQPtrListIterator<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 );
+
+ TQDragObject* dragObject = new TQTextDrag( mDragText, this );
+ dragObject->dragCopy();
+}
+
+TQStringList SensorBrowser::listHosts()
+{
+ TQStringList hostList;
+
+ TQPtrListIterator<HostInfo> it( mHostInfoList );
+ for ( ; it.current(); ++it )
+ hostList.append( (*it)->hostName() );
+
+ return hostList;
+}
+
+TQStringList SensorBrowser::listSensors( const TQString &hostName )
+{
+ TQPtrListIterator<HostInfo> it( mHostInfoList );
+ for ( ; it.current(); ++it ) {
+ if ( (*it)->hostName() == hostName ) {
+ return (*it)->allSensorNames();
+ }
+ }
+
+ return TQStringList();
+}
+
+/**
+ Helper classes
+ */
+SensorInfo::SensorInfo( TQListViewItem *lvi, const TQString &name,
+ const TQString &desc, const TQString &type )
+ : mLvi( lvi ), mName( name ), mDesc( desc ), mType( type )
+{
+}
+
+TQListViewItem* SensorInfo::listViewItem() const
+{
+ return mLvi;
+}
+
+const TQString& SensorInfo::name() const
+{
+ return mName;
+}
+
+const TQString& SensorInfo::type() const
+{
+ return mType;
+}
+
+const TQString& SensorInfo::description() const
+{
+ return mDesc;
+}
+
+HostInfo::HostInfo( int id, const KSGRD::SensorAgent *agent,
+ const TQString &name, TQListViewItem *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 TQString& HostInfo::hostName() const
+{
+ return mHostName;
+}
+
+TQListViewItem* HostInfo::listViewItem() const
+{
+ return mLvi;
+}
+
+const TQString& HostInfo::sensorName( const TQListViewItem *lvi ) const
+{
+ TQPtrListIterator<SensorInfo> it( mSensorList );
+ for ( ; it.current() && (*it)->listViewItem() != lvi; ++it );
+
+ Q_ASSERT( it.current() );
+ return ( (*it)->name() );
+}
+
+TQStringList HostInfo::allSensorNames() const
+{
+ TQStringList list;
+
+ TQPtrListIterator<SensorInfo> it( mSensorList );
+ for ( ; it.current(); ++it )
+ list.append( it.current()->name() );
+
+ return list;
+}
+
+const TQString& HostInfo::sensorType( const TQListViewItem *lvi ) const
+{
+ TQPtrListIterator<SensorInfo> it( mSensorList );
+ for ( ; it.current() && (*it)->listViewItem() != lvi; ++it );
+
+ Q_ASSERT( it.current() );
+ return ( (*it)->type() );
+}
+
+const TQString& HostInfo::sensorDescription( const TQListViewItem *lvi ) const
+{
+ TQPtrListIterator<SensorInfo> it( mSensorList );
+ for ( ; it.current() && (*it)->listViewItem() != lvi; ++it );
+
+ Q_ASSERT( it.current() );
+ return ( (*it)->description() );
+}
+
+void HostInfo::addSensor( TQListViewItem *lvi, const TQString& name,
+ const TQString& desc, const TQString& type )
+{
+ SensorInfo* info = new SensorInfo( lvi, name, desc, type );
+ mSensorList.append( info );
+}
+
+bool HostInfo::isRegistered( const TQString& name ) const
+{
+ TQPtrListIterator<SensorInfo> it( mSensorList );
+ for ( ; it.current(); ++it )
+ if ( (*it)->name() == name )
+ return true;
+
+ return false;
+}
+
+bool HostInfo::isRegistered( TQListViewItem *lvi ) const
+{
+ TQPtrListIterator<SensorInfo> it( mSensorList );
+ for ( ; it.current(); ++it )
+ if ( (*it)->listViewItem() == lvi )
+ return true;
+
+ return false;
+}
+
+#include "SensorBrowser.moc"