00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "karamba_python.h"
00025 #include "dcopinterface_stub.h"
00026 #include "richtextlabel.h"
00027 #include "karamba.h"
00028 #include "karambaapp.h"
00029 #include "themesdlg.h"
00030 #include "lineparser.h"
00031 #include "themelocale.h"
00032 #include "superkarambasettings.h"
00033
00034 #include <kdebug.h>
00035 #include <kmessagebox.h>
00036 #include <krun.h>
00037 #include <klocale.h>
00038 #include <kwin.h>
00039 #include <kdeversion.h>
00040 #include <kdirwatch.h>
00041
00042 #include <kparts/componentfactory.h>
00043 #include <kparts/part.h>
00044
00045 #include <qdir.h>
00046 #include <qwidgetlist.h>
00047
00048
00049 #define EDITSCRIPT 1
00050 #define THEMECONF 2
00051
00052 karamba::karamba(QString fn, QString name, bool reloading, int instance,
00053 bool sub_theme):
00054 QWidget(0,"karamba", Qt::WGroupLeader | WStyle_Customize |
00055 WRepaintNoErase| WStyle_NoBorder | WDestructiveClose ),
00056 meterList(0), imageList(0), clickList(0), kpop(0), widgetMask(0),
00057 config(0), kWinModule(0), tempUnit('C'), m_instance(instance),
00058 sensorList(0), timeList(0),
00059 themeConfMenu(0), toDesktopMenu(0), kglobal(0), clickPos(0, 0), accColl(0),
00060 menuAccColl(0), toggleLocked(0), pythonIface(0), defaultTextField(0),
00061 trayMenuSeperatorId(-1), trayMenuQuitId(-1), trayMenuToggleId(-1),
00062 trayMenuThemeId(-1),
00063 m_sysTimer(NULL)
00064 {
00065 themeStarted = false;
00066 want_right_button = false;
00067 prettyName = name;
00068 m_sub_theme = sub_theme;
00069
00070 KURL url;
00071
00072 if(fn.find('/') == -1)
00073 url.setFileName(fn);
00074 else
00075 url = fn;
00076 if(!m_theme.set(url))
00077 {
00078 setFixedSize(0, 0);
00079 QTimer::singleShot(100, this, SLOT(killWidget()));
00080 return;
00081 }
00082
00083
00084 karambaApp->addKaramba(this, reloading);
00085
00086 if(prettyName.isEmpty())
00087 prettyName = QString("%1 - %2").arg(m_theme.name()).arg(m_instance);
00088
00089 kdDebug() << "Starting theme: " << m_theme.name()
00090 << " pretty name: " << prettyName << endl;
00091 QString qName = "karamba - " + prettyName;
00092 setName(qName.ascii());
00093
00094 KDirWatch *dirWatch = KDirWatch::self();
00095 connect(dirWatch, SIGNAL( dirty( const QString & ) ),
00096 SLOT( slotFileChanged( const QString & ) ) );
00097
00098 if(!dirWatch->contains(m_theme.file()))
00099 dirWatch->addFile(m_theme.file());
00100
00101 if(!m_theme.isZipTheme() && m_theme.pythonModuleExists())
00102 {
00103 QString pythonFile = m_theme.path() + "/" + m_theme.pythonModule() + ".py";
00104 if(!dirWatch->contains(pythonFile))
00105 dirWatch->addFile(pythonFile);
00106 }
00107
00108 widgetUpdate = true;
00109
00110
00111 QString instanceString;
00112 if(m_instance > 1)
00113 instanceString = QString("-%1").arg(m_instance);
00114 QString cfg = QDir::home().absPath() + "/.superkaramba/"
00115 + m_theme.id() + instanceString + ".rc";
00116 kdDebug() << cfg << endl;
00117 QFile themeConfigFile(cfg);
00118
00119 if (!QFileInfo(themeConfigFile).exists())
00120 {
00121
00122 themeConfigFile.open(IO_ReadWrite);
00123 themeConfigFile.close();
00124 }
00125
00126 config = new KConfig(cfg, false, false);
00127 config -> sync();
00128 config -> setGroup("internal");
00129
00130 m_reloading = reloading;
00131 if(m_theme.pythonModuleExists())
00132 {
00133 kdDebug() << "Loading python module: " << m_theme.pythonModule() << endl;
00134 QTimer::singleShot(0, this, SLOT(initPythonInterface()));
00135 }
00136
00137 widgetMask = 0;
00138 info = new NETWinInfo( qt_xdisplay(), winId(), qt_xrootwin(), NET::WMState );
00139
00140
00141 kWinModule = new KWinModule();
00142 desktop = 0;
00143
00144 connect( kWinModule,SIGNAL(currentDesktopChanged(int)), this,
00145 SLOT(currentDesktopChanged(int)) );
00146 connect( kapp, SIGNAL(backgroundChanged(int)), this,
00147 SLOT(currentWallpaperChanged(int)));
00148
00149
00150 connect(&taskManager, SIGNAL(activeTaskChanged(Task*)), this,
00151 SLOT(activeTaskChanged(Task*)) );
00152 connect(&taskManager, SIGNAL(taskAdded(Task*)), this,
00153 SLOT(taskAdded(Task*)) );
00154 connect(&taskManager, SIGNAL(taskRemoved(Task*)), this,
00155 SLOT(taskRemoved(Task*)) );
00156 connect(&taskManager, SIGNAL(startupAdded(Startup*)), this,
00157 SLOT(startupAdded(Startup*)) );
00158 connect(&taskManager, SIGNAL(startupRemoved(Startup*)), this,
00159 SLOT(startupRemoved(Startup*)) );
00160
00161 themeConfMenu = new KPopupMenu( this);
00162 themeConfMenu -> setCheckable(true);
00163
00164
00165 DesktopChangeSlot *dslot;
00166
00167 int mid;
00168
00169 toDesktopMenu = new KPopupMenu (this);
00170 toDesktopMenu -> setCheckable(true);
00171 mid = toDesktopMenu -> insertItem (i18n("&All Desktops"),
00172 dslot = new DesktopChangeSlot(this,0),
00173 SLOT(receive()));
00174 dslot->setMenuId(mid);
00175
00176 toDesktopMenu -> insertSeparator();
00177 for (int ndesktop=1; ndesktop <= kWinModule->numberOfDesktops(); ndesktop++)
00178 {
00179 QString name = i18n("Desktop &");
00180 name += ('0' + ndesktop);
00181
00182 mid = toDesktopMenu -> insertItem (name,
00183 dslot = new DesktopChangeSlot(this, ndesktop), SLOT(receive()));
00184 dslot->setMenuId(mid);
00185 }
00186
00187
00188 kpop = new KPopupMenu( this );
00189 kpop -> setCheckable(true);
00190
00191 accColl = new KActionCollection( this );
00192 menuAccColl = new KActionCollection( this );
00193
00194 kpop->insertItem( SmallIconSet("reload"),i18n("Update"), this,
00195 SLOT(updateSensors()), Key_F5 );
00196 toggleLocked = new KToggleAction ( i18n("Toggle &Locked Position"),
00197 SmallIconSet("locked"),
00198 CTRL+Key_L, this,
00199 SLOT( slotToggleLocked() ),
00200 accColl, "Locked position" );
00201 accColl->insert(toggleLocked);
00202 toggleLocked -> setChecked(true);
00203
00204 toggleLocked->plug(kpop);
00205
00206 toggleFastTransforms = new KToggleAction(i18n("Use &Fast Image Scaling"),
00207 CTRL+Key_F, this,
00208 SLOT( slotToggleFastTransforms() ),
00209 accColl, "Fast transformations");
00210
00211 accColl->insert(toggleFastTransforms);
00212 toggleFastTransforms -> setChecked(true);
00213
00214 toggleFastTransforms -> plug(kpop);
00215
00216 kpop->insertSeparator();
00217
00218 kpop->insertItem(i18n("Configure &Theme"), themeConfMenu, THEMECONF);
00219 kpop->setItemEnabled(THEMECONF, false);
00220 kpop->insertItem(i18n("To Des&ktop"), toDesktopMenu);
00221
00222 kpop->insertItem( SmallIconSet("reload3"),i18n("&Reload Theme"),this,
00223 SLOT(reloadConfig()), CTRL+Key_R );
00224 kpop->insertItem( SmallIconSet("fileclose"),i18n("&Close This Theme"), this,
00225 SLOT(killWidget()), CTRL+Key_C );
00226
00227 if(!SuperKarambaSettings::showSysTray())
00228 showMenuExtension();
00229
00230 kpop->polish();
00231
00232 numberOfConfMenuItems = 0;
00233
00234 systray = 0;
00235 foundKaramba = false;
00236 onTop = false;
00237 managed = false;
00238 fixedPosition = false;
00239 defaultTextField = new TextField();
00240
00241 meterList = new QObjectList();
00242 meterList->setAutoDelete( true );
00243 sensorList = new QObjectList();
00244 sensorList->setAutoDelete( true );
00245 clickList = new QObjectList();
00246 timeList = new QObjectList();
00247 imageList = new QObjectList();
00248 menuList = new QObjectList();
00249 menuList->setAutoDelete( true );
00250
00251 client = kapp->dcopClient();
00252 if (!client->isAttached())
00253 client->attach();
00254 appId = client->registerAs(qApp->name());
00255
00256
00257 setBackgroundMode( NoBackground);
00258 if( !(onTop || managed))
00259 KWin::lowerWindow( winId() );
00260
00261 if( !parseConfig() )
00262 {
00263 setFixedSize(0,0);
00264 QTimer::singleShot( 100, this, SLOT(killWidget()) );
00265 qWarning("Could not read config file.");
00266 }
00267 else
00268 {
00269 kroot = new KarambaRootPixmap((QWidget*)this);
00270 kroot->start();
00271 }
00272
00273
00274 bool locked = toggleLocked->isChecked();
00275 locked = config->readBoolEntry("lockedPosition", locked);
00276 toggleLocked->setChecked(locked);
00277 slotToggleLocked();
00278
00279 if (!config -> readBoolEntry("fastTransforms", true))
00280 {
00281 toggleFastTransforms -> setChecked(false);
00282 slotToggleFastTransforms();
00283 }
00284
00285 desktop = config -> readNumEntry("desktop", desktop);
00286 if (desktop > kWinModule->numberOfDesktops())
00287 {
00288 desktop = 0;
00289 }
00290
00291 if (desktop)
00292 {
00293 info->setDesktop( desktop );
00294 }
00295 else
00296 info->setDesktop( NETWinInfo::OnAllDesktops);
00297
00298
00299 config -> setGroup("theme");
00300 if (config -> hasKey("widgetPosX") && config -> hasKey("widgetPosY"))
00301 {
00302 int xpos = config -> readNumEntry("widgetPosX");
00303 int ypos = config -> readNumEntry("widgetPosY");
00304
00305 if (xpos < 0)
00306 xpos = 0;
00307 if (ypos < 0)
00308 ypos = 0;
00309 move(xpos, ypos);
00310 }
00311
00312 haveUpdated = 0;
00313 this->setMouseTracking(true);
00314
00315
00316 setFocusPolicy(QWidget::StrongFocus);
00317 }
00318
00319 karamba::~karamba()
00320 {
00321
00322
00323 karambaApp->deleteKaramba(this, m_reloading);
00324
00325 widgetClosed();
00326 if(m_theme.isValid())
00327 writeConfigData();
00328
00329 delete config;
00330
00331 if(meterList != 0)
00332 {
00333 meterList->clear();
00334 delete meterList;
00335 }
00336
00337 if( sensorList != 0 )
00338 {
00339 sensorList->clear();
00340 delete sensorList;
00341 }
00342
00343 if( imageList != 0 )
00344 {
00345 imageList->clear();
00346 delete imageList;
00347 }
00348
00349 if( clickList != 0 )
00350 {
00351 clickList->clear();
00352 delete clickList;
00353 }
00354
00355 if( timeList != 0 )
00356 {
00357 timeList->clear();
00358 delete timeList;
00359 }
00360
00361 delete toggleLocked;
00362 delete accColl;
00363 delete menuAccColl;
00364 delete themeConfMenu;
00365 delete kpop;
00366 delete widgetMask;
00367 delete kWinModule;
00368 delete defaultTextField;
00369 if (pythonIface != NULL)
00370 delete pythonIface;
00371 }
00372
00373 bool karamba::parseConfig()
00374 {
00375
00376 bool passive = true;
00377
00378 if(m_theme.open())
00379 {
00380 QValueStack<QPoint> offsetStack;
00381 LineParser lineParser;
00382 int x=0;
00383 int y=0;
00384 int w=0;
00385 int h=0;
00386
00387 offsetStack.push(QPoint(0,0));
00388
00389 while(m_theme.nextLine(lineParser))
00390 {
00391 x = lineParser.getInt("X") + offsetStack.top().x();
00392 y = lineParser.getInt("Y") + offsetStack.top().y();
00393 w = lineParser.getInt("W");
00394 h = lineParser.getInt("H");
00395
00396 if(lineParser.meter() == "KARAMBA" && !foundKaramba )
00397 {
00398
00399 toggleLocked->setChecked(lineParser.getBoolean("LOCKED"));
00400 slotToggleLocked();
00401
00402 x = ( x < 0 ) ? 0:x;
00403 y = ( y < 0 ) ? 0:y;
00404
00405 if( w == 0 || h == 0)
00406 {
00407 w = 300;
00408 h = 300;
00409 }
00410 setFixedSize(w,h);
00411
00412 if(lineParser.getBoolean("RIGHT"))
00413 {
00414 QDesktopWidget *d = QApplication::desktop();
00415 x = d->width() - w;
00416 }
00417 else if(lineParser.getBoolean("LEFT"))
00418 {
00419 x = 0;
00420 }
00421
00422 if(lineParser.getBoolean("BOTTOM"))
00423 {
00424 QDesktopWidget *d = QApplication::desktop();
00425 y = d->height() - h;
00426 }
00427 else if(lineParser.getBoolean("TOP"))
00428 {
00429 y = 0;
00430 }
00431
00432 move(x,y);
00433
00434
00435 if(lineParser.getBoolean("ONTOP"))
00436 {
00437 onTop = true;
00438 KWin::setState( winId(), NET::StaysOnTop );
00439 }
00440
00441 if(lineParser.getBoolean("MANAGED"))
00442 {
00443 managed = true;
00444 reparent(0, Qt::WType_Dialog | WStyle_Customize | WStyle_NormalBorder
00445 | WRepaintNoErase | WDestructiveClose, pos());
00446 }
00447 else
00448 {
00449 info->setState( NETWinInfo::SkipTaskbar
00450 | NETWinInfo::SkipPager,NETWinInfo::SkipTaskbar
00451 | NETWinInfo::SkipPager );
00452 if (onTop)
00453 {
00454 KWin::setState( winId(), NET::StaysOnTop );
00455
00456 }
00457 }
00458
00459 if (lineParser.getBoolean("ONALLDESKTOPS"))
00460 {
00461 desktop = 200;
00462 }
00463
00464
00465 bool dfound=false;
00466
00467 if (dfound)
00468 {
00469 info->setDesktop( dfound );
00470 }
00471 if(lineParser.getBoolean("TOPBAR"))
00472 {
00473 move(x,0);
00474 KWin::setStrut( winId(), 0, 0, h, 0 );
00475 toggleLocked->setChecked( true );
00476 slotToggleLocked();
00477 toggleLocked->setEnabled(false);
00478 }
00479
00480 if(lineParser.getBoolean("BOTTOMBAR"))
00481 {
00482 int dh = QApplication::desktop()->height();
00483 move( x, dh - h );
00484 KWin::setStrut( winId(), 0, 0, 0, h );
00485 toggleLocked->setChecked( true );
00486 slotToggleLocked();
00487 toggleLocked->setEnabled(false);
00488 }
00489
00490 if(lineParser.getBoolean("RIGHTBAR"))
00491 {
00492 int dw = QApplication::desktop()->width();
00493 move( dw - w, y );
00494 KWin::setStrut( winId(), 0, w, 0, 0 );
00495 toggleLocked->setChecked( true );
00496 slotToggleLocked();
00497 toggleLocked->setEnabled(false);
00498 }
00499
00500 if(lineParser.getBoolean("LEFTBAR"))
00501 {
00502 move( 0, y );
00503 KWin::setStrut( winId(), w, 0, 0, 0 );
00504 toggleLocked->setChecked( true );
00505 slotToggleLocked();
00506 toggleLocked->setEnabled(false);
00507 }
00508
00509 QString path = lineParser.getString("MASK");
00510
00511 QFileInfo info(path);
00512 QString absPath;
00513 QBitmap bmMask;
00514 QByteArray ba;
00515 if( info.isRelative() )
00516 {
00517 absPath.setAscii(m_theme.path().ascii());
00518 absPath.append(path.ascii());
00519 ba = m_theme.readThemeFile(path);
00520 }
00521 else
00522 {
00523 absPath.setAscii(path.ascii());
00524 ba = m_theme.readThemeFile(info.fileName());
00525 }
00526 if(m_theme.isZipTheme())
00527 {
00528 bmMask.loadFromData(ba);
00529 }
00530 else
00531 {
00532 bmMask.load(absPath);
00533 }
00534 setMask(bmMask);
00535
00536 m_interval = lineParser.getInt("INTERVAL");
00537 m_interval = (m_interval == 0) ? 1000 : m_interval;
00538
00539 QString temp = lineParser.getString("TEMPUNIT", "C").upper();
00540 tempUnit = temp.ascii()[0];
00541 foundKaramba = true;
00542 }
00543
00544 if(lineParser.meter() == "THEME")
00545 {
00546 QString path = lineParser.getString("PATH");
00547 QFileInfo info(path);
00548 if( info.isRelative())
00549 path = m_theme.path() +"/" + path;
00550 (new karamba( path, QString() ))->show();
00551 }
00552
00553 if(lineParser.meter() == "<GROUP>")
00554 {
00555 int offsetX = offsetStack.top().x();
00556 int offsetY = offsetStack.top().y();
00557 offsetStack.push( QPoint( offsetX + lineParser.getInt("X"),
00558 offsetY + lineParser.getInt("Y")));
00559 }
00560
00561 if(lineParser.meter() == "</GROUP>")
00562 {
00563 offsetStack.pop();
00564 }
00565
00566 if(lineParser.meter() == "CLICKAREA")
00567 {
00568 if( !hasMouseTracking() )
00569 setMouseTracking(true);
00570 ClickArea *tmp = new ClickArea(this, x, y, w, h );
00571 tmp->setOnClick(lineParser.getString("ONCLICK"));
00572
00573 setSensor(lineParser, (Meter*)tmp);
00574 clickList->append( tmp );
00575 if( lineParser.getBoolean("PREVIEW"))
00576 meterList->append( tmp );
00577 }
00578
00579
00580 if(lineParser.meter() == "SENSOR=PROGRAM")
00581 {
00582 setSensor(lineParser, 0 );
00583 }
00584
00585 if(lineParser.meter() == "IMAGE")
00586 {
00587 QString file = lineParser.getString("PATH");
00588 QString file_roll = lineParser.getString("PATHROLL");
00589 int xon = lineParser.getInt("XROLL");
00590 int yon = lineParser.getInt("YROLL");
00591 QString tiptext = lineParser.getString("TOOLTIP");
00592 QString name = lineParser.getString("NAME");
00593 bool bg = lineParser.getBoolean("BACKGROUND");
00594 xon = ( xon <= 0 ) ? x:xon;
00595 yon = ( yon <= 0 ) ? y:yon;
00596
00597 ImageLabel *tmp = new ImageLabel(this, x, y, 0, 0);
00598 tmp->setValue(file);
00599 if(!file_roll.isEmpty())
00600 tmp->parseImages(file, file_roll, x,y, xon, yon);
00601 tmp->setBackground(bg);
00602 if (!name.isEmpty())
00603 tmp->setName(name.ascii());
00604 if (!tiptext.isEmpty())
00605 tmp->setTooltip(tiptext);
00606
00607 connect(tmp, SIGNAL(pixmapLoaded()), this, SLOT(externalStep()));
00608 setSensor(lineParser, (Meter*) tmp );
00609 meterList->append (tmp );
00610 imageList->append (tmp );
00611 }
00612
00613 if(lineParser.meter() == "DEFAULTFONT" )
00614 {
00615 delete defaultTextField;
00616 defaultTextField = new TextField( );
00617
00618 defaultTextField->setColor(lineParser.getColor("COLOR",
00619 QColor("black")));
00620 defaultTextField->setBGColor(lineParser.getColor("BGCOLOR",
00621 QColor("white")));
00622 defaultTextField->setFont(lineParser.getString("FONT", "Helvetica"));
00623 defaultTextField->setFontSize(lineParser.getInt("FONTSIZE", 12));
00624 defaultTextField->setAlignment(lineParser.getString("ALIGN",
00625 "LEFT"));
00626 defaultTextField->setFixedPitch(lineParser.getBoolean("FIXEDPITCH",
00627 false));
00628 defaultTextField->setShadow(lineParser.getInt("SHADOW", 0));
00629 }
00630
00631 if(lineParser.meter() == "TEXT" ||
00632 lineParser.meter() == "CLICKMAP" ||
00633 lineParser.meter() == "RICHTEXT" ||
00634 lineParser.meter() == "INPUT")
00635 {
00636 TextField defTxt;
00637
00638 if(defaultTextField)
00639 defTxt = *defaultTextField;
00640
00641 TextField* tmpText = new TextField();
00642
00643 tmpText->setColor(lineParser.getColor("COLOR", defTxt.getColor()));
00644 tmpText->setBGColor(lineParser.getColor("BGCOLOR",
00645 defTxt.getBGColor()));
00646 tmpText->setFont(lineParser.getString("FONT", defTxt.getFont()));
00647 tmpText->setFontSize(lineParser.getInt("FONTSIZE",
00648 defTxt.getFontSize()));
00649 tmpText->setAlignment(lineParser.getString("ALIGN",
00650 defTxt.getAlignmentAsString()));
00651 tmpText->setFixedPitch(lineParser.getInt("FIXEDPITCH",
00652 defTxt.getFixedPitch()));
00653
00654 tmpText->setShadow(lineParser.getInt("SHADOW", defTxt.getShadow()));
00655
00656
00657
00658 if(lineParser.meter() == "TEXT")
00659 {
00660
00661 TextLabel *tmp = new TextLabel(this, x, y, w, h );
00662 tmp->setTextProps(tmpText);
00663 tmp->setValue(
00664 m_theme.locale()->translate(lineParser.getString("VALUE")));
00665
00666 QString name = lineParser.getString("NAME");
00667 if (!name.isEmpty())
00668 tmp->setName(name.ascii());
00669
00670 setSensor(lineParser, (Meter*)tmp);
00671 meterList->append ( tmp );
00672 }
00673
00674 if(lineParser.meter() == "CLICKMAP")
00675 {
00676 if( !hasMouseTracking() )
00677 setMouseTracking(true);
00678 ClickMap *tmp = new ClickMap(this, x, y, w, h);
00679 tmp->setTextProps( tmpText );
00680
00681 setSensor(lineParser, (Meter*)tmp);
00682
00683 clickList -> append(tmp);
00684 meterList->append( tmp );
00685
00686 }
00687
00688 if(lineParser.meter() == "RICHTEXT")
00689 {
00690 RichTextLabel *tmp = new RichTextLabel(this, x, y, w, h);
00691
00692 bool dUl = lineParser.getBoolean("UNDERLINE");
00693
00694 tmp->setText(
00695 m_theme.locale()->translate(lineParser.getString("VALUE").ascii()), dUl);
00696 tmp->setTextProps( tmpText );
00697 tmp->setWidth(w);
00698 tmp->setHeight(h);
00699
00700 QString name = lineParser.getString("NAME");
00701 if (!name.isEmpty())
00702 tmp->setName(name.ascii());
00703
00704 setSensor(lineParser, (Meter*)tmp);
00705 clickList -> append(tmp);
00706 meterList->append ( tmp );
00707 }
00708
00709 if(lineParser.meter() == "INPUT")
00710 {
00711 Input *tmp = new Input(this, x, y, w, h);
00712
00713 QString name = lineParser.getString("NAME");
00714 if (!name.isEmpty())
00715 tmp->setName(name.ascii());
00716
00717 tmp->setTextProps(tmpText);
00718 tmp->setValue(
00719 m_theme.locale()->translate(lineParser.getString("VALUE").ascii()));
00720
00721 meterList->append(tmp);
00722 passive = false;
00723 }
00724 }
00725
00726 if(lineParser.meter() == "BAR")
00727 {
00728 Bar *tmp = new Bar(this, x, y, w, h );
00729 tmp->setImage(lineParser.getString("PATH").ascii());
00730 tmp->setVertical(lineParser.getBoolean("VERTICAL"));
00731 tmp->setMax(lineParser.getInt("MAX", 100));
00732 tmp->setMin(lineParser.getInt("MIN", 0));
00733 tmp->setValue(lineParser.getInt("VALUE"));
00734 QString name = lineParser.getString("NAME");
00735 if (!name.isEmpty())
00736 tmp->setName(name.ascii());
00737 setSensor(lineParser, (Meter*)tmp );
00738 meterList->append ( tmp );
00739 }
00740
00741 if(lineParser.meter() == "GRAPH")
00742 {
00743 int points = lineParser.getInt("POINTS");
00744
00745 Graph *tmp = new Graph(this, x, y, w, h, points);
00746 tmp->setMax(lineParser.getInt("MAX", 100));
00747 tmp->setMin(lineParser.getInt("MIN", 0));
00748 QString name = lineParser.getString("NAME");
00749 if (!name.isEmpty())
00750 tmp->setName(name.ascii());
00751
00752 tmp->setColor(lineParser.getColor("COLOR"));
00753
00754 setSensor(lineParser, (Graph*)tmp);
00755 meterList->append ( tmp );
00756 }
00757 }
00758
00759 if(passive && !managed)
00760 {
00761
00762
00763 KWin::setType(winId(), NET::Dock);
00764 #if defined(KDE_MAKE_VERSION)
00765 #if KDE_VERSION >= KDE_MAKE_VERSION(3,1,9)
00766
00767 KWin::setState(winId(), NET::KeepBelow);
00768 #endif
00769 #endif
00770 }
00771
00772 m_theme.close();
00773 }
00774
00775 if( !foundKaramba )
00776 {
00777
00778
00779
00780 return false;
00781 }
00782 else
00783 {
00784 return true;
00785 }
00786 }
00787
00788 void karamba::start()
00789 {
00790 m_sysTimer = new QTimer(this);
00791
00792 connect(m_sysTimer, SIGNAL(timeout()), SLOT(step()));
00793
00794 m_sysTimer->start(m_interval);
00795
00796
00797 QTimer::singleShot( 0, this, SLOT(step()) );
00798
00799 if( !(onTop || managed) )
00800 lowerTimer.start();
00801 }
00802
00803 void karamba::makeActive()
00804 {
00805 KWin::setType(winId(), NET::Normal);
00806
00807 #if defined(KDE_MAKE_VERSION)
00808 #if KDE_VERSION >= KDE_MAKE_VERSION(3,1,9)
00809
00810 KWin::setState(winId(), NET::Modal);
00811 #endif
00812 #endif
00813 }
00814
00815 void karamba::makePassive()
00816 {
00817 if(managed)
00818 return;
00819
00820 QObject *meter;
00821 for (meter = meterList->first(); meter; meter = meterList->next())
00822 {
00823 if((meter)->isA("Input"))
00824 return;
00825 }
00826
00827
00828
00829 KWin::setType(winId(), NET::Dock);
00830 #if defined(KDE_MAKE_VERSION)
00831 #if KDE_VERSION >= KDE_MAKE_VERSION(3,1,9)
00832
00833 KWin::setState(winId(), NET::KeepBelow);
00834 #endif
00835 #endif
00836 }
00837
00838 void karamba::popupNotify(int)
00839 {
00840
00841 }
00842
00843 void karamba::reloadConfig()
00844 {
00845
00846 writeConfigData();
00847 if(m_theme.exists())
00848 {
00849 QFileInfo fileInfo( m_theme.file() );
00850 (new karamba(m_theme.file(), fileInfo.baseName(), true, m_instance))->show();
00851 }
00852 closeTheme(true);
00853 }
00854
00855 void karamba::closeTheme(bool reloading)
00856 {
00857 m_reloading = reloading;
00858 close();
00859 }
00860
00861 void karamba::killWidget()
00862 {
00863 closeTheme();
00864 }
00865
00866 void karamba::initPythonInterface()
00867 {
00868 pythonIface = new KarambaPython(m_theme, m_reloading);
00869 }
00870
00871 void karamba::editConfig()
00872 {
00873
00874 QFileInfo fileInfo( m_theme.file() );
00875 QString path;
00876
00877 if( fileInfo.isRelative() )
00878 {
00879 path = m_theme.path() + "/" + m_theme.file();
00880 }
00881 else
00882 {
00883 path = m_theme.file();
00884 }
00885
00886 KRun::runURL( KURL( path ), "text/plain" );
00887 }
00888
00889 void karamba::editScript()
00890 {
00891
00892 QFileInfo fileInfo( m_theme.file() );
00893 QString path;
00894
00895 if( fileInfo.isRelative() )
00896 {
00897 path = m_theme.path() + "/" + m_theme.name() + ".py";
00898 }
00899 else
00900 {
00901 path = QFileInfo(m_theme.file()).dirPath() + "/" + m_theme.name() + ".py";
00902 }
00903 KRun::runURL( KURL( path ), "text/plain" );
00904 }
00905
00906 QString karamba::findSensorFromMap(Sensor* sensor)
00907 {
00908
00909 QMap<QString,Sensor*>::ConstIterator it;
00910 QMap<QString,Sensor*>::ConstIterator end( sensorMap.end() );
00911 for ( it = sensorMap.begin(); it != end; ++it )
00912 {
00913 if (it.data() == sensor)
00914 return it.key();
00915 }
00916 return "";
00917 }
00918
00919 Sensor* karamba::findSensorFromList(Meter* meter)
00920 {
00921
00922 QObjectListIt it( *sensorList );
00923
00924 while ( it != 0 )
00925 {
00926 if (((Sensor*) *it)->hasMeter(meter))
00927 return ((Sensor*)*it);
00928 ++it;
00929 }
00930 return NULL;
00931 }
00932
00933 QString karamba::getSensor(Meter* meter)
00934 {
00935
00936 QString s;
00937 Sensor* sensor = findSensorFromList(meter);
00938 if (sensor)
00939 s = findSensorFromMap(sensor);
00940 return s;
00941 }
00942
00943 void karamba::deleteMeterFromSensors(Meter* meter)
00944 {
00945
00946 Sensor* sensor = findSensorFromList(meter);
00947
00948 if (sensor)
00949 {
00950 sensor->deleteMeter(meter);
00951 if (sensor->isEmpty())
00952 {
00953 QString s = findSensorFromMap(sensor);
00954 sensorMap.erase(s);
00955 sensorList->removeRef(sensor);
00956 }
00957 }
00958 }
00959
00960 void karamba::setSensor(const LineParser& lineParser, Meter* meter)
00961 {
00962
00963 Sensor* sensor = 0;
00964
00965 deleteMeterFromSensors(meter);
00966
00967 QString sens = lineParser.getString("SENSOR").upper();
00968
00969 if( sens == "CPU" )
00970 {
00971 QString cpuNbr = lineParser.getString("CPU");
00972 sensor = sensorMap["CPU"+cpuNbr];
00973 if (sensor == 0)
00974 {
00975 int interval = lineParser.getInt("INTERVAL");
00976 interval = (interval == 0)?1000:interval;
00977 sensor = ( sensorMap["CPU"+cpuNbr] = new CPUSensor( cpuNbr, interval ) );
00978 sensorList->append( sensor );
00979 }
00980 SensorParams *sp = new SensorParams(meter);
00981 sp->addParam("FORMAT",
00982 m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
00983 sp->addParam("DECIMALS",lineParser.getString("DECIMALS"));
00984
00985 sensor->addMeter(sp);
00986 sensor->setMaxValue(sp);
00987
00988 }
00989
00990 if( sens == "MEMORY" )
00991 {
00992 sensor = sensorMap["MEMORY"];
00993 if (sensor == 0)
00994 {
00995 int interval = lineParser.getInt("INTERVAL");
00996 interval = (interval == 0)?3000:interval;
00997 sensor = ( sensorMap["MEMORY"] = new MemSensor( interval ) );
00998 sensorList->append( sensor );
00999 }
01000 SensorParams *sp = new SensorParams(meter);
01001 sp->addParam("FORMAT",
01002 m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
01003
01004 sensor->addMeter(sp);
01005 sensor->setMaxValue(sp);
01006 }
01007
01008
01009 if( sens == "DISK" )
01010 {
01011 sensor = sensorMap["DISK"];
01012 if (sensor == 0)
01013 {
01014 int interval = lineParser.getInt("INTERVAL");
01015 interval = (interval == 0)?5000:interval;
01016 sensor = ( sensorMap["DISK"] = new DiskSensor( interval ) );
01017 connect( sensor, SIGNAL(initComplete()), this, SLOT(externalStep()) );
01018 sensorList->append( sensor );
01019 }
01020
01021 SensorParams *sp = new SensorParams(meter);
01022 QString mntPt = lineParser.getString("MOUNTPOINT");
01023 if( mntPt.isEmpty() )
01024 {
01025 mntPt = "/";
01026 }
01027
01028
01029 if( mntPt.length() > 1 && mntPt.endsWith("/") )
01030 {
01031 mntPt.remove( mntPt.length()-1, 1 );
01032 }
01033 sp->addParam("MOUNTPOINT",mntPt);
01034 sp->addParam("FORMAT",
01035 m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
01036 sensor->addMeter(sp);
01037 sensor->setMaxValue(sp);
01038 }
01039
01040 if( sens == "NETWORK")
01041 {
01042 int interval = lineParser.getInt("INTERVAL");
01043 interval = (interval == 0)?2000:interval;
01044 QString device = lineParser.getString("DEVICE");
01045 sensor = sensorMap["NETWORK"+device];
01046 if (sensor == 0)
01047 {
01048 sensor = ( sensorMap["NETWORK"+device] =
01049 new NetworkSensor(device, interval));
01050 sensorList->append( sensor );
01051 }
01052 SensorParams *sp = new SensorParams(meter);
01053 sp->addParam("FORMAT",
01054 m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
01055 sp->addParam("DECIMALS", lineParser.getString("DECIMALS"));
01056 sensor->addMeter(sp);
01057 }
01058
01059 if( sens == "UPTIME" )
01060 {
01061 sensor = sensorMap["UPTIME"];
01062 if (sensor == 0)
01063 {
01064 int interval = lineParser.getInt("INTERVAL");
01065 interval = (interval == 0)?60000:interval;
01066 sensor = ( sensorMap["UPTIME"] = new UptimeSensor( interval ));
01067 sensorList->append( sensor );
01068
01069 }
01070 SensorParams *sp = new SensorParams(meter);
01071 sp->addParam("FORMAT",
01072 m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
01073 sensor->addMeter(sp);
01074 }
01075
01076 if( sens == "SENSOR" )
01077 {
01078 sensor = sensorMap["SENSOR"];
01079 if (sensor == 0)
01080 {
01081 int interval = lineParser.getInt("INTERVAL");
01082 interval = (interval == 0)?30000:interval;
01083 sensor = (sensorMap["SENSOR"] = new SensorSensor(interval, tempUnit));
01084 sensorList->append( sensor );
01085 }
01086 SensorParams *sp = new SensorParams(meter);
01087 sp->addParam("FORMAT",
01088 m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
01089 sp->addParam("TYPE", lineParser.getString("TYPE"));
01090 sensor->addMeter(sp);
01091 }
01092
01093
01094 if( sens == "TEXTFILE" )
01095 {
01096 QString path = lineParser.getString("PATH");
01097 bool rdf = lineParser.getBoolean("RDF");
01098 sensor = sensorMap["TEXTFILE"+path];
01099 if (sensor == 0)
01100 {
01101 int interval = lineParser.getInt("INTERVAL");
01102 interval = ( interval == 0 )?60000:interval;
01103 QString encoding = lineParser.getString("ENCODING");
01104
01105 sensor = ( sensorMap["TEXTFILE"+path] =
01106 new TextFileSensor( path, rdf, interval, encoding ) );
01107 sensorList->append( sensor );
01108 }
01109 SensorParams *sp = new SensorParams(meter);
01110 sp->addParam("LINE",QString::number(lineParser.getInt("LINE")));
01111 sensor->addMeter(sp);
01112 }
01113
01114
01115 if( sens == "TIME")
01116 {
01117 sensor = sensorMap["DATE"];
01118 if (sensor == 0)
01119 {
01120 int interval = lineParser.getInt("INTERVAL");
01121 interval = (interval == 0)?60000:interval;
01122 sensor = ( sensorMap["DATE"] = new DateSensor( interval ) );
01123 sensorList->append( sensor );
01124 timeList->append( sensor );
01125 }
01126 SensorParams *sp = new SensorParams(meter);
01127 sp->addParam("FORMAT",
01128 m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
01129 sp->addParam("CALWIDTH",lineParser.getString("CALWIDTH"));
01130 sp->addParam("CALHEIGHT",lineParser.getString("CALHEIGHT"));
01131 sensor->addMeter(sp);
01132 }
01133
01134 #ifdef HAVE_XMMS
01135
01136 if( sens == "XMMS" )
01137 {
01138 sensor = sensorMap["XMMS"];
01139 if (sensor == 0)
01140 {
01141 int interval = lineParser.getInt("INTERVAL");
01142 interval = (interval == 0)?1000:interval;
01143 QString encoding = lineParser.getString("ENCODING");
01144
01145 sensor = ( sensorMap["XMMS"] = new XMMSSensor( interval, encoding ) );
01146 sensorList->append( sensor );
01147 }
01148 SensorParams *sp = new SensorParams(meter);
01149 sp->addParam("FORMAT",
01150 m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
01151 sensor->addMeter(sp);
01152 sensor->setMaxValue(sp);
01153 }
01154 #endif // HAVE_XMMS
01155
01156
01157 if( sens == "NOATUN" )
01158 {
01159 sensor = sensorMap["NOATUN"];
01160 if (sensor == 0)
01161 {
01162 int interval = lineParser.getInt("INTERVAL");
01163 interval = (interval == 0)?1000:interval;
01164 sensor = ( sensorMap["NOATUN"] = new NoatunSensor( interval, client ) );
01165 sensorList->append( sensor );
01166 }
01167 SensorParams *sp = new SensorParams(meter);
01168 sp->addParam("FORMAT",
01169 m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
01170 sensor->addMeter(sp);
01171 sensor->setMaxValue(sp);
01172 }
01173
01174 if( sens == "PROGRAM")
01175 {
01176 QString progName = lineParser.getString("PROGRAM");
01177 sensor = sensorMap["PROGRAM"+progName];
01178 if (sensor == 0)
01179 {
01180 int interval = lineParser.getInt("INTERVAL");
01181 interval = (interval == 0)?3600000:interval;
01182 QString encoding = lineParser.getString("ENCODING");
01183
01184 sensor = (sensorMap["PROGRAM"+progName] =
01185 new ProgramSensor( progName, interval, encoding ) );
01186 sensorList->append( sensor );
01187 }
01188 SensorParams *sp = new SensorParams(meter);
01189 sp->addParam( "LINE", QString::number(lineParser.getInt("LINE")));
01190 sp->addParam( "THEMAPATH", m_theme.path() );
01191 sensor->addMeter(sp);
01192 }
01193
01194 if( sens == "RSS" )
01195 {
01196 QString source = lineParser.getString("SOURCE");
01197 QString format =
01198 m_theme.locale()->translate(lineParser.getString("FORMAT").ascii());
01199
01200 sensor = sensorMap["RSS"+source];
01201 if (sensor == 0)
01202 {
01203 int interval = lineParser.getInt( "INTERVAL");
01204 interval = ( interval == 0 )?60000:interval;
01205 QString encoding = lineParser.getString("ENCODING");
01206
01207 sensor = ( sensorMap["RSS"+source] =
01208 new RssSensor( source, interval, format, encoding ) );
01209 sensorList->append( sensor );
01210 }
01211 SensorParams *sp = new SensorParams(meter);
01212 sp->addParam("SOURCE",lineParser.getString("SOURCE"));
01213 sensor->addMeter(sp);
01214 }
01215
01216 if (sensor != 0)
01217 {
01218 QTimer::singleShot( 0, sensor, SLOT(update()) );
01219 sensor->start();
01220 }
01221 }
01222
01223 void karamba::slotFileChanged( const QString & file)
01224 {
01225
01226
01227 QString pythonFile = m_theme.path() + "/" + m_theme.pythonModule() + ".py";
01228
01229 if(file == m_theme.file() || file == pythonFile)
01230 reloadConfig();
01231 }
01232
01233 void karamba::passMenuOptionChanged(QString key, bool value)
01234 {
01235
01236 if (pythonIface && pythonIface->isExtensionLoaded())
01237 pythonIface->menuOptionChanged(this, key, value);
01238 }
01239
01240 void karamba::setIncomingData(QString theme, QString obj)
01241 {
01242 KarambaApplication* app = (KarambaApplication*)qApp;
01243
01244 kdDebug() << "karamba::setIncomingData " << theme << obj << endl;
01245
01246
01247
01248
01249
01250
01251
01252 DCOPClient *c = kapp->dcopClient();
01253 if (!c->isAttached())
01254 c->attach();
01255
01256 if(app->dcopStub())
01257 app->dcopStub()->setIncomingData(theme, obj);
01258 }
01259
01260 void karamba::callTheme(QString theme, QString txt)
01261 {
01262 KarambaApplication* app = (KarambaApplication*)qApp;
01263 kdDebug() << "karamba::callTheme " << theme << txt << endl;
01264
01265
01266
01267
01268
01269
01270
01271
01272 DCOPClient *c = kapp->dcopClient();
01273 if (!c->isAttached())
01274 c->attach();
01275
01276 if(app->dcopStub())
01277 app->dcopStub()->themeNotify(theme, txt);
01278 }
01279
01280 void karamba::themeNotify(QString theme, QString txt)
01281 {
01282 kdDebug() << "karamba::themeNotify" << theme << txt << endl;
01283 if (pythonIface->isExtensionLoaded())
01284 {
01285 pythonIface->themeNotify(this, theme.ascii(), txt.ascii());
01286 }
01287 }
01288
01289 void karamba::meterClicked(QMouseEvent* e, Meter* meter)
01290 {
01291
01292 if (pythonIface && pythonIface->isExtensionLoaded() && haveUpdated)
01293 {
01294 int button = 0;
01295
01296 if( e->button() == Qt::LeftButton )
01297 button = 1;
01298 else if( e->button() == Qt::MidButton )
01299 button = 2;
01300 else if( e->button() == Qt::RightButton )
01301 button = 3;
01302
01303 if (RichTextLabel* richText = dynamic_cast<RichTextLabel*>(meter))
01304 {
01305 pythonIface->meterClicked(this, richText->anchorAt(e->x(), e->y()),
01306 button);
01307 }
01308 else
01309 {
01310 pythonIface->meterClicked(this, meter, button);
01311 }
01312 }
01313 }
01314
01315 void karamba::changeInterval(int interval)
01316 {
01317 if (m_sysTimer != NULL)
01318 m_sysTimer->changeInterval(interval);
01319 }
01320
01321 void karamba::passClick(QMouseEvent *e)
01322 {
01323
01324 QObjectListIt it2( *timeList );
01325 while ( it2 != 0 )
01326 {
01327 (( DateSensor* ) *it2)->toggleCalendar( e );
01328 ++it2;
01329 }
01330
01331
01332
01333
01334 QObjectList clickListTmp(*clickList);
01335 QObjectListIt it(clickListTmp);
01336 while (it != 0)
01337 {
01338 Meter* meter = (Meter*)(*it);
01339
01340 if (clickList->containsRef(meter) && meter->click(e))
01341 {
01342
01343 meterClicked(e, meter);
01344 }
01345 ++it;
01346 }
01347
01348
01349 if (pythonIface && pythonIface->isExtensionLoaded() && haveUpdated)
01350 {
01351 int button = 0;
01352
01353 if( e->button() == Qt::LeftButton )
01354 button = 1;
01355 else if( e->button() == Qt::MidButton )
01356 button = 2;
01357 else if( e->button() == Qt::RightButton )
01358 button = 3;
01359
01360 pythonIface->widgetClicked(this, e->x(), e->y(), button);
01361 }
01362 }
01363
01364 void karamba::passWheelClick( QWheelEvent *e )
01365 {
01366
01367
01368 if (pythonIface && pythonIface->isExtensionLoaded() && haveUpdated)
01369 {
01370 int button = 0;
01371
01372 if( e->delta() > 0 )
01373 button = 4;
01374 else
01375 button = 5;
01376
01377 pythonIface->widgetClicked(this, e->x(), e->y(), button);
01378 }
01379 }
01380
01381 void karamba::management_popup( void )
01382 {
01383 kpop->popup(QCursor::pos());
01384 }
01385
01386 void karamba::mousePressEvent( QMouseEvent *e )
01387 {
01388
01389 if( e->button() == RightButton && !want_right_button )
01390 {
01391 management_popup();
01392 }
01393 else
01394 {
01395 clickPos = e->pos();
01396 if( toggleLocked -> isChecked() )
01397 passClick( e );
01398 if( !(onTop || managed))
01399 KWin::lowerWindow( winId() );
01400 }
01401 }
01402
01403 void karamba::wheelEvent( QWheelEvent *e )
01404 {
01405
01406 passWheelClick( e );
01407 }
01408
01409 void karamba::mouseReleaseEvent( QMouseEvent *e )
01410 {
01411
01412 clickPos = e->pos();
01413 }
01414
01415 void karamba::mouseDoubleClickEvent( QMouseEvent *e )
01416 {
01417
01418 if( !toggleLocked -> isChecked() )
01419 {
01420 passClick( e );
01421 }
01422 }
01423
01424 void karamba::keyPressEvent(QKeyEvent *e)
01425 {
01426
01427 keyPressed(e->text(), 0);
01428 }
01429
01430 void karamba::keyPressed(const QString& s, const Meter* meter)
01431 {
01432 if (pythonIface && pythonIface->isExtensionLoaded())
01433 pythonIface->keyPressed(this, meter, s);
01434 }
01435
01436 void karamba::mouseMoveEvent( QMouseEvent *e )
01437 {
01438
01439 if( e->state() != 0 && e->state() < 16 && !toggleLocked -> isChecked() )
01440 {
01441 move( e->globalPos() - clickPos );
01442 }
01443 else
01444 {
01445
01446 QObjectListIt it(*clickList);
01447 bool insideArea = false;
01448
01449 while (it != 0)
01450 {
01451 insideArea = ((Meter*)(*it)) -> insideActiveArea(e -> x(), e ->y());
01452 if (insideArea)
01453 {
01454 break;
01455 }
01456 ++it;
01457 }
01458
01459 if(insideArea)
01460 {
01461 if( cursor().shape() != PointingHandCursor )
01462 setCursor( PointingHandCursor );
01463 }
01464 else
01465 {
01466 if( cursor().shape() != ArrowCursor )
01467 setCursor( ArrowCursor );
01468 }
01469
01470 QObjectListIt image_it( *imageList);
01471 while ( image_it != 0 )
01472 {
01473 ((ImageLabel*) *image_it)->rolloverImage(e);
01474 ++image_it;
01475 }
01476 }
01477
01478 if (pythonIface && pythonIface->isExtensionLoaded())
01479 {
01480 int button = 0;
01481
01482
01483
01484
01485
01486 if( e->state() == LeftButton)
01487 button = 1;
01488
01489 else if( e->state() == MidButton )
01490 button = 2;
01491
01492 else if( e->state() == RightButton )
01493 button = 3;
01494
01495 pythonIface->widgetMouseMoved(this, e->x(), e->y(), button);
01496 }
01497 }
01498
01499 void karamba::closeEvent ( QCloseEvent * qc)
01500 {
01501
01502 qc->accept();
01503
01504
01505 }
01506
01507 void karamba::paintEvent ( QPaintEvent *e)
01508 {
01509
01510 if(pm.width() == 0)
01511 return;
01512 if( !(onTop || managed))
01513 {
01514 if( lowerTimer.elapsed() > 100 )
01515 {
01516 KWin::lowerWindow( winId() );
01517 lowerTimer.restart();
01518 }
01519 }
01520 QRect rect = e->rect();
01521 bitBlt(this,rect.topLeft(),&pm,rect,Qt::CopyROP);
01522 }
01523
01524 void karamba::updateSensors()
01525 {
01526
01527 QObjectListIt it( *sensorList );
01528 while ( it != 0 )
01529 {
01530 ((Sensor*) *it)->update();
01531 ++it;
01532 }
01533 QTimer::singleShot( 500, this, SLOT(step()) );
01534 }
01535
01536 void karamba::updateBackground(KSharedPixmap* kpm)
01537 {
01538
01539
01540
01541
01542 if( !themeStarted )
01543 {
01544 themeStarted = true;
01545 start();
01546 }
01547 background = QPixmap(*kpm);
01548
01549 QPixmap buffer = QPixmap(size());
01550
01551 pm = QPixmap(size());
01552 buffer.fill(Qt::black);
01553
01554 QObjectListIt it( *imageList );
01555 p.begin(&buffer);
01556 bitBlt(&buffer,0,0,&background,0,Qt::CopyROP);
01557
01558 while ( it != 0 )
01559 {
01560 if (((ImageLabel*) *it)->background == 1)
01561 {
01562 ((ImageLabel*) *it)->mUpdate(&p, 1);
01563 }
01564 ++it;
01565 }
01566 p.end();
01567
01568 bitBlt(&pm,0,0,&buffer,0,Qt::CopyROP);
01569 background = pm;
01570
01571 QPixmap buffer2 = QPixmap(size());
01572
01573 pm = QPixmap(size());
01574 buffer2.fill(Qt::black);
01575
01576 QObjectListIt it2( *meterList );
01577 p.begin(&buffer2);
01578 bitBlt(&buffer2,0,0,&background,0,Qt::CopyROP);
01579
01580 while ( it2 != 0 )
01581 {
01582 ((Meter*) *it2)->mUpdate(&p);
01583 ++it2;
01584 }
01585 p.end();
01586
01587 bitBlt(&pm,0,0,&buffer2,0,Qt::CopyROP);
01588 if (systray != 0)
01589 {
01590 systray->updateBackgroundPixmap(buffer2);
01591 }
01592 repaint();
01593 }
01594
01595 void karamba::currentDesktopChanged( int i )
01596 {
01597
01598 kroot->repaint( true );
01599 if (pythonIface && pythonIface->isExtensionLoaded())
01600 pythonIface->desktopChanged(this, i);
01601 }
01602
01603 void karamba::currentWallpaperChanged(int i )
01604 {
01605
01606 kroot->repaint( true );
01607 if (pythonIface && pythonIface->isExtensionLoaded())
01608 pythonIface->wallpaperChanged(this, i);
01609 }
01610
01611 void karamba::externalStep()
01612 {
01613
01614 if (widgetUpdate)
01615 {
01616 QPixmap buffer = QPixmap(size());
01617
01618 pm = QPixmap(size());
01619 buffer.fill(Qt::black);
01620
01621 QObjectListIt it( *meterList );
01622 p.begin(&buffer);
01623 bitBlt(&buffer,0,0,&background,0,Qt::CopyROP);
01624
01625 while ( it != 0 )
01626 {
01627 ((Meter*) *it)->mUpdate(&p);
01628 ++it;
01629 }
01630 p.end();
01631
01632 bitBlt(&pm,0,0,&buffer,0,Qt::CopyROP);
01633 repaint();
01634 }
01635 }
01636
01637 void karamba::step()
01638 {
01639
01640 if (widgetUpdate && haveUpdated)
01641 {
01642 pm = QPixmap(size());
01643 QPixmap buffer = QPixmap(size());
01644 buffer.fill(Qt::black);
01645
01646 QObjectListIt it( *meterList );
01647 p.begin(&buffer);
01648
01649 bitBlt(&buffer,0,0,&background,0,Qt::CopyROP);
01650
01651 while (it != 0)
01652 {
01653 ((Meter*) *it)->mUpdate(&p);
01654 ++it;
01655 }
01656 p.end();
01657
01658 bitBlt(&pm,0,0,&buffer,0,Qt::CopyROP);
01659 update();
01660 }
01661
01662 if (pythonIface && pythonIface->isExtensionLoaded())
01663 {
01664 if (haveUpdated == 0)
01665 pythonIface->initWidget(this);
01666 else
01667 pythonIface->widgetUpdated(this);
01668 }
01669
01670 if (haveUpdated == 0)
01671 haveUpdated = 1;
01672 }
01673
01674 void karamba::widgetClosed()
01675 {
01676
01677 if (pythonIface && pythonIface->isExtensionLoaded())
01678 pythonIface->widgetClosed(this);
01679 }
01680
01681 void karamba::slotToggleLocked()
01682 {
01683
01684 if(toggleLocked->isChecked())
01685 {
01686 toggleLocked->setIconSet(SmallIconSet("lock"));
01687 }
01688 else
01689 {
01690 toggleLocked->setIconSet(SmallIconSet("move"));
01691 }
01692 }
01693
01694 void karamba::slotToggleFastTransforms()
01695 {
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709 }
01710
01711
01712 bool karamba::useSmoothTransforms()
01713 {
01714
01715 return !toggleFastTransforms -> isChecked();
01716 }
01717
01718 void karamba::writeConfigData()
01719 {
01720
01721 config -> setGroup("internal");
01722 config -> writeEntry("lockedPosition", toggleLocked -> isChecked() );
01723 config -> writeEntry("fastTransforms", toggleFastTransforms -> isChecked() );
01724 config -> writeEntry("desktop", desktop );
01725 config -> setGroup("theme");
01726
01727 config -> writeEntry("widgetPosX", x());
01728 config -> writeEntry("widgetPosY", y());
01729
01730 config -> writeEntry("widgetWidth", width());
01731 config -> writeEntry("widgetHeight", height());
01732
01733
01734 config -> sync();
01735
01736
01737 }
01738
01739 void karamba::slotToggleConfigOption(QString key, bool value)
01740 {
01741
01742 config -> setGroup("config menu");
01743 config -> writeEntry(key, value);
01744 passMenuOptionChanged(key, value);
01745 }
01746
01747 void karamba::addMenuConfigOption(QString key, QString name)
01748 {
01749
01750 kpop -> setItemEnabled(THEMECONF, true);
01751
01752 SignalBridge* action = new SignalBridge(this, key, menuAccColl);
01753 KToggleAction* confItem = new KToggleAction (name, KShortcut::null(),
01754 action, SLOT(receive()),
01755 menuAccColl, key.ascii());
01756 confItem -> setName(key.ascii());
01757
01758 menuAccColl -> insert(confItem);
01759
01760 connect(action, SIGNAL( enabled(QString, bool) ),
01761 this, SLOT( slotToggleConfigOption(QString, bool) ));
01762
01763 config -> setGroup("config menu");
01764 confItem -> setChecked(config -> readBoolEntry(key));
01765
01766 confItem -> plug(themeConfMenu);
01767
01768 numberOfConfMenuItems++;
01769 }
01770
01771 bool karamba::setMenuConfigOption(QString key, bool value)
01772 {
01773
01774 KToggleAction* menuAction = ((KToggleAction*)menuAccColl -> action(key.ascii()));
01775 if (menuAction == NULL)
01776 {
01777 qWarning("Menu action %s not found.", key.ascii());
01778 return false;
01779 }
01780 else
01781 {
01782 menuAction -> setChecked(value);
01783 return true;
01784 }
01785 }
01786
01787 bool karamba::readMenuConfigOption(QString key)
01788 {
01789
01790 KToggleAction* menuAction = ((KToggleAction*)menuAccColl -> action(key.ascii()));
01791 if (menuAction == NULL)
01792 {
01793 qWarning("Menu action %s not found.", key.ascii());
01794 return false;
01795 }
01796 else
01797 {
01798 return menuAction -> isChecked();
01799 }
01800 }
01801
01802 void karamba::passMenuItemClicked(int id)
01803 {
01804
01805
01806 if (pythonIface && pythonIface->isExtensionLoaded())
01807 {
01808 KPopupMenu* menu = 0;
01809 for(int i = 0; i < (int)menuList->count(); i++)
01810 {
01811 KPopupMenu* tmp;
01812 if(i==0)
01813 {
01814 tmp = (KPopupMenu*) menuList->first();
01815 }
01816 else
01817 {
01818 tmp = (KPopupMenu*) menuList->next();
01819 }
01820 if(tmp != 0)
01821 {
01822 if(tmp->isItemVisible(id))
01823 {
01824 menu = tmp;
01825 break;
01826 }
01827 }
01828 }
01829 pythonIface->menuItemClicked(this, menu, id);
01830 }
01831 }
01832
01833 void karamba::activeTaskChanged(Task* t)
01834 {
01835
01836
01837 if (pythonIface && pythonIface->isExtensionLoaded())
01838 pythonIface->activeTaskChanged(this, t);
01839 }
01840
01841 void karamba::taskAdded(Task* t)
01842 {
01843
01844
01845 if (pythonIface && pythonIface->isExtensionLoaded())
01846 pythonIface->taskAdded(this, t);
01847 }
01848
01849 void karamba::taskRemoved(Task* t)
01850 {
01851
01852
01853 if (pythonIface && pythonIface->isExtensionLoaded())
01854 pythonIface->taskRemoved(this, t);
01855 }
01856
01857 void karamba::startupAdded(Startup* t)
01858 {
01859
01860
01861 if (pythonIface && pythonIface->isExtensionLoaded())
01862 pythonIface->startupAdded(this, t);
01863 }
01864
01865 void karamba::startupRemoved(Startup* t)
01866 {
01867
01868
01869 if (pythonIface && pythonIface->isExtensionLoaded())
01870 pythonIface->startupRemoved(this, t);
01871 }
01872
01873 void karamba::processExited (KProcess* proc)
01874 {
01875
01876 if (pythonIface && pythonIface->isExtensionLoaded())
01877 pythonIface->commandFinished(this, (int)proc->pid());
01878 }
01879
01880 void karamba::receivedStdout (KProcess *proc, char *buffer, int)
01881 {
01882
01883
01884 if (pythonIface && pythonIface->isExtensionLoaded())
01885 pythonIface->commandOutput(this, (int)proc->pid(), buffer);
01886 }
01887
01888
01889 void karamba::saveProperties(KConfig* config)
01890 {
01891
01892 config->setGroup("session");
01893 config->writeEntry("theme", m_theme.file());
01894 writeConfigData();
01895 }
01896
01897
01898 void karamba::readProperties(KConfig* config)
01899 {
01900
01901 config->setGroup("session");
01902 QString atheme = config->readEntry("theme");
01903 }
01904
01905
01906 void karamba::dragEnterEvent(QDragEnterEvent* event)
01907 {
01908
01909 event->accept(QTextDrag::canDecode(event));
01910 }
01911
01912
01913 void karamba::dropEvent(QDropEvent* event)
01914 {
01915
01916 QString text;
01917
01918 if ( QTextDrag::decode(event, text) )
01919 {
01920
01921 if (pythonIface && pythonIface->isExtensionLoaded())
01922 {
01923 const QPoint &p = event->pos();
01924 pythonIface->itemDropped(this, text, p.x(), p.y());
01925 }
01926 }
01927 }
01928
01929 void karamba::toDesktop(int id, int menuid)
01930 {
01931
01932 int i;
01933
01934 desktop = id;
01935 for (i=0; ; i++)
01936 {
01937 int mid = toDesktopMenu->idAt(i);
01938 if (mid == -1)
01939 break;
01940
01941 toDesktopMenu->setItemChecked(mid, false);
01942 }
01943 toDesktopMenu->setItemChecked(menuid, true);
01944
01945 if (desktop)
01946 info->setDesktop( desktop);
01947 else
01948 info->setDesktop( NETWinInfo::OnAllDesktops );
01949 }
01950
01951 void karamba::systrayUpdated()
01952 {
01953
01954 if (pythonIface && pythonIface->isExtensionLoaded())
01955 pythonIface->systrayUpdated(this);
01956 }
01957
01958 void karamba::toggleWidgetUpdate( bool b)
01959 {
01960
01961 if (pythonIface && pythonIface->isExtensionLoaded())
01962 widgetUpdate = b;
01963 }
01964
01965 SignalBridge::SignalBridge(QObject* parent, QString name, KActionCollection* ac)
01966 : QObject(parent, name.ascii()), collection(ac)
01967 {
01968 setName(name.ascii());
01969 }
01970
01971 void SignalBridge::receive()
01972 {
01973 emit enabled(name(), ((KToggleAction*)collection -> action(name())) ->
01974 isChecked());
01975 }
01976
01977 DesktopChangeSlot::DesktopChangeSlot(QObject *parent, int id)
01978 : QObject(parent, "")
01979 {
01980 desktopid = id;
01981 }
01982
01983 void DesktopChangeSlot::receive()
01984 {
01985 karamba *k = (karamba *)parent();
01986
01987
01988
01989 k->toDesktop(desktopid, menuid);
01990 }
01991
01992 void DesktopChangeSlot::setMenuId(int id)
01993 {
01994 menuid = id;
01995 }
01996
01997 int DesktopChangeSlot::menuId()
01998 {
01999 return menuid;
02000 }
02001
02002 void karamba::showMenuExtension()
02003 {
02004 kglobal = new KPopupMenu(this);
02005
02006 trayMenuToggleId = kglobal->insertItem(SmallIconSet("superkaramba"),
02007 i18n("Show System Tray Icon"), this,
02008 SLOT(slotToggleSystemTray()),
02009 CTRL+Key_S);
02010
02011 trayMenuThemeId = kglobal->insertItem(SmallIconSet("knewstuff"),
02012 i18n("&Manage Themes..."), this,
02013 SLOT(slotShowTheme()), CTRL+Key_M);
02014
02015 trayMenuQuitId = kglobal->insertItem(SmallIconSet("exit"),
02016 i18n("&Quit SuperKaramba"), this,
02017 SLOT(slotQuit()), CTRL+Key_Q);
02018
02019 kglobal->polish();
02020
02021 trayMenuSeperatorId = kpop->insertSeparator();
02022 kpop->insertItem("SuperKaramba", kglobal);
02023 }
02024
02025 void karamba::hideMenuExtension()
02026 {
02027 if(kglobal)
02028 {
02029 kpop->removeItem(trayMenuSeperatorId);
02030 kglobal->removeItem(trayMenuToggleId);
02031 kglobal->removeItem(trayMenuThemeId);
02032 kglobal->removeItem(trayMenuQuitId);
02033
02034 delete kglobal;
02035 kglobal = 0;
02036 }
02037 }
02038
02039 void karamba::slotToggleSystemTray()
02040 {
02041 karambaApp->globalHideSysTray(false);
02042 }
02043
02044 void karamba::slotQuit()
02045 {
02046 karambaApp->globalQuitSuperKaramba();
02047 }
02048
02049 void karamba::slotShowTheme()
02050 {
02051 karambaApp->globalShowThemeDialog();
02052 }
02053
02054 void karamba::setAlwaysOnTop(bool stay)
02055 {
02056 if(stay)
02057 {
02058 onTop = true;
02059 KWin::setState( winId(), NET::KeepAbove );
02060 }
02061 else
02062 {
02063 onTop = false;
02064 KWin::setState( winId(), NET::KeepBelow );
02065 }
02066 }
02067
02068 #include "karamba.moc"