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.
tdebase/ksysguard/gui/SensorDisplayLib/ListView.cc

372 lines
10 KiB

/*
KSysGuard, the KDE System Guard
Copyright (c) 2001 Tobias Koenig <tokoe@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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <config.h>
#include <qdom.h>
#include <kcolorbutton.h>
#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <ksgrd/SensorManager.h>
#include <ksgrd/StyleEngine.h>
#include "ListView.h"
#include "ListView.moc"
#include "ListViewSettings.h"
PrivateListViewItem::PrivateListViewItem(PrivateListView *parent)
: QListViewItem(parent)
{
_parent = parent;
}
int PrivateListViewItem::compare( QListViewItem *item, int col, bool ascending ) const
{
int type = ((PrivateListView*)listView())->columnType( col );
if ( type == PrivateListView::Int ) {
int prev = (int)KGlobal::locale()->readNumber( key( col, ascending ) );
int next = (int)KGlobal::locale()->readNumber( item->key( col, ascending ) );
if ( prev < next )
return -1;
else if ( prev == next )
return 0;
else
return 1;
} else if ( type == PrivateListView::Float ) {
double prev = KGlobal::locale()->readNumber( key( col, ascending ) );
double next = KGlobal::locale()->readNumber( item->key( col, ascending ) );
if ( prev < next )
return -1;
else
return 1;
} else if ( type == PrivateListView::Time ) {
int hourPrev, hourNext, minutesPrev, minutesNext;
sscanf( key( col, ascending ).latin1(), "%d:%d", &hourPrev, &minutesPrev );
sscanf( item->key( col, ascending ).latin1(), "%d:%d", &hourNext, &minutesNext );
int prev = hourPrev * 60 + minutesPrev;
int next = hourNext * 60 + minutesNext;
if ( prev < next )
return -1;
else if ( prev == next )
return 0;
else
return 1;
} else if ( type == PrivateListView::DiskStat ) {
QString prev = key( col, ascending );
QString next = item->key( col, ascending );
QString prevKey, nextKey;
uint counter = prev.length();
for ( uint i = 0; i < counter; ++i )
if ( prev[ i ].isDigit() ) {
prevKey.sprintf( "%s%016d", prev.left( i ).latin1(), prev.mid( i ).toInt() );
break;
}
counter = next.length();
for ( uint i = 0; i < counter; ++i )
if ( next[ i ].isDigit() ) {
nextKey.sprintf( "%s%016d", next.left( i ).latin1(), next.mid( i ).toInt() );
break;
}
return prevKey.compare( nextKey );
} else
return key( col, ascending ).localeAwareCompare( item->key( col, ascending ) );
}
PrivateListView::PrivateListView(QWidget *parent, const char *name)
: QListView(parent, name)
{
QColorGroup cg = colorGroup();
cg.setColor(QColorGroup::Link, KSGRD::Style->firstForegroundColor());
cg.setColor(QColorGroup::Text, KSGRD::Style->secondForegroundColor());
cg.setColor(QColorGroup::Base, KSGRD::Style->backgroundColor());
setPalette(QPalette(cg, cg, cg));
}
void PrivateListView::update(const QString& answer)
{
setUpdatesEnabled(false);
viewport()->setUpdatesEnabled(false);
int vpos = verticalScrollBar()->value();
int hpos = horizontalScrollBar()->value();
clear();
KSGRD::SensorTokenizer lines(answer, '\n');
for (uint i = 0; i < lines.count(); i++) {
PrivateListViewItem *item = new PrivateListViewItem(this);
KSGRD::SensorTokenizer records(lines[i], '\t');
for (uint j = 0; j < records.count(); j++) {
if ( mColumnTypes[ j ] == "f" )
item->setText(j, KGlobal::locale()->formatNumber( records[j].toFloat() ) );
else if ( mColumnTypes[ j ] == "D" )
item->setText(j, KGlobal::locale()->formatNumber( records[j].toDouble(), 0 ) );
else
item->setText(j, records[j]);
}
insertItem(item);
}
verticalScrollBar()->setValue(vpos);
horizontalScrollBar()->setValue(hpos);
viewport()->setUpdatesEnabled(true);
setUpdatesEnabled(true);
triggerUpdate();
}
int PrivateListView::columnType( uint pos ) const
{
if ( pos >= mColumnTypes.count() )
return 0;
if ( mColumnTypes[ pos ] == "d" || mColumnTypes[ pos ] == "D" )
return Int;
else if ( mColumnTypes[ pos ] == "f" || mColumnTypes[ pos ] == "F" )
return Float;
else if ( mColumnTypes[ pos ] == "t" )
return Time;
else if ( mColumnTypes[ pos ] == "M" )
return DiskStat;
else
return Text;
}
void PrivateListView::removeColumns(void)
{
for (int i = columns() - 1; i >= 0; --i)
removeColumn(i);
}
void PrivateListView::addColumn(const QString& label, const QString& type)
{
QListView::addColumn( label );
int col = columns() - 1;
if (type == "s" || type == "S")
setColumnAlignment(col, AlignLeft);
else if (type == "d" || type == "D")
setColumnAlignment(col, AlignRight);
else if (type == "t")
setColumnAlignment(col, AlignRight);
else if (type == "f")
setColumnAlignment(col, AlignRight);
else if (type == "M")
setColumnAlignment(col, AlignLeft);
else
{
kdDebug(1215) << "Unknown type " << type << " of column " << label
<< " in ListView!" << endl;
return;
}
mColumnTypes.append( type );
/* Just use some sensible default values as initial setting. */
QFontMetrics fm = fontMetrics();
setColumnWidth(col, fm.width(label) + 10);
}
ListView::ListView(QWidget* parent, const char* name, const QString& title, int, int)
: KSGRD::SensorDisplay(parent, name, title)
{
setBackgroundColor(KSGRD::Style->backgroundColor());
monitor = new PrivateListView( frame() );
Q_CHECK_PTR(monitor);
monitor->setSelectionMode(QListView::NoSelection);
monitor->setItemMargin(2);
setMinimumSize(50, 25);
setPlotterWidget(monitor);
setModified(false);
}
bool
ListView::addSensor(const QString& hostName, const QString& sensorName, const QString& sensorType, const QString& title)
{
if (sensorType != "listview")
return (false);
registerSensor(new KSGRD::SensorProperties(hostName, sensorName, sensorType, title));
setTitle(title);
/* To differentiate between answers from value requests and info
* requests we use 100 for info requests. */
sendRequest(hostName, sensorName + "?", 100);
sendRequest(hostName, sensorName, 19);
setModified(true);
return (true);
}
void
ListView::updateList()
{
sendRequest(sensors().at(0)->hostName(), sensors().at(0)->name(), 19);
}
void
ListView::answerReceived(int id, const QString& answer)
{
/* We received something, so the sensor is probably ok. */
sensorError(id, false);
switch (id)
{
case 100: {
/* We have received the answer to a '?' command that contains
* the information about the table headers. */
KSGRD::SensorTokenizer lines(answer, '\n');
if (lines.count() != 2)
{
kdDebug(1215) << "wrong number of lines" << endl;
return;
}
KSGRD::SensorTokenizer headers(lines[0], '\t');
KSGRD::SensorTokenizer colTypes(lines[1], '\t');
/* remove all columns from list */
monitor->removeColumns();
/* add the new columns */
for (unsigned int i = 0; i < headers.count(); i++)
/* TODO: Implement translation support for header texts */
monitor->addColumn(headers[i], colTypes[i]);
break;
}
case 19: {
monitor->update(answer);
break;
}
}
}
void
ListView::resizeEvent(QResizeEvent*)
{
frame()->setGeometry(0, 0, width(), height());
monitor->setGeometry(10, 20, width() - 20, height() - 30);
}
bool
ListView::restoreSettings(QDomElement& element)
{
addSensor(element.attribute("hostName"), element.attribute("sensorName"), (element.attribute("sensorType").isEmpty() ? "listview" : element.attribute("sensorType")), element.attribute("title"));
QColorGroup colorGroup = monitor->colorGroup();
colorGroup.setColor(QColorGroup::Link, restoreColor(element, "gridColor", KSGRD::Style->firstForegroundColor()));
colorGroup.setColor(QColorGroup::Text, restoreColor(element, "textColor", KSGRD::Style->secondForegroundColor()));
colorGroup.setColor(QColorGroup::Base, restoreColor(element, "backgroundColor", KSGRD::Style->backgroundColor()));
monitor->setPalette(QPalette(colorGroup, colorGroup, colorGroup));
SensorDisplay::restoreSettings(element);
setModified(false);
return (true);
}
bool
ListView::saveSettings(QDomDocument& doc, QDomElement& element, bool save)
{
element.setAttribute("hostName", sensors().at(0)->hostName());
element.setAttribute("sensorName", sensors().at(0)->name());
element.setAttribute("sensorType", sensors().at(0)->type());
QColorGroup colorGroup = monitor->colorGroup();
saveColor(element, "gridColor", colorGroup.color(QColorGroup::Link));
saveColor(element, "textColor", colorGroup.color(QColorGroup::Text));
saveColor(element, "backgroundColor", colorGroup.color(QColorGroup::Base));
SensorDisplay::saveSettings(doc, element);
if (save)
setModified(false);
return (true);
}
void
ListView::configureSettings()
{
lvs = new ListViewSettings(this, "ListViewSettings");
Q_CHECK_PTR(lvs);
connect(lvs, SIGNAL(applyClicked()), SLOT(applySettings()));
QColorGroup colorGroup = monitor->colorGroup();
lvs->setGridColor(colorGroup.color(QColorGroup::Link));
lvs->setTextColor(colorGroup.color(QColorGroup::Text));
lvs->setBackgroundColor(colorGroup.color(QColorGroup::Base));
lvs->setTitle(title());
if (lvs->exec())
applySettings();
delete lvs;
lvs = 0;
}
void
ListView::applySettings()
{
QColorGroup colorGroup = monitor->colorGroup();
colorGroup.setColor(QColorGroup::Link, lvs->gridColor());
colorGroup.setColor(QColorGroup::Text, lvs->textColor());
colorGroup.setColor(QColorGroup::Base, lvs->backgroundColor());
monitor->setPalette(QPalette(colorGroup, colorGroup, colorGroup));
setTitle(lvs->title());
setModified(true);
}
void
ListView::applyStyle()
{
QColorGroup colorGroup = monitor->colorGroup();
colorGroup.setColor(QColorGroup::Link, KSGRD::Style->firstForegroundColor());
colorGroup.setColor(QColorGroup::Text, KSGRD::Style->secondForegroundColor());
colorGroup.setColor(QColorGroup::Base, KSGRD::Style->backgroundColor());
monitor->setPalette(QPalette(colorGroup, colorGroup, colorGroup));
setModified(true);
}