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

Plasma

  • sources
  • kde-4.12
  • kdelibs
  • plasma
applet.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2005 by Aaron Seigo <aseigo@kde.org>
3  * Copyright 2007 by Riccardo Iaconelli <riccardo@kde.org>
4  * Copyright 2008 by Ménard Alexis <darktears31@gmail.com>
5  * Copyright (c) 2009 Chani Armitage <chani@kde.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Library General Public License as
9  * published by the Free Software Foundation; either version 2, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this program; if not, write to the
19  * Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 #include "applet.h"
24 #include "private/applet_p.h"
25 
26 #include "config-plasma.h"
27 
28 #include <plasma/animations/animation.h>
29 
30 #include <cmath>
31 #include <limits>
32 
33 #include <QApplication>
34 #include <QEvent>
35 #include <QFile>
36 #include <QGraphicsGridLayout>
37 #include <QGraphicsSceneMouseEvent>
38 #include <QGraphicsView>
39 #include <QHostInfo>
40 #include <QLabel>
41 #include <QList>
42 #include <QGraphicsLinearLayout>
43 #include <QPainter>
44 #include <QRegExp>
45 #include <QSize>
46 #include <QStyleOptionGraphicsItem>
47 #include <QTextDocument>
48 #include <QUiLoader>
49 #include <QVBoxLayout>
50 #include <QWidget>
51 
52 #include <kaction.h>
53 #include <kactioncollection.h>
54 #include <kauthorized.h>
55 #include <kcolorscheme.h>
56 #include <kdialog.h>
57 #include <kdesktopfile.h>
58 #include <kicon.h>
59 #include <kiconloader.h>
60 #include <kkeysequencewidget.h>
61 #include <kplugininfo.h>
62 #include <kstandarddirs.h>
63 #include <kservice.h>
64 #include <kservicetypetrader.h>
65 #include <kshortcut.h>
66 #include <kwindowsystem.h>
67 #include <kpushbutton.h>
68 
69 #ifndef PLASMA_NO_KUTILS
70 #include <kcmoduleinfo.h>
71 #include <kcmoduleproxy.h>
72 #else
73 #include <kcmodule.h>
74 #endif
75 
76 #ifndef PLASMA_NO_SOLID
77 #include <solid/powermanagement.h>
78 #endif
79 
80 #include "abstracttoolbox.h"
81 #include "authorizationmanager.h"
82 #include "authorizationrule.h"
83 #include "configloader.h"
84 #include "containment.h"
85 #include "corona.h"
86 #include "dataenginemanager.h"
87 #include "dialog.h"
88 #include "extenders/extender.h"
89 #include "extenders/extenderitem.h"
90 #include "package.h"
91 #include "plasma.h"
92 #include "scripting/appletscript.h"
93 #include "svg.h"
94 #include "framesvg.h"
95 #include "popupapplet.h"
96 #include "private/applethandle_p.h"
97 #include "private/extenderitem_p.h"
98 #include "private/framesvg_p.h"
99 #include "theme.h"
100 #include "view.h"
101 #include "widgets/iconwidget.h"
102 #include "widgets/label.h"
103 #include "widgets/pushbutton.h"
104 #include "widgets/busywidget.h"
105 #include "tooltipmanager.h"
106 #include "wallpaper.h"
107 #include "paintutils.h"
108 #include "abstractdialogmanager.h"
109 #include "pluginloader.h"
110 
111 #include "private/associatedapplicationmanager_p.h"
112 #include "private/authorizationmanager_p.h"
113 #include "private/containment_p.h"
114 #include "private/extenderapplet_p.h"
115 #include "private/package_p.h"
116 #include "private/packages_p.h"
117 #include "private/plasmoidservice_p.h"
118 #include "private/popupapplet_p.h"
119 #include "private/remotedataengine_p.h"
120 #include "private/service_p.h"
121 #include "ui_publish.h"
122 
123 
124 namespace Plasma
125 {
126 
127 Applet::Applet(const KPluginInfo &info, QGraphicsItem *parent, uint appletId)
128  : QGraphicsWidget(parent),
129  d(new AppletPrivate(KService::Ptr(), &info, appletId, this))
130 {
131  // WARNING: do not access config() OR globalConfig() in this method!
132  // that requires a scene, which is not available at this point
133  d->init();
134 }
135 
136 Applet::Applet(QGraphicsItem *parent, const QString &serviceID, uint appletId)
137  : QGraphicsWidget(parent),
138  d(new AppletPrivate(KService::serviceByStorageId(serviceID), 0, appletId, this))
139 {
140  // WARNING: do not access config() OR globalConfig() in this method!
141  // that requires a scene, which is not available at this point
142  d->init();
143 }
144 
145 Applet::Applet(QGraphicsItem *parent,
146  const QString &serviceID,
147  uint appletId,
148  const QVariantList &args)
149  : QGraphicsWidget(parent),
150  d(new AppletPrivate(KService::serviceByStorageId(serviceID), 0, appletId, this))
151 {
152  // WARNING: do not access config() OR globalConfig() in this method!
153  // that requires a scene, which is not available at this point
154 
155  QVariantList &mutableArgs = const_cast<QVariantList &>(args);
156  if (!mutableArgs.isEmpty()) {
157  mutableArgs.removeFirst();
158 
159  if (!mutableArgs.isEmpty()) {
160  mutableArgs.removeFirst();
161  }
162  }
163 
164  d->args = mutableArgs;
165 
166  d->init();
167 }
168 
169 Applet::Applet(QObject *parentObject, const QVariantList &args)
170  : QGraphicsWidget(0),
171  d(new AppletPrivate(
172  KService::serviceByStorageId(args.count() > 0 ? args[0].toString() : QString()), 0,
173  args.count() > 1 ? args[1].toInt() : 0, this))
174 {
175  // now remove those first two items since those are managed by Applet and subclasses shouldn't
176  // need to worry about them. yes, it violates the constness of this var, but it lets us add
177  // or remove items later while applets can just pretend that their args always start at 0
178  QVariantList &mutableArgs = const_cast<QVariantList &>(args);
179  if (!mutableArgs.isEmpty()) {
180  mutableArgs.removeFirst();
181 
182  if (!mutableArgs.isEmpty()) {
183  mutableArgs.removeFirst();
184  }
185  }
186 
187  d->args = mutableArgs;
188 
189  setParent(parentObject);
190 
191  // WARNING: do not access config() OR globalConfig() in this method!
192  // that requires a scene, which is not available at this point
193  d->init();
194 
195  // the brain damage seen in the initialization list is due to the
196  // inflexibility of KService::createInstance
197 }
198 
199 Applet::Applet(const QString &packagePath, uint appletId, const QVariantList &args)
200  : QGraphicsWidget(0),
201  d(new AppletPrivate(KService::Ptr(new KService(packagePath + "/metadata.desktop")), 0, appletId, this))
202 {
203  Q_UNUSED(args) // FIXME?
204  d->init(packagePath);
205 }
206 
207 Applet::~Applet()
208 {
209  //let people know that i will die
210  emit appletDestroyed(this);
211 
212  if (!d->transient && d->extender) {
213  //This would probably be nicer if it was located in extender. But in it's dtor, this won't
214  //work since when that get's called, the applet's config() isn't accessible anymore. (same
215  //problem with calling saveState(). Doing this in saveState() might be a possibility, but
216  //that would require every extender savestate implementation to call it's parent function,
217  //which isn't very nice.
218  d->extender.data()->saveState();
219 
220  foreach (ExtenderItem *item, d->extender.data()->attachedItems()) {
221  if (item->autoExpireDelay()) {
222  //destroy temporary extender items, or items that aren't detached, so their
223  //configuration won't linger after a plasma restart.
224  item->destroy();
225  }
226  }
227  }
228 
229  // clean up our config dialog, if any
230  delete KConfigDialog::exists(d->configDialogId());
231  delete d;
232 }
233 
234 PackageStructure::Ptr Applet::packageStructure()
235 {
236  if (!AppletPrivate::packageStructure) {
237  AppletPrivate::packageStructure = new PlasmoidPackage();
238  }
239 
240  return AppletPrivate::packageStructure;
241 }
242 
243 void Applet::init()
244 {
245  setFlag(ItemIsMovable, true);
246  if (d->script) {
247  d->setupScriptSupport();
248 
249  if (!d->script->init() && !d->failed) {
250  setFailedToLaunch(true, i18n("Script initialization failed"));
251  }
252  }
253 }
254 
255 uint Applet::id() const
256 {
257  return d->appletId;
258 }
259 
260 void Applet::save(KConfigGroup &g) const
261 {
262  if (d->transient) {
263  return;
264  }
265 
266  KConfigGroup group = g;
267  if (!group.isValid()) {
268  group = *d->mainConfigGroup();
269  }
270 
271  //kDebug() << "saving" << pluginName() << "to" << group.name();
272  // we call the dptr member directly for locked since isImmutable()
273  // also checks kiosk and parent containers
274  group.writeEntry("immutability", (int)d->immutability);
275  group.writeEntry("plugin", pluginName());
276 
277  group.writeEntry("geometry", geometry());
278  group.writeEntry("zvalue", zValue());
279 
280  if (!d->started) {
281  return;
282  }
283 
284  //FIXME: for containments, we need to have some special values here w/regards to
285  // screen affinity (e.g. "bottom of screen 0")
286  //kDebug() << pluginName() << "geometry is" << geometry()
287  // << "pos is" << pos() << "bounding rect is" << boundingRect();
288  if (transform() == QTransform()) {
289  group.deleteEntry("transform");
290  } else {
291  QList<qreal> m;
292  QTransform t = transform();
293  m << t.m11() << t.m12() << t.m13() << t.m21() << t.m22() << t.m23() << t.m31() << t.m32() << t.m33();
294  group.writeEntry("transform", m);
295  //group.writeEntry("transform", transformToString(transform()));
296  }
297 
298  KConfigGroup appletConfigGroup(&group, "Configuration");
299  saveState(appletConfigGroup);
300 
301  if (d->configLoader) {
302  // we're saving so we know its changed, we don't need or want the configChanged
303  // signal bubbling up at this point due to that
304  disconnect(d->configLoader, SIGNAL(configChanged()), this, SLOT(propagateConfigChanged()));
305  d->configLoader->writeConfig();
306  connect(d->configLoader, SIGNAL(configChanged()), this, SLOT(propagateConfigChanged()));
307  }
308 }
309 
310 void Applet::restore(KConfigGroup &group)
311 {
312  QList<qreal> m = group.readEntry("transform", QList<qreal>());
313  if (m.count() == 9) {
314  QTransform t(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
315  setTransform(t);
316  }
317 
318  qreal z = group.readEntry("zvalue", 0);
319 
320  if (z >= AppletPrivate::s_maxZValue) {
321  AppletPrivate::s_maxZValue = z;
322  }
323 
324  if (z > 0) {
325  setZValue(z);
326  }
327 
328  setImmutability((ImmutabilityType)group.readEntry("immutability", (int)Mutable));
329 
330  QRectF geom = group.readEntry("geometry", QRectF());
331  if (geom.isValid()) {
332  setGeometry(geom);
333  }
334 
335  KConfigGroup shortcutConfig(&group, "Shortcuts");
336  QString shortcutText = shortcutConfig.readEntryUntranslated("global", QString());
337  if (!shortcutText.isEmpty()) {
338  setGlobalShortcut(KShortcut(shortcutText));
339  /*
340  kDebug() << "got global shortcut for" << name() << "of" << QKeySequence(shortcutText);
341  kDebug() << "set to" << d->activationAction->objectName()
342  << d->activationAction->globalShortcut().primary();
343  */
344  }
345 
346  // local shortcut, if any
347  //TODO: implement; the shortcut will need to be registered with the containment
348  /*
349 #include "accessmanager.h"
350 #include "private/plasmoidservice_p.h"
351 #include "authorizationmanager.h"
352 #include "authorizationmanager.h"
353  shortcutText = shortcutConfig.readEntryUntranslated("local", QString());
354  if (!shortcutText.isEmpty()) {
355  //TODO: implement; the shortcut
356  }
357  */
358 }
359 
360 void AppletPrivate::setFocus()
361 {
362  //kDebug() << "setting focus";
363  q->setFocus(Qt::ShortcutFocusReason);
364 }
365 
366 void Applet::setFailedToLaunch(bool failed, const QString &reason)
367 {
368  if (d->failed == failed) {
369  if (failed && !reason.isEmpty()) {
370  foreach (QGraphicsItem *item, QGraphicsItem::children()) {
371  Label *l = dynamic_cast<Label *>(item);
372  if (l) {
373  l->setText(d->visibleFailureText(reason));
374  }
375  }
376  }
377  return;
378  }
379 
380  d->failed = failed;
381  prepareGeometryChange();
382 
383  foreach (QGraphicsItem *item, childItems()) {
384  if (!dynamic_cast<AppletHandle *>(item)) {
385  delete item;
386  }
387  }
388 
389  d->messageOverlay = 0;
390  if (d->messageDialog) {
391  d->messageDialog.data()->deleteLater();
392  d->messageDialog.clear();
393  }
394 
395  setLayout(0);
396 
397  if (failed) {
398  setBackgroundHints(d->backgroundHints|StandardBackground);
399 
400  QGraphicsLinearLayout *failureLayout = new QGraphicsLinearLayout(this);
401  failureLayout->setContentsMargins(0, 0, 0, 0);
402 
403  IconWidget *failureIcon = new IconWidget(this);
404  failureIcon->setIcon(KIcon("dialog-error"));
405  failureLayout->addItem(failureIcon);
406 
407  Label *failureWidget = new Plasma::Label(this);
408  failureWidget->setText(d->visibleFailureText(reason));
409  QLabel *label = failureWidget->nativeWidget();
410  label->setWordWrap(true);
411  failureLayout->addItem(failureWidget);
412 
413  Plasma::ToolTipManager::self()->registerWidget(failureIcon);
414  Plasma::ToolTipContent data(i18n("Unable to load the widget"), reason,
415  KIcon("dialog-error"));
416  Plasma::ToolTipManager::self()->setContent(failureIcon, data);
417 
418  setLayout(failureLayout);
419  resize(300, 250);
420  d->background->resizeFrame(geometry().size());
421  }
422 
423  update();
424 }
425 
426 void Applet::saveState(KConfigGroup &group) const
427 {
428  if (d->script) {
429  emit d->script->saveState(group);
430  }
431 
432  if (group.config()->name() != config().config()->name()) {
433  // we're being saved to a different file!
434  // let's just copy the current values in our configuration over
435  KConfigGroup c = config();
436  c.copyTo(&group);
437  }
438 }
439 
440 KConfigGroup Applet::config(const QString &group) const
441 {
442  if (d->transient) {
443  return KConfigGroup(KGlobal::config(), "PlasmaTransientsConfig");
444  }
445 
446  KConfigGroup cg = config();
447  return KConfigGroup(&cg, group);
448 }
449 
450 KConfigGroup Applet::config() const
451 {
452  if (d->transient) {
453  return KConfigGroup(KGlobal::config(), "PlasmaTransientsConfig");
454  }
455 
456  if (d->isContainment) {
457  return *(d->mainConfigGroup());
458  }
459 
460  return KConfigGroup(d->mainConfigGroup(), "Configuration");
461 }
462 
463 KConfigGroup Applet::globalConfig() const
464 {
465  KConfigGroup globalAppletConfig;
466  QString group = isContainment() ? "ContainmentGlobals" : "AppletGlobals";
467 
468  Corona *corona = qobject_cast<Corona*>(scene());
469  if (corona) {
470  KSharedConfig::Ptr coronaConfig = corona->config();
471  globalAppletConfig = KConfigGroup(coronaConfig, group);
472  } else {
473  globalAppletConfig = KConfigGroup(KGlobal::config(), group);
474  }
475 
476  return KConfigGroup(&globalAppletConfig, d->globalName());
477 }
478 
479 void Applet::destroy()
480 {
481  if (immutability() != Mutable || d->transient || !d->started) {
482  return; //don't double delete
483  }
484 
485  d->transient = true;
486 
487  if (isContainment()) {
488  d->cleanUpAndDelete();
489  } else {
490  Animation *zoomAnim = Plasma::Animator::create(Plasma::Animator::ZoomAnimation);
491  connect(zoomAnim, SIGNAL(finished()), this, SLOT(cleanUpAndDelete()));
492  zoomAnim->setTargetWidget(this);
493  zoomAnim->start();
494  }
495 }
496 
497 bool Applet::destroyed() const
498 {
499  return d->transient;
500 }
501 
502 void AppletPrivate::selectItemToDestroy()
503 {
504  //FIXME: this will not work nicely with multiple screens and being zoomed out!
505  if (isContainment) {
506  QGraphicsView *view = q->view();
507  if (view && view->transform().isScaling() &&
508  q->scene()->focusItem() != q) {
509  QGraphicsItem *focus = q->scene()->focusItem();
510 
511  if (focus) {
512  Containment *toDestroy = dynamic_cast<Containment*>(focus->topLevelItem());
513 
514  if (toDestroy) {
515  toDestroy->destroy();
516  return;
517  }
518  }
519  }
520  }
521 
522  q->destroy();
523 }
524 
525 void AppletPrivate::updateRect(const QRectF &rect)
526 {
527  q->update(rect);
528 }
529 
530 void AppletPrivate::cleanUpAndDelete()
531 {
532  //kDebug() << "???????????????? DESTROYING APPLET" << q->name() << q->scene() << " ???????????????????????????";
533  QGraphicsWidget *parent = dynamic_cast<QGraphicsWidget *>(q->parentItem());
534  //it probably won't matter, but right now if there are applethandles, *they* are the parent.
535  //not the containment.
536 
537  //is the applet in a containment and does the containment have a layout?
538  //if yes, we remove the applet in the layout
539  if (parent && parent->layout()) {
540  QGraphicsLayout *l = parent->layout();
541  for (int i = 0; i < l->count(); ++i) {
542  if (q == l->itemAt(i)) {
543  l->removeAt(i);
544  break;
545  }
546  }
547  }
548 
549  if (configLoader) {
550  configLoader->setDefaults();
551  }
552 
553  resetConfigurationObject();
554 
555  if (q->scene()) {
556  if (isContainment) {
557  // prematurely emit our destruction if we are a Containment,
558  // giving Corona a chance to remove this Containment from its collection
559  emit q->QObject::destroyed(q);
560  }
561 
562  q->scene()->removeItem(q);
563  }
564 
565  q->deleteLater();
566 }
567 
568 void AppletPrivate::createMessageOverlay(bool usePopup)
569 {
570  if (messageOverlay) {
571  qDeleteAll(messageOverlay->children());
572  messageOverlay->setLayout(0);
573  }
574 
575  PopupApplet *popup = qobject_cast<Plasma::PopupApplet*>(q);
576 
577  if (!messageOverlay) {
578  if (usePopup && popup) {
579  if (popup->widget()) {
580  messageOverlayProxy = new QGraphicsProxyWidget(q);
581  messageOverlayProxy->setWidget(popup->widget());
582  messageOverlay = new AppletOverlayWidget(messageOverlayProxy);
583  } else if (popup->graphicsWidget() &&
584  popup->graphicsWidget() != extender.data()) {
585  messageOverlay = new AppletOverlayWidget(popup->graphicsWidget());
586  }
587  }
588 
589  if (!messageOverlay) {
590  messageOverlay = new AppletOverlayWidget(q);
591  }
592  }
593 
594  positionMessageOverlay();
595 }
596 
597 void AppletPrivate::positionMessageOverlay()
598 {
599  if (!messageOverlay) {
600  return;
601  }
602 
603  PopupApplet *popup = qobject_cast<Plasma::PopupApplet*>(q);
604  const bool usePopup = popup && (messageOverlay->parentItem() != q);
605  QGraphicsItem *topItem = q;
606 
607  if (usePopup && popup->widget()) {
608  // popupapplet with widget()
609  topItem = popup->d->proxy.data();
610  messageOverlay->setGeometry(popup->widget()->contentsRect());
611  } else if (usePopup && popup->graphicsWidget() && popup->graphicsWidget() != extender.data()) {
612  // popupapplet with graphicsWidget()
613  topItem = popup->graphicsWidget();
614  QGraphicsWidget *w = dynamic_cast<QGraphicsWidget *>(topItem);
615  messageOverlay->setGeometry(w ? w->contentsRect() : topItem->boundingRect());
616  } else {
617  // normal applet
618  messageOverlay->setGeometry(q->contentsRect());
619  }
620 
621  // raise the overlay above all the other children!
622  int zValue = 100;
623  foreach (QGraphicsItem *child, topItem->children()) {
624  if (child->zValue() > zValue) {
625  zValue = child->zValue() + 1;
626  }
627  }
628  messageOverlay->setZValue(zValue);
629 }
630 
631 void AppletPrivate::destroyMessageOverlay()
632 {
633  if (messageDialog) {
634  messageDialog.data()->animatedHide(Plasma::locationToInverseDirection(q->location()));
635  //messageDialog.data()->deleteLater();
636  messageDialog.clear();
637  }
638 
639  if (!messageOverlay) {
640  return;
641  }
642 
643  messageOverlay->destroy();
644  messageOverlay = 0;
645 
646  if (messageOverlayProxy) {
647  messageOverlayProxy->setWidget(0);
648  delete messageOverlayProxy;
649  messageOverlayProxy = 0;
650  }
651 
652  MessageButton buttonCode = ButtonNo;
653  //find out if we're disappearing because of a button press
654  PushButton *button = qobject_cast<PushButton *>(q->sender());
655  if (button) {
656  if (button == messageOkButton.data()) {
657  buttonCode = ButtonOk;
658  }
659  if (button == messageYesButton.data()) {
660  buttonCode = ButtonYes;
661  }
662  if (button == messageNoButton.data()) {
663  buttonCode = ButtonNo;
664  }
665  if (button == messageCancelButton.data()) {
666  buttonCode = ButtonCancel;
667  }
668 
669  emit q->messageButtonPressed(buttonCode);
670  } else if (q->sender() == messageOverlay) {
671  emit q->messageButtonPressed(ButtonCancel);
672  }
673 }
674 
675 ConfigLoader *Applet::configScheme() const
676 {
677  return d->configLoader;
678 }
679 
680 DataEngine *Applet::dataEngine(const QString &name) const
681 {
682  if (!d->remoteLocation.isEmpty()) {
683  return d->remoteDataEngine(KUrl(d->remoteLocation), name);
684  } else if (!package() || package()->metadata().remoteLocation().isEmpty()) {
685  return d->dataEngine(name);
686  } else {
687  return d->remoteDataEngine(KUrl(package()->metadata().remoteLocation()), name);
688  }
689 }
690 
691 const Package *Applet::package() const
692 {
693  return d->package;
694 }
695 
696 QGraphicsView *Applet::view() const
697 {
698  // It's assumed that we won't be visible on more than one view here.
699  // Anything that actually needs view() should only really care about
700  // one of them anyway though.
701  if (!scene()) {
702  return 0;
703  }
704 
705  QGraphicsView *found = 0;
706  QGraphicsView *possibleFind = 0;
707  //kDebug() << "looking through" << scene()->views().count() << "views";
708  foreach (QGraphicsView *view, scene()->views()) {
709  //kDebug() << " checking" << view << view->sceneRect()
710  // << "against" << sceneBoundingRect() << scenePos();
711  if (view->sceneRect().intersects(sceneBoundingRect()) ||
712  view->sceneRect().contains(scenePos())) {
713  //kDebug() << " found something!" << view->isActiveWindow();
714  if (view->isActiveWindow()) {
715  found = view;
716  } else {
717  possibleFind = view;
718  }
719  }
720  }
721 
722  return found ? found : possibleFind;
723 }
724 
725 QRectF Applet::mapFromView(const QGraphicsView *view, const QRect &rect) const
726 {
727  // Why is this adjustment needed? Qt calculation error?
728  return mapFromScene(view->mapToScene(rect)).boundingRect().adjusted(0, 0, 1, 1);
729 }
730 
731 QRect Applet::mapToView(const QGraphicsView *view, const QRectF &rect) const
732 {
733  // Why is this adjustment needed? Qt calculation error?
734  return view->mapFromScene(mapToScene(rect)).boundingRect().adjusted(0, 0, -1, -1);
735 }
736 
737 QPoint Applet::popupPosition(const QSize &s) const
738 {
739  return popupPosition(s, Qt::AlignLeft);
740 }
741 
742 QPoint Applet::popupPosition(const QSize &s, Qt::AlignmentFlag alignment) const
743 {
744  Corona * corona = qobject_cast<Corona*>(scene());
745  Q_ASSERT(corona);
746 
747  return corona->popupPosition(this, s, alignment);
748 }
749 
750 void Applet::updateConstraints(Plasma::Constraints constraints)
751 {
752  d->scheduleConstraintsUpdate(constraints);
753 }
754 
755 void Applet::constraintsEvent(Plasma::Constraints constraints)
756 {
757  //NOTE: do NOT put any code in here that reacts to constraints updates
758  // as it will not get called for any applet that reimplements constraintsEvent
759  // without calling the Applet:: version as well, which it shouldn't need to.
760  // INSTEAD put such code into flushPendingConstraintsEvents
761  Q_UNUSED(constraints)
762  //kDebug() << constraints << "constraints are FormFactor: " << formFactor()
763  // << ", Location: " << location();
764  if (d->script) {
765  d->script->constraintsEvent(constraints);
766  }
767 }
768 
769 void Applet::initExtenderItem(ExtenderItem *item)
770 {
771  if (d->script) {
772  emit extenderItemRestored(item);
773  } else {
774  kWarning() << "Missing implementation of initExtenderItem in the applet "
775  << item->config().readEntry("SourceAppletPluginName", "")
776  << "!\n Any applet that uses extenders should implement initExtenderItem to "
777  << "instantiate a widget. Destroying the item...";
778  item->destroy();
779  }
780 }
781 
782 Extender *Applet::extender() const
783 {
784  if (!d->extender) {
785  new Extender(const_cast<Applet*>(this));
786  }
787 
788  return d->extender.data();
789 }
790 
791 void Applet::setBusy(bool busy)
792 {
793  if (busy) {
794  if (!d->busyWidget && !d->busyWidgetTimer.isActive()) {
795  d->busyWidgetTimer.start(500, this);
796  }
797  } else {
798  d->busyWidgetTimer.stop();
799  if (d->busyWidget) {
800  d->busyWidget = 0;
801  d->destroyMessageOverlay();
802  }
803  }
804 }
805 
806 bool Applet::isBusy() const
807 {
808  return d->busyWidgetTimer.isActive() || (d->busyWidget && d->busyWidget->isVisible());
809 }
810 
811 QString Applet::name() const
812 {
813  if (d->isContainment) {
814  const Containment *c = qobject_cast<const Containment*>(this);
815  if (c && c->d->isPanelContainment()) {
816  return i18n("Panel");
817  } else if (!d->appletDescription.isValid()) {
818  return i18n("Unknown");
819  } else {
820  return d->appletDescription.name();
821  }
822  } else if (!d->appletDescription.isValid()) {
823  return i18n("Unknown Widget");
824  }
825 
826  return d->appletDescription.name();
827 }
828 
829 QFont Applet::font() const
830 {
831  return QApplication::font();
832 }
833 
834 QString Applet::icon() const
835 {
836  if (!d->appletDescription.isValid()) {
837  return QString();
838  }
839 
840  return d->appletDescription.icon();
841 }
842 
843 QString Applet::pluginName() const
844 {
845  if (!d->appletDescription.isValid()) {
846  return d->mainConfigGroup()->readEntry("plugin", QString());
847  }
848 
849  return d->appletDescription.pluginName();
850 }
851 
852 bool Applet::shouldConserveResources() const
853 {
854 #ifndef PLASMA_NO_SOLID
855  return Solid::PowerManagement::appShouldConserveResources();
856 #else
857  return true;
858 #endif
859 }
860 
861 QString Applet::category() const
862 {
863  if (!d->appletDescription.isValid()) {
864  return i18nc("misc category", "Miscellaneous");
865  }
866 
867  return d->appletDescription.category();
868 }
869 
870 QString Applet::category(const KPluginInfo &applet)
871 {
872  return applet.property("X-KDE-PluginInfo-Category").toString();
873 }
874 
875 QString Applet::category(const QString &appletName)
876 {
877  if (appletName.isEmpty()) {
878  return QString();
879  }
880 
881  const QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(appletName);
882  KService::List offers = KServiceTypeTrader::self()->query("Plasma/Applet", constraint);
883 
884  if (offers.isEmpty()) {
885  return QString();
886  }
887 
888  return offers.first()->property("X-KDE-PluginInfo-Category").toString();
889 }
890 
891 ImmutabilityType Applet::immutability() const
892 {
893  // if this object is itself system immutable, then just return that; it's the most
894  // restrictive setting possible and will override anything that might be happening above it
895  // in the Corona->Containment->Applet hierarchy
896  if (d->transient || (d->mainConfig && d->mainConfig->isImmutable())) {
897  return SystemImmutable;
898  }
899 
900  //Returning the more strict immutability between the applet immutability, Containment and Corona
901  ImmutabilityType upperImmutability = Mutable;
902  Containment *cont = d->isContainment ? 0 : containment();
903 
904  if (cont) {
905  upperImmutability = cont->immutability();
906  } else if (Corona *corona = qobject_cast<Corona*>(scene())) {
907  upperImmutability = corona->immutability();
908  }
909 
910  if (upperImmutability != Mutable) {
911  // it's either system or user immutable, and we already check for local system immutability,
912  // so upperImmutability is guaranteed to be as or more severe as this object's immutability
913  return upperImmutability;
914  } else {
915  return d->immutability;
916  }
917 }
918 
919 void Applet::setImmutability(const ImmutabilityType immutable)
920 {
921  if (d->immutability == immutable || immutable == Plasma::SystemImmutable) {
922  // we do not store system immutability in d->immutability since that gets saved
923  // out to the config file; instead, we check with
924  // the config group itself for this information at all times. this differs from
925  // corona, where SystemImmutability is stored in d->immutability.
926  return;
927  }
928 
929  d->immutability = immutable;
930  updateConstraints(ImmutableConstraint);
931 }
932 
933 Applet::BackgroundHints Applet::backgroundHints() const
934 {
935  return d->backgroundHints;
936 }
937 
938 void Applet::setBackgroundHints(const BackgroundHints hints)
939 {
940  if (d->backgroundHints == hints) {
941  return;
942  }
943 
944  d->backgroundHints = hints;
945  d->preferredBackgroundHints = hints;
946 
947  //Draw the standard background?
948  if ((hints & StandardBackground) || (hints & TranslucentBackground)) {
949  if (!d->background) {
950  d->background = new Plasma::FrameSvg(this);
951  QObject::connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(themeChanged()));
952  }
953 
954  if ((hints & TranslucentBackground) &&
955  Plasma::Theme::defaultTheme()->currentThemeHasImage("widgets/translucentbackground")) {
956  d->background->setImagePath("widgets/translucentbackground");
957  } else {
958  d->background->setImagePath("widgets/background");
959  }
960 
961  d->background->setEnabledBorders(Plasma::FrameSvg::AllBorders);
962  qreal left, top, right, bottom;
963  d->background->getMargins(left, top, right, bottom);
964  setContentsMargins(left, right, top, bottom);
965  QSizeF fitSize(left + right, top + bottom);
966  d->background->resizeFrame(boundingRect().size());
967 
968  //if the background has an "overlay" element decide a random position for it and then save it so it's consistent across plasma starts
969  if (d->background->hasElement("overlay")) {
970  QSize overlaySize = d->background->elementSize("overlay");
971 
972  //position is in the boundaries overlaySize.width()*2, overlaySize.height()
973  qsrand(id());
974  d->background->d->overlayPos.rx() = - (overlaySize.width() /2) + (overlaySize.width() /4) * (qrand() % (4 + 1));
975  d->background->d->overlayPos.ry() = (- (overlaySize.height() /2) + (overlaySize.height() /4) * (qrand() % (4 + 1)))/2;
976  }
977  } else if (d->background) {
978  qreal left, top, right, bottom;
979  d->background->getMargins(left, top, right, bottom);
980 
981  delete d->background;
982  d->background = 0;
983  setContentsMargins(0, 0, 0, 0);
984  }
985 
986  update();
987 }
988 
989 bool Applet::hasFailedToLaunch() const
990 {
991  return d->failed;
992 }
993 
994 void Applet::paintWindowFrame(QPainter *painter,
995  const QStyleOptionGraphicsItem *option, QWidget *widget)
996 {
997  Q_UNUSED(painter)
998  Q_UNUSED(option)
999  Q_UNUSED(widget)
1000  //Here come the code for the window frame
1001  //kDebug() << windowFrameGeometry();
1002  //painter->drawRoundedRect(windowFrameGeometry(), 5, 5);
1003 }
1004 
1005 bool Applet::configurationRequired() const
1006 {
1007  return d->needsConfig;
1008 }
1009 
1010 void Applet::setConfigurationRequired(bool needsConfig, const QString &reason)
1011 {
1012  if (d->needsConfig == needsConfig) {
1013  return;
1014  }
1015 
1016  d->needsConfig = needsConfig;
1017 
1018  if (!needsConfig) {
1019  d->destroyMessageOverlay();
1020  return;
1021  }
1022 
1023  d->createMessageOverlay(true);
1024  d->messageOverlay->opacity = 0.4;
1025 
1026  QGraphicsGridLayout *configLayout = new QGraphicsGridLayout(d->messageOverlay);
1027  configLayout->setContentsMargins(0, 0, 0, 0);
1028 
1029  // configLayout->addStretch();
1030  configLayout->setColumnStretchFactor(0, 5);
1031  configLayout->setColumnStretchFactor(2, 5);
1032  configLayout->setRowStretchFactor(0, 5);
1033  configLayout->setRowStretchFactor(3, 5);
1034 
1035  int row = 1;
1036  if (!reason.isEmpty()) {
1037  Label *explanation = new Label(d->messageOverlay);
1038  explanation->setText(reason);
1039  configLayout->addItem(explanation, row, 1);
1040  configLayout->setColumnStretchFactor(1, 5);
1041  ++row;
1042  configLayout->setAlignment(explanation, Qt::AlignBottom | Qt::AlignCenter);
1043  }
1044 
1045  PushButton *configWidget = new PushButton(d->messageOverlay);
1046  if (!qobject_cast<Plasma::PopupApplet *>(this) && (formFactor() == Plasma::Horizontal || formFactor() == Plasma::Vertical)) {
1047  configWidget->setImage("widgets/configuration-icons", "configure");
1048  configWidget->setMaximumSize(24,24);
1049  configWidget->setMinimumSize(24,24);
1050  } else {
1051  configWidget->setText(i18n("Configure..."));
1052  }
1053  connect(configWidget, SIGNAL(clicked()), this, SLOT(showConfigurationInterface()));
1054  configLayout->addItem(configWidget, row, 1);
1055 
1056  //configLayout->setAlignment(configWidget, Qt::AlignTop | Qt::AlignCenter);
1057  //configLayout->addStretch();
1058 
1059  d->messageOverlay->show();
1060 }
1061 
1062 void Applet::showMessage(const QIcon &icon, const QString &message, const MessageButtons buttons)
1063 {
1064  if (message.isEmpty()) {
1065  d->destroyMessageOverlay();
1066  return;
1067  }
1068 
1069  Corona *corona = qobject_cast<Corona *>(scene());
1070  QGraphicsWidget *mainWidget = new QGraphicsWidget;
1071 
1072  QGraphicsLinearLayout *mainLayout = new QGraphicsLinearLayout(mainWidget);
1073  mainLayout->setOrientation(Qt::Vertical);
1074  mainLayout->addStretch();
1075 
1076  QGraphicsLinearLayout *messageLayout = new QGraphicsLinearLayout();
1077  messageLayout->setOrientation(Qt::Horizontal);
1078 
1079  QGraphicsLinearLayout *buttonLayout = new QGraphicsLinearLayout();
1080  buttonLayout->setOrientation(Qt::Horizontal);
1081 
1082  mainLayout->addItem(messageLayout);
1083  mainLayout->addItem(buttonLayout);
1084  mainLayout->addStretch();
1085 
1086  IconWidget *messageIcon = new IconWidget(mainWidget);
1087  Label *messageText = new Label(mainWidget);
1088  messageText->nativeWidget()->setWordWrap(true);
1089 
1090  messageLayout->addStretch();
1091  messageLayout->addItem(messageIcon);
1092  messageLayout->addItem(messageText);
1093  messageLayout->addStretch();
1094 
1095  messageIcon->setIcon(icon);
1096  messageText->setText(message);
1097 
1098  buttonLayout->addStretch();
1099 
1100  if (buttons & ButtonOk) {
1101  d->messageOkButton = new PushButton(mainWidget);
1102  d->messageOkButton.data()->setText(i18n("&OK"));
1103  d->messageOkButton.data()->setIcon(KIcon("dialog-ok"));
1104  buttonLayout->addItem(d->messageOkButton.data());
1105  connect(d->messageOkButton.data(), SIGNAL(clicked()), this, SLOT(destroyMessageOverlay()));
1106  }
1107 
1108  if (buttons & ButtonYes) {
1109  d->messageYesButton = new PushButton(mainWidget);
1110  d->messageYesButton.data()->setText(i18n("&Yes"));
1111  buttonLayout->addItem(d->messageYesButton.data());
1112  connect(d->messageYesButton.data(), SIGNAL(clicked()), this, SLOT(destroyMessageOverlay()));
1113  }
1114 
1115  if (buttons & ButtonNo) {
1116  d->messageNoButton = new PushButton(mainWidget);
1117  d->messageNoButton.data()->setText(i18n("&No"));
1118  buttonLayout->addItem(d->messageNoButton.data());
1119  connect(d->messageNoButton.data(), SIGNAL(clicked()), this, SLOT(destroyMessageOverlay()));
1120  }
1121 
1122  if (buttons & ButtonCancel) {
1123  d->messageCancelButton = new PushButton(mainWidget);
1124  d->messageCancelButton.data()->setText(i18n("&Cancel"));
1125  d->messageCancelButton.data()->setIcon(KIcon("dialog-cancel"));
1126  buttonLayout->addItem(d->messageCancelButton.data());
1127  connect(d->messageCancelButton.data(), SIGNAL(clicked()), this, SLOT(destroyMessageOverlay()));
1128  }
1129 
1130  d->messageCloseAction = new QAction(d->messageOverlay);
1131  d->messageCloseAction.data()->setShortcut(Qt::Key_Escape);
1132  mainWidget->addAction(d->messageCloseAction.data());
1133  connect(d->messageCloseAction.data(), SIGNAL(triggered()), this, SLOT(destroyMessageOverlay()));
1134 
1135  buttonLayout->addStretch();
1136 
1137  mainWidget->adjustSize();
1138  QSizeF hint = mainWidget->preferredSize();
1139  if (hint.height() > size().height() || hint.width() > size().width()) {
1140  // either a collapsed popup in h/v form factor or just too small,
1141  // so show it in a dialog associated with ourselves
1142  if (corona) {
1143  corona->addOffscreenWidget(mainWidget);
1144  }
1145 
1146  if (d->messageDialog) {
1147  delete d->messageDialog.data()->graphicsWidget();
1148  } else {
1149  d->messageDialog = new Plasma::Dialog;
1150  }
1151 
1152  ToolTipManager::self()->hide(this);
1153  KWindowSystem::setOnAllDesktops(d->messageDialog.data()->winId(), true);
1154  KWindowSystem::setState(d->messageDialog.data()->winId(), NET::SkipTaskbar | NET::SkipPager);
1155  d->messageDialog.data()->setGraphicsWidget(mainWidget);
1156  connect(d->messageDialog.data(), SIGNAL(destroyed(QObject*)), mainWidget, SLOT(deleteLater()));
1157 
1158  // if we are going to show it in a popup, then at least make sure it can be dismissed
1159  if (buttonLayout->count() < 1) {
1160  PushButton *ok = new PushButton(mainWidget);
1161  ok->setText(i18n("OK"));
1162  ok->setIcon(KIcon("dialog-ok"));
1163  buttonLayout->addItem(ok);
1164  connect(ok, SIGNAL(clicked()), this, SLOT(destroyMessageOverlay()));
1165  }
1166  } else {
1167  delete d->messageDialog.data();
1168  d->createMessageOverlay();
1169  d->messageOverlay->opacity = 0.8;
1170  mainWidget->setParentItem(d->messageOverlay);
1171  QGraphicsLinearLayout *l = new QGraphicsLinearLayout(d->messageOverlay);
1172  l->addItem(mainWidget);
1173  }
1174 
1175  if (d->messageDialog) {
1176  QPoint pos = geometry().topLeft().toPoint();
1177  if (corona) {
1178  pos = corona->popupPosition(this, d->messageDialog.data()->size());
1179  }
1180 
1181  d->messageDialog.data()->move(pos);
1182  d->messageDialog.data()->animatedShow(locationToDirection(location()));
1183  } else {
1184  d->messageOverlay->show();
1185  }
1186 }
1187 
1188 QVariantList Applet::startupArguments() const
1189 {
1190  return d->args;
1191 }
1192 
1193 ItemStatus Applet::status() const
1194 {
1195  return d->itemStatus;
1196 }
1197 
1198 void Applet::setStatus(const ItemStatus status)
1199 {
1200  d->itemStatus = status;
1201  emit newStatus(status);
1202 }
1203 
1204 void Applet::flushPendingConstraintsEvents()
1205 {
1206  if (d->pendingConstraints == NoConstraint) {
1207  return;
1208  }
1209 
1210  if (d->constraintsTimer.isActive()) {
1211  d->constraintsTimer.stop();
1212  }
1213 
1214  //kDebug() << "fushing constraints: " << d->pendingConstraints << "!!!!!!!!!!!!!!!!!!!!!!!!!!!";
1215  Plasma::Constraints c = d->pendingConstraints;
1216  d->pendingConstraints = NoConstraint;
1217 
1218  if (c & Plasma::StartupCompletedConstraint) {
1219  //common actions
1220  bool unlocked = immutability() == Mutable;
1221  QAction *closeApplet = d->actions->action("remove");
1222  if (closeApplet) {
1223  closeApplet->setEnabled(unlocked);
1224  closeApplet->setVisible(unlocked);
1225  connect(closeApplet, SIGNAL(triggered(bool)), this, SLOT(selectItemToDestroy()), Qt::UniqueConnection);
1226  }
1227 
1228  QAction *configAction = d->actions->action("configure");
1229  if (configAction) {
1230  if (d->isContainment) {
1231  connect(configAction, SIGNAL(triggered(bool)), this, SLOT(requestConfiguration()), Qt::UniqueConnection);
1232  } else {
1233  connect(configAction, SIGNAL(triggered(bool)), this, SLOT(showConfigurationInterface()), Qt::UniqueConnection);
1234  }
1235 
1236  if (d->hasConfigurationInterface) {
1237  bool canConfig = unlocked || KAuthorized::authorize("plasma/allow_configure_when_locked");
1238  configAction->setVisible(canConfig);
1239  configAction->setEnabled(canConfig);
1240  }
1241  }
1242 
1243  QAction *runAssociatedApplication = d->actions->action("run associated application");
1244  if (runAssociatedApplication) {
1245  connect(runAssociatedApplication, SIGNAL(triggered(bool)), this, SLOT(runAssociatedApplication()), Qt::UniqueConnection);
1246  }
1247 
1248  d->updateShortcuts();
1249  Corona * corona = qobject_cast<Corona*>(scene());
1250  if (corona) {
1251  connect(corona, SIGNAL(shortcutsChanged()), this, SLOT(updateShortcuts()), Qt::UniqueConnection);
1252  }
1253  }
1254 
1255  if (c & Plasma::ImmutableConstraint) {
1256  bool unlocked = immutability() == Mutable;
1257  QAction *action = d->actions->action("remove");
1258  if (action) {
1259  action->setVisible(unlocked);
1260  action->setEnabled(unlocked);
1261  }
1262 
1263  action = d->actions->action("configure");
1264  if (action && d->hasConfigurationInterface) {
1265  bool canConfig = unlocked || KAuthorized::authorize("plasma/allow_configure_when_locked");
1266  action->setVisible(canConfig);
1267  action->setEnabled(canConfig);
1268  }
1269 
1270  if (d->extender) {
1271  foreach (ExtenderItem *item, d->extender.data()->attachedItems()) {
1272  item->d->setMovable(unlocked);
1273  }
1274  }
1275 
1276  if (!unlocked && d->handle) {
1277  AppletHandle *h = d->handle.data();
1278  disconnect(this);
1279 
1280  QGraphicsScene *s = scene();
1281  if (s && h->scene() == s) {
1282  s->removeItem(h);
1283  }
1284 
1285  h->deleteLater();
1286  }
1287 
1288  emit immutabilityChanged(immutability());
1289  }
1290 
1291  if (c & Plasma::SizeConstraint) {
1292  d->positionMessageOverlay();
1293 
1294  if (d->started && layout()) {
1295  layout()->updateGeometry();
1296  }
1297  }
1298 
1299  if (c & Plasma::FormFactorConstraint) {
1300  FormFactor f = formFactor();
1301  if (!d->isContainment && f != Vertical && f != Horizontal) {
1302  setBackgroundHints(d->preferredBackgroundHints);
1303  } else {
1304  BackgroundHints hints = d->preferredBackgroundHints;
1305  setBackgroundHints(NoBackground);
1306  d->preferredBackgroundHints = hints;
1307  }
1308 
1309  if (d->failed) {
1310  if (f == Vertical || f == Horizontal) {
1311  QGraphicsLayoutItem *item = layout()->itemAt(1);
1312  layout()->removeAt(1);
1313  delete item;
1314  }
1315  }
1316 
1317  // avoid putting rotated applets in panels
1318  if (f == Vertical || f == Horizontal) {
1319  QTransform at;
1320  at.rotateRadians(0);
1321  setTransform(at);
1322  }
1323 
1324  //was a size saved for a particular form factor?
1325  if (d->sizeForFormFactor.contains(f)) {
1326  resize(d->sizeForFormFactor.value(f));
1327  }
1328  }
1329 
1330  if (!size().isEmpty() &&
1331  ((c & Plasma::StartupCompletedConstraint) || (c & Plasma::SizeConstraint && !(c & Plasma::FormFactorConstraint)))) {
1332  d->sizeForFormFactor[formFactor()] = size();
1333  }
1334 
1335  if (c & Plasma::SizeConstraint || c & Plasma::FormFactorConstraint) {
1336  if (aspectRatioMode() == Plasma::Square || aspectRatioMode() == Plasma::ConstrainedSquare) {
1337  // enforce square size in panels
1338  //save the old size policy. since ignored doesn't (yet) have a valid use case in containments, use it as special unset value
1339  if (d->preferredSizePolicy == QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)) {
1340  d->preferredSizePolicy = sizePolicy();
1341  }
1342  if (formFactor() == Horizontal) {
1343  setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding));
1344  } else if (formFactor() == Vertical) {
1345  setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
1346  } else if (d->preferredSizePolicy != QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)) {
1347  setSizePolicy(d->preferredSizePolicy);
1348  }
1349  }
1350  updateGeometry();
1351  }
1352 
1353  // now take care of constraints in special subclasses: Contaiment and PopupApplet
1354  Containment* containment = qobject_cast<Plasma::Containment*>(this);
1355  if (d->isContainment && containment) {
1356  containment->d->containmentConstraintsEvent(c);
1357  }
1358 
1359  PopupApplet* popup = qobject_cast<Plasma::PopupApplet*>(this);
1360  if (popup) {
1361  popup->d->popupConstraintsEvent(c);
1362  }
1363 
1364  // pass the constraint on to the actual subclass
1365  constraintsEvent(c);
1366 
1367  if (c & StartupCompletedConstraint) {
1368  // start up is done, we can now go do a mod timer
1369  if (d->modificationsTimer) {
1370  if (d->modificationsTimer->isActive()) {
1371  d->modificationsTimer->stop();
1372  }
1373  } else {
1374  d->modificationsTimer = new QBasicTimer;
1375  }
1376  }
1377 }
1378 
1379 int Applet::type() const
1380 {
1381  return Type;
1382 }
1383 
1384 QList<QAction*> Applet::contextualActions()
1385 {
1386  //kDebug() << "empty context actions";
1387  return d->script ? d->script->contextualActions() : QList<QAction*>();
1388 }
1389 
1390 QAction *Applet::action(QString name) const
1391 {
1392  return d->actions->action(name);
1393 }
1394 
1395 void Applet::addAction(QString name, QAction *action)
1396 {
1397  d->actions->addAction(name, action);
1398 }
1399 
1400 void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
1401 {
1402  if (!d->started) {
1403  //kDebug() << "not started";
1404  return;
1405  }
1406 
1407  if (transform().isRotating()) {
1408  painter->setRenderHint(QPainter::SmoothPixmapTransform);
1409  painter->setRenderHint(QPainter::Antialiasing);
1410  }
1411 
1412  if (d->background &&
1413  formFactor() != Plasma::Vertical &&
1414  formFactor() != Plasma::Horizontal) {
1415  //kDebug() << "option rect is" << option->rect;
1416  d->background->paintFrame(painter);
1417  }
1418 
1419  if (d->failed) {
1420  //kDebug() << "failed!";
1421  return;
1422  }
1423 
1424  qreal left, top, right, bottom;
1425  getContentsMargins(&left, &top, &right, &bottom);
1426  QRect contentsRect = QRectF(QPointF(0, 0),
1427  boundingRect().size()).adjusted(left, top, -right, -bottom).toRect();
1428 
1429  if (widget && d->isContainment) {
1430  // note that the widget we get is actually the viewport of the view, not the view itself
1431  View* v = qobject_cast<Plasma::View*>(widget->parent());
1432  Containment* c = qobject_cast<Plasma::Containment*>(this);
1433 
1434  if (!v || v->isWallpaperEnabled()) {
1435 
1436  // paint the wallpaper
1437  if (c && c->drawWallpaper() && c->wallpaper()) {
1438  Wallpaper *w = c->wallpaper();
1439  if (!w->isInitialized()) {
1440  // delayed paper initialization
1441  KConfigGroup wallpaperConfig = c->config();
1442  wallpaperConfig = KConfigGroup(&wallpaperConfig, "Wallpaper");
1443  wallpaperConfig = KConfigGroup(&wallpaperConfig, w->pluginName());
1444  w->restore(wallpaperConfig);
1445  disconnect(w, SIGNAL(update(QRectF)), this, SLOT(updateRect(QRectF)));
1446  connect(w, SIGNAL(update(QRectF)), this, SLOT(updateRect(QRectF)));
1447  }
1448 
1449  painter->save();
1450  c->wallpaper()->paint(painter, option->exposedRect);
1451  painter->restore();
1452  }
1453 
1454  // .. and now paint the actual containment interface, but with
1455  // a Containment style option based on the one we get
1456  // the view must be assigned only if its containment is actually our own
1457  Containment::StyleOption coption(*option);
1458  if (v && v->containment() == containment()) {
1459  coption.view = v;
1460  }
1461  paintInterface(painter, &coption, contentsRect);
1462  }
1463  } else {
1464  //kDebug() << "paint interface of" << (QObject*) this;
1465  // paint the applet's interface
1466  paintInterface(painter, option, contentsRect);
1467  }
1468 }
1469 
1470 void Applet::paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
1471 {
1472  if (d->script) {
1473  d->script->paintInterface(painter, option, contentsRect);
1474  } else {
1475  //kDebug() << "Applet::paintInterface() default impl";
1476  }
1477 }
1478 
1479 FormFactor Applet::formFactor() const
1480 {
1481  Containment *c = containment();
1482  QGraphicsWidget *pw = qobject_cast<QGraphicsWidget *>(parent());
1483  if (!pw) {
1484  pw = dynamic_cast<QGraphicsWidget *>(parentItem());
1485  }
1486  Plasma::Applet *parentApplet = qobject_cast<Plasma::Applet *>(pw);
1487  //assumption: this loop is usually is -really- short or doesn't run at all
1488  while (!parentApplet && pw && pw->parentWidget()) {
1489  QGraphicsWidget *parentWidget = qobject_cast<QGraphicsWidget *>(pw->parent());
1490  if (!parentWidget) {
1491  parentWidget = dynamic_cast<QGraphicsWidget *>(pw->parentItem());
1492  }
1493  pw = parentWidget;
1494  parentApplet = qobject_cast<Plasma::Applet *>(pw);
1495  }
1496 
1497 
1498  const PopupApplet *pa = dynamic_cast<const PopupApplet *>(this);
1499 
1500  //if the applet is in a widget that isn't a containment
1501  //try to retrieve the formFactor from the parent size
1502  //we can't use our own sizeHint here because it needs formFactor, so endless recursion.
1503  // a popupapplet can always be constrained.
1504  // a normal applet should to but
1505  //FIXME: not always constrained to not break systemmonitor
1506  if (parentApplet && parentApplet != c && c != this && (pa || layout())) {
1507  if (pa || (parentApplet->size().height() < layout()->effectiveSizeHint(Qt::MinimumSize).height())) {
1508  return Plasma::Horizontal;
1509  } else if (pa || (parentApplet->size().width() < layout()->effectiveSizeHint(Qt::MinimumSize).width())) {
1510  return Plasma::Vertical;
1511  }
1512  return parentApplet->formFactor();
1513  }
1514 
1515  return c ? c->d->formFactor : Plasma::Planar;
1516 }
1517 
1518 Containment *Applet::containment() const
1519 {
1520  if (d->isContainment) {
1521  Containment *c = qobject_cast<Containment*>(const_cast<Applet*>(this));
1522  if (c) {
1523  return c;
1524  }
1525  }
1526 
1527  QGraphicsItem *parent = parentItem();
1528  Containment *c = 0;
1529 
1530  while (parent) {
1531  Containment *possibleC = dynamic_cast<Containment*>(parent);
1532  if (possibleC && possibleC->Applet::d->isContainment) {
1533  c = possibleC;
1534  break;
1535  }
1536  parent = parent->parentItem();
1537  }
1538 
1539  if (!c) {
1540  //if the applet is an offscreen widget its parentItem will be 0, while its parent
1541  //will be its parentWidget, so here we check the QObject hierarchy.
1542  QObject *objParent = this->parent();
1543  while (objParent) {
1544  Containment *possibleC = qobject_cast<Containment*>(objParent);
1545  if (possibleC && possibleC->Applet::d->isContainment) {
1546  c = possibleC;
1547  break;
1548  }
1549  objParent = objParent->parent();
1550  }
1551  }
1552 
1553  return c;
1554 }
1555 
1556 void Applet::setGlobalShortcut(const KShortcut &shortcut)
1557 {
1558  if (!d->activationAction) {
1559  d->activationAction = new KAction(this);
1560  d->activationAction->setText(i18n("Activate %1 Widget", name()));
1561  d->activationAction->setObjectName(QString("activate widget %1").arg(id())); // NO I18N
1562  connect(d->activationAction, SIGNAL(triggered()), this, SIGNAL(activate()));
1563  connect(d->activationAction, SIGNAL(globalShortcutChanged(QKeySequence)),
1564  this, SLOT(globalShortcutChanged()));
1565 
1566  QList<QWidget *> widgets = d->actions->associatedWidgets();
1567  foreach (QWidget *w, widgets) {
1568  w->addAction(d->activationAction);
1569  }
1570  } else if (d->activationAction->globalShortcut() == shortcut) {
1571  return;
1572  }
1573 
1574  //kDebug() << "before" << shortcut.primary() << d->activationAction->globalShortcut().primary();
1575  d->activationAction->setGlobalShortcut(
1576  shortcut,
1577  KAction::ShortcutTypes(KAction::ActiveShortcut | KAction::DefaultShortcut),
1578  KAction::NoAutoloading);
1579  d->globalShortcutChanged();
1580 }
1581 
1582 void AppletPrivate::globalShortcutChanged()
1583 {
1584  if (!activationAction) {
1585  return;
1586  }
1587 
1588  KConfigGroup shortcutConfig(mainConfigGroup(), "Shortcuts");
1589  shortcutConfig.writeEntry("global", activationAction->globalShortcut().toString());
1590  scheduleModificationNotification();
1591  //kDebug() << "after" << shortcut.primary() << d->activationAction->globalShortcut().primary();
1592 }
1593 
1594 KShortcut Applet::globalShortcut() const
1595 {
1596  if (d->activationAction) {
1597  return d->activationAction->globalShortcut();
1598  }
1599 
1600  return KShortcut();
1601 }
1602 
1603 bool Applet::isPopupShowing() const
1604 {
1605  return false;
1606 }
1607 
1608 void Applet::addAssociatedWidget(QWidget *widget)
1609 {
1610  d->actions->addAssociatedWidget(widget);
1611 }
1612 
1613 void Applet::removeAssociatedWidget(QWidget *widget)
1614 {
1615  d->actions->removeAssociatedWidget(widget);
1616 }
1617 
1618 Location Applet::location() const
1619 {
1620  Containment *c = containment();
1621  return c ? c->d->location : Plasma::Desktop;
1622 }
1623 
1624 Context *Applet::context() const
1625 {
1626  Containment *c = containment();
1627  Q_ASSERT(c);
1628  return c->d->context();
1629 }
1630 
1631 Plasma::AspectRatioMode Applet::aspectRatioMode() const
1632 {
1633  return d->aspectRatioMode;
1634 }
1635 
1636 void Applet::setAspectRatioMode(Plasma::AspectRatioMode mode)
1637 {
1638  PopupApplet *popup = qobject_cast<PopupApplet *>(this);
1639  if (popup && popup->d->dialogPtr) {
1640  popup->d->dialogPtr.data()->setAspectRatioMode(mode);
1641  popup->d->savedAspectRatio = mode;
1642  }
1643 
1644  d->aspectRatioMode = mode;
1645 }
1646 
1647 void Applet::registerAsDragHandle(QGraphicsItem *item)
1648 {
1649  if (!item || d->registeredAsDragHandle.contains(item)) {
1650  return;
1651  }
1652 
1653  d->registeredAsDragHandle.insert(item);
1654  item->installSceneEventFilter(this);
1655 }
1656 
1657 void Applet::unregisterAsDragHandle(QGraphicsItem *item)
1658 {
1659  if (!item) {
1660  return;
1661  }
1662 
1663  if (d->registeredAsDragHandle.remove(item)) {
1664  if (item != this) {
1665  item->removeSceneEventFilter(this);
1666  }
1667  }
1668 }
1669 
1670 bool Applet::isRegisteredAsDragHandle(QGraphicsItem *item)
1671 {
1672  return d->registeredAsDragHandle.contains(item);
1673 }
1674 
1675 bool Applet::hasConfigurationInterface() const
1676 {
1677  return d->hasConfigurationInterface;
1678 }
1679 
1680 void Applet::publish(AnnouncementMethods methods, const QString &resourceName)
1681 {
1682  if (d->package) {
1683  d->package->d->publish(methods);
1684  } else if (d->appletDescription.isValid()) {
1685  if (!d->service) {
1686  d->service = new PlasmoidService(this);
1687  }
1688 
1689  kDebug() << "publishing package under name " << resourceName;
1690  PackageMetadata pm;
1691  pm.setName(d->appletDescription.name());
1692  pm.setDescription(d->appletDescription.comment());
1693  pm.setIcon(d->appletDescription.icon());
1694  d->service->d->publish(methods, resourceName, pm);
1695  } else {
1696  kDebug() << "Can not publish invalid applets.";
1697  }
1698 }
1699 
1700 void Applet::unpublish()
1701 {
1702  if (d->package) {
1703  d->package->d->unpublish();
1704  } else {
1705  if (d->service) {
1706  d->service->d->unpublish();
1707  }
1708  }
1709 }
1710 
1711 bool Applet::isPublished() const
1712 {
1713  if (d->package) {
1714  return d->package->d->isPublished();
1715  } else {
1716  if (d->service) {
1717  return d->service->d->isPublished();
1718  } else {
1719  return false;
1720  }
1721  }
1722 }
1723 
1724 void Applet::setHasConfigurationInterface(bool hasInterface)
1725 {
1726  if (hasInterface == d->hasConfigurationInterface) {
1727  return;
1728  }
1729 
1730  QAction *configAction = d->actions->action("configure");
1731  if (configAction) {
1732  bool enable = hasInterface;
1733  if (enable) {
1734  const bool unlocked = immutability() == Mutable;
1735  enable = unlocked || KAuthorized::authorize("plasma/allow_configure_when_locked");
1736  }
1737  configAction->setEnabled(enable);
1738  }
1739 
1740  d->hasConfigurationInterface = hasInterface;
1741 }
1742 
1743 KActionCollection* AppletPrivate::defaultActions(QObject *parent)
1744 {
1745  KActionCollection *actions = new KActionCollection(parent);
1746  actions->setConfigGroup("Shortcuts-Applet");
1747 
1748  KAction *configAction = actions->addAction("configure");
1749  configAction->setAutoRepeat(false);
1750  configAction->setText(i18n("Widget Settings"));
1751  configAction->setIcon(KIcon("configure"));
1752  configAction->setShortcut(KShortcut("alt+d, s"));
1753  configAction->setData(AbstractToolBox::ConfigureTool);
1754 
1755  KAction *closeApplet = actions->addAction("remove");
1756  closeApplet->setAutoRepeat(false);
1757  closeApplet->setText(i18n("Remove this Widget"));
1758  closeApplet->setIcon(KIcon("edit-delete"));
1759  closeApplet->setShortcut(KShortcut("alt+d, r"));
1760  closeApplet->setData(AbstractToolBox::DestructiveTool);
1761 
1762  KAction *runAssociatedApplication = actions->addAction("run associated application");
1763  runAssociatedApplication->setAutoRepeat(false);
1764  runAssociatedApplication->setText(i18n("Run the Associated Application"));
1765  runAssociatedApplication->setIcon(KIcon("system-run"));
1766  runAssociatedApplication->setShortcut(KShortcut("alt+d, t"));
1767  runAssociatedApplication->setVisible(false);
1768  runAssociatedApplication->setEnabled(false);
1769  runAssociatedApplication->setData(AbstractToolBox::ControlTool);
1770 
1771  return actions;
1772 }
1773 
1774 bool Applet::eventFilter(QObject *o, QEvent *e)
1775 {
1776  return QObject::eventFilter(o, e);
1777 }
1778 
1779 bool Applet::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
1780 {
1781  if (watched == this) {
1782  switch (event->type()) {
1783  case QEvent::GraphicsSceneHoverEnter:
1784  //kDebug() << "got hoverenterEvent" << immutability() << " " << immutability();
1785  if (immutability() == Mutable) {
1786  QGraphicsWidget *pw = this;
1787  //This is for the rare case of applet in applet (systray)
1788  //if the applet is in an applet that is not a containment, don't create the handle BUG:301648
1789  while ((pw = pw->parentWidget())) {
1790  if (qobject_cast<Containment *>(pw)) {
1791  break;
1792  } else if (qobject_cast<Applet *>(pw)) {
1793  return false;
1794  }
1795  }
1796 
1797  QGraphicsSceneHoverEvent *he = static_cast<QGraphicsSceneHoverEvent*>(event);
1798  if (d->handle) {
1799  d->handle.data()->setHoverPos(he->pos());
1800  } else {
1801  //kDebug() << "generated applet handle";
1802  AppletHandle *handle = new AppletHandle(containment(), this, he->pos());
1803  connect(handle, SIGNAL(disappearDone(AppletHandle*)),
1804  this, SLOT(handleDisappeared(AppletHandle*)));
1805  connect(this, SIGNAL(geometryChanged()),
1806  handle, SLOT(appletResized()));
1807  d->handle = handle;
1808  }
1809  }
1810  break;
1811 
1812  case QEvent::GraphicsSceneHoverMove:
1813  if (d->handle && !d->handle.data()->shown() && immutability() == Mutable) {
1814  QGraphicsSceneHoverEvent *he = static_cast<QGraphicsSceneHoverEvent*>(event);
1815  d->handle.data()->setHoverPos(he->pos());
1816  }
1817  break;
1818 
1819  case QEvent::GraphicsSceneMousePress: {
1820  QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(event);
1821  if (!contentsRect().contains(me->pos())) {
1822  event->setAccepted(false);
1823  return true;
1824  }
1825  break;
1826  }
1827 
1828  default:
1829  break;
1830  }
1831 
1832  }
1833 
1834  switch (event->type()) {
1835  case QEvent::GraphicsSceneMouseMove:
1836  case QEvent::GraphicsSceneMousePress:
1837  case QEvent::GraphicsSceneMouseRelease:
1838  {
1839  if (watched == this) {
1840  event->setAccepted(false);
1841  return false;
1842  }
1843  // don't move when the containment is not mutable,
1844  // in the rare case the containment doesn't exists consider it as mutable
1845  if ((flags() & ItemIsMovable) && d->registeredAsDragHandle.contains(watched)) {
1846  Containment *c = containment();
1847  if (!c || c->immutability() == Mutable) {
1848  scene()->sendEvent(this, event);
1849  return false;
1850  }
1851  }
1852  break;
1853  }
1854 
1855  default:
1856  break;
1857  }
1858 
1859  return QGraphicsItem::sceneEventFilter(watched, event);
1860 }
1861 
1862 void Applet::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
1863 {
1864  if (immutability() == Mutable && formFactor() == Plasma::Planar && (flags() & ItemIsMovable)) {
1865  QGraphicsWidget::mouseMoveEvent(event);
1866  }
1867 }
1868 
1869 void Applet::focusInEvent(QFocusEvent *event)
1870 {
1871  if (!isContainment() && containment()) {
1872  //focusing an applet may trigger this event again, but we won't be here more than twice
1873  containment()->d->focusApplet(this);
1874  }
1875 
1876  QGraphicsWidget::focusInEvent(event);
1877 }
1878 
1879 void Applet::resizeEvent(QGraphicsSceneResizeEvent *event)
1880 {
1881  QGraphicsWidget::resizeEvent(event);
1882 
1883  if (d->background) {
1884  d->background->resizeFrame(boundingRect().size());
1885  }
1886 
1887  updateConstraints(Plasma::SizeConstraint);
1888 
1889  d->scheduleModificationNotification();
1890  emit geometryChanged();
1891 }
1892 
1893 bool Applet::isUserConfiguring() const
1894 {
1895  return KConfigDialog::exists(d->configDialogId());
1896 }
1897 
1898 void Applet::showConfigurationInterface()
1899 {
1900  if (!hasConfigurationInterface()) {
1901  return;
1902  }
1903 
1904  if (immutability() != Mutable && !KAuthorized::authorize("plasma/allow_configure_when_locked")) {
1905  return;
1906  }
1907 
1908  KConfigDialog *dlg = KConfigDialog::exists(d->configDialogId());
1909 
1910  if (dlg) {
1911  KWindowSystem::setOnDesktop(dlg->winId(), KWindowSystem::currentDesktop());
1912  dlg->show();
1913  KWindowSystem::activateWindow(dlg->winId());
1914  return;
1915  }
1916 
1917  d->publishUI.publishCheckbox = 0;
1918  if (d->package) {
1919  KConfigDialog *dialog = 0;
1920 
1921  const QString uiFile = d->package->filePath("mainconfigui");
1922  KDesktopFile df(d->package->path() + "/metadata.desktop");
1923  const QStringList kcmPlugins = df.desktopGroup().readEntry("X-Plasma-ConfigPlugins", QStringList());
1924  if (!uiFile.isEmpty() || !kcmPlugins.isEmpty()) {
1925  KConfigSkeleton *configLoader = d->configLoader ? d->configLoader : new KConfigSkeleton(0);
1926  dialog = new AppletConfigDialog(0, d->configDialogId(), configLoader);
1927 
1928  if (!d->configLoader) {
1929  // delete the temporary when this dialog is done
1930  configLoader->setParent(dialog);
1931  }
1932 
1933  dialog->setWindowTitle(d->configWindowTitle());
1934  dialog->setAttribute(Qt::WA_DeleteOnClose, true);
1935  bool hasPages = false;
1936 
1937  QFile f(uiFile);
1938  QUiLoader loader;
1939  QWidget *w = loader.load(&f);
1940  if (w) {
1941  dialog->addPage(w, i18n("Settings"), icon(), i18n("%1 Settings", name()));
1942  hasPages = true;
1943  }
1944 
1945  foreach (const QString &kcm, kcmPlugins) {
1946 #ifndef PLASMA_NO_KUTILS
1947  KCModuleProxy *module = new KCModuleProxy(kcm);
1948  if (module->realModule()) {
1949  //preemptively load modules to prevent save() crashing on some kcms, like powerdevil ones
1950  module->load();
1951  connect(module, SIGNAL(changed(bool)), dialog, SLOT(settingsModified(bool)));
1952  connect(dialog, SIGNAL(okClicked()),
1953  module->realModule(), SLOT(save()));
1954  connect(dialog, SIGNAL(applyClicked()),
1955  module->realModule(), SLOT(save()));
1956  dialog->addPage(module, module->moduleInfo().moduleName(), module->moduleInfo().icon());
1957  hasPages = true;
1958  } else {
1959  delete module;
1960  }
1961 #else
1962  KService::Ptr service = KService::serviceByStorageId(kcm);
1963  if (service) {
1964  QString error;
1965  KCModule *module = service->createInstance<KCModule>(dialog, QVariantList(), &error);
1966  if (module) {
1967  module->load();
1968  connect(module, SIGNAL(changed(bool)), dialog, SLOT(settingsModified(bool)));
1969  connect(dialog, SIGNAL(okClicked()),
1970  module, SLOT(save()));
1971  connect(dialog, SIGNAL(applyClicked()),
1972  module, SLOT(save()));
1973  dialog->addPage(module, service->name(), service->icon());
1974  hasPages = true;
1975  } else {
1976 #ifndef NDEBUG
1977  kDebug() << "failed to load kcm" << kcm << "for" << name();
1978 #endif
1979  }
1980  }
1981 #endif
1982  }
1983 
1984  if (hasPages) {
1985  d->addGlobalShortcutsPage(dialog);
1986  dialog->show();
1987  } else {
1988  delete dialog;
1989  dialog = 0;
1990  }
1991  }
1992 
1993  if (!dialog && d->script) {
1994  d->script->showConfigurationInterface();
1995  }
1996  } else if (d->script) {
1997  d->script->showConfigurationInterface();
1998  } else {
1999  KConfigDialog *dialog = d->generateGenericConfigDialog();
2000  d->addStandardConfigurationPages(dialog);
2001  showConfigurationInterface(dialog);
2002  }
2003 
2004  emit releaseVisualFocus();
2005 }
2006 
2007 void Applet::showConfigurationInterface(QWidget *widget)
2008 {
2009  if (!containment() || !containment()->corona() ||
2010  !containment()->corona()->dialogManager()) {
2011  widget->show();
2012  return;
2013  }
2014 
2015  QMetaObject::invokeMethod(containment()->corona()->dialogManager(), "showDialog", Q_ARG(QWidget *, widget), Q_ARG(Plasma::Applet *, this));
2016 }
2017 
2018 QString AppletPrivate::configDialogId() const
2019 {
2020  return QString("%1settings%2").arg(appletId).arg(q->name());
2021 }
2022 
2023 QString AppletPrivate::configWindowTitle() const
2024 {
2025  return i18nc("@title:window", "%1 Settings", q->name());
2026 }
2027 
2028 QSet<QString> AppletPrivate::knownCategories()
2029 {
2030  // this is to trick the tranlsation tools into making the correct
2031  // strings for translation
2032  QSet<QString> categories = s_customCategories;
2033  categories << QString(I18N_NOOP("Accessibility")).toLower()
2034  << QString(I18N_NOOP("Application Launchers")).toLower()
2035  << QString(I18N_NOOP("Astronomy")).toLower()
2036  << QString(I18N_NOOP("Date and Time")).toLower()
2037  << QString(I18N_NOOP("Development Tools")).toLower()
2038  << QString(I18N_NOOP("Education")).toLower()
2039  << QString(I18N_NOOP("Environment and Weather")).toLower()
2040  << QString(I18N_NOOP("Examples")).toLower()
2041  << QString(I18N_NOOP("File System")).toLower()
2042  << QString(I18N_NOOP("Fun and Games")).toLower()
2043  << QString(I18N_NOOP("Graphics")).toLower()
2044  << QString(I18N_NOOP("Language")).toLower()
2045  << QString(I18N_NOOP("Mapping")).toLower()
2046  << QString(I18N_NOOP("Miscellaneous")).toLower()
2047  << QString(I18N_NOOP("Multimedia")).toLower()
2048  << QString(I18N_NOOP("Online Services")).toLower()
2049  << QString(I18N_NOOP("Productivity")).toLower()
2050  << QString(I18N_NOOP("System Information")).toLower()
2051  << QString(I18N_NOOP("Utilities")).toLower()
2052  << QString(I18N_NOOP("Windows and Tasks")).toLower();
2053  return categories;
2054 }
2055 
2056 KConfigDialog *AppletPrivate::generateGenericConfigDialog()
2057 {
2058  KConfigSkeleton *nullManager = new KConfigSkeleton(0);
2059  KConfigDialog *dialog = new AppletConfigDialog(0, configDialogId(), nullManager);
2060  nullManager->setParent(dialog);
2061  dialog->setFaceType(KPageDialog::Auto);
2062  dialog->setWindowTitle(configWindowTitle());
2063  dialog->setAttribute(Qt::WA_DeleteOnClose, true);
2064  q->createConfigurationInterface(dialog);
2065  dialog->showButton(KDialog::Default, false);
2066  dialog->showButton(KDialog::Help, false);
2067  QObject::connect(dialog, SIGNAL(applyClicked()), q, SLOT(configDialogFinished()));
2068  QObject::connect(dialog, SIGNAL(okClicked()), q, SLOT(configDialogFinished()));
2069  return dialog;
2070 }
2071 
2072 void AppletPrivate::addStandardConfigurationPages(KConfigDialog *dialog)
2073 {
2074  addGlobalShortcutsPage(dialog);
2075 }
2076 
2077 void AppletPrivate::addGlobalShortcutsPage(KConfigDialog *dialog)
2078 {
2079 #ifndef PLASMA_NO_GLOBAL_SHORTCUTS
2080  if (isContainment) {
2081  return;
2082  }
2083 
2084  QWidget *page = new QWidget;
2085  QVBoxLayout *layout = new QVBoxLayout(page);
2086 
2087  if (!shortcutEditor) {
2088  shortcutEditor = new KKeySequenceWidget(page);
2089  QObject::connect(shortcutEditor.data(), SIGNAL(keySequenceChanged(QKeySequence)), dialog, SLOT(settingsModified()));
2090  }
2091 
2092  shortcutEditor.data()->setKeySequence(q->globalShortcut().primary());
2093  layout->addWidget(shortcutEditor.data());
2094  layout->addStretch();
2095  dialog->addPage(page, i18n("Keyboard Shortcut"), "preferences-desktop-keyboard");
2096 
2097  QObject::connect(dialog, SIGNAL(applyClicked()), q, SLOT(configDialogFinished()), Qt::UniqueConnection);
2098  QObject::connect(dialog, SIGNAL(okClicked()), q, SLOT(configDialogFinished()), Qt::UniqueConnection);
2099 #endif
2100 }
2101 
2102 void AppletPrivate::publishCheckboxStateChanged(int state)
2103 {
2104  if (state == Qt::Checked) {
2105  publishUI.allUsersCheckbox->setEnabled(true);
2106  } else {
2107  publishUI.allUsersCheckbox->setEnabled(false);
2108  }
2109 }
2110 
2111 void AppletPrivate::configDialogFinished()
2112 {
2113  if (shortcutEditor) {
2114  QKeySequence sequence = shortcutEditor.data()->keySequence();
2115  if (sequence != q->globalShortcut().primary()) {
2116  q->setGlobalShortcut(KShortcut(sequence));
2117  emit q->configNeedsSaving();
2118  }
2119  }
2120 
2121 #ifdef ENABLE_REMOTE_WIDGETS
2122  if (KConfigDialog::exists(configDialogId()) && publishUI.publishCheckbox) {
2123  q->config().writeEntry("Share", publishUI.publishCheckbox->isChecked());
2124 
2125  if (publishUI.publishCheckbox->isChecked()) {
2126  QString resourceName =
2127  i18nc("%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is published on",
2128  "%1 on %2", q->name(), QHostInfo::localHostName());
2129  q->publish(Plasma::ZeroconfAnnouncement, resourceName);
2130  if (publishUI.allUsersCheckbox->isChecked()) {
2131  if (!AuthorizationManager::self()->d->matchingRule(resourceName, Credentials())) {
2132  AuthorizationRule *rule = new AuthorizationRule(resourceName, "");
2133  rule->setPolicy(AuthorizationRule::Allow);
2134  rule->setTargets(AuthorizationRule::AllUsers);
2135  AuthorizationManager::self()->d->rules.append(rule);
2136  }
2137  } else {
2138  AuthorizationRule *matchingRule =
2139  AuthorizationManager::self()->d->matchingRule(resourceName, Credentials());
2140  if (matchingRule) {
2141  AuthorizationManager::self()->d->rules.removeAll(matchingRule);
2142  }
2143  }
2144  } else {
2145  q->unpublish();
2146  }
2147  }
2148 #endif
2149 
2150  if (!configLoader) {
2151  // the config loader will trigger this for us, so we don't need to.
2152  propagateConfigChanged();
2153  if (KConfigDialog *dialog = qobject_cast<KConfigDialog *>(q->sender())) {
2154  dialog->enableButton(KDialog::Apply, false);
2155  }
2156  }
2157 }
2158 
2159 void AppletPrivate::updateShortcuts()
2160 {
2161  if (isContainment) {
2162  //a horrible hack to avoid clobbering corona settings
2163  //we pull them out, then read, then put them back
2164  QList<QString> names;
2165  QList<QAction*> qactions;
2166  names << "add sibling containment" << "configure shortcuts" << "lock widgets";
2167  foreach (const QString &name, names) {
2168  QAction *a = actions->action(name);
2169  actions->takeAction(a); //FIXME this is stupid, KActionCollection needs a takeAction(QString) method
2170  qactions << a;
2171  }
2172 
2173  actions->readSettings();
2174 
2175  for (int i = 0; i < names.size(); ++i) {
2176  QAction *a = qactions.at(i);
2177  if (a) {
2178  actions->addAction(names.at(i), a);
2179  }
2180  }
2181  } else {
2182  actions->readSettings();
2183  }
2184 }
2185 
2186 void AppletPrivate::propagateConfigChanged()
2187 {
2188  if (isContainment) {
2189  Containment *c = qobject_cast<Containment *>(q);
2190  if (c) {
2191  c->d->configChanged();
2192  }
2193  }
2194 
2195  q->configChanged();
2196 }
2197 
2198 void Applet::configChanged()
2199 {
2200  if (d->script) {
2201  if (d->configLoader) {
2202  d->configLoader->readConfig();
2203  }
2204  d->script->configChanged();
2205  }
2206 }
2207 
2208 void Applet::createConfigurationInterface(KConfigDialog *parent)
2209 {
2210  Q_UNUSED(parent)
2211  // virtual method reimplemented by subclasses.
2212  // do not put anything here ...
2213 }
2214 
2215 bool Applet::hasAuthorization(const QString &constraint) const
2216 {
2217  KConfigGroup constraintGroup(KGlobal::config(), "Constraints");
2218  return constraintGroup.readEntry(constraint, true);
2219 }
2220 
2221 void Applet::setAssociatedApplication(const QString &string)
2222 {
2223  AssociatedApplicationManager::self()->setApplication(this, string);
2224 
2225  QAction *runAssociatedApplication = d->actions->action("run associated application");
2226  if (runAssociatedApplication) {
2227  bool valid = AssociatedApplicationManager::self()->appletHasValidAssociatedApplication(this);
2228  valid = valid && hasAuthorization("LaunchApp"); //obey security!
2229  runAssociatedApplication->setVisible(valid);
2230  runAssociatedApplication->setEnabled(valid);
2231  }
2232 }
2233 
2234 void Applet::setAssociatedApplicationUrls(const KUrl::List &urls)
2235 {
2236  AssociatedApplicationManager::self()->setUrls(this, urls);
2237 
2238  QAction *runAssociatedApplication = d->actions->action("run associated application");
2239  if (runAssociatedApplication) {
2240  bool valid = AssociatedApplicationManager::self()->appletHasValidAssociatedApplication(this);
2241  valid = valid && hasAuthorization("LaunchApp"); //obey security!
2242  runAssociatedApplication->setVisible(valid);
2243  runAssociatedApplication->setEnabled(valid);
2244  }
2245 }
2246 
2247 QString Applet::associatedApplication() const
2248 {
2249  return AssociatedApplicationManager::self()->application(this);
2250 }
2251 
2252 KUrl::List Applet::associatedApplicationUrls() const
2253 {
2254  return AssociatedApplicationManager::self()->urls(this);
2255 }
2256 
2257 void Applet::runAssociatedApplication()
2258 {
2259  if (hasAuthorization("LaunchApp")) {
2260  AssociatedApplicationManager::self()->run(this);
2261  }
2262 }
2263 
2264 bool Applet::hasValidAssociatedApplication() const
2265 {
2266  return AssociatedApplicationManager::self()->appletHasValidAssociatedApplication(this);
2267 }
2268 
2269 void AppletPrivate::filterOffers(QList<KService::Ptr> &offers)
2270 {
2271  KConfigGroup constraintGroup(KGlobal::config(), "Constraints");
2272  foreach (const QString &key, constraintGroup.keyList()) {
2273  //kDebug() << "security constraint" << key;
2274  if (constraintGroup.readEntry(key, true)) {
2275  continue;
2276  }
2277 
2278  //ugh. a qlist of ksharedptr<kservice>
2279  QMutableListIterator<KService::Ptr> it(offers);
2280  while (it.hasNext()) {
2281  KService::Ptr p = it.next();
2282  QString prop = QString("X-Plasma-Requires-").append(key);
2283  QVariant req = p->property(prop, QVariant::String);
2284  //valid values: Required/Optional/Unused
2285  QString reqValue;
2286  if (req.isValid()) {
2287  reqValue = req.toString();
2288  } else if (p->property("X-Plasma-API").toString().toLower() == "javascript") {
2289  //TODO: be able to check whether or not a script engine provides "controled"
2290  //bindings; for now we just give a pass to the qscript ones
2291  reqValue = "Unused";
2292  }
2293 
2294  if (!(reqValue == "Optional" || reqValue == "Unused")) {
2295  //if (reqValue == "Required") {
2296  it.remove();
2297  }
2298  }
2299  }
2300 }
2301 
2302 QString AppletPrivate::parentAppConstraint(const QString &parentApp)
2303 {
2304  if (parentApp.isEmpty()) {
2305  return QString("((not exist [X-KDE-ParentApp] or [X-KDE-ParentApp] == '') or [X-KDE-ParentApp] == '%1')")
2306  .arg(KGlobal::mainComponent().aboutData()->appName());
2307  }
2308 
2309  return QString("[X-KDE-ParentApp] == '%1'").arg(parentApp);
2310 }
2311 
2312 KPluginInfo::List Applet::listAppletInfo(const QString &category, const QString &parentApp)
2313 {
2314  return PluginLoader::pluginLoader()->listAppletInfo(category, parentApp);
2315 }
2316 
2317 KPluginInfo::List Applet::listAppletInfoForMimetype(const QString &mimetype)
2318 {
2319  QString constraint = AppletPrivate::parentAppConstraint();
2320  constraint.append(QString(" and '%1' in [X-Plasma-DropMimeTypes]").arg(mimetype));
2321  //kDebug() << "listAppletInfoForMimetype with" << mimetype << constraint;
2322  KService::List offers = KServiceTypeTrader::self()->query("Plasma/Applet", constraint);
2323  AppletPrivate::filterOffers(offers);
2324  return KPluginInfo::fromServices(offers);
2325 }
2326 
2327 KPluginInfo::List Applet::listAppletInfoForUrl(const QUrl &url)
2328 {
2329  QString constraint = AppletPrivate::parentAppConstraint();
2330  constraint.append(" and exist [X-Plasma-DropUrlPatterns]");
2331  KService::List offers = KServiceTypeTrader::self()->query("Plasma/Applet", constraint);
2332  AppletPrivate::filterOffers(offers);
2333 
2334  KPluginInfo::List allApplets = KPluginInfo::fromServices(offers);
2335  KPluginInfo::List filtered;
2336  foreach (const KPluginInfo &info, allApplets) {
2337  QStringList urlPatterns = info.property("X-Plasma-DropUrlPatterns").toStringList();
2338  foreach (const QString &glob, urlPatterns) {
2339  QRegExp rx(glob);
2340  rx.setPatternSyntax(QRegExp::Wildcard);
2341  if (rx.exactMatch(url.toString())) {
2342  kDebug() << info.name() << "matches" << glob << url;
2343  filtered << info;
2344  }
2345  }
2346  }
2347 
2348  return filtered;
2349 }
2350 
2351 QStringList Applet::listCategories(const QString &parentApp, bool visibleOnly)
2352 {
2353  QString constraint = AppletPrivate::parentAppConstraint(parentApp);
2354  constraint.append(" and exist [X-KDE-PluginInfo-Category]");
2355 
2356  KConfigGroup group(KGlobal::config(), "General");
2357  const QStringList excluded = group.readEntry("ExcludeCategories", QStringList());
2358  foreach (const QString &category, excluded) {
2359  constraint.append(" and [X-KDE-PluginInfo-Category] != '").append(category).append("'");
2360  }
2361 
2362  KService::List offers = KServiceTypeTrader::self()->query("Plasma/Applet", constraint);
2363  AppletPrivate::filterOffers(offers);
2364 
2365  QStringList categories;
2366  QSet<QString> known = AppletPrivate::knownCategories();
2367  foreach (const KService::Ptr &applet, offers) {
2368  QString appletCategory = applet->property("X-KDE-PluginInfo-Category").toString();
2369  if (visibleOnly && applet->noDisplay()) {
2370  // we don't want to show the hidden category
2371  continue;
2372  }
2373 
2374  //kDebug() << " and we have " << appletCategory;
2375  if (!appletCategory.isEmpty() && !known.contains(appletCategory.toLower())) {
2376  kDebug() << "Unknown category: " << applet->name() << "says it is in the"
2377  << appletCategory << "category which is unknown to us";
2378  appletCategory.clear();
2379  }
2380 
2381  if (appletCategory.isEmpty()) {
2382  if (!categories.contains(i18nc("misc category", "Miscellaneous"))) {
2383  categories << i18nc("misc category", "Miscellaneous");
2384  }
2385  } else if (!categories.contains(appletCategory)) {
2386  categories << appletCategory;
2387  }
2388  }
2389 
2390  categories.sort();
2391  return categories;
2392 }
2393 
2394 void Applet::setCustomCategories(const QStringList &categories)
2395 {
2396  AppletPrivate::s_customCategories = QSet<QString>::fromList(categories);
2397 }
2398 
2399 QStringList Applet::customCategories()
2400 {
2401  return AppletPrivate::s_customCategories.toList();
2402 }
2403 
2404 Applet *Applet::loadPlasmoid(const QString &path, uint appletId, const QVariantList &args)
2405 {
2406  if (QFile::exists(path + "/metadata.desktop")) {
2407  KService service(path + "/metadata.desktop");
2408  const QStringList& types = service.serviceTypes();
2409 
2410  if (types.contains("Plasma/Containment")) {
2411  return new Containment(path, appletId, args);
2412  } else if (types.contains("Plasma/PopupApplet")) {
2413  return new PopupApplet(path, appletId, args);
2414  } else {
2415  return new Applet(path, appletId, args);
2416  }
2417  }
2418 
2419  return 0;
2420 }
2421 
2422 Applet *Applet::load(const QString &appletName, uint appletId, const QVariantList &args)
2423 {
2424  return PluginLoader::pluginLoader()->loadApplet(appletName, appletId, args);
2425 }
2426 
2427 Applet *Applet::load(const KPluginInfo &info, uint appletId, const QVariantList &args)
2428 {
2429  if (!info.isValid()) {
2430  return 0;
2431  }
2432 
2433  return load(info.pluginName(), appletId, args);
2434 }
2435 
2436 QVariant Applet::itemChange(GraphicsItemChange change, const QVariant &value)
2437 {
2438  QVariant ret = QGraphicsWidget::itemChange(change, value);
2439 
2440  //kDebug() << change;
2441  switch (change) {
2442  case ItemSceneHasChanged: {
2443  Corona *newCorona = qobject_cast<Corona *>(qvariant_cast<QGraphicsScene*>(value));
2444  if (newCorona && newCorona->immutability() != Mutable) {
2445  updateConstraints(ImmutableConstraint);
2446  }
2447  }
2448  break;
2449  case ItemParentChange:
2450  if (!d->isContainment) {
2451  Containment *c = containment();
2452  if (d->mainConfig && !c) {
2453  kWarning() << "Configuration object was requested prior to init(), which is too early. "
2454  "Please fix this item:" << parentItem() << value.value<QGraphicsItem *>()
2455  << name();
2456 
2457  Applet *newC = dynamic_cast<Applet*>(value.value<QGraphicsItem *>());
2458  if (newC) {
2459  // if this is an applet, and we've just been assigned to our first containment,
2460  // but the applet did something stupid like ask for the config() object prior to
2461  // this happening (e.g. inits ctor) then let's repair that situation for them.
2462  KConfigGroup *old = d->mainConfig;
2463  KConfigGroup appletConfig = newC->config();
2464  appletConfig = KConfigGroup(&appletConfig, "Applets");
2465  d->mainConfig = new KConfigGroup(&appletConfig, QString::number(d->appletId));
2466  old->copyTo(d->mainConfig);
2467  old->deleteGroup();
2468  delete old;
2469  }
2470  }
2471  }
2472  break;
2473  case ItemParentHasChanged:
2474  {
2475  if (isContainment()) {
2476  removeSceneEventFilter(this);
2477  } else {
2478  Containment *c = containment();
2479  if (c && c->containmentType() == Containment::DesktopContainment) {
2480  installSceneEventFilter(this);
2481  } else {
2482  removeSceneEventFilter(this);
2483  }
2484  }
2485  }
2486  break;
2487  case ItemPositionHasChanged:
2488  emit geometryChanged();
2489  // fall through!
2490  case ItemTransformHasChanged:
2491  d->scheduleModificationNotification();
2492  break;
2493  default:
2494  break;
2495  };
2496 
2497  return ret;
2498 }
2499 
2500 QPainterPath Applet::shape() const
2501 {
2502  if (d->script) {
2503  return d->script->shape();
2504  }
2505 
2506  return QGraphicsWidget::shape();
2507 }
2508 
2509 QSizeF Applet::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
2510 {
2511  QSizeF hint = QGraphicsWidget::sizeHint(which, constraint);
2512  const FormFactor ff = formFactor();
2513 
2514  // in panels make sure that the contents won't exit from the panel
2515  if (which == Qt::MinimumSize) {
2516  if (ff == Horizontal) {
2517  hint.setHeight(0);
2518  } else if (ff == Vertical) {
2519  hint.setWidth(0);
2520  }
2521  }
2522 
2523  // enforce a square size in panels
2524  if (d->aspectRatioMode == Plasma::Square) {
2525  if (ff == Horizontal) {
2526  hint.setWidth(size().height());
2527  } else if (ff == Vertical) {
2528  hint.setHeight(size().width());
2529  }
2530  } else if (d->aspectRatioMode == Plasma::ConstrainedSquare) {
2531  //enforce a size not wider than tall
2532  if (ff == Horizontal) {
2533  hint.setWidth(size().height());
2534  //enforce a size not taller than wide
2535  } else if (ff == Vertical && (which == Qt::MaximumSize || size().width() <= KIconLoader::SizeLarge)) {
2536  hint.setHeight(size().width());
2537  }
2538  }
2539 
2540  return hint;
2541 }
2542 
2543 void Applet::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
2544 {
2545  Q_UNUSED(event)
2546 }
2547 
2548 void Applet::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
2549 {
2550  Q_UNUSED(event)
2551 }
2552 
2553 void Applet::timerEvent(QTimerEvent *event)
2554 {
2555  if (d->transient) {
2556  d->constraintsTimer.stop();
2557  d->busyWidgetTimer.stop();
2558  if (d->modificationsTimer) {
2559  d->modificationsTimer->stop();
2560  }
2561  return;
2562  }
2563 
2564  if (event->timerId() == d->constraintsTimer.timerId()) {
2565  d->constraintsTimer.stop();
2566 
2567  // Don't flushPendingConstraints if we're just starting up
2568  // flushPendingConstraints will be called by Corona
2569  if(!(d->pendingConstraints & Plasma::StartupCompletedConstraint)) {
2570  flushPendingConstraintsEvents();
2571  }
2572  } else if (d->modificationsTimer && event->timerId() == d->modificationsTimer->timerId()) {
2573  d->modificationsTimer->stop();
2574  // invalid group, will result in save using the default group
2575  KConfigGroup cg;
2576 
2577  save(cg);
2578  emit configNeedsSaving();
2579  } else if (event->timerId() == d->busyWidgetTimer.timerId()) {
2580  if (!d->busyWidget) {
2581  d->createMessageOverlay(false);
2582  d->messageOverlay->opacity = 0;
2583 
2584  QGraphicsLinearLayout *mainLayout = new QGraphicsLinearLayout(d->messageOverlay);
2585  d->busyWidget = new Plasma::BusyWidget(d->messageOverlay);
2586  d->busyWidget->setAcceptHoverEvents(false);
2587  d->busyWidget->setAcceptedMouseButtons(Qt::NoButton);
2588  d->messageOverlay->setAcceptHoverEvents(false);
2589  d->messageOverlay->setAcceptedMouseButtons(Qt::NoButton);
2590 
2591  mainLayout->addStretch();
2592  mainLayout->addItem(d->busyWidget);
2593  mainLayout->addStretch();
2594  }
2595  }
2596 }
2597 
2598 QRect Applet::screenRect() const
2599 {
2600  QGraphicsView *v = view();
2601 
2602  if (v) {
2603  QPointF bottomRight = pos();
2604  bottomRight.rx() += size().width();
2605  bottomRight.ry() += size().height();
2606 
2607  QPoint tL = v->mapToGlobal(v->mapFromScene(pos()));
2608  QPoint bR = v->mapToGlobal(v->mapFromScene(bottomRight));
2609  return QRect(QPoint(tL.x(), tL.y()), QSize(bR.x() - tL.x(), bR.y() - tL.y()));
2610  }
2611 
2612  //The applet doesn't have a view on it.
2613  //So a screenRect isn't relevant.
2614  return QRect(QPoint(0, 0), QSize(0, 0));
2615 }
2616 
2617 void Applet::raise()
2618 {
2619  setZValue(++AppletPrivate::s_maxZValue);
2620 }
2621 
2622 void Applet::lower()
2623 {
2624  setZValue(--AppletPrivate::s_minZValue);
2625 }
2626 
2627 void AppletPrivate::setIsContainment(bool nowIsContainment, bool forceUpdate)
2628 {
2629  if (isContainment == nowIsContainment && !forceUpdate) {
2630  return;
2631  }
2632 
2633  isContainment = nowIsContainment;
2634  //FIXME I do not like this function.
2635  //currently it's only called before ctmt/applet init, with (true,true), and I'm going to assume it stays that way.
2636  //if someone calls it at some other time it'll cause headaches. :P
2637 
2638  delete mainConfig;
2639  mainConfig = 0;
2640 
2641  Containment *c = q->containment();
2642  if (c) {
2643  c->d->checkContainmentFurniture();
2644  }
2645 }
2646 
2647 bool Applet::isContainment() const
2648 {
2649  return d->isContainment;
2650 }
2651 
2652 // PRIVATE CLASS IMPLEMENTATION
2653 
2654 AppletPrivate::AppletPrivate(KService::Ptr service, const KPluginInfo *info, int uniqueID, Applet *applet)
2655  : appletId(uniqueID),
2656  q(applet),
2657  service(0),
2658  preferredBackgroundHints(Applet::StandardBackground),
2659  backgroundHints(Applet::NoBackground),
2660  aspectRatioMode(Plasma::KeepAspectRatio),
2661  immutability(Mutable),
2662  appletDescription(info ? *info : KPluginInfo(service)),
2663  background(0),
2664  mainConfig(0),
2665  pendingConstraints(NoConstraint),
2666  messageOverlay(0),
2667  messageOverlayProxy(0),
2668  busyWidget(0),
2669  script(0),
2670  package(0),
2671  configLoader(0),
2672  actions(AppletPrivate::defaultActions(applet)),
2673  activationAction(0),
2674  itemStatus(UnknownStatus),
2675  preferredSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored),
2676  modificationsTimer(0),
2677  hasConfigurationInterface(false),
2678  failed(false),
2679  isContainment(false),
2680  transient(false),
2681  needsConfig(false),
2682  started(false)
2683 {
2684  if (appletId == 0) {
2685  appletId = ++s_maxAppletId;
2686  } else if (appletId > s_maxAppletId) {
2687  s_maxAppletId = appletId;
2688  }
2689 
2690  publishUI.publishCheckbox = 0;
2691 }
2692 
2693 AppletPrivate::~AppletPrivate()
2694 {
2695  if (activationAction && activationAction->isGlobalShortcutEnabled()) {
2696  //kDebug() << "reseting global action for" << q->name() << activationAction->objectName();
2697  activationAction->forgetGlobalShortcut();
2698  }
2699 
2700  delete extender.data();
2701 
2702  delete script;
2703  script = 0;
2704  delete package;
2705  package = 0;
2706  delete configLoader;
2707  configLoader = 0;
2708  delete mainConfig;
2709  mainConfig = 0;
2710  delete modificationsTimer;
2711 }
2712 
2713 void AppletPrivate::init(const QString &packagePath)
2714 {
2715  // WARNING: do not access config() OR globalConfig() in this method!
2716  // that requires a scene, which is not available at this point
2717  q->setCacheMode(Applet::DeviceCoordinateCache);
2718  q->setAcceptsHoverEvents(true);
2719  q->setFlag(QGraphicsItem::ItemIsFocusable, true);
2720  q->setFocusPolicy(Qt::ClickFocus);
2721  // FIXME: adding here because nothing seems to be doing it in QGraphicsView,
2722  // but it doesn't actually work anyways =/
2723  q->setLayoutDirection(qApp->layoutDirection());
2724 
2725  //set a default size before any saved settings are read
2726  QSize size(200, 200);
2727  q->setBackgroundHints(Applet::DefaultBackground);
2728  q->setHasConfigurationInterface(true); //FIXME why not default it to true in the constructor?
2729 
2730  QAction *closeApplet = actions->action("remove");
2731  if (closeApplet) {
2732  closeApplet->setText(i18nc("%1 is the name of the applet", "Remove this %1", q->name()));
2733  }
2734 
2735  QAction *configAction = actions->action("configure");
2736  if (configAction) {
2737  configAction->setText(i18nc("%1 is the name of the applet", "%1 Settings", q->name()));
2738  }
2739 
2740  QObject::connect(q, SIGNAL(activate()), q, SLOT(setFocus()));
2741  if (!appletDescription.isValid()) {
2742  kDebug() << "Check your constructor! "
2743  << "You probably want to be passing in a Service::Ptr "
2744  << "or a QVariantList with a valid storageid as arg[0].";
2745  q->resize(size);
2746  return;
2747  }
2748 
2749  QVariant s = appletDescription.property("X-Plasma-DefaultSize");
2750  if (s.isValid()) {
2751  size = s.toSize();
2752  }
2753  //kDebug() << "size" << size;
2754  q->resize(size);
2755 
2756  QString api = appletDescription.property("X-Plasma-API").toString();
2757 
2758  // we have a scripted plasmoid
2759  if (!api.isEmpty()) {
2760  // find where the Package is
2761  QString path = packagePath.isEmpty() ? appletDescription.pluginName() : packagePath;
2762  // create the package and see if we have something real
2763  PackageStructure::Ptr structure = Plasma::packageStructure(api, Plasma::AppletComponent);
2764  package = new Package(path, structure);
2765  //kDebug() << "***** package is" << package->path();
2766 
2767  if (package->isValid()) {
2768  // now we try and set up the script engine.
2769  // it will be parented to this applet and so will get
2770  // deleted when the applet does
2771 
2772  script = Plasma::loadScriptEngine(api, q);
2773  if (!script) {
2774  delete package;
2775  package = 0;
2776  q->setFailedToLaunch(true,
2777  i18nc("API or programming language the widget was written in, name of the widget",
2778  "Could not create a %1 ScriptEngine for the %2 widget.",
2779  api, appletDescription.name()));
2780  }
2781  } else {
2782  q->setFailedToLaunch(true, i18nc("Package file, name of the widget",
2783  "Could not open the %1 package required for the %2 widget.",
2784  appletDescription.pluginName(), appletDescription.name()));
2785  delete package;
2786  package = 0;
2787  }
2788  }
2789 }
2790 
2791 // put all setup routines for script here. at this point we can assume that
2792 // package exists and that we have a script engine
2793 void AppletPrivate::setupScriptSupport()
2794 {
2795  if (!package) {
2796  return;
2797  }
2798 
2799  kDebug() << "setting up script support, package is in" << package->path()
2800  << "which is a" << package->structure()->type() << "package"
2801  << ", main script is" << package->filePath("mainscript");
2802 
2803  QString translationsPath = package->filePath("translations");
2804  if (!translationsPath.isEmpty()) {
2805  //FIXME: we should _probably_ use a KComponentData to segregate the applets
2806  // from each other; but I want to get the basics working first :)
2807  KGlobal::dirs()->addResourceDir("locale", translationsPath);
2808  KGlobal::locale()->insertCatalog(package->metadata().pluginName());
2809  }
2810 
2811  QString xmlPath = package->filePath("mainconfigxml");
2812  if (!xmlPath.isEmpty()) {
2813  QFile file(xmlPath);
2814  KConfigGroup config = q->config();
2815  configLoader = new ConfigLoader(&config, &file);
2816  QObject::connect(configLoader, SIGNAL(configChanged()), q, SLOT(propagateConfigChanged()));
2817  }
2818 
2819  if (!package->filePath("mainconfigui").isEmpty()) {
2820  q->setHasConfigurationInterface(true);
2821  }
2822 }
2823 
2824 QString AppletPrivate::globalName() const
2825 {
2826  if (!appletDescription.isValid()) {
2827  return QString();
2828  }
2829 
2830  return appletDescription.service()->library();
2831 }
2832 
2833 QString AppletPrivate::instanceName()
2834 {
2835  if (!appletDescription.isValid()) {
2836  return QString();
2837  }
2838 
2839  return appletDescription.service()->library() + QString::number(appletId);
2840 }
2841 
2842 void AppletPrivate::scheduleConstraintsUpdate(Plasma::Constraints c)
2843 {
2844  // Don't start up a timer if we're just starting up
2845  // flushPendingConstraints will be called by Corona
2846  if (started && !constraintsTimer.isActive() && !(c & Plasma::StartupCompletedConstraint)) {
2847  constraintsTimer.start(0, q);
2848  }
2849 
2850  if (c & Plasma::StartupCompletedConstraint) {
2851  started = true;
2852  }
2853 
2854  pendingConstraints |= c;
2855 }
2856 
2857 void AppletPrivate::scheduleModificationNotification()
2858 {
2859  // modificationsTimer is not allocated until we get our notice of being started
2860  if (modificationsTimer) {
2861  // schedule a save
2862  if (modificationsTimer->isActive()) {
2863  modificationsTimer->stop();
2864  }
2865 
2866  modificationsTimer->start(1000, q);
2867  }
2868 }
2869 
2870 KConfigGroup *AppletPrivate::mainConfigGroup()
2871 {
2872  if (mainConfig) {
2873  return mainConfig;
2874  }
2875 
2876  bool newGroup = false;
2877  if (isContainment) {
2878  Corona *corona = qobject_cast<Corona*>(q->scene());
2879  KConfigGroup containmentConfig;
2880  //kDebug() << "got a corona, baby?" << (QObject*)corona << (QObject*)q;
2881 
2882  if (corona) {
2883  containmentConfig = KConfigGroup(corona->config(), "Containments");
2884  } else {
2885  containmentConfig = KConfigGroup(KGlobal::config(), "Containments");
2886  }
2887 
2888  if (package && !containmentConfig.hasGroup(QString::number(appletId))) {
2889  newGroup = true;
2890  }
2891 
2892  mainConfig = new KConfigGroup(&containmentConfig, QString::number(appletId));
2893  } else {
2894  KConfigGroup appletConfig;
2895 
2896  Containment *c = q->containment();
2897  Applet *parentApplet = qobject_cast<Applet *>(q->parent());
2898  if (parentApplet && parentApplet != static_cast<Applet *>(c)) {
2899  // this applet is nested inside another applet! use it's config
2900  // as the parent group in the config
2901  appletConfig = parentApplet->config();
2902  appletConfig = KConfigGroup(&appletConfig, "Applets");
2903  } else if (c) {
2904  // applet directly in a Containment, as usual
2905  appletConfig = c->config();
2906  appletConfig = KConfigGroup(&appletConfig, "Applets");
2907  } else {
2908  kWarning() << "requesting config for" << q->name() << "without a containment!";
2909  appletConfig = KConfigGroup(KGlobal::config(), "Applets");
2910  }
2911 
2912  if (package && !appletConfig.hasGroup(QString::number(appletId))) {
2913  newGroup = true;
2914  }
2915 
2916  mainConfig = new KConfigGroup(&appletConfig, QString::number(appletId));
2917  }
2918 
2919  if (newGroup) {
2920  //see if we have a default configuration in our package
2921  const QString defaultConfigFile = q->package()->filePath("defaultconfig");
2922  if (!defaultConfigFile.isEmpty()) {
2923  kDebug() << "copying default config: " << q->package()->filePath("defaultconfig");
2924  KConfigGroup defaultConfig(KSharedConfig::openConfig(defaultConfigFile)->group("Configuration"));
2925  defaultConfig.copyTo(mainConfig);
2926  }
2927  }
2928 
2929  return mainConfig;
2930 }
2931 
2932 QString AppletPrivate::visibleFailureText(const QString &reason)
2933 {
2934  QString text;
2935 
2936  if (reason.isEmpty()) {
2937  text = i18n("This object could not be created.");
2938  } else {
2939  QString r = reason;
2940  r.replace('\n', "<br/>");
2941  text = i18n("This object could not be created for the following reason:<p><b>%1</b></p>", r);
2942  }
2943 
2944  return text;
2945 }
2946 
2947 void AppletPrivate::themeChanged()
2948 {
2949  if (background) {
2950  //do again the translucent background fallback
2951  q->setBackgroundHints(backgroundHints);
2952 
2953  qreal left;
2954  qreal right;
2955  qreal top;
2956  qreal bottom;
2957  background->getMargins(left, top, right, bottom);
2958  q->setContentsMargins(left, right, top, bottom);
2959  }
2960  q->update();
2961 }
2962 
2963 void AppletPrivate::resetConfigurationObject()
2964 {
2965  // make sure mainConfigGroup exists in all cases
2966  mainConfigGroup();
2967 
2968  mainConfig->deleteGroup();
2969  delete mainConfig;
2970  mainConfig = 0;
2971 
2972  Corona * corona = qobject_cast<Corona*>(q->scene());
2973  if (corona) {
2974  corona->requireConfigSync();
2975  }
2976 }
2977 
2978 void AppletPrivate::handleDisappeared(AppletHandle *h)
2979 {
2980  if (h == handle.data()) {
2981  h->detachApplet();
2982  QGraphicsScene *scene = q->scene();
2983  if (scene && h->scene() == scene) {
2984  scene->removeItem(h);
2985  }
2986  h->deleteLater();
2987  }
2988 }
2989 
2990 void ContainmentPrivate::checkRemoveAction()
2991 {
2992  q->enableAction("remove", q->immutability() == Mutable);
2993 }
2994 
2995 
2996 uint AppletPrivate::s_maxAppletId = 0;
2997 int AppletPrivate::s_maxZValue = 0;
2998 int AppletPrivate::s_minZValue = 0;
2999 PackageStructure::Ptr AppletPrivate::packageStructure(0);
3000 QSet<QString> AppletPrivate::s_customCategories;
3001 
3002 AppletOverlayWidget::AppletOverlayWidget(QGraphicsWidget *parent)
3003  : QGraphicsWidget(parent),
3004  opacity(0.4)
3005 {
3006  resize(parent->size());
3007 }
3008 
3009 void AppletOverlayWidget::destroy()
3010 {
3011  Animation *anim = Plasma::Animator::create(Plasma::Animator::DisappearAnimation);
3012  if (anim) {
3013  connect(anim, SIGNAL(finished()), this, SLOT(overlayAnimationComplete()));
3014  anim->setTargetWidget(this);
3015  anim->start();
3016  } else {
3017  overlayAnimationComplete();
3018  }
3019 }
3020 
3021 void AppletOverlayWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
3022 {
3023  event->accept();
3024 }
3025 
3026 void AppletOverlayWidget::overlayAnimationComplete()
3027 {
3028  if (scene()) {
3029  scene()->removeItem(this);
3030  }
3031  deleteLater();
3032 }
3033 
3034 void AppletOverlayWidget::paint(QPainter *painter,
3035  const QStyleOptionGraphicsItem *option,
3036  QWidget *widget)
3037 {
3038  Q_UNUSED(option)
3039  Q_UNUSED(widget)
3040 
3041  if (qFuzzyCompare(1, 1+opacity)) {
3042  return;
3043  }
3044 
3045  QColor wash = Plasma::Theme::defaultTheme()->color(Theme::BackgroundColor);
3046  wash.setAlphaF(opacity);
3047 
3048  Applet *applet = qobject_cast<Applet *>(parentWidget());
3049 
3050 
3051  QPainterPath backgroundShape;
3052  if (!applet || applet->backgroundHints() & Applet::StandardBackground) {
3053  //FIXME: a resize here is nasty, but perhaps still better than an eventfilter just for that..
3054  if (parentWidget()->contentsRect().size() != size()) {
3055  resize(parentWidget()->contentsRect().size());
3056  }
3057  backgroundShape = PaintUtils::roundedRectangle(contentsRect(), 5);
3058  } else {
3059  backgroundShape = shape();
3060  }
3061 
3062  painter->setRenderHints(QPainter::Antialiasing);
3063  painter->fillPath(backgroundShape, wash);
3064 }
3065 
3066 #if QT_VERSION >= 0x040700
3067 // in QGraphicsWidget now; preserve BC by implementing it as a protected method
3068 void Applet::geometryChanged()
3069 {
3070  emit QGraphicsWidget::geometryChanged();
3071 }
3072 #endif
3073 
3074 } // Plasma namespace
3075 
3076 #include "applet.moc"
3077 #include "private/applet_p.moc"
Plasma::Applet::hasValidAssociatedApplication
bool hasValidAssociatedApplication() const
Definition: applet.cpp:2264
Plasma::Applet::destroy
virtual void destroy()
Destroys the applet; it will be removed nicely and deleted.
Definition: applet.cpp:479
Plasma::SizeConstraint
the size of the applet was changed
Definition: plasma.h:49
Plasma::Applet::immutability
ImmutabilityType immutability
Definition: applet.h:84
Plasma::Applet::addAction
void addAction(QString name, QAction *action)
Adds the action to our collection under the given name.
Definition: applet.cpp:1395
Plasma::Vertical
The applet is constrained horizontally, but can expand vertically.
Definition: plasma.h:77
Plasma::Applet::package
const Package * package() const
Accessor for the associated Package object if any.
Definition: applet.cpp:691
Plasma::Applet::activate
void activate()
Emitted when activation is requested due to, for example, a global keyboard shortcut.
Plasma::Applet::setAssociatedApplication
void setAssociatedApplication(const QString &string)
Sets an application associated to this applet, that will be regarded as a full view of what is repres...
Definition: applet.cpp:2221
QGraphicsScene
ConfigLoader
A KConfigSkeleton that populates itself based on KConfigXT XML.
Plasma::StartupCompletedConstraint
application startup has completed
Definition: plasma.h:51
Plasma::PluginLoader::pluginLoader
static PluginLoader * pluginLoader()
Return the active plugin loader.
Definition: pluginloader.cpp:67
Plasma::UnknownStatus
The status is unknown.
Definition: plasma.h:257
Plasma::Applet::showConfigurationInterface
virtual void showConfigurationInterface()
Lets the user interact with the plasmoid options.
Definition: applet.cpp:1898
Plasma::Applet::flushPendingConstraintsEvents
void flushPendingConstraintsEvents()
Sends all pending contraints updates to the applet.
Definition: applet.cpp:1204
Plasma::ImmutabilityType
ImmutabilityType
Defines the immutability of items like applets, corona and containments they can be free to modify...
Definition: plasma.h:197
authorizationmanager.h
Plasma::Extender
Extends applets to allow detachable parts.
Definition: extender.h:65
Plasma::Applet::Type
Definition: applet.h:549
Plasma::Applet::customCategories
QStringList customCategories()
Definition: applet.cpp:2399
Plasma::Applet::initExtenderItem
virtual void initExtenderItem(ExtenderItem *item)
Gets called when an extender item has to be initialized after a plasma restart.
Definition: applet.cpp:769
Plasma::Applet::isPublished
bool isPublished() const
Definition: applet.cpp:1711
Plasma::AbstractToolBox::ConfigureTool
Definition: abstracttoolbox.h:49
animation.h
Plasma::ButtonCancel
Cancel Button.
Definition: plasma.h:248
Plasma::Containment::destroy
void destroy()
Destroys this containment and all its applets (after a confirmation dialog); it will be removed nicel...
Definition: containment.cpp:2053
busywidget.h
Plasma::Applet::mapFromView
QRectF mapFromView(const QGraphicsView *view, const QRect &rect) const
Maps a QRect from a view's coordinates to local coordinates.
Definition: applet.cpp:725
Plasma::ExtenderItem::config
KConfigGroup config() const
fetch the configuration of this widget.
Definition: extenderitem.cpp:240
pluginloader.h
Plasma::FrameSvg::AllBorders
Definition: framesvg.h:93
Plasma::Applet::AppletHandle
friend class AppletHandle
Definition: applet.h:1147
Plasma::Applet::Containment
friend class Containment
Definition: applet.h:1144
Plasma::Applet::timerEvent
void timerEvent(QTimerEvent *event)
Reimplemented from QObject.
Definition: applet.cpp:2553
extender.h
abstracttoolbox.h
Plasma::Applet::configScheme
ConfigLoader * configScheme() const
Returns the config skeleton object from this applet's package, if any.
Definition: applet.cpp:675
Plasma::Applet::hasAuthorization
bool hasAuthorization(const QString &constraint) const
Returns true if the applet is allowed to perform functions covered by the given constraint eg...
Definition: applet.cpp:2215
Plasma::Applet::restore
virtual void restore(KConfigGroup &group)
Restores state information about this applet saved previously in save(KConfigGroup&).
Definition: applet.cpp:310
Plasma::SystemImmutable
the item is locked down by the system, the user can't unlock it
Definition: plasma.h:201
Plasma::Applet::location
virtual Location location() const
Returns the location of the scene which is displaying applet.
Definition: applet.cpp:1618
Plasma::ButtonOk
OK Button.
Definition: plasma.h:245
Plasma::Applet::newStatus
void newStatus(Plasma::ItemStatus status)
Emitted when the applet status changes.
Plasma::Applet::formFactor
virtual FormFactor formFactor() const
Returns the current form factor the applet is being displayed in.
Definition: applet.cpp:1479
Plasma::ConstrainedSquare
The applet is no wider (in horizontal formfactors) or no higher (in vertical ones) than a square...
Definition: plasma.h:215
Plasma::Applet::Applet
Applet(QGraphicsItem *parent=0, const QString &serviceId=QString(), uint appletId=0)
Definition: applet.cpp:136
Plasma::Applet::constraintsEvent
virtual void constraintsEvent(Plasma::Constraints constraints)
Definition: applet.cpp:755
Plasma::Containment::containmentType
Type containmentType() const
Returns the type of containment.
Definition: containment.cpp:501
QWidget
Plasma::Applet::publish
void publish(Plasma::AnnouncementMethods methods, const QString &resourceName)
Publishes and optionally announces this applet on the network for remote access.
Definition: applet.cpp:1680
Plasma::Applet::hoverLeaveEvent
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
Reimplemented from QGraphicsLayoutItem.
Definition: applet.cpp:2548
Plasma::Label::setText
void setText(const QString &text)
Sets the display text for this Label.
Definition: label.cpp:117
Plasma::Label::nativeWidget
QLabel nativeWidget
Definition: label.h:52
Plasma::Applet::geometryChanged
void geometryChanged()
Emitted whenever the applet makes a geometry change, so that views can coordinate themselves with the...
Plasma::ToolTipManager::self
static ToolTipManager * self()
Definition: tooltipmanager.cpp:119
Plasma::Desktop
On the planar desktop layer, extending across the full screen from edge to edge.
Definition: plasma.h:111
Plasma::AbstractToolBox::DestructiveTool
Definition: abstracttoolbox.h:52
Plasma::Applet::listCategories
static QStringList listCategories(const QString &parentApp=QString(), bool visibleOnly=true)
Returns a list of all the categories used by installed applets.
Definition: applet.cpp:2351
Plasma::Context
Definition: context.h:33
theme.h
Plasma::MessageButton
MessageButton
Definition: plasma.h:243
Plasma::ImmutableConstraint
the immutability (locked) nature of the applet changed
Definition: plasma.h:50
KConfigSkeleton
Plasma::Applet::setCustomCategories
void setCustomCategories(const QStringList &categories)
Sets the list of custom categories that are used in addition to the default set of categories known t...
Definition: applet.cpp:2394
Plasma::Applet::saveState
virtual void saveState(KConfigGroup &config) const
When called, the Applet should write any information needed as part of the Applet's running state to ...
Definition: applet.cpp:426
iconwidget.h
containment.h
Plasma::PushButton
Provides a plasma-themed KPushButton.
Definition: pushbutton.h:41
Plasma::PluginLoader::listAppletInfo
KPluginInfo::List listAppletInfo(const QString &category, const QString &parentApp=QString())
Returns a list of all known applets.
Definition: pluginloader.cpp:247
Plasma::Animation
Abstract representation of a single animation.
Definition: animation.h:46
Plasma::FrameSvg
Provides an SVG with borders.
Definition: framesvg.h:76
Plasma::Applet::hoverEnterEvent
void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
Reimplemented from QGraphicsLayoutItem.
Definition: applet.cpp:2543
Plasma::Applet::associatedApplicationUrls
KUrl::List associatedApplicationUrls() const
Definition: applet.cpp:2252
QObject
Plasma::Square
The applet is always a square.
Definition: plasma.h:214
Plasma::Applet::NoBackground
Not drawing a background under the applet, the applet has its own implementation. ...
Definition: applet.h:104
Plasma::ExtenderItem::autoExpireDelay
uint autoExpireDelay
Definition: extenderitem.h:90
Plasma::Applet::itemChange
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
Reimplemented from QGraphicsItem.
Definition: applet.cpp:2436
Plasma::loadScriptEngine
AppletScript * loadScriptEngine(const QString &language, Applet *applet)
Loads an Applet script engine for the given language.
Definition: scriptengine.cpp:206
Plasma::Horizontal
The applet is constrained vertically, but can expand horizontally.
Definition: plasma.h:75
Plasma::Applet::setHasConfigurationInterface
void setHasConfigurationInterface(bool hasInterface)
Sets whether or not this applet provides a user interface for configuring the applet.
Definition: applet.cpp:1724
Plasma::AuthorizationManager::self
static AuthorizationManager * self()
Singleton pattern accessor.
Definition: authorizationmanager.cpp:64
tooltipmanager.h
Plasma::Applet::configurationRequired
bool configurationRequired() const
Plasma::Applet::paintInterface
virtual void paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
This method is called when the interface should be painted.
Definition: applet.cpp:1470
Plasma::Mutable
The item can be modified in any way.
Definition: plasma.h:198
Plasma::ToolTipContent
Definition: tooltipcontent.h:47
Plasma::ExtenderItem::destroy
void destroy()
Destroys the extender item.
Definition: extenderitem.cpp:579
wallpaper.h
Plasma::Applet::configChanged
virtual void configChanged()
Called when applet configuration values have changed.
Definition: applet.cpp:2198
Plasma::Applet::immutability
ImmutabilityType immutability() const
Plasma::Applet::Corona
friend class Corona
Definition: applet.h:1142
pushbutton.h
Plasma::Applet
The base Applet class.
Definition: applet.h:77
Plasma::Applet::StandardBackground
The standard background from the theme is drawn.
Definition: applet.h:106
Plasma::Applet::associatedApplication
QString associatedApplication() const
Definition: applet.cpp:2247
Plasma::Corona::popupPosition
QPoint popupPosition(const QGraphicsItem *item, const QSize &size)
Recommended position for a popup window like a menu or a tooltip given its size.
Definition: corona.cpp:459
Plasma::Applet::setGlobalShortcut
void setGlobalShortcut(const KShortcut &shortcut)
Sets the global shorcut to associate with this widget.
Definition: applet.cpp:1556
Plasma::Corona::config
KSharedConfig::Ptr config() const
Returns the config file used to store the configuration for this Corona.
Definition: corona.cpp:340
Plasma::Applet::shouldConserveResources
bool shouldConserveResources() const
Whether the applet should conserve resources.
Plasma::Dialog
A dialog that uses the Plasma style.
Definition: dialog.h:51
Plasma::Applet::createConfigurationInterface
virtual void createConfigurationInterface(KConfigDialog *parent)
Reimplement this method so provide a configuration interface, parented to the supplied widget...
Definition: applet.cpp:2208
Plasma::Applet::packageStructure
static PackageStructure::Ptr packageStructure()
Definition: applet.cpp:234
Plasma::Applet::sceneEventFilter
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
Definition: applet.cpp:1779
Plasma::Animator::DisappearAnimation
Definition: animator.h:57
Plasma::View
A QGraphicsView for a single Containment.
Definition: view.h:47
Plasma::PaintUtils::roundedRectangle
QPainterPath roundedRectangle(const QRectF &rect, qreal radius)
Returns a nicely rounded rectanglular path for painting.
Definition: paintutils.cpp:159
Plasma::Applet::registerAsDragHandle
void registerAsDragHandle(QGraphicsItem *item)
Register the widgets that manage mouse clicks but you still want to be able to drag the applet around...
Definition: applet.cpp:1647
Plasma::Location
Location
The Location enumeration describes where on screen an element, such as an Applet or its managing cont...
Definition: plasma.h:108
view.h
Plasma::Applet::unregisterAsDragHandle
void unregisterAsDragHandle(QGraphicsItem *item)
Unregister a widget registered with registerAsDragHandle.
Definition: applet.cpp:1657
Plasma::Applet::listAppletInfo
static KPluginInfo::List listAppletInfo(const QString &category=QString(), const QString &parentApp=QString())
Returns a list of all known applets.
Definition: applet.cpp:2312
Plasma::ButtonYes
Yes Button.
Definition: plasma.h:246
Plasma::Applet::isBusy
bool isBusy() const
Plasma::Label
Provides a plasma-themed QLabel.
Definition: label.h:40
Plasma::Applet::lower
void lower()
Causes this applet to lower below all the other applets.
Definition: applet.cpp:2622
Plasma::Applet::setStatus
void setStatus(const ItemStatus stat)
sets the status for this applet
Definition: applet.cpp:1198
Plasma::Applet::listAppletInfoForMimetype
static KPluginInfo::List listAppletInfoForMimetype(const QString &mimetype)
Returns a list of all known applets associated with a certain mimetype.
Definition: applet.cpp:2317
Plasma::PopupApplet
Allows applets to automatically 'collapse' into an icon when put in an panel, and is a convenient bas...
Definition: popupapplet.h:52
Plasma::Animator::ZoomAnimation
Definition: animator.h:67
Plasma::Applet::globalShortcut
KShortcut globalShortcut() const
Definition: applet.cpp:1594
paintutils.h
Plasma::PackageStructure::Ptr
KSharedPtr< PackageStructure > Ptr
Definition: packagestructure.h:77
Plasma::Applet::paintWindowFrame
void paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
Definition: applet.cpp:994
Plasma::DataEngine
Data provider for plasmoids (Plasma plugins)
Definition: dataengine.h:58
applet.h
Plasma::PackageMetadata::setDescription
void setDescription(const QString &)
Set the description used to provide some general information what the package is about.
Definition: packagemetadata.cpp:269
Plasma::ToolTipManager::registerWidget
void registerWidget(QGraphicsWidget *widget)
Registers a widget with the tooltip manager.
Definition: tooltipmanager.cpp:200
Plasma::IconWidget::setIcon
void setIcon(const QIcon &icon)
Sets the graphical icon for this Plasma::IconWidget.
Definition: iconwidget.cpp:1324
Plasma::Applet::setImmutability
void setImmutability(const ImmutabilityType immutable)
Sets the immutability type for this applet (not immutable, user immutable or system immutable) ...
Definition: applet.cpp:919
Plasma::FormFactor
FormFactor
The FormFactor enumeration describes how a Plasma::Applet should arrange itself.
Definition: plasma.h:64
Plasma::KeepAspectRatio
The applet keeps a fixed aspect ratio.
Definition: plasma.h:213
Plasma::Applet::PopupApplet
friend class PopupApplet
Definition: applet.h:1151
Plasma::Applet::runAssociatedApplication
void runAssociatedApplication()
Open the application associated to this applet, if it's not set but some urls are, open those urls with the proper application for their mimetype.
Definition: applet.cpp:2257
Plasma::PushButton::setImage
void setImage(const QString &path)
Sets the path to an image to display.
Definition: pushbutton.cpp:234
Plasma::Applet::containment
Containment * containment() const
Definition: applet.cpp:1518
Plasma::Applet::removeAssociatedWidget
virtual void removeAssociatedWidget(QWidget *widget)
un-associate actions from this widget, including ones added after this call.
Definition: applet.cpp:1613
Plasma::Applet::sizeHint
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
Reimplemented from QGraphicsLayoutItem.
Definition: applet.cpp:2509
Plasma::Package
object representing an installed Plasmagik package
Definition: package.h:42
Plasma::Applet::dataEngine
Q_INVOKABLE DataEngine * dataEngine(const QString &name) const
Loads the given DataEngine.
Definition: applet.cpp:680
Plasma::Applet::raise
void raise()
Causes this applet to raise above all other applets.
Definition: applet.cpp:2617
Plasma::Applet::font
QFont font() const
Definition: applet.cpp:829
Plasma::locationToDirection
Direction locationToDirection(Location location)
Converts a location to a direction.
Definition: plasma.cpp:51
abstractdialogmanager.h
Plasma::Applet::shape
QPainterPath shape() const
Reimplemented from QGraphicsItem.
Definition: applet.cpp:2500
Plasma::Applet::Extender
friend class Extender
Definition: applet.h:1155
Plasma::ToolTipManager::hide
void hide(QGraphicsWidget *widget)
Hides the tooltip for a widget immediately.
Definition: tooltipmanager.cpp:188
Plasma::Applet::icon
QString icon() const
Returns the icon related to this applet.
Definition: applet.cpp:834
QGraphicsProxyWidget
Plasma::ButtonNo
No Button.
Definition: plasma.h:247
Plasma::FormFactorConstraint
The FormFactor for an object.
Definition: plasma.h:46
Plasma::Applet::startupArguments
QVariantList startupArguments() const
Definition: applet.cpp:1188
Plasma::PluginLoader::loadApplet
Applet * loadApplet(const QString &name, uint appletId=0, const QVariantList &args=QVariantList())
Load an Applet plugin.
Definition: pluginloader.cpp:79
Plasma::toString
static QScriptValue toString(QScriptContext *ctx, QScriptEngine *eng)
Definition: easingcurve.cpp:57
Plasma::Applet::aspectRatioMode
Plasma::AspectRatioMode aspectRatioMode() const
Definition: applet.cpp:1631
Plasma::PushButton::setIcon
void setIcon(const QIcon &icon)
sets the icon for this push button
Definition: pushbutton.cpp:299
Plasma::locationToInverseDirection
Direction locationToInverseDirection(Location location)
Converts a location to the direction facing it.
Definition: plasma.cpp:72
Plasma::Applet::listAppletInfoForUrl
static KPluginInfo::List listAppletInfoForUrl(const QUrl &url)
Returns a list of all known applets associated with a certain URL.
Definition: applet.cpp:2327
dataenginemanager.h
Plasma::Applet::loadPlasmoid
static Applet * loadPlasmoid(const QString &path, uint appletId=0, const QVariantList &args=QVariantList())
Attempts to load an applet from a package.
Definition: applet.cpp:2404
configloader.h
Plasma::Applet::focusInEvent
void focusInEvent(QFocusEvent *event)
Reimplemented from QGraphicsItem.
Definition: applet.cpp:1869
plasma.h
Plasma::Applet::resizeEvent
void resizeEvent(QGraphicsSceneResizeEvent *event)
Reimplemented from QGraphicsItem.
Definition: applet.cpp:1879
Plasma::PushButton::setText
void setText(const QString &text)
Sets the display text for this PushButton.
Definition: pushbutton.cpp:223
Plasma::Applet::setConfigurationRequired
void setConfigurationRequired(bool needsConfiguring, const QString &reason=QString())
When the applet needs to be configured before being usable, this method can be called to show a stand...
Definition: applet.cpp:1010
Plasma::AuthorizationRule::AllUsers
specify that this rule is valid for all users
Definition: authorizationrule.h:86
Plasma::Applet::config
KConfigGroup config() const
Returns the KConfigGroup to access the applets configuration.
Definition: applet.cpp:450
Plasma::Applet::setFailedToLaunch
void setFailedToLaunch(bool failed, const QString &reason=QString())
Call this method when the applet fails to launch properly.
Definition: applet.cpp:366
Plasma::Planar
The applet lives in a plane and has two degrees of freedom to grow.
Definition: plasma.h:65
Plasma::Applet::view
QGraphicsView * view() const
Returns the view this widget is visible on, or 0 if none can be found.
Definition: applet.cpp:696
Plasma::Applet::mapToView
QRect mapToView(const QGraphicsView *view, const QRectF &rect) const
Maps a QRectF from local coordinates to a view's coordinates.
Definition: applet.cpp:731
Plasma::AppletComponent
Plasma::Applet based plugins.
Definition: plasma.h:226
Plasma::Applet::isRegisteredAsDragHandle
bool isRegisteredAsDragHandle(QGraphicsItem *item)
Definition: applet.cpp:1670
dialog.h
Plasma::BusyWidget
A widget that provides a waiting spinner.
Definition: busywidget.h:41
Plasma::Applet::extenderItemRestored
void extenderItemRestored(Plasma::ExtenderItem *item)
Emitted when an ExtenderItem in a scripting applet needs to be initialized.
Plasma::AuthorizationRule::Allow
access for messages matching this rule is allowed.
Definition: authorizationrule.h:75
Plasma::Applet::isPopupShowing
virtual bool isPopupShowing() const
Definition: applet.cpp:1603
Plasma::Applet::category
QString category() const
Returns the category the applet is in, as specified in the .desktop file.
package.h
Plasma::Applet::popupPosition
QPoint popupPosition(const QSize &s) const
Reccomended position for a popup window like a menu or a tooltip given its size.
Definition: applet.cpp:737
Plasma::Applet::globalConfig
KConfigGroup globalConfig() const
Returns a KConfigGroup object to be shared by all applets of this type.
Definition: applet.cpp:463
Plasma::Applet::setBackgroundHints
void setBackgroundHints(const BackgroundHints hints)
Sets the BackgroundHints for this applet.
Definition: applet.cpp:938
QGraphicsLayout
Plasma::Theme::defaultTheme
static Theme * defaultTheme()
Singleton pattern accessor.
Definition: theme.cpp:544
Plasma::Applet::updateConstraints
void updateConstraints(Plasma::Constraints constraints=Plasma::AllConstraints)
Called when any of the geometry constraints have been updated.
Definition: applet.cpp:750
Plasma::Applet::name
QString name() const
Returns the user-visible name for the applet, as specified in the .desktop file.
Plasma::Applet::setAssociatedApplicationUrls
void setAssociatedApplicationUrls(const KUrl::List &urls)
Sets a list of urls associated to this application, they will be used as parameters for the associate...
Definition: applet.cpp:2234
Plasma::Applet::id
uint id() const
Plasma::Animator::create
static Plasma::Animation * create(Animator::Animation type, QObject *parent=0)
Factory to build new animation objects.
Definition: animator.cpp:61
corona.h
Plasma::AbstractToolBox::ControlTool
Definition: abstracttoolbox.h:50
Plasma::Applet::extender
Extender * extender() const
Definition: applet.cpp:782
framesvg.h
Plasma::IconWidget
Definition: iconwidget.h:56
Plasma::Applet::showMessage
void showMessage(const QIcon &icon, const QString &message, const Plasma::MessageButtons buttons)
Shows a message as an overlay of the applet: the message has an icon, text and (optional) buttons...
Definition: applet.cpp:1062
Plasma::Applet::save
virtual void save(KConfigGroup &group) const
Saves state information about this applet that will be accessed when next instantiated in the restore...
Definition: applet.cpp:260
QGraphicsView
Plasma::PackageMetadata
Provides metadata for a Package.
Definition: packagemetadata.h:39
label.h
Plasma::Applet::immutabilityChanged
void immutabilityChanged(Plasma::ImmutabilityType immutable)
Emitted when the immutability changes.
Plasma::ZeroconfAnnouncement
Announcements via ZeroConf.
Definition: plasma.h:267
Plasma::Applet::type
int type() const
Reimplemented from QGraphicsItem.
Definition: applet.cpp:1379
Plasma::Applet::addAssociatedWidget
virtual void addAssociatedWidget(QWidget *widget)
associate actions with this widget, including ones added after this call.
Definition: applet.cpp:1608
Plasma::ToolTipManager::setContent
void setContent(QGraphicsWidget *widget, const ToolTipContent &data)
Sets the content for the tooltip associated with a widget.
Definition: tooltipmanager.cpp:229
Plasma::Applet::status
ItemStatus status() const
Definition: applet.cpp:1193
Plasma::Applet::backgroundHints
BackgroundHints backgroundHints() const
Plasma::Applet::setAspectRatioMode
void setAspectRatioMode(Plasma::AspectRatioMode)
Sets the preferred aspect ratio mode for placement and resizing.
Definition: applet.cpp:1636
Plasma::Applet::hasFailedToLaunch
bool hasFailedToLaunch() const
If for some reason, the applet fails to get up on its feet (the library couldn't be loaded...
Plasma::Containment::DesktopContainment
A desktop containment.
Definition: containment.h:101
Plasma::Theme::color
Q_INVOKABLE QColor color(ColorRole role) const
Returns the text color to be used by items resting on the background.
Definition: theme.cpp:918
Plasma::Applet::hasConfigurationInterface
bool hasConfigurationInterface() const
Plasma::Applet::appletDestroyed
void appletDestroyed(Plasma::Applet *applet)
Emitted when the applet is deleted.
Plasma::Applet::eventFilter
bool eventFilter(QObject *o, QEvent *e)
Definition: applet.cpp:1774
Plasma::Containment
The base class for plugins that provide backgrounds and applet grouping containers.
Definition: containment.h:72
Plasma::Corona::immutability
ImmutabilityType immutability() const
Definition: corona.cpp:658
Plasma::ItemStatus
ItemStatus
Status of an applet.
Definition: plasma.h:256
Plasma::Applet::configNeedsSaving
void configNeedsSaving()
Emitted when an applet has changed values in its configuration and wishes for them to be saved at the...
appletscript.h
Plasma::Applet::busy
bool busy
Definition: applet.h:87
Plasma::Theme::BackgroundColor
the default background color
Definition: theme.h:66
Plasma::Applet::AppletPrivate
friend class AppletPrivate
Definition: applet.h:1148
Plasma::Corona::addOffscreenWidget
void addOffscreenWidget(QGraphicsWidget *widget)
Adds a widget in the topleft quadrant in the scene.
Definition: corona.cpp:377
Plasma::Applet::TranslucentBackground
An alternate version of the background is drawn, usually more translucent.
Definition: applet.h:107
Plasma::Applet::action
Q_INVOKABLE QAction * action(QString name) const
Returns the QAction with the given name from our collection.
Definition: applet.cpp:1390
Plasma::Applet::isContainment
bool isContainment() const
Definition: applet.cpp:2647
popupapplet.h
Plasma::Applet::DefaultBackground
Default settings: both standard background.
Definition: applet.h:109
Plasma::Applet::init
virtual void init()
This method is called once the applet is loaded and added to a Corona.
Definition: applet.cpp:243
Plasma::ConfigLoader
Definition: configloader.h:75
Plasma::ExtenderItem
Provides detachable items for an Extender.
Definition: extenderitem.h:80
Plasma::Applet::isUserConfiguring
bool isUserConfiguring() const
Definition: applet.cpp:1893
QStyleOptionGraphicsItem
Plasma::packageStructure
PackageStructure::Ptr packageStructure(const QString &language, ComponentType type)
Loads an appropriate PackageStructure for the given language and type.
Definition: scriptengine.cpp:274
Plasma::Applet::context
Context * context() const
Returns the workspace context which the applet is operating in.
Definition: applet.cpp:1624
Plasma::PackageMetadata::setName
void setName(const QString &)
Set the name of the package used to displayed a short describing name.
Definition: packagemetadata.cpp:264
Plasma::Applet::screenRect
QRect screenRect() const
This method returns screen coordinates for the widget; this method can be somewhat expensive and shou...
Definition: applet.cpp:2598
Plasma::Applet::setBusy
void setBusy(bool busy)
Shows a busy indicator that overlays the applet.
Definition: applet.cpp:791
Plasma::Applet::mouseMoveEvent
void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
Definition: applet.cpp:1862
Plasma::Applet::releaseVisualFocus
void releaseVisualFocus()
This signal indicates that an application launch, window creation or window focus event was triggered...
Plasma::NoConstraint
No constraint; never passed in to Applet::constraintsEvent on its own.
Definition: plasma.h:45
Plasma::Applet::contextualActions
virtual QList< QAction * > contextualActions()
Returns a list of context-related QAction instances.
Definition: applet.cpp:1384
extenderitem.h
Plasma::Applet::geometry
QRectF geometry
Definition: applet.h:89
Plasma::Applet::unpublish
void unpublish()
Definition: applet.cpp:1700
Plasma::PackageMetadata::setIcon
void setIcon(const QString &icon)
Set the icon name to be used with this package.
Definition: packagemetadata.cpp:189
svg.h
Plasma::Applet::pluginName
QString pluginName() const
Returns the plugin name for the applet.
Plasma::Animation::setTargetWidget
void setTargetWidget(QGraphicsWidget *widget)
Set the widget on which the animation is to be performed.
Definition: animation.cpp:62
authorizationrule.h
Plasma::Corona
A QGraphicsScene for Plasma::Applets.
Definition: corona.h:48
Plasma::AspectRatioMode
AspectRatioMode
Defines the aspect ratio used when scaling an applet.
Definition: plasma.h:208
QGraphicsWidget
Plasma::Applet::destroyed
bool destroyed() const
Definition: applet.cpp:497
Plasma::Applet::load
static Applet * load(const QString &name, uint appletId=0, const QVariantList &args=QVariantList())
Attempts to load an applet.
Definition: applet.cpp:2422
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:33 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Plasma

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

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