KCPULoad – a small CPU meter for Kicker
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.
 
 
kcpuload/kcpuload/kcpuload/statpopup.cpp

485 lines
14 KiB

/***************************************************************************
* *
* KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
* (c) 2002, Ben Burton *
* *
* 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 "icontoggleaction.h"
#include "speeddialog.h"
#include "statdock.h"
#include "statpopup.h"
#include <tqpainter.h>
#include <tqtimer.h>
#include <tdeaction.h>
#include <kcolordialog.h>
#include <tdeconfig.h>
#include <kdebug.h>
#include <tdeglobal.h>
#include <khelpmenu.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdepopupmenu.h>
#include <twin.h>
#include <cstdlib>
#define DEFAULT_SPEED 1000
#define TEXT_EXPANSION_HORIZONTAL 10
#define TEXT_EXPANSION_VERTICAL 3
const TQColor StatPopup::colorBorder(0, 0, 0);
StatPopup::Reading::Reading() :
dock(0),
actColor(0)
{ }
StatPopup::Reading::~Reading()
{
delete actColor;
delete dock;
}
void StatPopup::Reading::Init(int which, StatPopup* popup)
{
char colorid[30];
sprintf(colorid, "Color%d", which);
color = popup->defaultDockColor(which);
color = popup->config->readColorEntry(colorid, &color);
actColor = new TDEAction(i18n("Color (%1)...").arg(popup->dockName(which)),
"color", 0, TQT_TQOBJECT(popup), TQT_SLOT(selectColor()), popup->coll, colorid);
}
StatPopup::StatPopup(bool useSupportSplit, TQWidget *parent, const char *name) :
TQWidget(parent, name, TQt::WStyle_Customize | TQt::WStyle_NoBorder |
TQt::WStyle_StaysOnTop | TQt::WDestructiveClose | TQt::WType_TopLevel),
supportSplit(useSupportSplit) {
// Window management.
KWin::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
// TODO: Get all-desktops working, even after a hide/reshow.
//KWin::setOnAllDesktops(winId(), true);
// Basic variable initialisation.
relX = relY = 0;
isDragged = closing = false;
// Initialise the text contents of this pop-up.
fullReading = i18n("Inactive.");
resizeToText();
// Prepare for actions and the config file, but don't actually add
// any actions or read the configuration.
config = TDEGlobal::config();
coll = new TDEActionCollection(this);
// Set up a timer for our periodic updates.
timer = new TQTimer(this);
connect(timer, TQT_SIGNAL(timeout()), TQT_TQOBJECT(this), TQT_SLOT(takeReading()));
}
StatPopup::~StatPopup() {
}
void StatPopup::readPopupState() {
config->setGroup("Popup Options");
// Read the position.
int useX = config->readNumEntry("PopupX", 0);
int useY = config->readNumEntry("PopupY", 0);
if (useX || useY)
move(useX, useY);
// Show the pop-up if appropriate.
if (config->readBoolEntry("PopupActive", false))
show();
else
hide();
}
void StatPopup::savePopupState() {
config->setGroup("Popup Options");
config->writeEntry("PopupActive", isVisible());
config->writeEntry("PopupX", x());
config->writeEntry("PopupY", y());
config->sync();
}
void StatPopup::initDock(StatDock* target, TDEPopupMenu* menu, int whichDock) {
// Initialise the menus.
actActive->plug(menu);
actClearHistory->plug(menu);
menu->insertSeparator();
actSpeed->plug(menu);
if (supportSplit)
actSplit->plug(menu);
menu->insertSeparator();
insertCustomItems(menu);
TDEPopupMenu* fillMenu = new TDEPopupMenu(menu);
actFillLines->plug(fillMenu);
actFillBars->plug(fillMenu);
actFillShaded->plug(fillMenu);
menu->insertItem(SmallIcon("style"), i18n("St&yle"), fillMenu);
actSoft->plug(menu);
actLabelled->plug(menu);
actGrid->plug(menu);
r[whichDock].actColor->plug(menu);
menu->insertSeparator();
menu->insertItem(SmallIcon("help"), i18n("&Help"),
(new KHelpMenu(0, TDEGlobal::instance()->aboutData(), false))->menu());
// Set up display properties for the dock.
target->setActive(actActive->isChecked());
target->setSplit(isSplit());
target->setFill(fillStyle);
target->setSoft(actSoft->isChecked());
target->setLabelled(actLabelled->isChecked());
target->setGrid(actGrid->isChecked());
target->setColor(r[whichDock].color);
setCustomProperties(target);
}
bool StatPopup::isActive() const {
return actActive->isChecked();
}
bool StatPopup::isSplit() const {
return (supportSplit ? actSplit->isChecked() : false);
}
void StatPopup::setActive(bool set) {
if (set)
startUpdates();
else
stopUpdates();
for (int i = 0; i < r.size(); i++) {
r[i].dock->setActive(set);
}
config->setGroup("General Options");
config->writeEntry("Active", set);
config->sync();
}
void StatPopup::clearHistory() {
for (int i = 0; i < r.size(); i++) {
r[i].dock->clearHistory();
}
}
void StatPopup::selectSpeed() {
SpeedDialog dlg(speed, firstDock());
if (dlg.exec()) {
int newSpeed = dlg.getSpeed();
if (newSpeed > 0) {
speed = newSpeed;
if (timer->isActive())
timer->changeInterval(speed);
config->setGroup("General Options");
config->writeEntry("Speed", speed);
config->sync();
}
}
}
void StatPopup::setSplit(bool set) {
if (! supportSplit)
return;
for (int i = 0; i < r.size(); i++) {
r[i].dock->setSplit(set);
}
requestResize();
config->setGroup("General Options");
config->writeEntry("Split", set);
config->sync();
}
void StatPopup::setFillLines() {
fillStyle = StatDock::fillLines;
actFillLines->setChecked(true);
actFillBars->setChecked(false);
actFillShaded->setChecked(false);
for (int i = 0; i < r.size(); i++) {
r[i].dock->setFill(StatDock::fillLines);
}
config->setGroup("General Options");
config->writeEntry("StyleID", StatDock::fillLines);
config->sync();
}
void StatPopup::setFillBars() {
fillStyle = StatDock::fillBars;
actFillLines->setChecked(false);
actFillBars->setChecked(true);
actFillShaded->setChecked(false);
for (int i = 0; i < r.size(); i++) {
r[i].dock->setFill(StatDock::fillBars);
}
config->setGroup("General Options");
config->writeEntry("StyleID", StatDock::fillBars);
config->sync();
}
void StatPopup::setFillShaded() {
fillStyle = StatDock::fillShaded;
actFillLines->setChecked(false);
actFillBars->setChecked(false);
actFillShaded->setChecked(true);
for (int i = 0; i < r.size(); i++) {
r[i].dock->setFill(StatDock::fillShaded);
}
config->setGroup("General Options");
config->writeEntry("StyleID", StatDock::fillShaded);
config->sync();
}
void StatPopup::setSoft(bool set) {
for (int i = 0; i < r.size(); i++) {
r[i].dock->setSoft(set);
}
config->setGroup("General Options");
config->writeEntry("Soft", set);
config->sync();
}
void StatPopup::setLabelled(bool set) {
for (int i = 0; i < r.size(); i++) {
r[i].dock->setLabelled(set);
}
config->setGroup("General Options");
config->writeEntry("Labelled", set);
config->sync();
}
void StatPopup::setGrid(bool set) {
for (int i = 0; i < r.size(); i++) {
r[i].dock->setGrid(set);
}
config->setGroup("General Options");
config->writeEntry("Grid", set);
config->sync();
}
void StatPopup::selectColor() {
// which color?
int whichDock;
if (sscanf(TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender()))->name(), "Color%d", &whichDock) != 1)
return;
if (whichDock < 0 || whichDock >= r.size())
return;
if (r[whichDock].dock) {
TQColor ans;
if (KColorDialog::getColor(ans, r[whichDock].color, firstDock()) ==
TQDialog::Accepted) {
r[whichDock].color = ans;
r[whichDock].dock->setColor(ans);
config->setGroup("General Options");
TQString n;
n.sprintf("Color%d", whichDock);
config->writeEntry(n, ans);
config->sync();
}
}
}
StatDock* StatPopup::firstDock() {
return r.size() > 0 ? r[0].dock : 0;
}
void StatPopup::startUpdates() {
takeReading();
timer->start(speed);
}
void StatPopup::stopUpdates() {
timer->stop();
fullReading = i18n("Inactive.");
}
void StatPopup::setupActions() {
config->setGroup("General Options");
bool bVal;
bVal = config->readBoolEntry("Active", true);
actActive = new TDEToggleAction(i18n("&Active"), 0, coll, "active");
actActive->setChecked(bVal);
connect(actActive, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(setActive(bool)));
actClearHistory = new TDEAction(i18n("&Clear"), "edit-delete", 0,
TQT_TQOBJECT(this), TQT_SLOT(clearHistory()), coll, "clear");
speed = config->readNumEntry("Speed", DEFAULT_SPEED);
actSpeed = new TDEAction(i18n("&Speed..."), "speedarrow", 0,
TQT_TQOBJECT(this), TQT_SLOT(selectSpeed()), coll, "speed");
if (supportSplit) {
bVal = config->readBoolEntry("Split", true);
actSplit = new IconToggleAction(i18n("Sp&lit Graph"), "split",
i18n("Graph Sp&litting Enabled"), "spliton", 0, coll, "split");
actSplit->setChecked(bVal);
connect(actSplit, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(setSplit(bool)));
}
fillStyle = config->readNumEntry("StyleID", StatDock::fillShaded);
actFillLines = new IconToggleAction(i18n("&Lines"), "lines", "lineson", 0,
TQT_TQOBJECT(this), TQT_SLOT(setFillLines()), coll, "filllines");
actFillLines->setChecked(fillStyle == StatDock::fillLines);
actFillBars = new IconToggleAction(i18n("&Bars"), "bars", "barson", 0,
TQT_TQOBJECT(this), TQT_SLOT(setFillBars()), coll, "fillbars");
actFillBars->setChecked(fillStyle == StatDock::fillBars);
actFillShaded = new IconToggleAction(i18n("&Shaded"), "shaded", "shadedon",
0, TQT_TQOBJECT(this), TQT_SLOT(setFillShaded()), coll, "fillshaded");
actFillShaded->setChecked(fillStyle == StatDock::fillShaded);
bVal = config->readBoolEntry("Soft", false);
actSoft = new IconToggleAction(i18n("So&ft Curves"), "soft",
i18n("So&ft Curves Enabled"), "softon", 0, coll, "soft");
actSoft->setChecked(bVal);
connect(actSoft, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(setSoft(bool)));
bVal = config->readBoolEntry("Labelled", true);
actLabelled= new IconToggleAction(i18n("Show &Labels"), "labels",
i18n("&Labels Enabled"), "labelson", 0, coll, "labelled");
actLabelled->setChecked(bVal);
connect(actLabelled, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(setLabelled(bool)));
bVal = config->readBoolEntry("Grid", true);
actGrid = new IconToggleAction(i18n("Show &Grid"), "grid",
i18n("&Grid Enabled"), "gridon", 0, coll, "grid");
actGrid->setChecked(bVal);
connect(actGrid, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(setGrid(bool)));
setupCustomActions();
}
void StatPopup::paintEvent(TQPaintEvent*) {
TQPainter p(this);
// Draw the border.
p.setPen(colorBorder);
p.drawLine(0, 0, width(), 0);
p.drawLine(0, 1, width(), 1);
p.drawLine(0, 2, 0, height());
p.drawLine(1, 2, 1, height());
p.drawLine(width() - 2, 2, width() - 2, height());
p.drawLine(width() - 1, 2, width() - 1, height());
p.drawLine(2, height() - 2, width() - 2, height() - 2);
p.drawLine(2, height() - 1, width() - 2, height() - 1);
// Draw the text.
p.setFont(font());
p.setPen(colorGroup().foreground());
p.drawText(rect(), AlignHCenter | AlignVCenter, fullReading);
}
void StatPopup::mousePressEvent(TQMouseEvent* e) {
if(e->button() == Qt::RightButton) {
// Hide the pop-up.
hide();
} else {
// Begin a drag operation.
isDragged = true;
relX = e->x();
relY = e->y();
repaint();
}
}
void StatPopup::mouseMoveEvent(TQMouseEvent* e) {
// In the middle of a drag operation.
move(e->globalX() - relX, e->globalY() - relY);
}
void StatPopup::mouseReleaseEvent(TQMouseEvent* e) {
// The end of a drag operation.
move(e->globalX() - relX, e->globalY() - relY);
isDragged = false;
repaint();
}
void StatPopup::closeEvent(TQCloseEvent* e) {
// We're about to close. Save the current state for the last time.
savePopupState();
closing = true;
TQWidget::closeEvent(e);
}
void StatPopup::hideEvent(TQHideEvent* e) {
// We're about to hide. Save the current state if we're not
// closing altogether.
if (! closing)
savePopupState();
TQWidget::hideEvent(e);
}
void StatPopup::showEvent(TQShowEvent* e) {
// Make sure we're up-to-date and properly resized.
if (isActive())
takeReading();
else
resizeToText();
// Window management - fix so a taskbar button doesn't appear
KWin::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
TQWidget::showEvent(e);
}
void StatPopup::takeReading() {
takeReadingInternal();
for (int i = 0; i < r.size(); i++) {
r[i].dock->addPercentReading(r[i].upper, r[i].lower);
}
if (isVisible()) {
// Only resize if the pop-up is visible; otherwise fullReading
// might be stale anyway so we'll do it when we show the pop-up.
if (resizeRequested)
resizeToText();
repaint();
}
}
void StatPopup::resizeToText() {
resizeRequested = false;
TQSize size = fontMetrics().size(0, fullReading);
resize(size.width() + 2 * TEXT_EXPANSION_HORIZONTAL,
size.height() + 2 * TEXT_EXPANSION_VERTICAL);
repaint();
}
#include "statpopup.moc"