summaryrefslogtreecommitdiffstats
path: root/src/kima.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/kima.cpp')
-rw-r--r--src/kima.cpp432
1 files changed, 432 insertions, 0 deletions
diff --git a/src/kima.cpp b/src/kima.cpp
new file mode 100644
index 0000000..56d4bfe
--- /dev/null
+++ b/src/kima.cpp
@@ -0,0 +1,432 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ken Werner *
+ * ken.werner@web.de *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <list>
+
+// Qt
+#include <qlabel.h>
+#include <qfile.h>
+#include <qspinbox.h>
+#include <qcombobox.h>
+#include <qtextedit.h>
+#include <qtimer.h>
+#include <qcursor.h>
+#include <klistview.h>
+#include <qlistview.h>
+#include <qwidgetstack.h>
+
+// KDE
+#include <kmessagebox.h>
+#include <kaboutapplication.h>
+#include <kpopupmenu.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kactioncollection.h>
+#include <kactionclasses.h>
+#include <kapplication.h>
+#include <kdialogbase.h>
+#include <kconfig.h>
+//#include <kglobal.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+// Kima
+#include "kima.h"
+#include "flowlayout.h"
+#include "sourcelistitem.h"
+#include "prefs.h"
+
+// Kima Soures
+#include "sources/acpithermalsrc.h"
+#include "sources/ibmacpithermalsrc.h"
+#include "sources/ibmacpifansrc.h"
+#include "sources/ibmhdaps.h"
+#include "sources/omnibookthermalsrc.h"
+#include "sources/ibookg4thermalsrc.h"
+#include "sources/hwmonthermalsrc.h"
+#include "sources/hwmonfansrc.h"
+#include "sources/sysfreqsrc.h"
+#include "sources/cpuinfofreqsrc.h"
+#include "sources/i8ksrc.h"
+#include "sources/nvidiathermalsrc.h"
+#include "sources/hddtempsrc.h"
+#include "sources/uptimesrc.h"
+#include "sources/batterysrc.h"
+
+//#include "kdebug.h"
+
+extern "C" {
+ KPanelApplet* init( QWidget* inParent, const QString& inConfigFile) {
+ KGlobal::locale()->insertCatalogue("kima");
+ return new Kima(inConfigFile, KPanelApplet::Normal,
+ //KPanelApplet::About | KPanelApplet::Help | KPanelApplet::Preferences,
+ KPanelApplet::About | KPanelApplet::Preferences,
+ inParent, "kima");
+ }
+}
+
+Kima::Kima(const QString& inConfigFile, Type inType, int inActions, QWidget* inParent, const char* inName):
+ KPanelApplet(inConfigFile, inType, inActions, inParent, inName),
+ QToolTip(this),
+ mCachedWFH(0),
+ mCachedHeight(0),
+ mDraggedSourceItem(NULL){
+ mAboutDialog = 0; // aboutData is created in the about() method
+ mPrefsDlg = 0; // the prefs dialog is created in the preferences() method
+ mPrefs = 0; // the prefs ui is created in the preferences() method
+
+ // Get the current application configuration handle
+ mKConfig = config();
+ mKConfig->setGroup("Kima");
+
+ // automatically delete pointers
+ mSources.setAutoDelete(TRUE);
+
+ // create layout
+ mLayout = new FlowLayout(this, orientation() );
+ mLayout->setSpacing(8);
+
+
+ // add the sources into the sources list
+ addSources(NVidiaThermalSrc::createInstances(this));
+ addSources(ACPIThermalSrc::createInstances(this));
+ addSources(IBMACPIThermalSrc::createInstances(this));
+ addSources(IBMACPIFanSrc::createInstances(this));
+ addSources(IBMHDAPSSrc::createInstances(this));
+ addSources(OmnibookThermalSrc::createInstances(this));
+ addSources(IbookG4ThermalSrc::createInstances(this));
+ addSources(HwMonThermalSrc::createInstances(this));
+ addSources(SysFreqSrc::createInstances(this));
+ addSources(CpuinfoFreqSrc::createInstances(this));
+ addSources(I8kSrc::createInstances(this));
+ addSources(HDDTempSrc::createInstances(this));
+ addSources(HwMonFanSrc::createInstances(this));
+ addSources(UptimeSrc::createInstances(this));
+ addSources(BatterySrc::createInstances(this));
+
+
+ QPtrListIterator<Source> itSync(mSources);
+ Source* source;
+ while((source = itSync.current()) != 0){
+ ++itSync;
+ registerSource(source);
+ }
+ mLayout->updatePositions(mKConfig);
+
+ // create the menu
+ mMenu = new KPopupMenu(this);
+ mMenu->insertTitle(SmallIcon("hwinfo"), i18n("Kima"));
+
+ if (mCpufreqd.enabled()) {
+ mMenu->insertItem(i18n("&Performance Profiles"), mCpufreqd.menu());
+ }
+
+ KActionCollection* actionCollection = new KActionCollection(this, "actionCollection", kapp);
+
+ KAction* action = KStdAction::preferences(this, SLOT(preferences()), actionCollection);
+ action->setText(i18n("&Preferences"));
+ action->plug(mMenu);
+
+ action = KStdAction::aboutApp(this, SLOT(about()), actionCollection);
+ action->setText(i18n("&About Kima"));
+ action->plug(mMenu);
+
+ //menu->insertSeparator();
+ //KStdAction::quit( kapp, SLOT( quit() ), actionCollection )->plug( menu );
+}
+
+Kima::~Kima() {
+ // super class deletes the widgets
+}
+
+void Kima::addSources(const std::list<Source*>& inList){
+ for(std::list<Source*>::const_iterator it = inList.begin(); it != inList.end(); ++it){
+ mSources.append(*it);
+ }
+}
+
+void Kima::displaySource(bool inDisplay, Source* inSource){
+ if(inDisplay){
+ //kdDebug() << "Kima::displaySource mLayout->add: " << inSource->getName() << endl;
+ mLayout->addSource(inSource); // add the source
+ //kdDebug() << "Pos of " << inSource->getID() << ": " << inSource->getPosition() << endl;
+ }else{
+ //kdDebug() << "Kima::displaySource mLayout->remove: " << inSource->getName() << endl;
+ mLayout->remove(inSource->getWidget());
+ }
+}
+
+void Kima::about() {
+ if(!mAboutDialog){
+ KAboutData* aboutData = new KAboutData("libkima",
+ "Kima",
+ "0.7.3.2",
+ I18N_NOOP("Kicker monitoring applet.\n\n"
+ "This applet monitors various temperature, frequency and fan sources.\n"
+ "Make sure you have enabled a supported kernel module.\n"),
+ KAboutData::License_GPL,
+ "(c) 2004-2007, Ken Werner");
+ aboutData->addAuthor("Ken Werner", 0, "ken.werner@web.de");
+ aboutData->addAuthor("Johannes Schaub", 0, "schaub-johannes@web.de");
+ aboutData->addAuthor("Valentine Sinitsyn", I18N_NOOP("cpufreqd control module"), "e_val@inbox.ru");
+ aboutData->addCredit("Franziska Simmank");
+ aboutData->addCredit("Manfred Paul");
+ aboutData->addCredit("Rainer Dorsch");
+ aboutData->addCredit("Flavio Castelli");
+ aboutData->addCredit("Jocke Andersson");
+ aboutData->addCredit("Raoul Martin");
+ aboutData->addCredit("Donnie Bhayangkara");
+ aboutData->addCredit("Gonzalo Nemmi");
+ aboutData->addCredit("Mariusz Ciesla");
+ aboutData->addCredit("Mark Rosenstand");
+ aboutData->addCredit("Santiago Bruno");
+ aboutData->addCredit("Dark Apostrophe");
+ aboutData->addCredit("Sascha Hoogen");
+ aboutData->addCredit("Peter Avramucz");
+ aboutData->addCredit("Oskar Ellström");
+ aboutData->addCredit("Uğur Çetin");
+ mAboutDialog = new KAboutApplication(aboutData, this, "aboutApp", false);
+ }
+ mAboutDialog->show();
+}
+
+void Kima::help() {
+ KMessageBox::information(0, i18n("This is a help box"));
+}
+
+void Kima::preferences() {
+ //KMessageBox::information(0, i18n("This is a preferences box"));
+ if(!mPrefsDlg){
+ //create the prefs dialog
+ mPrefsDlg = new KDialogBase( this, "prefsDlg", false, i18n("Configuration"), KDialogBase::Ok|KDialogBase::Apply|KDialogBase::Cancel, KDialogBase::Ok, false );
+ //create the prefs ui
+ mPrefs = new Prefs( mPrefsDlg, "prefsui" ); //the uic generated class
+
+ //setup the dialog
+ //mPrefsDlg->setFixedSize(mPrefs->size());
+ mPrefsDlg->setMainWidget(mPrefs); //embed the uic generated class into the kde dialog
+ connect(mPrefsDlg, SIGNAL(applyClicked()), this, SLOT(savePreferences()));
+ connect(mPrefsDlg, SIGNAL(okClicked()), this, SLOT(savePreferences()));
+ connect(mPrefsDlg, SIGNAL(cancelClicked()), this, SLOT(cancelPreferences()));
+
+ // create new list items and the widgetStack widgets
+ QPtrListIterator<Source> it(mSources);
+ Source* source;
+ while((source = it.current()) != 0){
+ ++it;
+ // create the specific source prefs and add them to the widgetStack
+ mPrefs->widgetStack->addWidget(source->createPrefs(mPrefs->widgetStack));
+
+ // create the SourceListItem to switch and to enable/disable the widgetstack item (the source)
+ // and connect the apply/ok signals to the item, so it can change it's text to a potentially
+ // new source name.
+ SourceListItem * item = new SourceListItem(source, mPrefs->sourceListView, QCheckListItem::CheckBox);
+ connect(mPrefsDlg, SIGNAL(applyClicked()), item, SLOT(updateText()));
+ connect(mPrefsDlg, SIGNAL(okClicked()), item, SLOT(updateText()));
+ }
+
+ if(mPrefs->sourceListView->firstChild()){
+ mPrefs->sourceListView->setSelected(mPrefs->sourceListView->firstChild(), true); // select the first list item
+ raiseSourcePrefsWidget(mPrefs->sourceListView->firstChild()); // raise that item
+ }
+
+ connect(mPrefs->sourceListView, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(raiseSourcePrefsWidget(QListViewItem*)));
+ }
+
+ // update prefs gui
+ QPtrListIterator<Source> srcIt(mSources);
+ Source* source;
+ while((source = srcIt.current()) != 0){
+ ++srcIt;
+ source->updatePrefsGUI();
+ }
+
+ // update the sourcelist checkbox
+ QPtrList<QListViewItem> lst;
+ QListViewItemIterator lvIt(mPrefs->sourceListView);
+ while(lvIt.current()){
+ SourceListItem* sli = static_cast<SourceListItem*>(lvIt.current());
+ sli->setOn(sli->getSource()->isEnabled());
+ ++lvIt;
+ }
+
+ //show the dialog
+ mPrefsDlg->show();
+}
+
+void Kima::raiseSourcePrefsWidget(QListViewItem* inListViewItem){
+ mPrefs->widgetStack->raiseWidget(static_cast<SourceListItem*>(inListViewItem)->getSource()->getPrefs());
+}
+
+void Kima::cancelPreferences(){
+ // update prefs gui
+ QPtrListIterator<Source> it(mSources);
+ Source* source;
+ while((source = it.current()) != 0){
+ ++it;
+ source->updatePrefsGUI();
+ }
+}
+
+void Kima::savePreferences(){
+ // save prefs
+ QPtrListIterator<Source> it(mSources);
+ Source* source;
+ while((source = it.current()) != 0){
+ ++it;
+ source->applyPrefs();
+ source->savePrefs(mKConfig);
+ }
+ // save the position of all sources because they might have changed.
+ mLayout->updatePositions(mKConfig);
+ // update the source widgets
+ updateSourceWidgets();
+ // write config
+ mKConfig->sync();
+ // reset cached witdh for height to force recalculation of the applets width
+ mCachedWFH = 0;
+}
+
+int Kima::widthForHeight(int inHeight) const{
+ //kdDebug() << "widthForHeight: " << height << endl;
+ mLayout->setOrientation(Qt::Horizontal);
+ if(mCachedHeight != inHeight){
+ mCachedHeight = inHeight;
+ mCachedWFH = 0;
+ }
+ mCachedWFH = QMAX(mLayout->widthForHeight(inHeight), mCachedWFH);
+ return mCachedWFH;
+}
+
+int Kima::heightForWidth(int inWidth) const{
+ //kdDebug() << "heightForWidth: " << width << endl;
+ mLayout->setOrientation(Qt::Vertical);
+ return mLayout->heightForWidth(inWidth);
+ //return sizeHint().height();
+}
+
+void Kima::mousePressEvent(QMouseEvent* inEvent ){
+ if(inEvent->button() == QMouseEvent::RightButton){
+ mMenu->popup( inEvent->globalPos() );
+ if(mDraggedSourceItem)
+ mDraggedSourceItem->widget()->unsetCursor(); // unset drag cursor
+ }
+ else if(inEvent->button() == QMouseEvent::LeftButton){
+ QLayoutIterator it = mLayout->iterator();
+ while(it.current()){
+ QWidget * c = it.current()->widget();
+ if(c->rect().contains(c->mapFromGlobal(inEvent->globalPos()))){
+ mDraggedSourceItem = it.current(); // remenber the clicked source
+ c->setCursor(Qt::SizeAllCursor); // set drag cursor
+ mDragFactor = (c->rect().height()/2.0) / (double)c->mapFromGlobal(inEvent->globalPos()).y();
+ break;
+ }
+ ++it;
+ }
+ }
+}
+
+void Kima::mouseReleaseEvent(QMouseEvent* inEvent){
+ //if(inEvent->button() == QMouseEvent::LeftButton && mDraggedSourceItem){
+ if(mDraggedSourceItem){
+ mCachedWFH = 0; // reset cached witdh for height to force recalculation of the applets width
+ mDraggedSourceItem->widget()->unsetCursor(); // unset drag cursor
+ mDraggedSourceItem = NULL;
+ }
+}
+
+void Kima::mouseMoveEvent( QMouseEvent* inEvent ) {
+ if(!mDraggedSourceItem)
+ return;
+ QLayoutIterator it = mLayout->iterator();
+ while(it.current()){
+ QWidget * c = it.current()->widget();
+ if(c->rect().contains(c->mapFromGlobal(inEvent->globalPos()))){
+ if(it.current() == mDraggedSourceItem)
+ break;
+ // we are over a source-widget.
+ // move the dragged widget above / below that
+ // widget, depending where the cursor is.
+ QRect crect = c->rect();
+ double relPos = c->mapFromGlobal(inEvent->globalPos()).y() * mDragFactor;
+ if(mLayout->moveItem(mDraggedSourceItem, it.current(), crect.height()/2.0 > relPos ? FlowLayout::ABOVE : FlowLayout::BELOW)){
+ mLayout->updatePositions(mKConfig);
+ updateGeometry();
+ mKConfig->sync(); // write config
+ updateSourceWidgets();
+ }
+ break;
+ }
+ ++it;
+ }
+ // outside kima?
+ if(!rect().contains(mapToParent(inEvent->pos())))
+ mDraggedSourceItem->widget()->setCursor(Qt::ForbiddenCursor);
+ else
+ mDraggedSourceItem->widget()->setCursor(Qt::SizeAllCursor);
+}
+
+void Kima::paintEvent(QPaintEvent* inEvent){
+ KPanelApplet::paintEvent(inEvent);
+ updateSourceWidgets();
+}
+
+void Kima::updateSourceWidgets(){
+ // repaint the source widgets
+ for(Source* source = mSources.first(); source; source = mSources.next())
+ if(source->showOnApplet())
+ source->getWidget()->update();
+}
+
+void Kima::registerSource(Source* source) {
+ // then, tell the source to set up its widget
+ source->realizeWidget();
+
+ // enable transparency
+ source->getWidget()->setBackgroundMode(X11ParentRelative);
+
+ // load prefs from the configuration
+ // this call also emits enabledChanged
+ source->loadPrefs(mKConfig);
+
+ // add the source to the layout if necessary
+ displaySource(source->isEnabled() && source->showOnApplet(), source);
+
+ // connection to add and remove sources from mLayout
+ connect(source, SIGNAL(displaySource(bool, Source*)), this, SLOT(displaySource(bool, Source*)));
+}
+
+void Kima::maybeTip(const QPoint& inPos){
+ if(!rect().contains(inPos))
+ return;
+ QString text = "<b>" + i18n("Sources:") + "</b><br><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">";
+
+ QPtrListIterator<Source> it(mSources);
+ Source* source;
+ while((source = it.current()) != 0){
+ ++it;
+ if(source->isEnabled() && source->isToolTipEnabled())
+ text.append("<tr><td>" +
+ source->getName() + "</td><td>" +
+ source->getValue() + "</td><td>");
+ }
+ text.append("</table>");
+ tip(rect(), text);
+}