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

Plasma

  • 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  d->addPublishPage(dialog);
1987  dialog->show();
1988  } else {
1989  delete dialog;
1990  dialog = 0;
1991  }
1992  }
1993 
1994  if (!dialog && d->script) {
1995  d->script->showConfigurationInterface();
1996  }
1997  } else if (d->script) {
1998  d->script->showConfigurationInterface();
1999  } else {
2000  KConfigDialog *dialog = d->generateGenericConfigDialog();
2001  d->addStandardConfigurationPages(dialog);
2002  showConfigurationInterface(dialog);
2003  }
2004 
2005  emit releaseVisualFocus();
2006 }
2007 
2008 void Applet::showConfigurationInterface(QWidget *widget)
2009 {
2010  if (!containment() || !containment()->corona() ||
2011  !containment()->corona()->dialogManager()) {
2012  widget->show();
2013  return;
2014  }
2015 
2016  QMetaObject::invokeMethod(containment()->corona()->dialogManager(), "showDialog", Q_ARG(QWidget *, widget), Q_ARG(Plasma::Applet *, this));
2017 }
2018 
2019 QString AppletPrivate::configDialogId() const
2020 {
2021  return QString("%1settings%2").arg(appletId).arg(q->name());
2022 }
2023 
2024 QString AppletPrivate::configWindowTitle() const
2025 {
2026  return i18nc("@title:window", "%1 Settings", q->name());
2027 }
2028 
2029 QSet<QString> AppletPrivate::knownCategories()
2030 {
2031  // this is to trick the tranlsation tools into making the correct
2032  // strings for translation
2033  QSet<QString> categories = s_customCategories;
2034  categories << QString(I18N_NOOP("Accessibility")).toLower()
2035  << QString(I18N_NOOP("Application Launchers")).toLower()
2036  << QString(I18N_NOOP("Astronomy")).toLower()
2037  << QString(I18N_NOOP("Date and Time")).toLower()
2038  << QString(I18N_NOOP("Development Tools")).toLower()
2039  << QString(I18N_NOOP("Education")).toLower()
2040  << QString(I18N_NOOP("Environment and Weather")).toLower()
2041  << QString(I18N_NOOP("Examples")).toLower()
2042  << QString(I18N_NOOP("File System")).toLower()
2043  << QString(I18N_NOOP("Fun and Games")).toLower()
2044  << QString(I18N_NOOP("Graphics")).toLower()
2045  << QString(I18N_NOOP("Language")).toLower()
2046  << QString(I18N_NOOP("Mapping")).toLower()
2047  << QString(I18N_NOOP("Miscellaneous")).toLower()
2048  << QString(I18N_NOOP("Multimedia")).toLower()
2049  << QString(I18N_NOOP("Online Services")).toLower()
2050  << QString(I18N_NOOP("Productivity")).toLower()
2051  << QString(I18N_NOOP("System Information")).toLower()
2052  << QString(I18N_NOOP("Utilities")).toLower()
2053  << QString(I18N_NOOP("Windows and Tasks")).toLower();
2054  return categories;
2055 }
2056 
2057 KConfigDialog *AppletPrivate::generateGenericConfigDialog()
2058 {
2059  KConfigSkeleton *nullManager = new KConfigSkeleton(0);
2060  KConfigDialog *dialog = new AppletConfigDialog(0, configDialogId(), nullManager);
2061  nullManager->setParent(dialog);
2062  dialog->setFaceType(KPageDialog::Auto);
2063  dialog->setWindowTitle(configWindowTitle());
2064  dialog->setAttribute(Qt::WA_DeleteOnClose, true);
2065  q->createConfigurationInterface(dialog);
2066  dialog->showButton(KDialog::Default, false);
2067  dialog->showButton(KDialog::Help, false);
2068  QObject::connect(dialog, SIGNAL(applyClicked()), q, SLOT(configDialogFinished()));
2069  QObject::connect(dialog, SIGNAL(okClicked()), q, SLOT(configDialogFinished()));
2070  return dialog;
2071 }
2072 
2073 void AppletPrivate::addStandardConfigurationPages(KConfigDialog *dialog)
2074 {
2075  addGlobalShortcutsPage(dialog);
2076  addPublishPage(dialog);
2077 }
2078 
2079 void AppletPrivate::addGlobalShortcutsPage(KConfigDialog *dialog)
2080 {
2081 #ifndef PLASMA_NO_GLOBAL_SHORTCUTS
2082  if (isContainment) {
2083  return;
2084  }
2085 
2086  QWidget *page = new QWidget;
2087  QVBoxLayout *layout = new QVBoxLayout(page);
2088 
2089  if (!shortcutEditor) {
2090  shortcutEditor = new KKeySequenceWidget(page);
2091  QObject::connect(shortcutEditor.data(), SIGNAL(keySequenceChanged(QKeySequence)), dialog, SLOT(settingsModified()));
2092  }
2093 
2094  shortcutEditor.data()->setKeySequence(q->globalShortcut().primary());
2095  layout->addWidget(shortcutEditor.data());
2096  layout->addStretch();
2097  dialog->addPage(page, i18n("Keyboard Shortcut"), "preferences-desktop-keyboard");
2098 
2099  QObject::connect(dialog, SIGNAL(applyClicked()), q, SLOT(configDialogFinished()), Qt::UniqueConnection);
2100  QObject::connect(dialog, SIGNAL(okClicked()), q, SLOT(configDialogFinished()), Qt::UniqueConnection);
2101 #endif
2102 }
2103 
2104 void AppletPrivate::addPublishPage(KConfigDialog *dialog)
2105 {
2106 #ifdef ENABLE_REMOTE_WIDGETS
2107  QWidget *page = new QWidget;
2108  publishUI.setupUi(page);
2109  publishUI.publishCheckbox->setChecked(q->isPublished());
2110  QObject::connect(publishUI.publishCheckbox, SIGNAL(clicked(bool)), dialog, SLOT(settingsModified()));
2111  publishUI.allUsersCheckbox->setEnabled(q->isPublished());
2112  QObject::connect(publishUI.allUsersCheckbox, SIGNAL(clicked(bool)), dialog, SLOT(settingsModified()));
2113 
2114  QString resourceName =
2115  i18nc("%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is published on",
2116  "%1 on %2", q->name(), QHostInfo::localHostName());
2117  if (AuthorizationManager::self()->d->matchingRule(resourceName, Credentials())) {
2118  publishUI.allUsersCheckbox->setChecked(true);
2119  } else {
2120  publishUI.allUsersCheckbox->setChecked(false);
2121  }
2122 
2123  q->connect(publishUI.publishCheckbox, SIGNAL(stateChanged(int)),
2124  q, SLOT(publishCheckboxStateChanged(int)));
2125  dialog->addPage(page, i18n("Share"), "applications-internet");
2126 #endif
2127 }
2128 
2129 void AppletPrivate::publishCheckboxStateChanged(int state)
2130 {
2131  if (state == Qt::Checked) {
2132  publishUI.allUsersCheckbox->setEnabled(true);
2133  } else {
2134  publishUI.allUsersCheckbox->setEnabled(false);
2135  }
2136 }
2137 
2138 void AppletPrivate::configDialogFinished()
2139 {
2140  if (shortcutEditor) {
2141  QKeySequence sequence = shortcutEditor.data()->keySequence();
2142  if (sequence != q->globalShortcut().primary()) {
2143  q->setGlobalShortcut(KShortcut(sequence));
2144  emit q->configNeedsSaving();
2145  }
2146  }
2147 
2148 #ifdef ENABLE_REMOTE_WIDGETS
2149  if (KConfigDialog::exists(configDialogId()) && publishUI.publishCheckbox) {
2150  q->config().writeEntry("Share", publishUI.publishCheckbox->isChecked());
2151 
2152  if (publishUI.publishCheckbox->isChecked()) {
2153  QString resourceName =
2154  i18nc("%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is published on",
2155  "%1 on %2", q->name(), QHostInfo::localHostName());
2156  q->publish(Plasma::ZeroconfAnnouncement, resourceName);
2157  if (publishUI.allUsersCheckbox->isChecked()) {
2158  if (!AuthorizationManager::self()->d->matchingRule(resourceName, Credentials())) {
2159  AuthorizationRule *rule = new AuthorizationRule(resourceName, "");
2160  rule->setPolicy(AuthorizationRule::Allow);
2161  rule->setTargets(AuthorizationRule::AllUsers);
2162  AuthorizationManager::self()->d->rules.append(rule);
2163  }
2164  } else {
2165  AuthorizationRule *matchingRule =
2166  AuthorizationManager::self()->d->matchingRule(resourceName, Credentials());
2167  if (matchingRule) {
2168  AuthorizationManager::self()->d->rules.removeAll(matchingRule);
2169  }
2170  }
2171  } else {
2172  q->unpublish();
2173  }
2174  }
2175 #endif
2176 
2177  if (!configLoader) {
2178  // the config loader will trigger this for us, so we don't need to.
2179  propagateConfigChanged();
2180  if (KConfigDialog *dialog = qobject_cast<KConfigDialog *>(q->sender())) {
2181  dialog->enableButton(KDialog::Apply, false);
2182  }
2183  }
2184 }
2185 
2186 void AppletPrivate::updateShortcuts()
2187 {
2188  if (isContainment) {
2189  //a horrible hack to avoid clobbering corona settings
2190  //we pull them out, then read, then put them back
2191  QList<QString> names;
2192  QList<QAction*> qactions;
2193  names << "add sibling containment" << "configure shortcuts" << "lock widgets";
2194  foreach (const QString &name, names) {
2195  QAction *a = actions->action(name);
2196  actions->takeAction(a); //FIXME this is stupid, KActionCollection needs a takeAction(QString) method
2197  qactions << a;
2198  }
2199 
2200  actions->readSettings();
2201 
2202  for (int i = 0; i < names.size(); ++i) {
2203  QAction *a = qactions.at(i);
2204  if (a) {
2205  actions->addAction(names.at(i), a);
2206  }
2207  }
2208  } else {
2209  actions->readSettings();
2210  }
2211 }
2212 
2213 void AppletPrivate::propagateConfigChanged()
2214 {
2215  if (isContainment) {
2216  Containment *c = qobject_cast<Containment *>(q);
2217  if (c) {
2218  c->d->configChanged();
2219  }
2220  }
2221 
2222  q->configChanged();
2223 }
2224 
2225 void Applet::configChanged()
2226 {
2227  if (d->script) {
2228  if (d->configLoader) {
2229  d->configLoader->readConfig();
2230  }
2231  d->script->configChanged();
2232  }
2233 }
2234 
2235 void Applet::createConfigurationInterface(KConfigDialog *parent)
2236 {
2237  Q_UNUSED(parent)
2238  // virtual method reimplemented by subclasses.
2239  // do not put anything here ...
2240 }
2241 
2242 bool Applet::hasAuthorization(const QString &constraint) const
2243 {
2244  KConfigGroup constraintGroup(KGlobal::config(), "Constraints");
2245  return constraintGroup.readEntry(constraint, true);
2246 }
2247 
2248 void Applet::setAssociatedApplication(const QString &string)
2249 {
2250  AssociatedApplicationManager::self()->setApplication(this, string);
2251 
2252  QAction *runAssociatedApplication = d->actions->action("run associated application");
2253  if (runAssociatedApplication) {
2254  bool valid = AssociatedApplicationManager::self()->appletHasValidAssociatedApplication(this);
2255  valid = valid && hasAuthorization("LaunchApp"); //obey security!
2256  runAssociatedApplication->setVisible(valid);
2257  runAssociatedApplication->setEnabled(valid);
2258  }
2259 }
2260 
2261 void Applet::setAssociatedApplicationUrls(const KUrl::List &urls)
2262 {
2263  AssociatedApplicationManager::self()->setUrls(this, urls);
2264 
2265  QAction *runAssociatedApplication = d->actions->action("run associated application");
2266  if (runAssociatedApplication) {
2267  bool valid = AssociatedApplicationManager::self()->appletHasValidAssociatedApplication(this);
2268  valid = valid && hasAuthorization("LaunchApp"); //obey security!
2269  runAssociatedApplication->setVisible(valid);
2270  runAssociatedApplication->setEnabled(valid);
2271  }
2272 }
2273 
2274 QString Applet::associatedApplication() const
2275 {
2276  return AssociatedApplicationManager::self()->application(this);
2277 }
2278 
2279 KUrl::List Applet::associatedApplicationUrls() const
2280 {
2281  return AssociatedApplicationManager::self()->urls(this);
2282 }
2283 
2284 void Applet::runAssociatedApplication()
2285 {
2286  if (hasAuthorization("LaunchApp")) {
2287  AssociatedApplicationManager::self()->run(this);
2288  }
2289 }
2290 
2291 bool Applet::hasValidAssociatedApplication() const
2292 {
2293  return AssociatedApplicationManager::self()->appletHasValidAssociatedApplication(this);
2294 }
2295 
2296 void AppletPrivate::filterOffers(QList<KService::Ptr> &offers)
2297 {
2298  KConfigGroup constraintGroup(KGlobal::config(), "Constraints");
2299  foreach (const QString &key, constraintGroup.keyList()) {
2300  //kDebug() << "security constraint" << key;
2301  if (constraintGroup.readEntry(key, true)) {
2302  continue;
2303  }
2304 
2305  //ugh. a qlist of ksharedptr<kservice>
2306  QMutableListIterator<KService::Ptr> it(offers);
2307  while (it.hasNext()) {
2308  KService::Ptr p = it.next();
2309  QString prop = QString("X-Plasma-Requires-").append(key);
2310  QVariant req = p->property(prop, QVariant::String);
2311  //valid values: Required/Optional/Unused
2312  QString reqValue;
2313  if (req.isValid()) {
2314  reqValue = req.toString();
2315  } else if (p->property("X-Plasma-API").toString().toLower() == "javascript") {
2316  //TODO: be able to check whether or not a script engine provides "controled"
2317  //bindings; for now we just give a pass to the qscript ones
2318  reqValue = "Unused";
2319  }
2320 
2321  if (!(reqValue == "Optional" || reqValue == "Unused")) {
2322  //if (reqValue == "Required") {
2323  it.remove();
2324  }
2325  }
2326  }
2327 }
2328 
2329 QString AppletPrivate::parentAppConstraint(const QString &parentApp)
2330 {
2331  if (parentApp.isEmpty()) {
2332  return QString("((not exist [X-KDE-ParentApp] or [X-KDE-ParentApp] == '') or [X-KDE-ParentApp] == '%1')")
2333  .arg(KGlobal::mainComponent().aboutData()->appName());
2334  }
2335 
2336  return QString("[X-KDE-ParentApp] == '%1'").arg(parentApp);
2337 }
2338 
2339 KPluginInfo::List Applet::listAppletInfo(const QString &category, const QString &parentApp)
2340 {
2341  return PluginLoader::pluginLoader()->listAppletInfo(category, parentApp);
2342 }
2343 
2344 KPluginInfo::List Applet::listAppletInfoForMimetype(const QString &mimetype)
2345 {
2346  QString constraint = AppletPrivate::parentAppConstraint();
2347  constraint.append(QString(" and '%1' in [X-Plasma-DropMimeTypes]").arg(mimetype));
2348  //kDebug() << "listAppletInfoForMimetype with" << mimetype << constraint;
2349  KService::List offers = KServiceTypeTrader::self()->query("Plasma/Applet", constraint);
2350  AppletPrivate::filterOffers(offers);
2351  return KPluginInfo::fromServices(offers);
2352 }
2353 
2354 KPluginInfo::List Applet::listAppletInfoForUrl(const QUrl &url)
2355 {
2356  QString constraint = AppletPrivate::parentAppConstraint();
2357  constraint.append(" and exist [X-Plasma-DropUrlPatterns]");
2358  KService::List offers = KServiceTypeTrader::self()->query("Plasma/Applet", constraint);
2359  AppletPrivate::filterOffers(offers);
2360 
2361  KPluginInfo::List allApplets = KPluginInfo::fromServices(offers);
2362  KPluginInfo::List filtered;
2363  foreach (const KPluginInfo &info, allApplets) {
2364  QStringList urlPatterns = info.property("X-Plasma-DropUrlPatterns").toStringList();
2365  foreach (const QString &glob, urlPatterns) {
2366  QRegExp rx(glob);
2367  rx.setPatternSyntax(QRegExp::Wildcard);
2368  if (rx.exactMatch(url.toString())) {
2369  kDebug() << info.name() << "matches" << glob << url;
2370  filtered << info;
2371  }
2372  }
2373  }
2374 
2375  return filtered;
2376 }
2377 
2378 QStringList Applet::listCategories(const QString &parentApp, bool visibleOnly)
2379 {
2380  QString constraint = AppletPrivate::parentAppConstraint(parentApp);
2381  constraint.append(" and exist [X-KDE-PluginInfo-Category]");
2382 
2383  KConfigGroup group(KGlobal::config(), "General");
2384  const QStringList excluded = group.readEntry("ExcludeCategories", QStringList());
2385  foreach (const QString &category, excluded) {
2386  constraint.append(" and [X-KDE-PluginInfo-Category] != '").append(category).append("'");
2387  }
2388 
2389  KService::List offers = KServiceTypeTrader::self()->query("Plasma/Applet", constraint);
2390  AppletPrivate::filterOffers(offers);
2391 
2392  QStringList categories;
2393  QSet<QString> known = AppletPrivate::knownCategories();
2394  foreach (const KService::Ptr &applet, offers) {
2395  QString appletCategory = applet->property("X-KDE-PluginInfo-Category").toString();
2396  if (visibleOnly && applet->noDisplay()) {
2397  // we don't want to show the hidden category
2398  continue;
2399  }
2400 
2401  //kDebug() << " and we have " << appletCategory;
2402  if (!appletCategory.isEmpty() && !known.contains(appletCategory.toLower())) {
2403  kDebug() << "Unknown category: " << applet->name() << "says it is in the"
2404  << appletCategory << "category which is unknown to us";
2405  appletCategory.clear();
2406  }
2407 
2408  if (appletCategory.isEmpty()) {
2409  if (!categories.contains(i18nc("misc category", "Miscellaneous"))) {
2410  categories << i18nc("misc category", "Miscellaneous");
2411  }
2412  } else if (!categories.contains(appletCategory)) {
2413  categories << appletCategory;
2414  }
2415  }
2416 
2417  categories.sort();
2418  return categories;
2419 }
2420 
2421 void Applet::setCustomCategories(const QStringList &categories)
2422 {
2423  AppletPrivate::s_customCategories = QSet<QString>::fromList(categories);
2424 }
2425 
2426 QStringList Applet::customCategories()
2427 {
2428  return AppletPrivate::s_customCategories.toList();
2429 }
2430 
2431 Applet *Applet::loadPlasmoid(const QString &path, uint appletId, const QVariantList &args)
2432 {
2433  if (QFile::exists(path + "/metadata.desktop")) {
2434  KService service(path + "/metadata.desktop");
2435  const QStringList& types = service.serviceTypes();
2436 
2437  if (types.contains("Plasma/Containment")) {
2438  return new Containment(path, appletId, args);
2439  } else if (types.contains("Plasma/PopupApplet")) {
2440  return new PopupApplet(path, appletId, args);
2441  } else {
2442  return new Applet(path, appletId, args);
2443  }
2444  }
2445 
2446  return 0;
2447 }
2448 
2449 Applet *Applet::load(const QString &appletName, uint appletId, const QVariantList &args)
2450 {
2451  return PluginLoader::pluginLoader()->loadApplet(appletName, appletId, args);
2452 }
2453 
2454 Applet *Applet::load(const KPluginInfo &info, uint appletId, const QVariantList &args)
2455 {
2456  if (!info.isValid()) {
2457  return 0;
2458  }
2459 
2460  return load(info.pluginName(), appletId, args);
2461 }
2462 
2463 QVariant Applet::itemChange(GraphicsItemChange change, const QVariant &value)
2464 {
2465  QVariant ret = QGraphicsWidget::itemChange(change, value);
2466 
2467  //kDebug() << change;
2468  switch (change) {
2469  case ItemSceneHasChanged: {
2470  Corona *newCorona = qobject_cast<Corona *>(qvariant_cast<QGraphicsScene*>(value));
2471  if (newCorona && newCorona->immutability() != Mutable) {
2472  updateConstraints(ImmutableConstraint);
2473  }
2474  }
2475  break;
2476  case ItemParentChange:
2477  if (!d->isContainment) {
2478  Containment *c = containment();
2479  if (d->mainConfig && !c) {
2480  kWarning() << "Configuration object was requested prior to init(), which is too early. "
2481  "Please fix this item:" << parentItem() << value.value<QGraphicsItem *>()
2482  << name();
2483 
2484  Applet *newC = dynamic_cast<Applet*>(value.value<QGraphicsItem *>());
2485  if (newC) {
2486  // if this is an applet, and we've just been assigned to our first containment,
2487  // but the applet did something stupid like ask for the config() object prior to
2488  // this happening (e.g. inits ctor) then let's repair that situation for them.
2489  KConfigGroup *old = d->mainConfig;
2490  KConfigGroup appletConfig = newC->config();
2491  appletConfig = KConfigGroup(&appletConfig, "Applets");
2492  d->mainConfig = new KConfigGroup(&appletConfig, QString::number(d->appletId));
2493  old->copyTo(d->mainConfig);
2494  old->deleteGroup();
2495  delete old;
2496  }
2497  }
2498  }
2499  break;
2500  case ItemParentHasChanged:
2501  {
2502  if (isContainment()) {
2503  removeSceneEventFilter(this);
2504  } else {
2505  Containment *c = containment();
2506  if (c && c->containmentType() == Containment::DesktopContainment) {
2507  installSceneEventFilter(this);
2508  } else {
2509  removeSceneEventFilter(this);
2510  }
2511  }
2512  }
2513  break;
2514  case ItemPositionHasChanged:
2515  emit geometryChanged();
2516  // fall through!
2517  case ItemTransformHasChanged:
2518  d->scheduleModificationNotification();
2519  break;
2520  default:
2521  break;
2522  };
2523 
2524  return ret;
2525 }
2526 
2527 QPainterPath Applet::shape() const
2528 {
2529  if (d->script) {
2530  return d->script->shape();
2531  }
2532 
2533  return QGraphicsWidget::shape();
2534 }
2535 
2536 QSizeF Applet::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
2537 {
2538  QSizeF hint = QGraphicsWidget::sizeHint(which, constraint);
2539  const FormFactor ff = formFactor();
2540 
2541  // in panels make sure that the contents won't exit from the panel
2542  if (which == Qt::MinimumSize) {
2543  if (ff == Horizontal) {
2544  hint.setHeight(0);
2545  } else if (ff == Vertical) {
2546  hint.setWidth(0);
2547  }
2548  }
2549 
2550  // enforce a square size in panels
2551  if (d->aspectRatioMode == Plasma::Square) {
2552  if (ff == Horizontal) {
2553  hint.setWidth(size().height());
2554  } else if (ff == Vertical) {
2555  hint.setHeight(size().width());
2556  }
2557  } else if (d->aspectRatioMode == Plasma::ConstrainedSquare) {
2558  //enforce a size not wider than tall
2559  if (ff == Horizontal) {
2560  hint.setWidth(size().height());
2561  //enforce a size not taller than wide
2562  } else if (ff == Vertical && (which == Qt::MaximumSize || size().width() <= KIconLoader::SizeLarge)) {
2563  hint.setHeight(size().width());
2564  }
2565  }
2566 
2567  return hint;
2568 }
2569 
2570 void Applet::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
2571 {
2572  Q_UNUSED(event)
2573 }
2574 
2575 void Applet::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
2576 {
2577  Q_UNUSED(event)
2578 }
2579 
2580 void Applet::timerEvent(QTimerEvent *event)
2581 {
2582  if (d->transient) {
2583  d->constraintsTimer.stop();
2584  d->busyWidgetTimer.stop();
2585  if (d->modificationsTimer) {
2586  d->modificationsTimer->stop();
2587  }
2588  return;
2589  }
2590 
2591  if (event->timerId() == d->constraintsTimer.timerId()) {
2592  d->constraintsTimer.stop();
2593 
2594  // Don't flushPendingConstraints if we're just starting up
2595  // flushPendingConstraints will be called by Corona
2596  if(!(d->pendingConstraints & Plasma::StartupCompletedConstraint)) {
2597  flushPendingConstraintsEvents();
2598  }
2599  } else if (d->modificationsTimer && event->timerId() == d->modificationsTimer->timerId()) {
2600  d->modificationsTimer->stop();
2601  // invalid group, will result in save using the default group
2602  KConfigGroup cg;
2603 
2604  save(cg);
2605  emit configNeedsSaving();
2606  } else if (event->timerId() == d->busyWidgetTimer.timerId()) {
2607  if (!d->busyWidget) {
2608  d->createMessageOverlay(false);
2609  d->messageOverlay->opacity = 0;
2610 
2611  QGraphicsLinearLayout *mainLayout = new QGraphicsLinearLayout(d->messageOverlay);
2612  d->busyWidget = new Plasma::BusyWidget(d->messageOverlay);
2613  d->busyWidget->setAcceptHoverEvents(false);
2614  d->busyWidget->setAcceptedMouseButtons(Qt::NoButton);
2615  d->messageOverlay->setAcceptHoverEvents(false);
2616  d->messageOverlay->setAcceptedMouseButtons(Qt::NoButton);
2617 
2618  mainLayout->addStretch();
2619  mainLayout->addItem(d->busyWidget);
2620  mainLayout->addStretch();
2621  }
2622  }
2623 }
2624 
2625 QRect Applet::screenRect() const
2626 {
2627  QGraphicsView *v = view();
2628 
2629  if (v) {
2630  QPointF bottomRight = pos();
2631  bottomRight.rx() += size().width();
2632  bottomRight.ry() += size().height();
2633 
2634  QPoint tL = v->mapToGlobal(v->mapFromScene(pos()));
2635  QPoint bR = v->mapToGlobal(v->mapFromScene(bottomRight));
2636  return QRect(QPoint(tL.x(), tL.y()), QSize(bR.x() - tL.x(), bR.y() - tL.y()));
2637  }
2638 
2639  //The applet doesn't have a view on it.
2640  //So a screenRect isn't relevant.
2641  return QRect(QPoint(0, 0), QSize(0, 0));
2642 }
2643 
2644 void Applet::raise()
2645 {
2646  setZValue(++AppletPrivate::s_maxZValue);
2647 }
2648 
2649 void Applet::lower()
2650 {
2651  setZValue(--AppletPrivate::s_minZValue);
2652 }
2653 
2654 void AppletPrivate::setIsContainment(bool nowIsContainment, bool forceUpdate)
2655 {
2656  if (isContainment == nowIsContainment && !forceUpdate) {
2657  return;
2658  }
2659 
2660  isContainment = nowIsContainment;
2661  //FIXME I do not like this function.
2662  //currently it's only called before ctmt/applet init, with (true,true), and I'm going to assume it stays that way.
2663  //if someone calls it at some other time it'll cause headaches. :P
2664 
2665  delete mainConfig;
2666  mainConfig = 0;
2667 
2668  Containment *c = q->containment();
2669  if (c) {
2670  c->d->checkContainmentFurniture();
2671  }
2672 }
2673 
2674 bool Applet::isContainment() const
2675 {
2676  return d->isContainment;
2677 }
2678 
2679 // PRIVATE CLASS IMPLEMENTATION
2680 
2681 AppletPrivate::AppletPrivate(KService::Ptr service, const KPluginInfo *info, int uniqueID, Applet *applet)
2682  : appletId(uniqueID),
2683  q(applet),
2684  service(0),
2685  preferredBackgroundHints(Applet::StandardBackground),
2686  backgroundHints(Applet::NoBackground),
2687  aspectRatioMode(Plasma::KeepAspectRatio),
2688  immutability(Mutable),
2689  appletDescription(info ? *info : KPluginInfo(service)),
2690  background(0),
2691  mainConfig(0),
2692  pendingConstraints(NoConstraint),
2693  messageOverlay(0),
2694  messageOverlayProxy(0),
2695  busyWidget(0),
2696  script(0),
2697  package(0),
2698  configLoader(0),
2699  actions(AppletPrivate::defaultActions(applet)),
2700  activationAction(0),
2701  itemStatus(UnknownStatus),
2702  preferredSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored),
2703  modificationsTimer(0),
2704  hasConfigurationInterface(false),
2705  failed(false),
2706  isContainment(false),
2707  transient(false),
2708  needsConfig(false),
2709  started(false)
2710 {
2711  if (appletId == 0) {
2712  appletId = ++s_maxAppletId;
2713  } else if (appletId > s_maxAppletId) {
2714  s_maxAppletId = appletId;
2715  }
2716 
2717  publishUI.publishCheckbox = 0;
2718 }
2719 
2720 AppletPrivate::~AppletPrivate()
2721 {
2722  if (activationAction && activationAction->isGlobalShortcutEnabled()) {
2723  //kDebug() << "reseting global action for" << q->name() << activationAction->objectName();
2724  activationAction->forgetGlobalShortcut();
2725  }
2726 
2727  delete extender.data();
2728 
2729  delete script;
2730  script = 0;
2731  delete package;
2732  package = 0;
2733  delete configLoader;
2734  configLoader = 0;
2735  delete mainConfig;
2736  mainConfig = 0;
2737  delete modificationsTimer;
2738 }
2739 
2740 void AppletPrivate::init(const QString &packagePath)
2741 {
2742  // WARNING: do not access config() OR globalConfig() in this method!
2743  // that requires a scene, which is not available at this point
2744  q->setCacheMode(Applet::DeviceCoordinateCache);
2745  q->setAcceptsHoverEvents(true);
2746  q->setFlag(QGraphicsItem::ItemIsFocusable, true);
2747  q->setFocusPolicy(Qt::ClickFocus);
2748  // FIXME: adding here because nothing seems to be doing it in QGraphicsView,
2749  // but it doesn't actually work anyways =/
2750  q->setLayoutDirection(qApp->layoutDirection());
2751 
2752  //set a default size before any saved settings are read
2753  QSize size(200, 200);
2754  q->setBackgroundHints(Applet::DefaultBackground);
2755  q->setHasConfigurationInterface(true); //FIXME why not default it to true in the constructor?
2756 
2757  QAction *closeApplet = actions->action("remove");
2758  if (closeApplet) {
2759  closeApplet->setText(i18nc("%1 is the name of the applet", "Remove this %1", q->name()));
2760  }
2761 
2762  QAction *configAction = actions->action("configure");
2763  if (configAction) {
2764  configAction->setText(i18nc("%1 is the name of the applet", "%1 Settings", q->name()));
2765  }
2766 
2767  QObject::connect(q, SIGNAL(activate()), q, SLOT(setFocus()));
2768  if (!appletDescription.isValid()) {
2769  kDebug() << "Check your constructor! "
2770  << "You probably want to be passing in a Service::Ptr "
2771  << "or a QVariantList with a valid storageid as arg[0].";
2772  q->resize(size);
2773  return;
2774  }
2775 
2776  QVariant s = appletDescription.property("X-Plasma-DefaultSize");
2777  if (s.isValid()) {
2778  size = s.toSize();
2779  }
2780  //kDebug() << "size" << size;
2781  q->resize(size);
2782 
2783  QString api = appletDescription.property("X-Plasma-API").toString();
2784 
2785  // we have a scripted plasmoid
2786  if (!api.isEmpty()) {
2787  // find where the Package is
2788  QString path = packagePath.isEmpty() ? appletDescription.pluginName() : packagePath;
2789  // create the package and see if we have something real
2790  PackageStructure::Ptr structure = Plasma::packageStructure(api, Plasma::AppletComponent);
2791  package = new Package(path, structure);
2792  //kDebug() << "***** package is" << package->path();
2793 
2794  if (package->isValid()) {
2795  // now we try and set up the script engine.
2796  // it will be parented to this applet and so will get
2797  // deleted when the applet does
2798 
2799  script = Plasma::loadScriptEngine(api, q);
2800  if (!script) {
2801  delete package;
2802  package = 0;
2803  q->setFailedToLaunch(true,
2804  i18nc("API or programming language the widget was written in, name of the widget",
2805  "Could not create a %1 ScriptEngine for the %2 widget.",
2806  api, appletDescription.name()));
2807  }
2808  } else {
2809  q->setFailedToLaunch(true, i18nc("Package file, name of the widget",
2810  "Could not open the %1 package required for the %2 widget.",
2811  appletDescription.pluginName(), appletDescription.name()));
2812  delete package;
2813  package = 0;
2814  }
2815  }
2816 }
2817 
2818 // put all setup routines for script here. at this point we can assume that
2819 // package exists and that we have a script engine
2820 void AppletPrivate::setupScriptSupport()
2821 {
2822  if (!package) {
2823  return;
2824  }
2825 
2826  kDebug() << "setting up script support, package is in" << package->path()
2827  << "which is a" << package->structure()->type() << "package"
2828  << ", main script is" << package->filePath("mainscript");
2829 
2830  QString translationsPath = package->filePath("translations");
2831  if (!translationsPath.isEmpty()) {
2832  //FIXME: we should _probably_ use a KComponentData to segregate the applets
2833  // from each other; but I want to get the basics working first :)
2834  KGlobal::dirs()->addResourceDir("locale", translationsPath);
2835  KGlobal::locale()->insertCatalog(package->metadata().pluginName());
2836  }
2837 
2838  QString xmlPath = package->filePath("mainconfigxml");
2839  if (!xmlPath.isEmpty()) {
2840  QFile file(xmlPath);
2841  KConfigGroup config = q->config();
2842  configLoader = new ConfigLoader(&config, &file);
2843  QObject::connect(configLoader, SIGNAL(configChanged()), q, SLOT(propagateConfigChanged()));
2844  }
2845 
2846  if (!package->filePath("mainconfigui").isEmpty()) {
2847  q->setHasConfigurationInterface(true);
2848  }
2849 }
2850 
2851 QString AppletPrivate::globalName() const
2852 {
2853  if (!appletDescription.isValid()) {
2854  return QString();
2855  }
2856 
2857  return appletDescription.service()->library();
2858 }
2859 
2860 QString AppletPrivate::instanceName()
2861 {
2862  if (!appletDescription.isValid()) {
2863  return QString();
2864  }
2865 
2866  return appletDescription.service()->library() + QString::number(appletId);
2867 }
2868 
2869 void AppletPrivate::scheduleConstraintsUpdate(Plasma::Constraints c)
2870 {
2871  // Don't start up a timer if we're just starting up
2872  // flushPendingConstraints will be called by Corona
2873  if (started && !constraintsTimer.isActive() && !(c & Plasma::StartupCompletedConstraint)) {
2874  constraintsTimer.start(0, q);
2875  }
2876 
2877  if (c & Plasma::StartupCompletedConstraint) {
2878  started = true;
2879  }
2880 
2881  pendingConstraints |= c;
2882 }
2883 
2884 void AppletPrivate::scheduleModificationNotification()
2885 {
2886  // modificationsTimer is not allocated until we get our notice of being started
2887  if (modificationsTimer) {
2888  // schedule a save
2889  if (modificationsTimer->isActive()) {
2890  modificationsTimer->stop();
2891  }
2892 
2893  modificationsTimer->start(1000, q);
2894  }
2895 }
2896 
2897 KConfigGroup *AppletPrivate::mainConfigGroup()
2898 {
2899  if (mainConfig) {
2900  return mainConfig;
2901  }
2902 
2903  bool newGroup = false;
2904  if (isContainment) {
2905  Corona *corona = qobject_cast<Corona*>(q->scene());
2906  KConfigGroup containmentConfig;
2907  //kDebug() << "got a corona, baby?" << (QObject*)corona << (QObject*)q;
2908 
2909  if (corona) {
2910  containmentConfig = KConfigGroup(corona->config(), "Containments");
2911  } else {
2912  containmentConfig = KConfigGroup(KGlobal::config(), "Containments");
2913  }
2914 
2915  if (package && !containmentConfig.hasGroup(QString::number(appletId))) {
2916  newGroup = true;
2917  }
2918 
2919  mainConfig = new KConfigGroup(&containmentConfig, QString::number(appletId));
2920  } else {
2921  KConfigGroup appletConfig;
2922 
2923  Containment *c = q->containment();
2924  Applet *parentApplet = qobject_cast<Applet *>(q->parent());
2925  if (parentApplet && parentApplet != static_cast<Applet *>(c)) {
2926  // this applet is nested inside another applet! use it's config
2927  // as the parent group in the config
2928  appletConfig = parentApplet->config();
2929  appletConfig = KConfigGroup(&appletConfig, "Applets");
2930  } else if (c) {
2931  // applet directly in a Containment, as usual
2932  appletConfig = c->config();
2933  appletConfig = KConfigGroup(&appletConfig, "Applets");
2934  } else {
2935  kWarning() << "requesting config for" << q->name() << "without a containment!";
2936  appletConfig = KConfigGroup(KGlobal::config(), "Applets");
2937  }
2938 
2939  if (package && !appletConfig.hasGroup(QString::number(appletId))) {
2940  newGroup = true;
2941  }
2942 
2943  mainConfig = new KConfigGroup(&appletConfig, QString::number(appletId));
2944  }
2945 
2946  if (newGroup) {
2947  //see if we have a default configuration in our package
2948  const QString defaultConfigFile = q->package()->filePath("defaultconfig");
2949  if (!defaultConfigFile.isEmpty()) {
2950  kDebug() << "copying default config: " << q->package()->filePath("defaultconfig");
2951  KConfigGroup defaultConfig(KSharedConfig::openConfig(defaultConfigFile)->group("Configuration"));
2952  defaultConfig.copyTo(mainConfig);
2953  }
2954  }
2955 
2956  return mainConfig;
2957 }
2958 
2959 QString AppletPrivate::visibleFailureText(const QString &reason)
2960 {
2961  QString text;
2962 
2963  if (reason.isEmpty()) {
2964  text = i18n("This object could not be created.");
2965  } else {
2966  QString r = reason;
2967  r.replace('\n', "<br/>");
2968  text = i18n("This object could not be created for the following reason:<p><b>%1</b></p>", r);
2969  }
2970 
2971  return text;
2972 }
2973 
2974 void AppletPrivate::themeChanged()
2975 {
2976  if (background) {
2977  //do again the translucent background fallback
2978  q->setBackgroundHints(backgroundHints);
2979 
2980  qreal left;
2981  qreal right;
2982  qreal top;
2983  qreal bottom;
2984  background->getMargins(left, top, right, bottom);
2985  q->setContentsMargins(left, right, top, bottom);
2986  }
2987  q->update();
2988 }
2989 
2990 void AppletPrivate::resetConfigurationObject()
2991 {
2992  // make sure mainConfigGroup exists in all cases
2993  mainConfigGroup();
2994 
2995  mainConfig->deleteGroup();
2996  delete mainConfig;
2997  mainConfig = 0;
2998 
2999  Corona * corona = qobject_cast<Corona*>(q->scene());
3000  if (corona) {
3001  corona->requireConfigSync();
3002  }
3003 }
3004 
3005 void AppletPrivate::handleDisappeared(AppletHandle *h)
3006 {
3007  if (h == handle.data()) {
3008  h->detachApplet();
3009  QGraphicsScene *scene = q->scene();
3010  if (scene && h->scene() == scene) {
3011  scene->removeItem(h);
3012  }
3013  h->deleteLater();
3014  }
3015 }
3016 
3017 void ContainmentPrivate::checkRemoveAction()
3018 {
3019  q->enableAction("remove", q->immutability() == Mutable);
3020 }
3021 
3022 
3023 uint AppletPrivate::s_maxAppletId = 0;
3024 int AppletPrivate::s_maxZValue = 0;
3025 int AppletPrivate::s_minZValue = 0;
3026 PackageStructure::Ptr AppletPrivate::packageStructure(0);
3027 QSet<QString> AppletPrivate::s_customCategories;
3028 
3029 AppletOverlayWidget::AppletOverlayWidget(QGraphicsWidget *parent)
3030  : QGraphicsWidget(parent),
3031  opacity(0.4)
3032 {
3033  resize(parent->size());
3034 }
3035 
3036 void AppletOverlayWidget::destroy()
3037 {
3038  Animation *anim = Plasma::Animator::create(Plasma::Animator::DisappearAnimation);
3039  if (anim) {
3040  connect(anim, SIGNAL(finished()), this, SLOT(overlayAnimationComplete()));
3041  anim->setTargetWidget(this);
3042  anim->start();
3043  } else {
3044  overlayAnimationComplete();
3045  }
3046 }
3047 
3048 void AppletOverlayWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
3049 {
3050  event->accept();
3051 }
3052 
3053 void AppletOverlayWidget::overlayAnimationComplete()
3054 {
3055  if (scene()) {
3056  scene()->removeItem(this);
3057  }
3058  deleteLater();
3059 }
3060 
3061 void AppletOverlayWidget::paint(QPainter *painter,
3062  const QStyleOptionGraphicsItem *option,
3063  QWidget *widget)
3064 {
3065  Q_UNUSED(option)
3066  Q_UNUSED(widget)
3067 
3068  if (qFuzzyCompare(1, 1+opacity)) {
3069  return;
3070  }
3071 
3072  QColor wash = Plasma::Theme::defaultTheme()->color(Theme::BackgroundColor);
3073  wash.setAlphaF(opacity);
3074 
3075  Applet *applet = qobject_cast<Applet *>(parentWidget());
3076 
3077 
3078  QPainterPath backgroundShape;
3079  if (!applet || applet->backgroundHints() & Applet::StandardBackground) {
3080  //FIXME: a resize here is nasty, but perhaps still better than an eventfilter just for that..
3081  if (parentWidget()->contentsRect().size() != size()) {
3082  resize(parentWidget()->contentsRect().size());
3083  }
3084  backgroundShape = PaintUtils::roundedRectangle(contentsRect(), 5);
3085  } else {
3086  backgroundShape = shape();
3087  }
3088 
3089  painter->setRenderHints(QPainter::Antialiasing);
3090  painter->fillPath(backgroundShape, wash);
3091 }
3092 
3093 #if QT_VERSION >= 0x040700
3094 // in QGraphicsWidget now; preserve BC by implementing it as a protected method
3095 void Applet::geometryChanged()
3096 {
3097  emit QGraphicsWidget::geometryChanged();
3098 }
3099 #endif
3100 
3101 } // Plasma namespace
3102 
3103 #include "applet.moc"
3104 #include "private/applet_p.moc"
Plasma::Applet::hasValidAssociatedApplication
bool hasValidAssociatedApplication() const
Definition: applet.cpp:2291
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:2248
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:2426
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&#39;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:2580
extender.h
abstracttoolbox.h
Plasma::Applet::configScheme
ConfigLoader * configScheme() const
Returns the config skeleton object from this applet&#39;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:2242
Plasma::Applet::restore
virtual void restore(KConfigGroup &group)
Restores state information about this applet saved previously in save(KConfigGroup&amp;).
Definition: applet.cpp:310
Plasma::SystemImmutable
the item is locked down by the system, the user can&#39;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:2575
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:2378
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:2421
Plasma::Applet::saveState
virtual void saveState(KConfigGroup &config) const
When called, the Applet should write any information needed as part of the Applet&#39;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:2570
Plasma::Applet::associatedApplicationUrls
KUrl::List associatedApplicationUrls() const
Definition: applet.cpp:2279
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:2463
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:2225
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:2274
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:456
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:337
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:2235
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:2339
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:2649
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:2344
Plasma::PopupApplet
Allows applets to automatically &#39;collapse&#39; 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:277
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&#39;s not set but some urls are, open those urls with the proper application for their mimetype.
Definition: applet.cpp:2284
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:2536
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:2644
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:2527
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:2354
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:2431
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&#39;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:467
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:2261
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:40
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&#39;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:836
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:655
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:374
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:2674
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:272
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:2625
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:192
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:2449
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Jun 17 2014 17:07:41 by doxygen 1.8.5 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-4.10.5 API Reference

Skip menu "kdelibs-4.10.5 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
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
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