/*************************************************************************** * 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 // Qt #include #include #include #include #include #include #include #include #include #include // KDE #include #include #include #include #include #include #include #include #include #include //#include #include #include // 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 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& inList){ for(std::list::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 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 srcIt(mSources); Source* source; while((source = srcIt.current()) != 0){ ++srcIt; source->updatePrefsGUI(); } // update the sourcelist checkbox QPtrList lst; QListViewItemIterator lvIt(mPrefs->sourceListView); while(lvIt.current()){ SourceListItem* sli = static_cast(lvIt.current()); sli->setOn(sli->getSource()->isEnabled()); ++lvIt; } //show the dialog mPrefsDlg->show(); } void Kima::raiseSourcePrefsWidget(QListViewItem* inListViewItem){ mPrefs->widgetStack->raiseWidget(static_cast(inListViewItem)->getSource()->getPrefs()); } void Kima::cancelPreferences(){ // update prefs gui QPtrListIterator it(mSources); Source* source; while((source = it.current()) != 0){ ++it; source->updatePrefsGUI(); } } void Kima::savePreferences(){ // save prefs QPtrListIterator 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 = "" + i18n("Sources:") + "
"; QPtrListIterator it(mSources); Source* source; while((source = it.current()) != 0){ ++it; if(source->isEnabled() && source->isToolTipEnabled()) text.append("
" + source->getName() + "" + source->getValue() + ""); } text.append("
"); tip(rect(), text); }