Commit 98990284 authored by Chris Schlaeger's avatar Chris Schlaeger
Browse files

type qualifier added to monitor info

Attention: changes ktopd -> ktop API

svn path=/trunk/kdeutils/ktop/; revision=37743
parent 800d1677
/*
KTop, the KDE Task Manager
Copyright (c) 1999 Chris Schlaeger
cs@kde.org
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
KTop is currently maintained by Chris Schlaeger <cs@kde.org>. Please do
not commit any changes without consulting me first. Thanks!
*/
// $Id$
#include <assert.h>
#include <qstring.h>
#include <kapp.h>
#include <khelpmenu.h>
#include <klocale.h>
#include <kstdaccel.h>
#include "version.h"
#include "MainMenu.moc"
MainMenu* MainMenuBar = 0;
MainMenu::MainMenu(QWidget* parent, const char* name)
:KMenuBar(parent, name)
{
KStdAccel accel;
assert(MainMenuBar == 0);
MainMenuBar = this;
// 'File' submenu
file = new QPopupMenu();
file->insertItem(i18n("&Quit"), this, SLOT(slotQuit()), accel.quit());
connect(file, SIGNAL(activated(int)), this, SLOT(handler(int)));
// 'Help' submenu
QString about;
about = i18n(""
"KDE Task Manager (KTop) Version %1\n\n"
"Copyright:\n"
"1996 : A. Sanda <alex@darkstar.ping.at>\n"
"1997 : Ralf Mueller <ralf@bj-ig.de>\n"
"1997-98 : Bernd Johannes Wuebben <wuebben@kde.org>\n"
"1998 : Nicolas Leclercq <nicknet@planete.net>\n"
"1999 : Chris Schlaeger <cs@kde.org>\n")
.arg(KTOP_VERSION);
mHelpMenu = new KHelpMenu( this, about );
// 'Refresh Rate' submenu
refresh = new QPopupMenu();
refresh->setCheckable(true);
refresh->insertItem(i18n("Manual Refresh"), MENU_ID_REFRESH_MANUAL, -1);
refresh->insertItem(i18n("Slow Refresh"), MENU_ID_REFRESH_SLOW, -1);
refresh->insertItem(i18n("Medium Refresh"), MENU_ID_REFRESH_MEDIUM, -1);
refresh->insertItem(i18n("Fast Refresh"), MENU_ID_REFRESH_FAST, -1);
connect(refresh, SIGNAL(activated(int)), this, SLOT(handler(int)));
// 'Process' submenu
process = new ProcessMenu();
process->setItemEnabled(MENU_ID_MENU_PROCESS, false);
connect(process, SIGNAL(requestUpdate(void)),
this, SLOT(requestUpdateSlot(void)));
// register submenues
setLineWidth(1);
insertItem(i18n("&File"), file, 2, -1);
insertItem(i18n("&Refresh Rate"), refresh, MENU_ID_MENU_REFRESH, -1);
insertItem(i18n("&Process"), process, MENU_ID_MENU_PROCESS, -1);
insertSeparator(-1);
insertItem(i18n("&Help"), mHelpMenu->menu(), 2, -1);
}
MainMenu::~MainMenu( void )
{
delete file;
delete refresh;
delete process;
delete mHelpMenu->menu(); // The menu is created only once
delete mHelpMenu;
}
void MainMenu::handler(int id)
{
switch(id)
{
case MENU_ID_REFRESH_MANUAL:
case MENU_ID_REFRESH_SLOW:
case MENU_ID_REFRESH_MEDIUM:
case MENU_ID_REFRESH_FAST:
emit(setRefreshRate(id - MENU_ID_REFRESH_MANUAL));
break;
default:
break;
}
}
void MainMenu::checkRefreshRate(int rate)
{
// uncheck old and check new rate
for (int i = MENU_ID_REFRESH_MANUAL; i <= MENU_ID_REFRESH_FAST; i++)
refresh->setItemChecked(i, rate == i - MENU_ID_REFRESH_MANUAL);
}
/*
KTop, the KDE Task Manager
Copyright (c) 1999 Chris Schlaeger
cs@kde.org
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
KTop is currently maintained by Chris Schlaeger <cs@kde.org>. Please do
not commit any changes without consulting me first. Thanks!
*/
// $Id$
#ifndef _MainMenu_h_
#define _MainMenu_h_
#include <khelpmenu.h>
#include <kmenubar.h>
class KHelpMenu;
#include "ProcessMenu.h"
/**
* This class implements the main menu. All triggered actions are activated
* through signals. For on-the-fly modification of the menus slots are
* provided.
*/
class MainMenu : public KMenuBar
{
Q_OBJECT
public:
enum
{
MENU_ID_ABOUT = 100,
MENU_ID_MENU_REFRESH,
MENU_ID_REFRESH_MANUAL,
MENU_ID_REFRESH_SLOW,
MENU_ID_REFRESH_MEDIUM,
MENU_ID_REFRESH_FAST,
MENU_ID_MENU_PROCESS,
MENU_ID_HELP
};
MainMenu(QWidget* parent = 0, const char* name = 0);
~MainMenu( void );
public slots:
void checkRefreshRate(int);
void enableRefreshMenu(bool enable)
{
setItemEnabled(MENU_ID_MENU_REFRESH, enable);
}
void processSelected(int pid)
{
setItemEnabled(MENU_ID_MENU_PROCESS, pid >= 0);
process->processSelected(pid);
}
signals:
void quit(void);
void setRefreshRate(int);
void requestUpdate(void);
private slots:
void handler(int);
void requestUpdateSlot(void)
{
emit(requestUpdate());
}
void slotQuit()
{
emit(quit());
}
private:
QPopupMenu* file;
QPopupMenu* refresh;
ProcessMenu* process;
KHelpMenu *mHelpMenu;
} ;
extern MainMenu* MainMenuBar;
#endif
This CVS version of KTop is work in progress! Although I only try to
check in reasonably stable versions, I cannot guarantee this. I
typically develop on SuSE Linux 6.0 with 2.2 kernel. If your system is
typically develop on SuSE Linux 6.x with 2.2 kernel. If your system is
different, this program might not even compile.
If you want to join this development please contact me first. Please
......@@ -8,9 +8,8 @@ do *NOT* check in unsolicited code as I might am rearranging the code
and merging becomes a real headache so your code will be lost.
This does not mean that I don't appreciate your help. Especially
porting to other platforms is difficult for me. I have introduced a
nice interface so porting is fairly easy. See OSStatus.cpp if you are
interested. I really like to have a Solaris 2.x and HPUX 7 port!
porting to other platforms is difficult for me. Each platform has it's
specific back-end. See the ktopd directory for details.
16-Feb-1999 Chris Schlaeger <cs@kde.org>
5-Jan-2000 Chris Schlaeger <cs@kde.org>
/*
KTop, the KDE Task Manager
Copyright (c) 1999 Chris Schlaeger
cs@kde.org
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
KTop is currently maintained by Chris Schlaeger <cs@kde.org>. Please do
not commit any changes without consulting me first. Thanks!
*/
// $Id$
#ifndef _SignalPlotter_h_
#define _SignalPlotter_h_
#include <qwidget.h>
#include <qarray.h>
#include <qbrush.h>
class QColor;
#define MAXBEAMS 5
class SignalPlotter : public QWidget
{
Q_OBJECT
public:
SignalPlotter(QWidget* parent = 0, const char* name = 0, int min = 0,
int max = 100);
~SignalPlotter();
bool addBeam(QColor col);
void addSample(int s0, int s1 = 0, int s2 = 0, int s3 = 0, int s4 = 0);
void setLowPass(bool lp)
{
lowPass = lp;
}
protected:
virtual void resizeEvent(QResizeEvent*);
virtual void paintEvent(QPaintEvent*);
private:
int minValue;
int maxValue;
bool lowPass;
int* beamData[MAXBEAMS];
QColor beamColor[MAXBEAMS];
int beams;
} ;
#endif
......@@ -25,6 +25,9 @@
#include <qevent.h>
#include <qapplication.h>
#include <qstring.h>
#include <kprocess.h>
#include "SensorAgent.h"
#include "SensorClient.h"
......@@ -56,9 +59,10 @@ SensorAgent::~SensorAgent()
}
bool
SensorAgent::start(const QString& host, const QString& shell)
SensorAgent::start(const QString& /* host */, const QString& /* shell */)
{
ktopd = new KProcess;
CHECK_PTR(ktopd);
connect(ktopd, SIGNAL(processExited(KProcess *)),
this, SLOT(ktopdExited(KProcess*)));
......@@ -72,7 +76,12 @@ SensorAgent::start(const QString& host, const QString& shell)
*ktopd << "ktopd";
if (!ktopd->start(KProcess::NotifyOnExit, KProcess::All))
{
cout << "Can't start ktopd" << endl;
return (false);
}
return (true);
}
bool
......@@ -82,11 +91,16 @@ SensorAgent::sendRequest(const QString& req, SensorClient* client, int id)
* routed back to the requesting client. */
inputFIFO.prepend(new SensorRequest(req, client, id));
if (ktopdOnLine && (inputFIFO.count() == 1))
{
executeCommand();
return (true);
}
return (false);
}
void
SensorAgent::msgSent(KProcess* proc)
SensorAgent::msgSent(KProcess*)
{
// remove oldest (sent) request from input FIFO
SensorRequest* req = inputFIFO.last();
......@@ -98,7 +112,7 @@ SensorAgent::msgSent(KProcess* proc)
}
void
SensorAgent::msgRcvd(KProcess* proc, char* buffer, int buflen)
SensorAgent::msgRcvd(KProcess*, char* buffer, int buflen)
{
answerBuffer += QString(buffer).left(buflen);
......@@ -136,13 +150,14 @@ SensorAgent::msgRcvd(KProcess* proc, char* buffer, int buflen)
}
void
SensorAgent::errMsgRcvd(KProcess* proc, char* buffer, int buflen)
SensorAgent::errMsgRcvd(KProcess*, char* buffer, int /* buflen */)
{
/* TODO: Better error handling */
cout << "RCVD Error: " << buffer << endl;
}
void
SensorAgent::ktopdExited(KProcess* proc)
SensorAgent::ktopdExited(KProcess*)
{
ktopdOnLine = false;
cout << "ktopd exited" << endl;
......
......@@ -24,12 +24,14 @@
#define _SensorAgent_h_
#include <qobject.h>
#include <qstring.h>
#include <kprocess.h>
class QString;
class KProcess;
class SensorClient;
/**
* This auxilliary class is used to store requests during their processing.
*/
class SensorRequest
{
friend class SensorAgent;
......@@ -44,7 +46,13 @@ private:
SensorClient* client;
int id;
} ;
/**
* The SensorAgent starts a ktopd process and handles the asynchronous
* communication. It keeps a list of pending requests that have not been
* answered yet by ktopd. The current implementation only allowes one
* pending requests. Incoming requests are queued in an input FIFO.
*/
class SensorAgent : public QObject
{
Q_OBJECT
......@@ -58,10 +66,10 @@ public:
bool sendRequest(const QString& req, SensorClient* client, int id = 0);
private slots:
void msgSent(KProcess* proc);
void msgRcvd(KProcess* proc, char* buffer, int buflen);
void errMsgRcvd(KProcess* proc, char* buffer, int buflen);
void ktopdExited(KProcess* proc);
void msgSent(KProcess*);
void msgRcvd(KProcess*, char* buffer, int buflen);
void errMsgRcvd(KProcess*, char* buffer, int buflen);
void ktopdExited(KProcess*);
private:
void executeCommand();
......
......@@ -23,6 +23,8 @@
$Id$
*/
#include <assert.h>
#include <qevent.h>
#include <qdragobject.h>
......@@ -41,6 +43,18 @@ SensorBrowser::SensorBrowser(QWidget* parent, SensorManager* sm,
addColumn(i18n("Sensor Browser"));
setRootIsDecorated(TRUE);
// Fill the sensor description dictionary.
dict.insert("cpuidle", new QString(i18n("CPU Idle Load")));
dict.insert("cpusys", new QString(i18n("CPU System Load")));
dict.insert("cpunice", new QString(i18n("CPU Nice Load")));
dict.insert("cpuuser", new QString(i18n("CPU User Load")));
dict.insert("memswap", new QString(i18n("Swap Memory")));
dict.insert("memcached", new QString(i18n("Cached Memory")));
dict.insert("membuf", new QString(i18n("Buffered Memory")));
dict.insert("memused", new QString(i18n("Used Memory")));
dict.insert("memfree", new QString(i18n("Free Memory")));
dict.insert("pscount", new QString(i18n("Process Count")));
}
void
......@@ -48,27 +62,59 @@ SensorBrowser::update()
{
SensorManagerIterator it(sensorManager);
sensors.clear();
for (int i = 0 ; it.current(); ++it, ++i)
hostInfos.clear();
SensorAgent* host;
for (int i = 0 ; (host = it.current()); ++it, ++i)
{
QListViewItem* lvi = new QListViewItem(this,
sensorManager->
getHostName(it.current()));
QString hostName = sensorManager-> getHostName(host);
QListViewItem* lvi = new QListViewItem(this, hostName);
CHECK_PTR(lvi);
sensors.append(lvi);
(*it).sendRequest("monitors", this, i);
HostInfo* hostInfo = new HostInfo(hostName, lvi);
CHECK_PTR(hostInfo);
hostInfos.append(hostInfo);
// request sensor list from host
host->sendRequest("monitors", this, i);
}
}
void
SensorBrowser::answerReceived(int id, const QString& s)
{
SensorLinesTokenizer tok(s);
/* An answer has the following format:
cpuidle integer
cpusys integer
cpunice integer
cpuuser integer
ps table
*/
for (unsigned int i = 0; i < tok.numberOfTokens(); ++i)
SensorTokenizer lines(s, '\n');
for (unsigned int i = 0; i < lines.numberOfTokens(); ++i)
{
QListViewItem* lvi = new QListViewItem(sensors.at(id), tok[i]);
SensorTokenizer words(lines[i], '\t');
QString sensorName = words[0];
QString sensorType = words[1];
// retrieve localized description from dictionary
QString sensorDescription;
if (!dict[sensorName])
sensorDescription = sensorName;
else
sensorDescription = *(dict[sensorName]);
QListViewItem* lvi = new QListViewItem(hostInfos.at(id)->getLVI(),
sensorDescription);
CHECK_PTR(lvi);
// add sensor info to internal data structure
hostInfos.at(id)->addSensor(lvi, sensorName, sensorDescription,
sensorType);
}
}
......@@ -83,8 +129,14 @@ SensorBrowser::viewportMouseMoveEvent(QMouseEvent* ev)
if (!parent)
return; // item is not a sensor name
// find the host info record that belongs to the LVI
QListIterator<HostInfo> it(hostInfos);
for ( ; it.current() && (*it)->getLVI() != parent; ++it)
;
assert(it.current());
// Create text drag object as "<hostname> <sensorname>".
dragText = parent->text(0) + " " + item->text(0);
dragText = (*it)->getHostName() + " " + (*it)->getSensorName(item);
QDragObject* dObj = new QTextDrag(dragText, this);
CHECK_PTR(dObj);
......
......@@ -27,12 +27,95 @@
#define _SensorBrowser_h_
#include <qlistview.h>
#include <qdict.h>
#include "SensorClient.h"
class QMouseEvent;
class SensorManager;
class SensorInfo
{
public:
SensorInfo(QListViewItem* l, const QString& n, const QString& d,
const QString& t)
: lvi(l), name(n), description(d), type(t) { }
~SensorInfo() { }
QListViewItem* getLVI()
{
return (lvi);
}
const QString& getName()
{
return (name);
}
private:
/// pointer to the entry in the browser QListView
QListViewItem* lvi;
/// the name of the sensor as provided by ktopd
QString name;
/// the localized description of the sensor
QString description;
/// qualifies the class of the sensor (ps, integer, etc.)
QString type;
} ;
class HostInfo
{
public:
HostInfo(const QString& n, QListViewItem* l) : hostName(n), lvi(l)
{
sensors.setAutoDelete(TRUE);
}
~HostInfo() { }
const QString& getHostName()
{
return (hostName);
}
QListViewItem* getLVI()
{
return (lvi);
}
const QString& getSensorName(const QListViewItem* lvi)
{
QListIterator<SensorInfo> it(sensors);
for ( ; it.current() && (*it)->getLVI() != lvi; ++it)
;
assert(it.current());
return ((*it)->getName());
}
void addSensor(QListViewItem* lvi, const QString& name,
const QString& descr, const QString& type)
{