diff options
Diffstat (limited to 'ksysguard/gui/SensorDisplayLib/ListView.cc')
-rw-r--r-- | ksysguard/gui/SensorDisplayLib/ListView.cc | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/ksysguard/gui/SensorDisplayLib/ListView.cc b/ksysguard/gui/SensorDisplayLib/ListView.cc new file mode 100644 index 000000000..885daded6 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/ListView.cc @@ -0,0 +1,371 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 2001 Tobias Koenig <[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 <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); +} |