• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeutils API Reference
  • KDE Home
  • Contact Us
 

superkaramba

  • sources
  • kde-4.12
  • kdeutils
  • superkaramba
  • src
karamba.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
3  * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
4  * Copyright (C) 2004,2005 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
5  * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
6  * Copyright (c) 2007 Alexander Wiedenbruch <mail@wiedenbruch.de>
7  *
8  * This file is part of SuperKaramba.
9  *
10  * SuperKaramba is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * SuperKaramba is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with SuperKaramba; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  ****************************************************************************/
24 
25 #include "karamba.h"
26 #include "karamba.moc"
27 
28 #include <QGraphicsView>
29 #include <QGraphicsScene>
30 #include <QStack>
31 #include <QDesktopWidget>
32 #include <QApplication>
33 #include <QX11Info>
34 #include <QBitmap>
35 #include <QSignalMapper>
36 
37 #include <KDebug>
38 #include <KWindowSystem>
39 #include <KIcon>
40 #include <KLocale>
41 #include <KDirWatch>
42 #include <KMenu>
43 #include <KConfig>
44 #include <KToggleAction>
45 #include <KCmdLineArgs>
46 
47 #include "config-superkaramba.h"
48 
49 #include "karambamanager.h"
50 
51 #include "meters/textfield.h"
52 #include "meters/richtextlabel.h"
53 #include "meters/bar.h"
54 #include "meters/graph.h"
55 #include "meters/textlabel.h"
56 #include "meters/input.h"
57 #include "meters/imagelabel.h"
58 #include "meters/clickarea.h"
59 #include "meters/clickmap.h"
60 
61 #include "sensors/sensor.h"
62 #include "sensors/mem.h"
63 #include "sensors/disk.h"
64 #include "sensors/network.h"
65 #include "sensors/date.h"
66 #include "sensors/program.h"
67 #include "sensors/sensorparams.h"
68 #include "sensors/textfile.h"
69 #include "sensors/rss.h"
70 #include "sensors/uptime.h"
71 #include "sensors/lmsensor.h"
72 #include "sensors/cpu.h"
73 
74 #ifdef PLASMASENSOR_ENABLED
75  #include "sensors/plasmaengine.h"
76 #endif
77 
78 #include "python/karamba.h"
79 
80 #include "karambaapp.h"
81 #include "systemtray.h"
82 #include "karambainterface.h"
83 #include "mainwidget.h"
84 #include "lineparser.h"
85 #include "themelocale.h"
86 #include "superkarambasettings.h"
87 
88 extern "C" {
89  KDE_EXPORT QGraphicsItemGroup* startKaramba(const KUrl &theme, QGraphicsView *view)
90  {
91  return new Karamba(theme, view);
92  }
93 }
94 
95 class Karamba::Private
96 {
97  public:
98  ThemeFile theme;
99  QGraphicsScene *scene;
100  QGraphicsView *view;
101 
102  KWindowSystem *KWinModule;
103 
104  bool useKross;
105 #ifdef PYTHON_INCLUDE_PATH
106  KarambaPython *python;
107 #endif
108  KarambaInterface *interface;
109 
110  bool foundKaramba;
111  bool onTop;
112  bool managed;
113 
114  NETWinInfo *info;
115 
116  QRect size;
117 
118  u_int desktop;
119 
120  u_int interval;
121 
122  char tempUnit;
123 
124  TextField *defaultTextField;
125 
126  int scaleStep;
127  bool showMenu;
128 
129  QList<Sensor*> sensorList;
130  QMap<QString, Sensor*> sensorMap;
131 
132  KMenu *popupMenu;
133  KToggleAction *toggleLocked;
134  KAction* reloadTheme;
135  KMenu *themeConfMenu;
136  KMenu *toDesktopMenu;
137  KMenu *globalMenu;
138 
139  QTimer stepTimer;
140 
141  QSignalMapper *signalMapperConfig;
142  QSignalMapper *signalMapperDesktop;
143 
144  KConfig *config;
145 
146  int instance;
147 
148  QList<KMenu*> menuList;
149 
150  QString prettyName;
151 
152  QString storedData;
153 
154  double updateTime;
155 
156  bool wantRightButton;
157 
158  QPoint mouseClickPos;
159 
160  bool globalView;
161 
162  bool subTheme;
163 
164  QPoint themeCenter;
165 
166  QGraphicsItemAnimation *animation;
167  QTimeLine *timer;
168 
169  //OrgKdeKdesktopBackgroundInterface* backgroundInterface;
170 
171  bool useFancyEffects;
172  bool useAntialiasing;
173 
174  bool errorInInit;
175 
176  K3Process *currProcess;
177  Systemtray *systray;
178 
179  Private(QGraphicsView *view, int instance, bool subTheme) :
180  scene(view ? view->scene() : 0),
181  view(view),
182  KWinModule(0),
183  useKross(true),
184 #ifdef PYTHON_INCLUDE_PATH
185  python(0),
186 #endif
187  interface(0),
188  foundKaramba(false),
189  onTop(false),
190  managed(false),
191  info(0),
192  desktop(0),
193  interval(0),
194  tempUnit('C'),
195  defaultTextField(0),
196  scaleStep(-1),
197  showMenu(false),
198  popupMenu(0),
199  toggleLocked(0),
200  reloadTheme(0),
201  themeConfMenu(0),
202  toDesktopMenu(0),
203  globalMenu(0),
204  signalMapperConfig(0),
205  signalMapperDesktop(0),
206  config(0),
207  instance(instance),
208  storedData(""),
209  wantRightButton(false),
210  globalView(view ? true : false),
211  subTheme(subTheme),
212  animation(0),
213  timer(0),
214  //backgroundInterface(0),
215  useFancyEffects(true),
216  useAntialiasing(true),
217  errorInInit(false),
218  currProcess(0),
219  systray(0)
220  {
221  }
222 
223  ~Private()
224  {
225  delete config;
226 
227  delete info;
228 
229 #ifdef PYTHON_INCLUDE_PATH
230  if (python) {
231  delete python;
232  }
233 #endif
234 
235  if (interface) {
236  delete interface;
237  }
238 
239  qDeleteAll(sensorList);
240  sensorList.clear();
241 
242  delete toDesktopMenu;
243  delete themeConfMenu,
244  delete toggleLocked;
245  delete reloadTheme;
246  delete popupMenu;
247 
248  delete animation;
249  delete timer;
250 
251  //delete backgroundInterface;
252 
253  if (!globalView) {
254  delete view;
255  delete scene;
256  }
257 
258  delete currProcess;
259  delete systray;
260  }
261 };
262 
263 Karamba::Karamba(const KUrl &themeFile, QGraphicsView *view, int instance, bool subTheme, const QPoint &startPos, bool reload, bool startkaramba)
264  : QObject(),
265  QGraphicsItemGroup(0, view ? view->scene() : 0),
266  d(new Private(view, instance, subTheme))
267 {
268 #ifdef PYTHON_INCLUDE_PATH
269  if (!d->globalView) {
270  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
271  if (args->isSet("usefallback")) {
272  d->useKross = false;
273  }
274  }
275 #endif
276 
277  QString environment = getenv("SK_FANCY");
278  if (!environment.compare("false", Qt::CaseInsensitive)) {
279  d->useFancyEffects = false;
280  }
281 
282  environment = getenv("SK_AA");
283  if (!environment.compare("false", Qt::CaseInsensitive)) {
284  d->useAntialiasing = false;
285  }
286 
287  if (!d->globalView) {
288  d->scene = new QGraphicsScene;
289  d->scene->addItem(this);
290  d->view = new MainWidget(d->scene);
291 
292  if (d->useAntialiasing) {
293  d->view->setRenderHints(QPainter::Antialiasing |
294  QPainter::SmoothPixmapTransform);
295  }
296 
297  d->scene->setItemIndexMethod(QGraphicsScene::NoIndex);
298 
299  d->view->show();
300  }
301 
302  hide();
303 
304  if (!d->globalView) {
305  d->view->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
306  }
307 
308  if (!d->theme.set(themeFile)) {
309  kDebug() << "Could not load theme file" ;
310  d->errorInInit = true;
311  if (startkaramba)
312  QTimer::singleShot(0, this, SLOT(startKaramba()));
313  return;
314  }
315 
316  KDirWatch *dirWatch = KDirWatch::self();
317  connect(dirWatch, SIGNAL(dirty(QString)),
318  SLOT(slotFileChanged(QString)));
319 
320  if (!dirWatch->contains(d->theme.file()))
321  dirWatch->addFile(d->theme.file());
322 
323  if (!d->theme.isZipTheme() && d->theme.scriptModuleExists()) {
324  QString scriptFile = d->theme.path() + '/' + d->theme.scriptModule();
325  if (!dirWatch->contains(scriptFile))
326  dirWatch->addFile(scriptFile);
327  }
328 
329  if (d->prettyName.isEmpty())
330  d->prettyName = QString("%1 - %2").arg(d->theme.name()).arg(d->instance);
331 
332  setObjectName( QLatin1String("karamba - " ) + d->prettyName);
333 
334  if (!d->globalView) {
335  d->info = new NETWinInfo(QX11Info::display(), d->view->winId(),
336  QX11Info::appRootWindow(), NET::WMState);
337  }
338 
339  d->defaultTextField = new TextField();
340 
341  d->KWinModule = KWindowSystem::self();
342  connect(d->KWinModule, SIGNAL(currentDesktopChanged(int)), this,
343  SLOT(currentDesktopChanged(int)));
344 //TODO port it
345 
346 #if 0
347  d->backgroundInterface = new org::kde::kdesktop::Background("org.kde.kdesktop", "/Background", QDBusConnection::sessionBus());
348  connect(d->backgroundInterface, SIGNAL(backgroundChanged(int)), this,
349  SLOT(currentWallpaperChanged(int)));
350 #endif
351  setAcceptsHoverEvents(true);
352 
353  // Setup of the Task Manager Callbacks
354  connect(TaskManager::self(), SIGNAL(activeTaskChanged(Task::TaskPtr)), this,
355  SLOT(activeTaskChanged(Task::TaskPtr)));
356  connect(TaskManager::self(), SIGNAL(taskAdded(Task::TaskPtr)), this,
357  SLOT(taskAdded(Task::TaskPtr)));
358  connect(TaskManager::self(), SIGNAL(taskRemoved(Task::TaskPtr)), this,
359  SLOT(taskRemoved(Task::TaskPtr)));
360  connect(TaskManager::self(), SIGNAL(startupAdded(Startup::StartupPtr)), this,
361  SLOT(startupAdded(Startup::StartupPtr)));
362  connect(TaskManager::self(), SIGNAL(startupRemoved(Startup::StartupPtr)), this,
363  SLOT(startupRemoved(Startup::StartupPtr)));
364 
365  d->signalMapperConfig = new QSignalMapper(this);
366  connect(d->signalMapperConfig, SIGNAL(mapped(QObject*)), this,
367  SLOT(slotToggleConfigOption(QObject*)));
368 
369  d->signalMapperDesktop = new QSignalMapper(this);
370  connect(d->signalMapperDesktop, SIGNAL(mapped(int)), this,
371  SLOT(slotDesktopChanged(int)));
372 
373  preparePopupMenu();
374 
375  parseConfig();
376 
377  QString instanceString;
378  if (d->instance > 1)
379  instanceString = QString("-%1").arg(d->instance);
380 
381  QString cfg = QDir::home().absolutePath() + "/.superkaramba/"
382  + d->theme.id() + instanceString + ".rc";
383  kDebug() << cfg ;
384 
385  QFile themeConfigFile(cfg);
386  // Tests if config file Exists
387  if (!QFileInfo(themeConfigFile).exists()) {
388  // Create config file
389  themeConfigFile.open(QIODevice::ReadWrite);
390  themeConfigFile.close();
391  }
392 
393  d->config = new KConfig(cfg, KConfig::NoGlobals);
394 
395  // Karamba specific Config Entries
396  KConfigGroup cg(d->config, "internal");
397  bool locked = d->toggleLocked->isChecked();
398  locked = cg.readEntry("lockedPosition", locked);
399  d->toggleLocked->setChecked(locked);
400 
401  int desktop = 0;
402  desktop = cg.readEntry("desktop", desktop);
403  if (desktop > d->KWinModule->numberOfDesktops()) {
404  desktop = 0;
405  }
406 
407  slotDesktopChanged(desktop);
408 
409  cg = KConfigGroup(d->config, "theme");
410  if (cg.hasKey("widgetPosX") && cg.hasKey("widgetPosY")) {
411  int xpos = cg.readEntry("widgetPosX", 0);
412  int ypos = cg.readEntry("widgetPosY", 0);
413 
414  if (xpos < 0)
415  xpos = 0;
416  if (ypos < 0)
417  ypos = 0;
418 
419  if (startPos.isNull()) {
420  moveToPos(QPoint(xpos, ypos));
421  }
422  }
423 
424  if (!startPos.isNull()) {
425  moveToPos(startPos - d->themeCenter);
426 
427  d->toggleLocked->setChecked(false);
428  }
429 
430  if (!d->globalView && !reload && d->useFancyEffects) {
431  d->timer = new QTimeLine(1000);
432  d->timer->setFrameRange(0, 1000);
433 
434  d->animation = new QGraphicsItemAnimation;
435  d->animation->setItem(this);
436  d->animation->setTimeLine(d->timer);
437 
438  // Use 201 here because 200.0/200.0 < 1 => theme is still scaled
439  for (int i = 0; i < 201; i++) {
440  d->animation->setScaleAt(i / 200.0, 1 / 200.0 * i, 1 / 200.0 * i);
441  QPointF animPos(
442  boundingRect().width()/2*(1-d->animation->verticalScaleAt(i / 200.0)),
443  boundingRect().height()/2*(1-d->animation->horizontalScaleAt(i / 200.0))
444  );
445  d->animation->setPosAt(i / 200.0, animPos);
446  }
447 
448  d->timer->start();
449  }
450 
451  if (startkaramba)
452  QTimer::singleShot(0, this, SLOT(startKaramba()));
453 
454  if (!(d->onTop || d->managed) && !d->globalView) {
455  KWindowSystem::setState(d->view->winId(), NET::KeepBelow);
456  KWindowSystem::lowerWindow(d->view->winId());
457  }
458 }
459 
460 Karamba::~Karamba()
461 {
462  if (d->toggleLocked) // may NULL e.g. if "Could not load theme file"
463  writeConfigData();
464 
465  d->scene->removeItem(this);
466 
467  delete d;
468 }
469 
470 void Karamba::startKaramba()
471 {
472  if (d->errorInInit) {
473  deleteLater();
474  return;
475  }
476 
477  KarambaManager::self()->addKaramba(this);
478 
479  if (d->theme.scriptModuleExists()) {
480  kDebug() << "Loading script module: " << d->theme.scriptModule() ;
481 
482  d->stepTimer.setSingleShot(true);
483 
484  if (!d->useKross) {
485 #ifdef PYTHON_INCLUDE_PATH
486  d->python = new KarambaPython(d->theme, false);
487  d->python->initWidget(this);
488 #endif
489  } else {
490  d->interface = new KarambaInterface(this);
491  bool interpreterStarted = d->interface->initInterpreter();
492 
493  if (!interpreterStarted) {
494  delete d->interface;
495  d->interface = 0;
496  } else {
497  d->interface->startInterpreter();
498  d->interface->callInitWidget(this);
499  }
500  }
501 
502  update();
503 
504  connect(&d->stepTimer, SIGNAL(timeout()), SLOT(step()));
505  d->stepTimer.start(d->interval);
506  }
507 
508  show();
509 }
510 
511 QString Karamba::prettyName() const
512 {
513  return d->prettyName;
514 }
515 
516 void Karamba::setPrettyName(const QString &prettyThemeName)
517 {
518  d->prettyName = prettyThemeName;
519 }
520 
521 void Karamba::step()
522 {
523  d->stepTimer.start(d->interval);
524 
525 #ifdef PYTHON_INCLUDE_PATH
526  if (d->python)
527  d->python->widgetUpdated(this);
528 #endif
529 
530  if (d->interface)
531  d->interface->callWidgetUpdated(this);
532 
533  update();
534 }
535 
536 void Karamba::redrawWidget()
537 {
538  // Force the event loop to process the update() calls
539  // QCoreApplication::processEvents();
540 }
541 
542 bool Karamba::parseConfig()
543 {
544  //qDebug("karamba::parseConfig");
545  bool passive = true;
546 
547  if (d->theme.open()) {
548  QStack<QPoint> offsetStack;
549  LineParser lineParser;
550  int x = 0;
551  int y = 0;
552  int w = 0;
553  int h = 0;
554 
555  offsetStack.push(QPoint(0, 0));
556 
557  while (d->theme.nextLine(lineParser)) {
558  x = lineParser.getInt("X") + offsetStack.top().x();
559  y = lineParser.getInt("Y") + offsetStack.top().y();
560  w = lineParser.getInt("W");
561  h = lineParser.getInt("H");
562 
563  bool hidden = lineParser.getBoolean("HIDDEN");
564 
565  if (lineParser.meter() == "KARAMBA" && !d->foundKaramba) {
566  d->toggleLocked->setChecked(lineParser.getBoolean("LOCKED"));
567 
568  x = (x < 0) ? 0 : x;
569  y = (y < 0) ? 0 : y;
570 
571  if (w == 0 || h == 0) {
572  w = 300;
573  h = 300;
574  }
575 
576  // Store the center of the theme,
577  // so it can be centered when a user
578  // drags it from the theme dialog.
579  d->themeCenter = QPoint(w/2, h/2);
580 
581  setFixedSize(w, h);
582  if (!d->globalView) {
583  d->view->setFixedSize(w + 5, h + 5);
584  }
585 
586  if (lineParser.getBoolean("RIGHT")) {
587  QDesktopWidget *d = QApplication::desktop();
588  x = d->width() - w;
589  } else if (lineParser.getBoolean("LEFT")) {
590  x = 0;
591  }
592 
593  if (lineParser.getBoolean("BOTTOM")) {
594  QDesktopWidget *d = QApplication::desktop();
595  y = d->height() - h;
596  } else if (lineParser.getBoolean("TOP")) {
597  y = 0;
598  }
599 
600  moveToPos(QPoint(x, y));
601 
602  if (lineParser.getBoolean("ONTOP")) {
603  d->onTop = true;
604  if (!d->globalView) {
605  KWindowSystem::setState(d->view->winId(), NET::StaysOnTop);
606  }
607  }
608 
609  if (lineParser.getBoolean("MANAGED")) {
610  d->managed = true;
611  if (!d->globalView) {
612  Qt::WindowFlags flags = Qt::Dialog;
613  flags & Qt::WA_DeleteOnClose;
614  d->view->setWindowFlags(flags);
615  d->view->show();
616  }
617  } else {
618  if (!d->globalView) {
619  d->info->setState(NETWinInfo::SkipTaskbar
620  | NETWinInfo::SkipPager, NETWinInfo::SkipTaskbar
621  | NETWinInfo::SkipPager);
622  }
623  if (d->onTop && !d->globalView) {
624  KWindowSystem::setState(d->view->winId(), NET::KeepAbove);
625  }
626  }
627 
628  if (lineParser.getBoolean("ONALLDESKTOPS")) {
629  d->desktop = 200; // ugly
630  }
631 
632  bool dfound = false;
633  //int desktop = lineParser.getInt("DESKTOP", line, dfound);
634  if (dfound && !d->globalView) {
635  d->info->setDesktop(dfound);
636  }
637 
638  if (lineParser.getBoolean("TOPBAR")) {
639  if (!d->globalView) {
640  KWindowSystem::setStrut(d->view->winId(), 0, 0, h, 0);
641  d->view->move(x, 0);
642  } else {
643  moveToPos(QPoint(x, 0));
644  }
645 
646  d->toggleLocked->setChecked(true);
647  d->toggleLocked->setEnabled(false);
648  }
649 
650  if (lineParser.getBoolean("BOTTOMBAR")) {
651  int dh = QApplication::desktop()->height();
652  if (d->globalView) {
653  moveToPos(QPoint(x, dh - h));
654  } else {
655  KWindowSystem::setStrut(d->view->winId(), 0, 0, 0, h);
656  d->view->move(x, dh - h);
657  }
658  d->toggleLocked->setChecked(true);
659  d->toggleLocked->setEnabled(false);
660  }
661 
662  if (lineParser.getBoolean("RIGHTBAR")) {
663  int dw = QApplication::desktop()->width();
664  if (d->globalView) {
665  moveToPos(QPoint(dw - w, y));
666  } else {
667  KWindowSystem::setStrut(d->view->winId(), 0, w, 0, 0);
668  d->view->move(dw - w, y);
669  }
670  d->toggleLocked->setChecked(true);
671  d->toggleLocked->setEnabled(false);
672  }
673 
674  if (lineParser.getBoolean("LEFTBAR")) {
675  if (d->globalView) {
676  moveToPos(QPoint(0, y));
677  } else {
678  KWindowSystem::setStrut(d->view->winId(), w, 0, 0, 0);
679  d->view->move(0, y);
680  }
681  d->toggleLocked->setChecked( true );
682  d->toggleLocked->setEnabled(false);
683  }
684 
685  if (d->globalView)
686  setFlag(QGraphicsItem::ItemIsMovable,
687  d->toggleLocked->isChecked());
688 
689 
690  /* Masking gone
691  QString path = lineParser.getString("MASK");
692 
693  QFileInfo info(path);
694  QString absPath;
695  QBitmap bmMask;
696  QByteArray ba;
697  if( info.isRelative() )
698  {
699  absPath = d->theme.path();
700  absPath.append(path);
701  ba = d->theme.readThemeFile(path);
702  }
703  else
704  {
705  absPath = path;
706  ba = d->theme.readThemeFile(info.fileName());
707  }
708  if(d->theme.isZipTheme())
709  {
710  bmMask.loadFromData(ba);
711  }
712  else
713  {
714  bmMask.load(absPath);
715  }
716  d->view->setMask(bmMask);
717  */
718 
719  d->interval = lineParser.getInt("INTERVAL");
720  d->interval = (d->interval == 0) ? 1000 : d->interval;
721 
722  QString temp = lineParser.getString("TEMPUNIT", "C").toUpper();
723  d->tempUnit = temp.at(0).toAscii();
724  d->foundKaramba = true;
725  }
726 
727  if (lineParser.meter() == "THEME") {
728  QString path = lineParser.getString("PATH");
729  QFileInfo info(path);
730  if (info.isRelative())
731  path = d->theme.path() + '/' + path;
732 
733  new Karamba(path/*, d->view, d->scene*/);
734  }
735 
736  if (lineParser.meter() == "<GROUP>") {
737  int offsetX = offsetStack.top().x();
738  int offsetY = offsetStack.top().y();
739  offsetStack.push(QPoint(offsetX + lineParser.getInt("X"),
740  offsetY + lineParser.getInt("Y")));
741  }
742 
743  if (lineParser.meter() == "</GROUP>") {
744  offsetStack.pop();
745  }
746 
747  if (lineParser.meter() == "CLICKAREA") {
748  if (!d->globalView) {
749  d->view->setInteractive(true);
750  }
751 
752  bool preview = lineParser.getBoolean("PREVIEW");
753  ClickArea *tmp = new ClickArea(this, preview, x, y, w, h);
754  tmp->setOnClick(lineParser.getString("ONCLICK"));
755 
756 
757  setSensor(lineParser, (Meter*)tmp);
758  }
759 
760  if (lineParser.meter() == "SENSOR=PROGRAM") {
761  setSensor(lineParser, 0);
762  }
763 
764  if (lineParser.meter() == "IMAGE") {
765  QString file = lineParser.getString("PATH");
766  QString file_roll = lineParser.getString("PATHROLL");
767  int xon = lineParser.getInt("XROLL");
768  int yon = lineParser.getInt("YROLL");
769  QString tiptext = lineParser.getString("TOOLTIP");
770  QString name = lineParser.getString("NAME");
771  bool bg = lineParser.getBoolean("BACKGROUND");
772  xon = (xon <= 0) ? x : xon;
773  yon = (yon <= 0) ? y : yon;
774 
775  ImageLabel *tmp = new ImageLabel(this, x, y, 0, 0);
776  tmp->setValue(file);
777 
778  if (!file_roll.isEmpty())
779  tmp->parseImages(file, file_roll, x, y, xon, yon);
780 
781  tmp->setBackground(bg);
782 
783  if (!name.isEmpty())
784  tmp->setObjectName(name);
785 
786  if (!tiptext.isEmpty())
787  tmp->setTooltip(tiptext);
788  if ( hidden )
789  tmp->hide();
790 
791  setSensor(lineParser, (Meter*)tmp);
792  }
793 
794  if (lineParser.meter() == "DEFAULTFONT") {
795  delete d->defaultTextField;
796  d->defaultTextField = new TextField();
797 
798  d->defaultTextField->setColor(lineParser.getColor("COLOR",
799  QColor("black")));
800  d->defaultTextField->setBGColor(lineParser.getColor("BGCOLOR",
801  QColor("white")));
802  d->defaultTextField->setFont(lineParser.getString("FONT", "Helvetica"));
803  d->defaultTextField->setFontSize(lineParser.getInt("FONTSIZE", 12));
804  d->defaultTextField->setAlignment(lineParser.getString("ALIGN",
805  "LEFT"));
806  d->defaultTextField->setFixedPitch(lineParser.getBoolean("FIXEDPITCH",
807  false));
808  d->defaultTextField->setShadow(lineParser.getInt("SHADOW", 0));
809  }
810 
811  if (lineParser.meter() == "TEXT" ||
812  lineParser.meter() == "CLICKMAP" ||
813  lineParser.meter() == "RICHTEXT" ||
814  lineParser.meter() == "INPUT") {
815  TextField defTxt;
816 
817  if (d->defaultTextField)
818  defTxt = *d->defaultTextField;
819 
820  TextField* tmpText = new TextField();
821 
822  tmpText->setColor(lineParser.getColor("COLOR", defTxt.getColor()));
823  tmpText->setBGColor(lineParser.getColor("BGCOLOR",
824  defTxt.getBGColor()));
825  tmpText->setFont(lineParser.getString("FONT", defTxt.getFont()));
826  tmpText->setFontSize(lineParser.getInt("FONTSIZE",
827  defTxt.getFontSize()));
828  tmpText->setAlignment(lineParser.getString("ALIGN",
829  defTxt.getAlignmentAsString()));
830  tmpText->setFixedPitch(lineParser.getInt("FIXEDPITCH",
831  defTxt.getFixedPitch()));
832 
833  tmpText->setShadow(lineParser.getInt("SHADOW", defTxt.getShadow()));
834 
836  // Now handle the specifics
837  if (lineParser.meter() == "TEXT") {
838  TextLabel *tmp = new TextLabel(this, x, y, w, h);
839  tmp->setValue(
840  d->theme.locale()->translate(lineParser.getString("VALUE")));
841  tmp->setTextProps(tmpText);
842 
843  QString name = lineParser.getString("NAME");
844  if (!name.isEmpty())
845  tmp->setObjectName(name);
846 
847  if ( hidden )
848  tmp->hide();
849 
850  setSensor(lineParser, (Meter*)tmp);
851  }
852 
853  if (lineParser.meter() == "CLICKMAP") {
854  if (!d->globalView) {
855  d->view->setInteractive(true);
856  }
857 
858  ClickMap *tmp = new ClickMap(this, x, y, w, h);
859  tmp->setTextProps(tmpText);
860 
861  setSensor(lineParser, (Meter*)tmp);
862  // set all params
863  //clickList -> append(tmp);
864  //meterList->append( tmp );
865 
866  }
867 
868  if (lineParser.meter() == "RICHTEXT") {
869  RichTextLabel *tmp = new RichTextLabel(this, x, y, w, h);
870 
871  bool dUl = lineParser.getBoolean("UNDERLINE");
872 
873  tmp->setText(
874  d->theme.locale()->translate(lineParser.getString("VALUE")), dUl);
875  tmp->setTextProps(tmpText);
876 // tmp->setWidth(w);
877 // tmp->setHeight(h);
878 
879  QString name = lineParser.getString("NAME");
880  if (!name.isEmpty())
881  tmp->setObjectName(name);
882 
883  if ( hidden )
884  tmp->hide();
885 
886  setSensor(lineParser, (Meter*)tmp);
887  //clickList->append(tmp);
888  //meterList->append(tmp);
889  }
890 
891  if (lineParser.meter() == "INPUT") {
892  Input *tmp = new Input(this, x, y, w, h);
893 
894  QString name = lineParser.getString("NAME");
895  //if (!name.isEmpty())
896  //tmp->setObjectName(name);
897 
898  tmp->setTextProps(tmpText);
899  tmp->setValue(
900  d->theme.locale()->translate(lineParser.getString("VALUE")));
901 
902  //meterList->append(tmp);
903  passive = false;
904  }
905 
906  delete tmpText;
907  }
908 
909  if (lineParser.meter() == "BAR") {
910  Bar *tmp = new Bar(this, x, y, w, h);
911 
912  tmp->setImage(lineParser.getString("PATH"));
913  tmp->setVertical(lineParser.getBoolean("VERTICAL"));
914  tmp->setMax(lineParser.getInt("MAX", 100));
915  tmp->setMin(lineParser.getInt("MIN", 0));
916  tmp->setValue(lineParser.getInt("VALUE"));
917 
918  QString name = lineParser.getString("NAME");
919  if (!name.isEmpty())
920  tmp->setObjectName(name);
921 
922  if ( hidden )
923  tmp->hide();
924 
925  setSensor(lineParser, (Meter*)tmp);
926  //meterList->append(tmp);
927  }
928 
929  if (lineParser.meter() == "GRAPH") {
930  int points = lineParser.getInt("POINTS");
931 
932  Graph *tmp = new Graph(this, x, y, w, h, points);
933  tmp->setMax(lineParser.getInt("MAX", 100));
934  tmp->setMin(lineParser.getInt("MIN", 0));
935  QString name = lineParser.getString("NAME");
936  if (!name.isEmpty())
937  tmp->setObjectName(name);
938 
939  tmp->setPlotDirection(lineParser.getString("PLOT"));
940  tmp->setScrollDirection(lineParser.getString("SCROLL"));
941  tmp->setColor(lineParser.getColor("COLOR"));
942 
943  QString fillString = lineParser.getString("FILLCOLOR");
944  if ( ! fillString.isEmpty() )
945  tmp->setFillColor(lineParser.getColor("FILLCOLOR"));
946 
947  if ( hidden )
948  tmp->hide();
949 
950  setSensor(lineParser, (Graph*)tmp);
951  //meterList->append(tmp);
952  }
953  }
954 
955  if (passive && !d->managed && !d->onTop && !d->globalView) {
956  KWindowSystem::setType(d->view->winId(), NET::Dock);
957  KWindowSystem::setState(d->view->winId(), NET::KeepBelow);
958  }
959 
960  d->theme.close();
961  }
962  //qDebug("parseConfig ok: %d", foundKaramba);
963  if (!d->foundKaramba) {
964  // interval = initKaramba( "", 0, 0, 0, 0 );
965  // this->close(true);
966  //delete this;
967  return false;
968  } else {
969  return true;
970  }
971 }
972 
973 void Karamba::makeActive()
974 {
975  if (!d->globalView) {
976  KWindowSystem::setType(d->view->winId(), NET::Normal);
977  KWindowSystem::setState(d->view->winId(), NET::Modal);
978  }
979 }
980 
981 void Karamba::makePassive()
982 {
983  if (d->managed) {
984  return;
985  }
986 
987  QList<QGraphicsItem*> items = QGraphicsItemGroup::children();
988  foreach (QGraphicsItem* item, items) {
989  if (dynamic_cast<Input*>(item) != 0) {
990  return;
991  }
992  }
993 
994  if (!d->globalView) {
995  KWindowSystem::setType(d->view->winId(), NET::Dock);
996  KWindowSystem::setState(d->view->winId(), NET::KeepBelow);
997  }
998 }
999 
1000 TextField* Karamba::getDefaultTextProps()
1001 {
1002  return d->defaultTextField;
1003 }
1004 
1005 QString Karamba::findSensorFromMap(const Sensor* sensor) const
1006 {
1007  //qDebug("karamba::findSensorFromMap");
1008  QMap<QString, Sensor*>::ConstIterator it;
1009  QMap<QString, Sensor*>::ConstIterator end(d->sensorMap.constEnd());
1010  for (it = d->sensorMap.constBegin(); it != end; ++it) {
1011  if (it.value() == sensor)
1012  return it.key();
1013  }
1014  return "";
1015 }
1016 
1017 Sensor *Karamba::findSensorFromList(const Meter* meter) const
1018 {
1019  foreach(Sensor *sensor, d->sensorList) {
1020  if (sensor->hasMeter(meter))
1021  return sensor;
1022  }
1023 
1024  return 0;
1025 }
1026 
1027 void Karamba::deleteMeterFromSensors(Meter* meter)
1028 {
1029  //qDebug("karamba::deleteMeterFromSensors");
1030  Sensor* sensor = findSensorFromList(meter);
1031 
1032  if (sensor) {
1033  sensor->deleteMeter(meter);
1034  if (sensor->isEmpty()) {
1035  QString s = findSensorFromMap(sensor);
1036  d->sensorMap.remove(s);
1037  d->sensorList.removeAll(sensor);
1038  delete sensor;
1039  }
1040  }
1041 }
1042 
1043 QString Karamba::getSensor(const Meter* meter) const
1044 {
1045  Sensor* sensor = findSensorFromList(meter);
1046 
1047  if (sensor)
1048  return findSensorFromMap(sensor);
1049 
1050  return QString();
1051 }
1052 
1053 bool Karamba::removeMeter(Meter* meter)
1054 {
1055  QList<QGraphicsItem*> items = QGraphicsItemGroup::children();
1056 
1057  if (items.contains(meter)) {
1058  deleteMeterFromSensors(meter);
1059  delete meter;
1060  return true;
1061  } else
1062  return false;
1063 }
1064 
1065 void Karamba::setSensor(const LineParser& lineParser, Meter* meter)
1066 {
1067  Sensor* sensor = 0;
1068 
1069  deleteMeterFromSensors(meter);
1070 
1071  QString sens = lineParser.getString("SENSOR").toUpper();
1072 
1073  if (sens == "CPU") {
1074  QString cpuNbr = lineParser.getString("CPU");
1075  sensor = d->sensorMap["CPU"+cpuNbr];
1076 
1077  if (sensor == 0) {
1078  int interval = lineParser.getInt("INTERVAL");
1079  interval = (interval == 0) ? 1000 : interval;
1080  sensor = (d->sensorMap["CPU" + cpuNbr] = new CPUSensor(cpuNbr, interval));
1081  d->sensorList.append(sensor);
1082  }
1083 
1084  SensorParams *sp = new SensorParams(meter);
1085  sp->addParam("FORMAT",
1086  d->theme.locale()->translate(lineParser.getString("FORMAT")));
1087 
1088  sp->addParam("DECIMALS", lineParser.getString("DECIMALS"));
1089 
1090  sensor->addMeter(sp);
1091  sensor->setMaxValue(sp);
1092  }
1093 
1094  if (sens == "MEMORY") {
1095  sensor = d->sensorMap["MEMORY"];
1096  if (sensor == 0) {
1097  int interval = lineParser.getInt("INTERVAL");
1098  interval = (interval == 0) ? 3000 : interval;
1099  sensor = (d->sensorMap["MEMORY"] = new MemSensor(interval));
1100  d->sensorList.append(sensor);
1101  }
1102 
1103  SensorParams *sp = new SensorParams(meter);
1104  sp->addParam("FORMAT",
1105  d->theme.locale()->translate(lineParser.getString("FORMAT")));
1106 
1107  sensor->addMeter(sp);
1108  sensor->setMaxValue(sp);
1109  }
1110 
1111  if (sens == "DISK") {
1112  sensor = d->sensorMap["DISK"];
1113 
1114  if (sensor == 0) {
1115  int interval = lineParser.getInt("INTERVAL");
1116  interval = (interval == 0) ? 5000 : interval;
1117  sensor = (d->sensorMap["DISK"] = new DiskSensor(interval));
1118  d->sensorList.append(sensor);
1119  }
1120  // meter->setMax( ((DiskSensor*)sensor)->getTotalSpace(mntPt)/1024 );
1121  SensorParams *sp = new SensorParams(meter);
1122  QString mntPt = lineParser.getString("MOUNTPOINT");
1123  if (mntPt.isEmpty()) {
1124  mntPt = '/';
1125  }
1126  // remove any trailing '/' from mount points in the .theme config, our
1127  // mntMap doesn't like trailing '/'s for matching in DiskSensor
1128  if (mntPt.length() > 1 && mntPt.endsWith('/')) {
1129  mntPt.remove(mntPt.length() - 1, 1);
1130  }
1131  sp->addParam("MOUNTPOINT", mntPt);
1132  sp->addParam("FORMAT",
1133  d->theme.locale()->translate(lineParser.getString("FORMAT")));
1134  sensor->addMeter(sp);
1135  sensor->setMaxValue(sp);
1136  }
1137 
1138  if (sens == "NETWORK") {
1139  int interval = lineParser.getInt("INTERVAL");
1140  interval = (interval == 0) ? 2000 : interval;
1141  QString device = lineParser.getString("DEVICE");
1142  sensor = d->sensorMap["NETWORK"+device];
1143 
1144  if (sensor == 0) {
1145  sensor = (d->sensorMap["NETWORK"+device] =
1146  new NetworkSensor(device, interval));
1147  d->sensorList.append(sensor);
1148  }
1149 
1150  SensorParams *sp = new SensorParams(meter);
1151  sp->addParam("FORMAT",
1152  d->theme.locale()->translate(lineParser.getString("FORMAT")));
1153 
1154  sp->addParam("DECIMALS", lineParser.getString("DECIMALS"));
1155  sensor->addMeter(sp);
1156  }
1157 
1158  if (sens == "UPTIME") {
1159  sensor = d->sensorMap["UPTIME"];
1160  if (sensor == 0) {
1161  int interval = lineParser.getInt("INTERVAL");
1162  interval = (interval == 0) ? 1000 : interval;
1163  sensor = (d->sensorMap["UPTIME"] = new UptimeSensor(interval));
1164  d->sensorList.append(sensor);
1165  }
1166 
1167  SensorParams *sp = new SensorParams(meter);
1168  sp->addParam("FORMAT",
1169  d->theme.locale()->translate(lineParser.getString("FORMAT")));
1170 
1171  sensor->addMeter(sp);
1172  }
1173 
1174  if (sens == "SENSOR") {
1175  sensor = d->sensorMap["SENSOR"];
1176 
1177  if (sensor == 0) {
1178  int interval = lineParser.getInt("INTERVAL");
1179  interval = (interval == 0) ? 5000 : interval;
1180  sensor = (d->sensorMap["SENSOR"] = new SensorSensor(interval, d->tempUnit));
1181  d->sensorList.append(sensor);
1182  }
1183 
1184  SensorParams *sp = new SensorParams(meter);
1185  sp->addParam("FORMAT",
1186  d->theme.locale()->translate(lineParser.getString("FORMAT")));
1187  sp->addParam("TYPE", lineParser.getString("TYPE"));
1188  sensor->addMeter(sp);
1189  }
1190 
1191  if (sens == "TEXTFILE") {
1192  QString path = lineParser.getString("PATH");
1193  bool rdf = lineParser.getBoolean("RDF");
1194  sensor = d->sensorMap["TEXTFILE"+path];
1195 
1196  if (sensor == 0) {
1197  int interval = lineParser.getInt("INTERVAL");
1198  interval = (interval == 0) ? 60000 : interval;
1199  QString encoding = lineParser.getString("ENCODING");
1200 
1201  sensor = (d->sensorMap["TEXTFILE"+path] =
1202  new TextFileSensor(path, rdf, interval, encoding));
1203  d->sensorList.append(sensor);
1204  }
1205 
1206  SensorParams *sp = new SensorParams(meter);
1207  sp->addParam("LINE", QString::number(lineParser.getInt("LINE")));
1208  }
1209 
1210  if (sens == "TIME") {
1211  sensor = d->sensorMap["DATE"];
1212  if (sensor == 0) {
1213  int interval = lineParser.getInt("INTERVAL");
1214  interval = (interval == 0) ? 1000 : interval;
1215  sensor = (d->sensorMap["DATE"] = new DateSensor(interval));
1216  d->sensorList.append(sensor);
1217  }
1218  SensorParams *sp = new SensorParams(meter);
1219 
1220  sp->addParam("FORMAT",
1221  d->theme.locale()->translate(lineParser.getString("FORMAT")));
1222  sp->addParam("CALWIDTH", lineParser.getString("CALWIDTH"));
1223  sp->addParam("CALHEIGHT", lineParser.getString("CALHEIGHT"));
1224 
1225  sensor->addMeter(sp);
1226  }
1227 
1228 #ifdef HAVE_XMMS
1229 
1230  if (sens == "XMMS") {
1231  sensor = sensorMap["XMMS"];
1232  if (sensor == 0) {
1233  int interval = lineParser.getInt("INTERVAL");
1234  interval = (interval == 0) ? 1000 : interval;
1235  QString encoding = lineParser.getString("ENCODING");
1236 
1237  sensor = (sensorMap["XMMS"] = new XMMSSensor(interval, encoding));
1238  sensorList->append(sensor);
1239  }
1240  SensorParams *sp = new SensorParams(meter);
1241  sp->addParam("FORMAT",
1242  d->theme.locale()->translate(lineParser.getString("FORMAT")));
1243  sensor->addMeter(sp);
1244  sensor->setMaxValue(sp);
1245  }
1246 #endif // HAVE_XMMS
1247 
1248 
1249  /*
1250  Not used in KDE4
1251 
1252  if( sens == "NOATUN" )
1253  {
1254  sensor = sensorMap["NOATUN"];
1255  if (sensor == 0)
1256  {
1257  int interval = lineParser.getInt("INTERVAL");
1258  interval = (interval == 0)?1000:interval;
1259  sensor = ( sensorMap["NOATUN"] = new NoatunSensor( interval, client ) );
1260  sensorList->append( sensor );
1261  }
1262  SensorParams *sp = new SensorParams(meter);
1263  sp->addParam("FORMAT",
1264  d->theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
1265  sensor->addMeter(sp);
1266  sensor->setMaxValue(sp);
1267  }
1268  */
1269 
1270  if (sens == "PROGRAM") {
1271  QString progName = lineParser.getString("PROGRAMNAME");
1272  if (progName.isEmpty()) {
1273  progName = lineParser.getString("PROGRAM");
1274  }
1275 
1276  sensor = d->sensorMap["PROGRAM"+progName];
1277 
1278  if (sensor == 0) {
1279  int interval = lineParser.getInt("INTERVAL");
1280 
1281  interval = (interval == 0) ? 60000 : interval;
1282  QString encoding = lineParser.getString("ENCODING");
1283 
1284  QString prog = lineParser.getString("PROGRAM");
1285  sensor = (d->sensorMap["PROGRAM"+progName] =
1286  new ProgramSensor(this, prog, interval, encoding));
1287  d->sensorList.append(sensor);
1288  }
1289 
1290  SensorParams *sp = new SensorParams(meter);
1291  sp->addParam("LINE", QString::number(lineParser.getInt("LINE")));
1292  sp->addParam("THEMAPATH", d->theme.path());
1293  sp->addParam("FORMAT", d->theme.locale()->translate(lineParser.getString("FORMAT")));
1294  sensor->addMeter(sp);
1295  }
1296 
1297  if (sens == "RSS") {
1298  QString source = lineParser.getString("SOURCE");
1299  QString format =
1300  d->theme.locale()->translate(lineParser.getString("FORMAT"));
1301 
1302  sensor = d->sensorMap["RSS"+source];
1303  if (sensor == 0) {
1304  int interval = lineParser.getInt("INTERVAL");
1305  interval = (interval == 0) ? 60000 : interval;
1306  QString encoding = lineParser.getString("ENCODING");
1307 
1308  sensor = (d->sensorMap["RSS"+source] =
1309  new RssSensor(source, interval, format, encoding));
1310  d->sensorList.append(sensor);
1311  }
1312  SensorParams *sp = new SensorParams(meter);
1313  sp->addParam("SOURCE", lineParser.getString("SOURCE"));
1314  sensor->addMeter(sp);
1315  }
1316 
1317 #ifdef PLASMASENSOR_ENABLED
1318  if (sens == "PLASMA") {
1319  QString engine = lineParser.getString("ENGINE");
1320  QString source = lineParser.getString("SOURCE");
1321  kDebug()<<"PlasmaEngineSensor engine="<<engine<<" source="<<source<<endl;
1322  sensor = d->sensorMap["PLASMA." + engine + '.' + source];
1323  if (sensor == 0) {
1324  PlasmaSensor* plasmasensor = new PlasmaSensor();
1325  plasmasensor->setEngine(engine);
1326  if( ! source.isEmpty() ) {
1327  QObject* connector = plasmasensor->connectSource(source, meter);
1328  if( PlasmaSensorConnector* c = dynamic_cast<PlasmaSensorConnector*>(connector) ) {
1329  c->setFormat( lineParser.getString("FORMAT") );
1330  }
1331  }
1332 
1333  QString propertiesLine = lineParser.getString("PROPERTIES");
1334  const QStringList properties = propertiesLine.split(',');
1335  foreach (const QString &property, properties) {
1336  QStringList options = property.split(':');
1337  if (options.count() == 2) {
1338  plasmasensor->setProperty(options[0].toLatin1(), options[1]);
1339  }
1340  }
1341 
1342  sensor = plasmasensor;
1343  d->sensorMap["PLASMA." + engine + '.' + source] = sensor;
1344  d->sensorList.append(sensor);
1345  }
1346 
1347  SensorParams *sp = new SensorParams(meter);
1348  sp->addParam("THEMAPATH", d->theme.path());
1349  sp->addParam("ENGINE", engine);
1350  sp->addParam("SOURCE", source);
1351  sensor->addMeter(sp);
1352  }
1353 #endif
1354 
1355  if (sensor != 0) {
1356  sensor->update();
1357  update();
1358 
1359  sensor->start();
1360  }
1361 }
1362 
1363 void Karamba::updateSensors()
1364 {
1365  foreach(Sensor *sensor, d->sensorList)
1366  sensor->update();
1367 }
1368 
1369 void Karamba::slotToggleLocked()
1370 {
1371  if (d->globalView)
1372  setFlag(QGraphicsItem::ItemIsMovable,
1373  d->toggleLocked->isChecked());
1374 }
1375 
1376 void Karamba::closeWidget()
1377 {
1378 #ifdef PYTHON_INCLUDE_PATH
1379  if (d->python)
1380  d->python->widgetClosed(this);
1381 #endif
1382 
1383  if (d->interface)
1384  d->interface->callWidgetClosed(this);
1385 
1386  KarambaManager::self()->removeKaramba(this);
1387 }
1388 
1389 KConfig* Karamba::getConfig() const
1390 {
1391  return d->config;
1392 }
1393 
1394 void Karamba::writeConfigData()
1395 {
1396  KConfigGroup cg(d->config, "internal");
1397  cg.writeEntry("lockedPosition", d->toggleLocked-> isChecked());
1398  cg.writeEntry("desktop", d->desktop);
1399 
1400  cg = KConfigGroup(d->config, "theme");
1401 
1402  // Widget Position
1403  if (!d->globalView) {
1404  cg.writeEntry("widgetPosX", d->view->x());
1405  cg.writeEntry("widgetPosY", d->view->y());
1406  } else {
1407  if (parentItem()) {
1408  cg.writeEntry("widgetPosX", parentItem()->x());
1409  cg.writeEntry("widgetPosY", parentItem()->y());
1410  } else {
1411  cg.writeEntry("widgetPosX", x());
1412  cg.writeEntry("widgetPosY", y());
1413  }
1414  }
1415 
1416  // Widget Size
1417  cg.writeEntry("widgetWidth", boundingRect().width());
1418  cg.writeEntry("widgetHeight", boundingRect().height());
1419 
1420  // write changes to DiskSensor
1421  d->config->sync();
1422 }
1423 
1424 void Karamba::reloadConfig()
1425 {
1426  writeConfigData();
1427 
1428  Karamba *k = 0;
1429 
1430  if (d->globalView)
1431  k = new Karamba(d->theme.getUrlPath(), d->view, -1, false, QPoint(), true);
1432  else
1433  k = new Karamba(d->theme.getUrlPath(), 0, -1, false, QPoint(), true);
1434 
1435  closeWidget();
1436 }
1437 
1438 void Karamba::setOnTop(bool stayOnTop)
1439 {
1440  if (stayOnTop) {
1441  if (!d->globalView) {
1442  KWindowSystem::setState(d->view->winId(), NET::KeepAbove);
1443  }
1444  } else {
1445  if (!d->globalView) {
1446  KWindowSystem::setState(d->view->winId(), NET::KeepBelow);
1447  }
1448  }
1449 
1450  d->onTop = stayOnTop;
1451 }
1452 
1453 void Karamba::preparePopupMenu()
1454 {
1455  d->popupMenu = new KMenu();
1456 
1457  d->popupMenu->addAction(KIcon("view-refresh"), i18n("Update"), this,
1458  SLOT(updateSensors()), Qt::Key_F5);
1459 
1460  d->toggleLocked = new KToggleAction(i18n("&Locked Position"), this);
1461  d->toggleLocked->setObjectName( QLatin1String("lockedAction" ));
1462  d->toggleLocked->setShortcut(KShortcut(Qt::CTRL + Qt::Key_L));
1463  d->toggleLocked->setCheckedState(KGuiItem(i18n("&Locked Position")));
1464  connect(d->toggleLocked, SIGNAL(triggered()), this, SLOT(slotToggleLocked()));
1465  d->popupMenu->addAction(d->toggleLocked);
1466 
1467  d->popupMenu->addSeparator();
1468 
1469  d->themeConfMenu = new KMenu();
1470  d->themeConfMenu->setTitle(i18n("Configure &Theme"));
1471  QAction *newAC = d->popupMenu->addMenu(d->themeConfMenu);
1472  newAC->setObjectName( QLatin1String("configureTheme" ));
1473  newAC->setParent(this);
1474  newAC->setVisible(false);
1475 
1476  if (d->globalView) {
1477  return;
1478  }
1479 
1480  d->toDesktopMenu = new KMenu();
1481  d->toDesktopMenu->setTitle(i18n("To Des&ktop"));
1482  d->popupMenu->addMenu(d->toDesktopMenu);
1483 
1484  QAction *allDesktop = d->toDesktopMenu->addAction((i18n("&All Desktops")));
1485  connect(allDesktop, SIGNAL(triggered()), d->signalMapperDesktop, SLOT(map()));
1486  allDesktop->setCheckable(true);
1487  d->signalMapperDesktop->setMapping(allDesktop, 0);
1488 
1489  for (int desktop = 1; desktop <= d->KWinModule->numberOfDesktops(); desktop++) {
1490  QString name = i18n("Desktop");
1491  name += QString(" &%1").arg(desktop);
1492  QAction* action = d->toDesktopMenu->addAction(name);
1493  action->setCheckable(true);
1494  connect(action, SIGNAL(triggered()), d->signalMapperDesktop, SLOT(map()));
1495  d->signalMapperDesktop->setMapping(action, desktop);
1496  }
1497 
1498  d->reloadTheme = new KAction(KIcon("view-refresh"), i18n("&Reload Theme"), this);
1499  d->reloadTheme->setObjectName( QLatin1String("reloadAction" ));
1500  d->reloadTheme->setShortcut(KShortcut(Qt::CTRL + Qt::Key_R));
1501  connect(d->reloadTheme, SIGNAL(triggered()), this, SLOT(reloadConfig()));
1502  d->popupMenu->addAction(d->reloadTheme);
1503 
1504  d->popupMenu->addAction(KIcon("window-close"), i18n("&Close This Theme"), this,
1505  SLOT(closeWidget()), Qt::CTRL + Qt::Key_C);
1506 }
1507 
1508 void Karamba::slotDesktopChanged(int desktop)
1509 {
1510  if (d->globalView) {
1511  return;
1512  }
1513 
1514  QList<QAction*> actions = d->toDesktopMenu->actions();
1515 
1516  for (int i = 0; i < actions.count(); i++) {
1517  if (i == desktop)
1518  actions[i]->setChecked(true);
1519  else
1520  actions[i]->setChecked(false);
1521  }
1522 
1523  if (desktop) {
1524  d->info->setDesktop(desktop);
1525  } else {
1526  d->info->setDesktop(NETWinInfo::OnAllDesktops);
1527  }
1528 }
1529 
1530 void Karamba::currentWallpaperChanged(int desktop)
1531 {
1532 #ifdef PYTHON_INCLUDE_PATH
1533  if (d->python) {
1534  d->python->wallpaperChanged(this, desktop);
1535  }
1536 #endif
1537 
1538  if (d->interface) {
1539  d->interface->callWallpaperChanged(this, desktop);
1540  }
1541 }
1542 
1543 void Karamba::addMenuConfigOption(const QString &key, const QString &name)
1544 {
1545  d->themeConfMenu->menuAction()->setVisible(true);
1546 
1547  KAction *newAction = new KToggleAction(name, this);
1548 
1549  newAction->setObjectName(key);
1550  connect(newAction, SIGNAL(triggered()), d->signalMapperConfig, SLOT(map()));
1551  d->signalMapperConfig->setMapping(newAction, newAction);
1552  d->themeConfMenu->addAction(newAction);
1553 
1554  newAction->setChecked(d->config->group("config menu").readEntry(key, false));
1555 }
1556 
1557 void Karamba::slotToggleConfigOption(QObject* sender)
1558 {
1559  KToggleAction *action = (KToggleAction*)sender;
1560 
1561  d->config->group("config menu").writeEntry(action->objectName(), action->isChecked());
1562 
1563 #ifdef PYTHON_INCLUDE_PATH
1564  if (d->python)
1565  d->python->menuOptionChanged(this, action->objectName(), action->isChecked());
1566 #endif
1567 
1568  if (d->interface)
1569  d->interface->callMenuOptionChanged(this, action->objectName(), action->isChecked());
1570 }
1571 
1572 bool Karamba::setMenuConfigOption(const QString &key, bool value)
1573 {
1574  QList<QAction*> actions = d->themeConfMenu->actions();
1575  QAction *action;
1576  foreach(action, actions) {
1577  if (action->objectName() == key) {
1578  action->setChecked(value);
1579  return true;
1580  }
1581  }
1582 
1583  return false;
1584 }
1585 
1586 bool Karamba::readMenuConfigOption(const QString &key) const
1587 {
1588  QList<QAction*> actions = d->themeConfMenu->actions();
1589  QAction *action;
1590  foreach(action, actions) {
1591  if (action->objectName() == key) {
1592  return action->isChecked();
1593  }
1594  }
1595 
1596  return false;
1597 }
1598 
1599 KMenu *Karamba::addPopupMenu()
1600 {
1601  KMenu *tmp = new KMenu();
1602 
1603  connect(tmp, SIGNAL(triggered(QAction*)), this,
1604  SLOT(passMenuItemClicked(QAction*)));
1605 
1606  d->menuList.append(tmp);
1607  return tmp;
1608 }
1609 
1610 QAction* Karamba::addMenuItem(KMenu *menu, const QString &text, const QString &icon)
1611 {
1612  QAction *action = menu->addAction(KIcon(icon), text);
1613  return action;
1614 }
1615 
1616 void Karamba::popupMenu(KMenu *menu, const QPoint &pos) const
1617 {
1618  if (!d->globalView) {
1619  menu->popup(d->view->pos() + pos + boundingRect().toRect().topLeft());
1620  } else {
1621  menu->popup(mapToScene(pos).toPoint());
1622  }
1623 }
1624 
1625 void Karamba::deletePopupMenu(KMenu *menu)
1626 {
1627  int index = d->menuList.indexOf(menu);
1628  d->menuList.takeAt(index);
1629 
1630  menu->deleteLater();
1631 }
1632 
1633 void Karamba::deleteMenuItem(QAction *action)
1634 {
1635  foreach(KMenu* menu, d->menuList) {
1636  QList<QAction*> actions = menu->actions();
1637  if (actions.contains(action)) {
1638  menu->removeAction(action);
1639  delete action;
1640  }
1641  }
1642 }
1643 
1644 bool Karamba::popupMenuExisting(const KMenu *menu) const
1645 {
1646  return d->menuList.contains(const_cast<KMenu*>(menu));
1647 }
1648 
1649 void Karamba::scaleImageLabel(Meter *meter, int width,
1650  int height) const
1651 {
1652  if (ImageLabel *image = dynamic_cast<ImageLabel*>(meter)) {
1653  image->smoothScale(width, height);
1654  }
1655 }
1656 
1657 void Karamba::moveMeter(Meter *meter, int x, int y) const
1658 {
1659  meter->setSize(x, y,
1660  meter->getWidth(),
1661  meter->getHeight());
1662 }
1663 
1664 
1665 void Karamba::passMenuItemClicked(QAction* action)
1666 {
1667 #ifdef PYTHON_INCLUDE_PATH
1668  if (d->python)
1669  d->python->menuItemClicked(this, (KMenu*)action->parentWidget(), (long)action);
1670 #endif
1671 
1672  if (d->interface)
1673  d->interface->callMenuItemClicked(this, (KMenu*)action->parentWidget(), action);
1674 
1675 }
1676 
1677 void Karamba::popupGlobalMenu() const
1678 {
1679  d->popupMenu->popup(QCursor::pos());
1680 }
1681 
1682 bool Karamba::hasMeter(const Meter* meter) const
1683 {
1684  QList<QGraphicsItem*> items = QGraphicsItemGroup::children();
1685  return items.contains(const_cast<Meter*>(meter));
1686 }
1687 
1688 QRectF Karamba::boundingRect() const
1689 {
1690  return d->size;
1691 }
1692 
1693 void Karamba::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
1694  QWidget *widget)
1695 {
1696  Q_UNUSED(painter);
1697  Q_UNUSED(option);
1698  Q_UNUSED(widget);
1699  /*
1700  if(d->showMenu || d->scaleStep > 0)
1701  {
1702  setZValue(1);
1703  painter->setOpacity(0.075*d->scaleStep);
1704  painter->setBrush(Qt::gray);
1705  painter->setPen(Qt::gray);
1706 
1707  QRect frame(150,150,150,150);
1708  frame.moveCenter(boundingRect().center().toPoint());
1709  painter->drawRoundRect(frame);
1710  }
1711  */
1712 }
1713 
1714 void Karamba::timerEvent(QTimerEvent *event)
1715 {
1716  Q_UNUSED(event);
1717  /*
1718  QGraphicsItem *item;
1719  QList<QGraphicsItem*> items = d->view->items
1720  (mapToScene(boundingRect()).toPolygon());
1721  foreach(item, items)
1722  {
1723  ((Meter*)item)->setOpacity(1-0.05*d->scaleStep);
1724  }
1725 
1726  if(d->showMenu)
1727  d->scaleStep++;
1728  else
1729  d->scaleStep--;
1730 
1731  update();
1732 
1733  if((d->scaleStep == -1) || (d->scaleStep == 10))
1734  killTimer(event->timerId());
1735  */
1736 }
1737 
1738 void Karamba::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
1739 {
1740  if (!d->wantRightButton) {
1741  d->popupMenu->exec(event->screenPos());
1742  }
1743 }
1744 
1745 void Karamba::activeTaskChanged(Task::TaskPtr t)
1746 {
1747 #ifdef PYTHON_INCLUDE_PATH
1748  if (d->python)
1749  d->python->activeTaskChanged(this, t.data());
1750 #endif
1751 
1752  if (d->interface)
1753  d->interface->callActiveTaskChanged(this, t.data());
1754 }
1755 
1756 void Karamba::taskAdded(Task::TaskPtr t)
1757 {
1758 #ifdef PYTHON_INCLUDE_PATH
1759  if (d->python)
1760  d->python->taskAdded(this, t.data());
1761 #endif
1762 
1763  if (d->interface)
1764  d->interface->callTaskAdded(this, t.data());
1765 }
1766 
1767 void Karamba::taskRemoved(Task::TaskPtr t)
1768 {
1769 #ifdef PYTHON_INCLUDE_PATH
1770  if (d->python)
1771  d->python->taskRemoved(this, t.data());
1772 #endif
1773 
1774  if (d->interface)
1775  d->interface->callTaskRemoved(this, t.data());
1776 }
1777 
1778 void Karamba::startupAdded(Startup::StartupPtr t)
1779 {
1780 #ifdef PYTHON_INCLUDE_PATH
1781  if (d->python)
1782  d->python->startupAdded(this, t.data());
1783 #endif
1784 
1785  if (d->interface)
1786  d->interface->callStartupAdded(this, t.data());
1787 }
1788 
1789 void Karamba::startupRemoved(Startup::StartupPtr t)
1790 {
1791 #ifdef PYTHON_INCLUDE_PATH
1792  if (d->python)
1793  d->python->startupRemoved(this, t.data());
1794 #endif
1795 
1796  if (d->interface)
1797  d->interface->callStartupRemoved(this, t.data());
1798 }
1799 
1800 void Karamba::processExited(K3Process* proc)
1801 {
1802 #ifdef PYTHON_INCLUDE_PATH
1803  if (d->python)
1804  d->python->commandFinished(this, (int)proc->pid());
1805 #endif
1806 
1807  if (d->interface)
1808  d->interface->callCommandFinished(this, (int)proc->pid());
1809 }
1810 
1811 void Karamba::receivedStdout(K3Process *proc, char *buffer, int)
1812 {
1813 #ifdef PYTHON_INCLUDE_PATH
1814  if (d->python)
1815  d->python->commandOutput(this, (int)proc->pid(), buffer);
1816 #endif
1817 
1818  if (d->interface)
1819  d->interface->callCommandOutput(this, (int)proc->pid(), buffer);
1820 }
1821 
1822 void Karamba::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
1823 {
1824  //event->accept(QTextDrag::canDecode(event));
1825  if (event->mimeData()->hasText())
1826  event->acceptProposedAction();
1827 }
1828 
1829 void Karamba::dropEvent(QGraphicsSceneDragDropEvent *event)
1830 {
1831  if (event->mimeData()->hasText()) {
1832  #ifdef PYTHON_INCLUDE_PATH
1833  if (d->python)
1834  d->python->itemDropped(this, event->mimeData()->text(),
1835  (int)event->pos().x(), (int)event->pos().y());
1836  #endif
1837 
1838  if (d->interface)
1839  d->interface->callItemDropped(this, event->mimeData()->text(),
1840  (int)event->pos().x(), (int)event->pos().y());
1841 
1842  }
1843 }
1844 
1845 void Karamba::mousePressEvent(QGraphicsSceneMouseEvent *event)
1846 {
1847  d->mouseClickPos = event->pos().toPoint();
1848 
1849  if (!(d->onTop || d->managed) && !d->globalView) {
1850  KWindowSystem::lowerWindow(d->view->winId());
1851  }
1852 
1853  if (!d->toggleLocked->isChecked()) {
1854  return;
1855  }
1856 
1857  int button = passEvent(event);
1858 
1859 #ifdef PYTHON_INCLUDE_PATH
1860  if (d->python) {
1861  d->python->widgetClicked(this, (int)event->pos().x(),
1862  (int)event->pos().y(), button);
1863  }
1864 #endif
1865 
1866  if (d->interface) {
1867  d->interface->callWidgetClicked(this, (int)event->pos().x(),
1868  (int)event->pos().y(), button);
1869  }
1870 }
1871 
1872 void Karamba::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
1873 {
1874  if (!d->toggleLocked->isChecked())
1875  return;
1876 
1877  QList<QGraphicsItem*>items = d->scene->items(mapToScene(event->pos()));
1878  foreach (QGraphicsItem *item, items) {
1879  if (Input *input = dynamic_cast<Input*>(item)) {
1880  input->mouseEventRelease(event);
1881  }
1882  }
1883 }
1884 
1885 void Karamba::setWantRightButton(bool enable)
1886 {
1887  d->wantRightButton = enable;
1888 }
1889 
1890 void Karamba::currentDesktopChanged(int i)
1891 {
1892 #ifdef PYTHON_INCLUDE_PATH
1893  if (d->python)
1894  d->python->desktopChanged(this, i);
1895 #endif
1896 
1897  if (d->interface)
1898  d->interface->callDesktopChanged(this, i);
1899 }
1900 
1901 int Karamba::passEvent(QEvent *e)
1902 {
1903  QList<QGraphicsItem*> items;
1904  QPointF pos;
1905  int button = 0;
1906 
1907  if (QGraphicsSceneMouseEvent *event = dynamic_cast<QGraphicsSceneMouseEvent*>(e)) {
1908  items = d->scene->items(mapToScene(event->pos()));
1909  pos = event->pos();
1910 
1911  if (event->button() == Qt::LeftButton)
1912  button = 1;
1913  else if (event->button() == Qt::MidButton)
1914  button = 2;
1915  else if (event->button() == Qt::RightButton)
1916  button = 3;
1917  } else if (QGraphicsSceneWheelEvent *event = dynamic_cast<QGraphicsSceneWheelEvent*>(e)) {
1918  items = d->scene->items(mapToScene(event->pos()));
1919  pos = event->pos();
1920 
1921  if (event->delta() > 0)
1922  button = 4;
1923  else
1924  button = 5;
1925  }
1926 
1927  if (button == 3 && !d->wantRightButton) {
1928  return 0;
1929  }
1930 
1931  foreach(QGraphicsItem *item, items) {
1932  bool pass = false;
1933  bool allowClick = false;
1934 
1935  if (item == this)
1936  continue;
1937 
1938  else if (ImageLabel* image = dynamic_cast<ImageLabel*>(item)) {
1939  allowClick = image->clickable();
1940  pass = image->mouseEvent(e);
1941  } else if (TextLabel* text = dynamic_cast<TextLabel*>(item)) {
1942  allowClick = text->clickable();
1943  pass = text->mouseEvent(e);
1944  } else if (ClickArea* area = dynamic_cast<ClickArea*>(item)) {
1945  pass = area->mouseEvent(e);
1946  } else if (RichTextLabel* rich = dynamic_cast<RichTextLabel*>(item)) {
1947  allowClick = false;
1948  pass = rich->mouseEvent(e);
1949  if (pass) {
1950  QString anchor = rich->getAnchor(pos);
1951  #ifdef PYTHON_INCLUDE_PATH
1952  if (d->python)
1953  d->python->meterClicked(this, anchor.toAscii().data(), button);
1954  #endif
1955  if (d->interface)
1956  d->interface->callMeterClicked(this, anchor, button);
1957  }
1958  }
1959 
1960  if (Input *input = dynamic_cast<Input*>(item)) {
1961  input->setFocus();
1962  input->mouseEvent(e);
1963  }
1964 
1965  if (pass && allowClick) {
1966  #ifdef PYTHON_INCLUDE_PATH
1967  if (d->python)
1968  d->python->meterClicked(this, (Meter*)item, button);
1969  #endif
1970 
1971  if (d->interface)
1972  d->interface->callMeterClicked(this, (Meter*)item, button);
1973  }
1974  }
1975 
1976  return button;
1977 }
1978 
1979 void Karamba::wheelEvent(QGraphicsSceneWheelEvent *event)
1980 {
1981  int button = passEvent(event);
1982 
1983 #ifdef PYTHON_INCLUDE_PATH
1984  if (d->python)
1985  d->python->widgetClicked(this, (int)event->pos().x(), (int)event->pos().y(), button);
1986 #endif
1987 
1988  if (d->interface)
1989  d->interface->callWidgetClicked(this, (int)event->pos().x(), (int)event->pos().y(), button);
1990 }
1991 
1992 void Karamba::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
1993 {
1994  QList<QGraphicsItem*>items = d->scene->items(mapToScene(event->pos()));
1995  foreach (QGraphicsItem *item, items) {
1996  if (Input *input = dynamic_cast<Input*>(item)) {
1997  input->mouseEventMove(event);
1998  }
1999  }
2000 
2001  foreach (QGraphicsItem *item, QGraphicsItemGroup::children()) {
2002  if (ImageLabel *image = dynamic_cast<ImageLabel*>(item)) {
2003  image->rolloverImage(event);
2004  }
2005  }
2006 
2007 #ifdef PYTHON_INCLUDE_PATH
2008  if (d->python)
2009  d->python->widgetMouseMoved(this, (int)event->pos().x(), (int)event->pos().y(), 0/*button*/);
2010 #endif
2011 
2012  if (d->interface)
2013  d->interface->callWidgetMouseMoved(this, (int)event->pos().x(), (int)event->pos().y(), 0/*button*/);
2014 
2015 }
2016 
2017 QGraphicsScene* Karamba::getScene() const
2018 {
2019  return d->scene;
2020 }
2021 
2022 QGraphicsView* Karamba::getView() const
2023 {
2024  return d->view;
2025 }
2026 
2027 int Karamba::getNumberOfDesktops() const
2028 {
2029  return d->KWinModule->numberOfDesktops();
2030 }
2031 
2032 void Karamba::changeInterval(u_int newInterval)
2033 {
2034  d->interval = newInterval;
2035 }
2036 
2037 double Karamba::getUpdateTime() const
2038 {
2039  return d->updateTime;
2040 }
2041 
2042 void Karamba::setUpdateTime(double newTime)
2043 {
2044  d->updateTime = newTime;
2045 }
2046 
2047 void Karamba::keyPressed(const QString& s, const Meter* meter)
2048 {
2049  if (s.isEmpty()) {
2050  return;
2051  }
2052 
2053 #ifdef PYTHON_INCLUDE_PATH
2054  if (d->python) {
2055  d->python->keyPressed(this, meter, s);
2056  }
2057 #endif
2058 
2059  if (d->interface) {
2060  d->interface->callKeyPressed(this, (Meter*)meter, s);
2061  }
2062 }
2063 
2064 void Karamba::setFixedSize(u_int w, u_int h)
2065 {
2066  d->size.setWidth(w);
2067  d->size.setHeight(h);
2068  emit sizeChanged();
2069 }
2070 
2071 const ThemeFile& Karamba::theme() const
2072 {
2073  return d->theme;
2074 }
2075 
2076 void Karamba::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
2077 {
2078  if (!d->globalView) {
2079  if (!d->toggleLocked->isChecked()) {
2080  d->view->move(event->screenPos() - d->mouseClickPos);
2081  }
2082  } else {
2083  if (!d->toggleLocked->isChecked()) {
2084  QPointF diff = event->pos() - d->mouseClickPos;
2085  parentItem()->moveBy(diff.x(), diff.y());
2086  }
2087  }
2088 }
2089 
2090 void Karamba::keyPressEvent(QKeyEvent *event)
2091 {
2092  QGraphicsItem *item = d->scene->focusItem();
2093 
2094  if (Input* input = dynamic_cast<Input*>(item)) {
2095  if (input && input->hasFocus()) {
2096  input->keyPress(event);
2097  }
2098  }
2099 
2100  keyPressed(event->text(), (Meter*)item);
2101 }
2102 
2103 QVariant Karamba::itemChange(GraphicsItemChange change, const QVariant &value)
2104 {
2105  if(change == QGraphicsItem::ItemPositionHasChanged) {
2106  emit positionChanged();
2107  }
2108  return QGraphicsItemGroup::itemChange(change, value);
2109 }
2110 
2111 void Karamba::slotFileChanged(const QString &file)
2112 {
2113  QString pythonFile = d->theme.path() + '/' + d->theme.scriptModule();
2114  if (file == d->theme.file() || file == pythonFile) {
2115  reloadConfig();
2116  }
2117 }
2118 
2119 void Karamba::setMenuExtension(KMenu *menu)
2120 {
2121  d->popupMenu->addSeparator();
2122 
2123  d->globalMenu = menu;
2124  d->popupMenu->addMenu(menu);
2125 }
2126 
2127 void Karamba::removeMenuExtension()
2128 {
2129  d->popupMenu->removeAction(d->globalMenu->menuAction());
2130  d->globalMenu = 0; // d->globalMenu is deleted in removeAction
2131 }
2132 
2133 bool Karamba::hasMenuExtension() const
2134 {
2135  return d->globalMenu != 0;
2136 }
2137 
2138 int Karamba::instance()
2139 {
2140  return d->instance;
2141 }
2142 
2143 void Karamba::setInstance(int instance)
2144 {
2145  d->instance = instance;
2146 }
2147 
2148 void Karamba::moveToPos(QPoint pos)
2149 {
2150  if (!d->globalView) {
2151  d->view->move(pos);
2152  } else {
2153  if (parentItem()) {
2154  setPos(0,0);
2155  parentItem()->setPos(pos);
2156  } else {
2157  setPos(pos);
2158  }
2159  }
2160  emit positionChanged();
2161 }
2162 
2163 void Karamba::resizeTo(int width, int height)
2164 {
2165  if (!d->globalView) {
2166  d->view->setFixedSize(width, height);
2167  }
2168 
2169  setFixedSize(width, height);
2170 }
2171 
2172 QPoint Karamba::getPosition() const
2173 {
2174  if (!d->globalView) {
2175  return d->view->pos();
2176  } else {
2177  if (parentItem()) {
2178  return parentItem()->pos().toPoint();
2179  } else {
2180  return pos().toPoint();
2181  }
2182  }
2183 }
2184 
2185 void Karamba::setIncomingData(const QString &data)
2186 {
2187  d->storedData = data;
2188 }
2189 
2190 void Karamba::notifyTheme(const QString &sender, const QString &data)
2191 {
2192  d->interface->callThemeNotify(this, sender, data);
2193 }
2194 
2195 bool Karamba::sendDataToTheme(const QString &prettyThemeName, const QString &data)
2196 {
2197  Karamba *k = KarambaManager::self()->getKarambaByName(prettyThemeName);
2198  if (k == 0) {
2199  return false;
2200  }
2201 
2202  k->notifyTheme(d->prettyName, data);
2203 
2204  return true;
2205 }
2206 
2207 QString Karamba::retrieveReceivedData() const
2208 {
2209  return d->storedData;
2210 }
2211 
2212 bool Karamba::sendData(const QString &prettyThemeName, const QString &data)
2213 {
2214  Karamba *k = KarambaManager::self()->getKarambaByName(prettyThemeName);
2215  if (k == 0) {
2216  return false;
2217  }
2218 
2219  k->setIncomingData(data);
2220 
2221  return true;
2222 }
2223 
2224 bool Karamba::isSubTheme() const
2225 {
2226  return d->subTheme;
2227 }
2228 
2229 void Karamba::setProcess(K3Process *process)
2230 {
2231  delete d->currProcess;
2232  d->currProcess = process;
2233 }
2234 
2235 K3Process* Karamba::process() const
2236 {
2237  return d->currProcess;
2238 }
2239 
2240 void Karamba::setSystemTray(Systemtray *systray)
2241 {
2242  d->systray = systray;
2243 }
2244 
2245 Systemtray* Karamba::systemTray()
2246 {
2247  return d->systray;
2248 }
2249 
2250 QObject* Karamba::getPlasmaSensor(const QString& engine, const QString& source)
2251 {
2252 #ifdef PLASMASENSOR_ENABLED
2253  Sensor* sensor = d->sensorMap["PLASMA." + engine + '.' + source];
2254  if (sensor == 0) {
2255  PlasmaSensor* plasmasensor = new PlasmaSensor();
2256  plasmasensor->setEngine(engine);
2257  sensor = plasmasensor;
2258  d->sensorMap["PLASMA." + engine + '.' + source] = sensor;
2259  d->sensorList.append(sensor);
2260  }
2261  return sensor;
2262 #else
2263  Q_UNUSED(engine);
2264  Q_UNUSED(source);
2265  return 0;
2266 #endif
2267 }
2268 
2269 QString Karamba::getMeterValue(const QString& name)
2270 {
2271  if ( ! name.isNull() ) {
2272  Meter* meter = (Meter*) getMeter(name);
2273  if(meter != 0) {
2274  QString retVal = meter->getStringValue();
2275  if( retVal.isEmpty() ) {
2276  int intVal = meter->getValue();
2277  // if intVal > minimum, consider it a valid value
2278  if ( intVal >= meter->getMin() ) {
2279  retVal = QString::number(intVal);
2280  }
2281  }
2282  return retVal;
2283  }
2284  }
2285  return QString("");
2286 }
2287 
2288 void Karamba::replaceNamedValues(QString* source)
2289 {
2290  //kDebug() << "%named replacement before:'" + *source + "'";
2291  QRegExp rx ("%named:(\\w+)", Qt::CaseInsensitive);
2292  int pos = 0;
2293  while ( pos >= 0 ) {
2294  pos = rx.indexIn(*source, pos);
2295  if ( pos >= 0 ) {
2296  QString namedReplacement = rx.cap(1);
2297  if( !namedReplacement.isEmpty() ) {
2298  QString replacementValue = getMeterValue(namedReplacement);
2299  if( replacementValue.isNull()) {
2300  replacementValue = QString("");
2301  }
2302  source->replace(QRegExp("%named:" + namedReplacement, Qt::CaseInsensitive), replacementValue);
2303  }
2304  }
2305  }
2306  //kDebug() << "%named replacement after:'" + *source + "'";
2307 }
2308 
2309 Meter* Karamba::getMeter(const QString& name)
2310 {
2311  //meterList...how I miss thee
2312  QList<QGraphicsItem*> items = QGraphicsItemGroup::children();
2313  foreach (QGraphicsItem *item, items) {
2314  if (Meter* meter = dynamic_cast<Meter*>(item)) {
2315  if(name == meter->objectName()){
2316  return (Meter*) meter;
2317  }
2318  }
2319  }
2320  return 0;
2321 }
2322 
2323 void Karamba::emitError(const QString& errormessage)
2324 {
2325  emit error(errormessage);
2326 }
sensorparams.h
Karamba::deletePopupMenu
void deletePopupMenu(KMenu *menu)
Definition: karamba.cpp:1625
KarambaManager::removeKaramba
void removeKaramba(Karamba *karamba)
Definition: karambamanager.cpp:62
Karamba::updateSensors
void updateSensors()
Definition: karamba.cpp:1363
superkarambasettings.h
input.h
rss.h
Meter::getHeight
virtual int getHeight() const
Definition: meters/meter.cpp:97
Karamba::moveMeter
void moveMeter(Meter *meter, int x, int y) const
Definition: karamba.cpp:1657
TextField::getFontSize
int getFontSize() const
Definition: textfield.cpp:99
Karamba::makePassive
void makePassive()
Definition: karamba.cpp:981
Karamba::getScene
QGraphicsScene * getScene() const
Definition: karamba.cpp:2017
Karamba::makeActive
void makeActive()
Definition: karamba.cpp:973
TextField::setBGColor
void setBGColor(QColor clr)
Definition: textfield.cpp:70
graph.h
Meter::getWidth
virtual int getWidth() const
Definition: meters/meter.cpp:83
ThemeFile
Definition: themefile.h:41
Karamba::emitError
void emitError(const QString &errormessage)
Definition: karamba.cpp:2323
mem.h
Karamba::startKaramba
void startKaramba()
Definition: karamba.cpp:470
TextField::getShadow
int getShadow() const
Definition: textfield.cpp:150
Karamba::moveToPos
void moveToPos(QPoint pos)
Definition: karamba.cpp:2148
hide
int hide(long widget)
Definition: misc.cpp:618
Karamba::startupAdded
void startupAdded(Startup::StartupPtr)
Definition: karamba.cpp:1778
TextLabel
Definition: meters/textlabel.h:19
LineParser::meter
const QString & meter() const
Definition: lineparser.h:19
TextField::setFont
void setFont(const QString &)
Definition: textfield.cpp:81
Karamba::slotFileChanged
void slotFileChanged(const QString &file)
Definition: karamba.cpp:2111
TextField::setShadow
void setShadow(int)
Definition: textfield.cpp:145
KarambaManager::addKaramba
void addKaramba(Karamba *newKaramba)
Definition: karambamanager.cpp:56
LineParser::getColor
QColor getColor(const QString &w, const QColor &def=QColor()) const
Definition: lineparser.cpp:53
TextField::getFont
QString getFont() const
Definition: textfield.cpp:88
lmsensor.h
Karamba::process
K3Process * process() const
Definition: karamba.cpp:2235
Karamba::popupGlobalMenu
void popupGlobalMenu() const
Definition: karamba.cpp:1677
Karamba::keyPressed
void keyPressed(const QString &s, const Meter *meter)
Definition: karamba.cpp:2047
Karamba::prettyName
QString prettyName() const
Definition: karamba.cpp:511
Karamba::getView
QGraphicsView * getView() const
Definition: karamba.cpp:2022
Karamba::keyPressEvent
void keyPressEvent(QKeyEvent *event)
Definition: karamba.cpp:2090
RichTextLabel::setTextProps
void setTextProps(TextField *t)
Definition: meters/richtextlabel.cpp:130
Graph
Definition: meters/graph.h:19
Meter::getMin
virtual int getMin() const
Definition: meters/meter.cpp:111
Meter::setSize
virtual void setSize(int x, int y, int width, int height)
Definition: meters/meter.cpp:159
clickmap.h
Sensor::start
void start()
Definition: sensor.cpp:19
Karamba::Karamba
Karamba(const KUrl &themeFile, QGraphicsView *view=0, int instance=-1, bool subTheme=false, const QPoint &startPos=QPoint(), bool reload=false, bool startkaramba=true)
Definition: karamba.cpp:263
imagelabel.h
QGraphicsItem
Karamba::setSystemTray
void setSystemTray(Systemtray *)
Definition: karamba.cpp:2240
Karamba::getMeterValue
QString getMeterValue(const QString &name)
Definition: karamba.cpp:2269
Karamba::addPopupMenu
KMenu * addPopupMenu()
Definition: karamba.cpp:1599
QWidget
Karamba::removeMenuExtension
void removeMenuExtension()
Definition: karamba.cpp:2127
Karamba::setMenuExtension
void setMenuExtension(KMenu *)
Definition: karamba.cpp:2119
NetworkSensor
Definition: network.h:36
Karamba::setFixedSize
void setFixedSize(u_int w, u_int h)
Definition: karamba.cpp:2064
MemSensor
Definition: mem.h:23
themelocale.h
ImageLabel::parseImages
void parseImages(const QString &fn, const QString &fn_roll, int, int, int, int)
Definition: meters/imagelabel.cpp:434
karamba.h
uptime.h
DiskSensor
Definition: disk.h:17
Bar::setVertical
void setVertical(bool)
Definition: meters/bar.cpp:139
Karamba::hasMenuExtension
bool hasMenuExtension() const
Definition: karamba.cpp:2133
CPUSensor
Definition: cpu.h:15
Karamba::deleteMeterFromSensors
void deleteMeterFromSensors(Meter *meter)
Definition: karamba.cpp:1027
TextField::getColor
QColor getColor() const
Definition: textfield.cpp:65
ClickMap::setTextProps
void setTextProps(TextField *)
Definition: clickmap.cpp:40
Karamba::redrawWidget
void redrawWidget()
Definition: karamba.cpp:536
LineParser::getString
QString getString(const QString &w, const QString &def=QString()) const
Definition: lineparser.cpp:68
QObject
Karamba::notifyTheme
void notifyTheme(const QString &sender, const QString &data)
Definition: karamba.cpp:2190
TextLabel::setValue
void setValue(const QString &text)
Definition: meters/textlabel.cpp:144
Sensor
Definition: sensor.h:17
KarambaManager::getKarambaByName
Karamba * getKarambaByName(const QString &name) const
Definition: karambamanager.cpp:80
Sensor::hasMeter
SensorParams * hasMeter(const Meter *meter) const
Definition: sensor.cpp:43
Karamba::startupRemoved
void startupRemoved(Startup::StartupPtr)
Definition: karamba.cpp:1789
TextField::getBGColor
QColor getBGColor() const
Definition: textfield.cpp:75
Karamba::positionChanged
void positionChanged()
Karamba::theme
const ThemeFile & theme() const
Definition: karamba.cpp:2071
Karamba::getMeter
Meter * getMeter(const QString &name)
Definition: karamba.cpp:2309
Karamba::processExited
void processExited(K3Process *proc)
Definition: karamba.cpp:1800
Karamba::mouseMoveEvent
void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
Definition: karamba.cpp:2076
ClickArea::setOnClick
void setOnClick(const QString &)
Definition: clickarea.cpp:58
Karamba::setProcess
void setProcess(K3Process *process)
Definition: karamba.cpp:2229
Karamba::mousePressEvent
void mousePressEvent(QGraphicsSceneMouseEvent *event)
Definition: karamba.cpp:1845
karambainterface.h
TextField::setAlignment
void setAlignment(int)
Definition: textfield.cpp:115
Meter::getStringValue
virtual QString getStringValue() const
Definition: meters/meter.cpp:140
Input::setTextProps
void setTextProps(TextField *)
Definition: meters/input.cpp:454
Startup::StartupPtr
KSharedPtr< Startup > StartupPtr
Definition: taskmanager.h:555
Karamba
Definition: karamba.h:52
Sensor::deleteMeter
void deleteMeter(Meter *meter)
Definition: sensor.cpp:55
richtextlabel.h
ImageLabel::hide
virtual void hide()
Definition: meters/imagelabel.cpp:187
Bar
Definition: meters/bar.h:18
Bar::setImage
bool setImage(const QString &imagePath)
Definition: meters/bar.cpp:38
Graph::setPlotDirection
void setPlotDirection(const QString &)
Definition: meters/graph.cpp:105
TextField::setColor
void setColor(QColor clr)
Definition: textfield.cpp:60
program.h
karamba.h
Input::setValue
void setValue(const QString &text)
Definition: meters/input.cpp:329
Karamba::changeInterval
void changeInterval(u_int newInterval)
Definition: karamba.cpp:2032
Karamba::replaceNamedValues
void replaceNamedValues(QString *source)
Definition: karamba.cpp:2288
sensor.h
TextField::setFixedPitch
void setFixedPitch(bool)
Definition: textfield.cpp:135
Karamba::reloadConfig
void reloadConfig()
Definition: karamba.cpp:1424
Karamba::getSensor
QString getSensor(const Meter *meter) const
Definition: karamba.cpp:1043
Karamba::setWantRightButton
void setWantRightButton(bool enable)
Definition: karamba.cpp:1885
SensorParams::addParam
void addParam(const QString &name, const QString &value)
Definition: sensorparams.cpp:21
Karamba::retrieveReceivedData
QString retrieveReceivedData() const
Definition: karamba.cpp:2207
Karamba::passMenuItemClicked
void passMenuItemClicked(QAction *action)
Definition: karamba.cpp:1665
textfield.h
LineParser::getBoolean
bool getBoolean(const QString &w, bool def=false) const
Definition: lineparser.cpp:90
plasmaengine.h
Karamba::popupMenuExisting
bool popupMenuExisting(const KMenu *menu) const
Definition: karamba.cpp:1644
Karamba::addMenuItem
QAction * addMenuItem(KMenu *menu, const QString &text, const QString &icon)
Definition: karamba.cpp:1610
SensorParams
Hans Karlsson.
Definition: sensorparams.h:30
textlabel.h
lineparser.h
Sensor::update
virtual void update()=0
Karamba::isSubTheme
bool isSubTheme() const
Definition: karamba.cpp:2224
Karamba::resizeTo
void resizeTo(int width, int height)
Definition: karamba.cpp:2163
TextField::getFixedPitch
bool getFixedPitch() const
Definition: textfield.cpp:140
Karamba::activeTaskChanged
void activeTaskChanged(Task::TaskPtr)
Definition: karamba.cpp:1745
Karamba::getNumberOfDesktops
int getNumberOfDesktops() const
Definition: karamba.cpp:2027
SensorSensor
Hans Karlsson.
Definition: lmsensor.h:14
PlasmaSensorConnector
This is a helper class that connects a Plasma::DataEngine together with a SuperKaramba Meter widget...
Definition: plasmaengine.h:36
LineParser
Definition: lineparser.h:6
Karamba::mouseReleaseEvent
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
Definition: karamba.cpp:1872
Karamba::writeConfigData
void writeConfigData()
Definition: karamba.cpp:1394
Meter::hide
virtual void hide()
Definition: meters/meter.cpp:186
startKaramba
KDE_EXPORT QGraphicsItemGroup * startKaramba(const KUrl &theme, QGraphicsView *view)
Definition: karamba.cpp:89
Karamba::paint
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
Definition: karamba.cpp:1693
TextLabel::hide
virtual void hide()
Definition: meters/textlabel.cpp:78
RichTextLabel
Definition: meters/richtextlabel.h:24
PlasmaSensor::setEngine
virtual void setEngine(const QString &name)
Set the engine that should be used.
Definition: plasmaengine.cpp:166
ProgramSensor
Definition: program.h:21
Bar::setMin
virtual void setMin(int m)
Definition: meters/bar.cpp:133
bar.h
network.h
Karamba::popupMenu
void popupMenu(KMenu *menu, const QPoint &pos) const
Definition: karamba.cpp:1616
Karamba::setPrettyName
void setPrettyName(const QString &prettyThemeName)
Definition: karamba.cpp:516
Karamba::setOnTop
void setOnTop(bool stayOnTop)
Definition: karamba.cpp:1438
Graph::setScrollDirection
void setScrollDirection(const QString &)
Definition: meters/graph.cpp:90
Meter::getValue
virtual int getValue() const
Definition: meters/meter.cpp:131
textfile.h
ImageLabel::setTooltip
void setTooltip(QString txt)
Definition: meters/imagelabel.cpp:553
karambamanager.h
Systemtray
Definition: systemtray.h:35
Karamba::getUpdateTime
double getUpdateTime() const
Definition: karamba.cpp:2037
Karamba::setIncomingData
void setIncomingData(const QString &data)
Definition: karamba.cpp:2185
KarambaManager::self
static KarambaManager * self()
Definition: karambamanager.cpp:47
DateSensor
Definition: date.h:27
Karamba::error
void error(const QString &errormessage)
Meter::setMax
virtual void setMax(int max)
Definition: meters/meter.cpp:126
Karamba::~Karamba
virtual ~Karamba()
Definition: karamba.cpp:460
KarambaInterface
Definition: karambainterface.h:42
Input
Definition: meters/input.h:32
ClickArea
Hans Karlsson.
Definition: clickarea.h:36
ImageLabel::setValue
void setValue(const QString &imagePath)
Definition: meters/imagelabel.cpp:299
cpu.h
Sensor::setMaxValue
virtual void setMaxValue(SensorParams *s)
Definition: sensor.cpp:65
Karamba::receivedStdout
void receivedStdout(K3Process *proc, char *buffer, int buflen)
Definition: karamba.cpp:1811
mainwidget.h
Karamba::setUpdateTime
void setUpdateTime(double newTime)
Definition: karamba.cpp:2042
Karamba::itemChange
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
Definition: karamba.cpp:2103
Graph::setFillColor
void setFillColor(QColor)
Definition: meters/graph.cpp:37
TaskManager::self
static TaskManager * self()
Definition: taskmanager.cpp:49
Karamba::getPlasmaSensor
QObject * getPlasmaSensor(const QString &engine, const QString &source=QString())
Definition: karamba.cpp:2250
clickarea.h
ImageLabel::setBackground
void setBackground(int b)
Definition: meters/imagelabel.cpp:514
UptimeSensor
Definition: uptime.h:15
Karamba::hasMeter
bool hasMeter(const Meter *meter) const
Definition: karamba.cpp:1682
Karamba::deleteMenuItem
void deleteMenuItem(QAction *action)
Definition: karamba.cpp:1633
Karamba::hoverMoveEvent
void hoverMoveEvent(QGraphicsSceneHoverEvent *event)
Definition: karamba.cpp:1992
PlasmaSensor::connectSource
virtual QObject * connectSource(const QString &source, QObject *visualization=0)
Connect with a source.
Definition: plasmaengine.cpp:216
Meter::setColor
virtual void setColor(QColor color)
Definition: meters/meter.cpp:154
Karamba::taskAdded
void taskAdded(Task::TaskPtr)
Definition: karamba.cpp:1756
Karamba::getConfig
KConfig * getConfig() const
Definition: karamba.cpp:1389
Meter::setMin
virtual void setMin(int min)
Definition: meters/meter.cpp:116
Meter
Definition: meters/meter.h:23
Sensor::isEmpty
int isEmpty()
Definition: sensor.h:28
Karamba::getDefaultTextProps
TextField * getDefaultTextProps()
Definition: karamba.cpp:1000
TextLabel::setTextProps
void setTextProps(TextField *)
Definition: meters/textlabel.cpp:84
Karamba::setMenuConfigOption
bool setMenuConfigOption(const QString &key, bool value)
Definition: karamba.cpp:1572
Karamba::removeMeter
bool removeMeter(Meter *meter)
Definition: karamba.cpp:1053
Karamba::addMenuConfigOption
void addMenuConfigOption(const QString &key, const QString &name)
Definition: karamba.cpp:1543
Karamba::dropEvent
void dropEvent(QGraphicsSceneDragDropEvent *event)
Definition: karamba.cpp:1829
QGraphicsItemGroup
Karamba::closeWidget
void closeWidget()
Definition: karamba.cpp:1376
Karamba::instance
int instance()
Definition: karamba.cpp:2138
Karamba::wheelEvent
void wheelEvent(QGraphicsSceneWheelEvent *event)
Definition: karamba.cpp:1979
QGraphicsView
Karamba::taskRemoved
void taskRemoved(Task::TaskPtr)
Definition: karamba.cpp:1767
Karamba::boundingRect
QRectF boundingRect() const
Definition: karamba.cpp:1688
Karamba::systemTray
Systemtray * systemTray()
Definition: karamba.cpp:2245
Karamba::setInstance
void setInstance(int instance)
Definition: karamba.cpp:2143
TextFileSensor
Hans Karlsson.
Definition: textfile.h:33
ClickMap
Definition: clickmap.h:17
karambaapp.h
Karamba::dragEnterEvent
void dragEnterEvent(QGraphicsSceneDragDropEvent *event)
Definition: karamba.cpp:1822
Karamba::scaleImageLabel
void scaleImageLabel(Meter *meter, int width, int height) const
Definition: karamba.cpp:1649
Karamba::setSensor
void setSensor(const LineParser &lineParser, Meter *meter)
Definition: karamba.cpp:1065
Karamba::readMenuConfigOption
bool readMenuConfigOption(const QString &key) const
Definition: karamba.cpp:1586
TextField::setFontSize
void setFontSize(int)
Definition: textfield.cpp:93
Karamba::getPosition
QPoint getPosition() const
Definition: karamba.cpp:2172
PlasmaSensor
The PlasmaSensor class implements a SuperKaramba sensor that provides access to Plasma::DataEngine ob...
Definition: plasmaengine.h:97
date.h
Task::TaskPtr
KSharedPtr< Task > TaskPtr
Definition: taskmanager.h:97
TextField
Ralph M.
Definition: textfield.h:22
TextField::getAlignmentAsString
QString getAlignmentAsString() const
Definition: textfield.cpp:125
Bar::setValue
void setValue(const QString &)
Definition: meters/bar.cpp:82
PlasmaSensor::setProperty
void setProperty(const QByteArray &name, const QVariant &value)
Set a property.
Definition: plasmaengine.cpp:204
Karamba::sendDataToTheme
bool sendDataToTheme(const QString &prettyThemeName, const QString &data)
Definition: karamba.cpp:2195
Karamba::sizeChanged
void sizeChanged()
RichTextLabel::setText
void setText(const QString &text, bool linkUnderline=false)
Definition: meters/richtextlabel.cpp:54
Karamba::timerEvent
void timerEvent(QTimerEvent *event)
Definition: karamba.cpp:1714
Karamba::sendData
bool sendData(const QString &prettyThemeName, const QString &data)
Definition: karamba.cpp:2212
Karamba::contextMenuEvent
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
Definition: karamba.cpp:1738
Bar::setMax
virtual void setMax(int m)
Definition: meters/bar.cpp:127
LineParser::getInt
int getInt(const QString &w, int def=0) const
Definition: lineparser.cpp:44
KarambaPython
Definition: python/karamba.h:40
disk.h
MainWidget
Definition: mainwidget.h:28
ImageLabel
Definition: meters/imagelabel.h:108
Sensor::addMeter
void addMeter(SensorParams *s)
Definition: sensor.cpp:38
systemtray.h
show
int show(long widget)
Definition: misc.cpp:600
RssSensor
Definition: rss.h:18
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:07:19 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

superkaramba

Skip menu "superkaramba"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeutils API Reference

Skip menu "kdeutils API Reference"
  • ark
  • filelight
  • kcalc
  • kcharselect
  • kdf
  • kfloppy
  • kgpg
  • kremotecontrol
  • ktimer
  • kwallet
  • superkaramba
  • sweeper

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal