Libplasma

applet.cpp
1/*
2 SPDX-FileCopyrightText: 2005 Aaron Seigo <aseigo@kde.org>
3 SPDX-FileCopyrightText: 2007 Riccardo Iaconelli <riccardo@kde.org>
4 SPDX-FileCopyrightText: 2008 Ménard Alexis <darktears31@gmail.com>
5 SPDX-FileCopyrightText: 2009 Chani Armitage <chani@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#include "applet.h"
11#include "private/applet_p.h"
12
13#include "config-plasma.h"
14
15#include <QDebug>
16#include <QFile>
17#include <QJSEngine>
18#include <QList>
19#include <QMetaEnum>
20
21#include <KAuthorized>
22#include <KConfigLoader>
23#include <KConfigPropertyMap>
24#include <KGlobalAccel>
25#include <KLocalizedString>
26#include <KPackage/Package>
27
28#include "containment.h"
29#include "corona.h"
30#include "plasma.h"
31#include "pluginloader.h"
32
33#include "debug_p.h"
34#include "private/containment_p.h"
35
36#include <cmath>
37#include <limits>
38
39namespace Plasma
40{
41Applet::Applet(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args)
42 : QObject(parentObject)
43 , d(new AppletPrivate(data, args.count() > 1 ? args[1].toInt() : 0, this))
44{
45 if (!args.isEmpty()) {
46 const QVariant first = args.first();
47 if (first.canConvert<KPackage::Package>()) {
48 d->package = first.value<KPackage::Package>();
49 }
50 }
51 d->icon = d->appletDescription.iconName();
52
53 if (args.contains(QVariant::fromValue(QStringLiteral("org.kde.plasma:force-create")))) {
54 setProperty("org.kde.plasma:force-create", true);
55 }
56
57 // WARNING: do not access config() OR globalConfig() in this method!
58 // that requires a scene, which is not available at this point
59 d->init(args.mid(2));
60}
61
62Applet::~Applet()
63{
64 for (QAction *a : d->actions.values()) {
65 disconnect(a, nullptr, this, nullptr);
66 }
67 for (QAction *a : d->contextualActions) {
68 disconnect(a, nullptr, this, nullptr);
69 }
70
71 // let people know that i will die
72 Q_EMIT appletDeleted(this);
73
74 if (d->transient) {
75 d->resetConfigurationObject();
76 }
77
78 // ConfigLoader is deleted when AppletPrivate closes not Applet
79 // It saves on closure and emits a signal.
80 // disconnect early to avoid a crash. See 411221
81 if (d->configLoader) {
82 disconnect(d->configLoader, SIGNAL(configChanged()), this, SLOT(propagateConfigChanged()));
83 }
84 delete d;
85}
86
88{
89 // Don't implement anything here, it will be overridden by subclasses
90}
91
92uint Applet::id() const
93{
94 return d->appletId;
95}
96
97QVariantList Applet::startupArguments() const
98{
99 return d->startupArguments;
100}
101
103{
104 if (d->transient || !d->appletDescription.isValid()) {
105 return;
106 }
107
108 KConfigGroup group = g;
109 if (!group.isValid()) {
110 group = *d->mainConfigGroup();
111 }
112
113 // qCDebug(LOG_PLASMA) << "saving" << pluginName() << "to" << group.name();
114 // we call the dptr member directly for locked since isImmutable()
115 // also checks kiosk and parent containers
116 group.writeEntry("immutability", (int)d->immutability);
117 group.writeEntry("plugin", d->appletDescription.pluginId());
118
119 if (!d->started) {
120 return;
121 }
122
123 KConfigGroup appletConfigGroup(&group, QStringLiteral("Configuration"));
124 saveState(appletConfigGroup);
125
126 if (d->configLoader) {
127 // we're saving so we know its changed, we don't need or want the configChanged
128 // signal bubbling up at this point due to that
129 disconnect(d->configLoader, SIGNAL(configChanged()), this, SLOT(propagateConfigChanged()));
130 d->configLoader->save();
131 connect(d->configLoader, SIGNAL(configChanged()), this, SLOT(propagateConfigChanged()));
132 }
133}
134
136{
138
139 KConfigGroup shortcutConfig(&group, QStringLiteral("Shortcuts"));
140 QString shortcutText = shortcutConfig.readEntryUntranslated("global", QString());
141 if (!shortcutText.isEmpty()) {
142 setGlobalShortcut(QKeySequence(shortcutText));
143 /*
144 #ifndef NDEBUG
145 // qCDebug(LOG_PLASMA) << "got global shortcut for" << name() << "of" << QKeySequence(shortcutText);
146 #endif
147 #ifndef NDEBUG
148 // qCDebug(LOG_PLASMA) << "set to" << d->activationAction->objectName()
149 #endif
150 << d->activationAction->globalShortcut().primary();
151 */
152 }
153
154 // User background hints
155 // TODO support flags in the config
156 QByteArray hintsString = config().readEntry("UserBackgroundHints", QString()).toUtf8();
158 bool ok;
159 int value = hintEnum.keyToValue(hintsString.constData(), &ok);
160 if (ok) {
161 d->userBackgroundHints = Plasma::Types::BackgroundHints(value);
162 d->userBackgroundHintsInitialized = true;
164 if (d->backgroundHints & Plasma::Types::ConfigurableBackground) {
166 }
167 }
168}
170void Applet::setLaunchErrorMessage(const QString &message)
171{
172 if (message == d->launchErrorMessage) {
173 return;
174 }
175
176 d->failed = true;
177 d->launchErrorMessage = message;
178}
180void Applet::saveState(KConfigGroup &group) const
181{
182 if (group.config()->name() != config().config()->name()) {
183 // we're being saved to a different file!
184 // let's just copy the current values in our configuration over
185 KConfigGroup c = config();
186 c.copyTo(&group);
187 }
188}
191{
192 if (d->transient) {
193 return KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("PlasmaTransientsConfig"));
194 }
195
196 if (isContainment()) {
197 return *(d->mainConfigGroup());
198 }
199
200 return KConfigGroup(d->mainConfigGroup(), QStringLiteral("Configuration"));
201}
204{
205 KConfigGroup globalAppletConfig;
206 QString group = isContainment() ? QStringLiteral("ContainmentGlobals") : QStringLiteral("AppletGlobals");
207
208 Containment *cont = containment();
209 Corona *corona = nullptr;
210 if (cont) {
211 corona = cont->corona();
212 }
213 if (corona) {
214 KSharedConfig::Ptr coronaConfig = corona->config();
215 globalAppletConfig = KConfigGroup(coronaConfig, group);
216 } else {
217 globalAppletConfig = KConfigGroup(KSharedConfig::openConfig(), group);
218 }
219
220 return KConfigGroup(&globalAppletConfig, d->globalName());
221}
223void Applet::destroy()
224{
225 Corona *cor = nullptr;
226 Containment *cont = containment();
227 if (cont) {
228 cor = cont->corona();
229 }
230
231 if (d->transient) {
232 // If the applet is transient, we can delete it anyways, unless
233 // Corona itself is immutable
234 if (!d->started || (cor && cor->immutability() != Types::Mutable)) {
235 return;
236 }
237 }
238
239 d->setDestroyed(true);
240 // FIXME: an animation on leave if !isContainment() would be good again .. which should be handled by the containment class
241 d->cleanUpAndDelete();
242}
244bool Applet::destroyed() const
245{
246 return d->transient;
247}
250{
251 if (!d->configLoader) {
252 QString xmlPath;
253
254 if (d->package.isValid()) {
255 xmlPath = d->package.filePath("mainconfigxml");
256 } else {
257 if (QFile::exists(qrcPath() + QLatin1String("main.xml"))) {
258 xmlPath = qrcPath() + QLatin1String("main.xml");
259 }
260 }
261
262 KConfigGroup cfg = config();
263 if (xmlPath.isEmpty()) {
264 d->configLoader = new KConfigLoader(cfg, nullptr);
265 } else {
266 QFile file(xmlPath);
267 d->configLoader = new KConfigLoader(cfg, &file);
268 QObject::connect(d->configLoader, SIGNAL(configChanged()), this, SLOT(propagateConfigChanged()));
269 }
270 }
271
272 return d->configLoader;
273}
274
276{
277 if (!d->configPropertyMap) {
278 d->configPropertyMap = new KConfigPropertyMap(configScheme(), this);
279 connect(d->configPropertyMap, &KConfigPropertyMap::valueChanged, this, [this]() {
280 d->scheduleModificationNotification();
281 });
282 }
283 return d->configPropertyMap;
284}
286void Applet::updateConstraints(Constraints constraints)
287{
288 d->scheduleConstraintsUpdate(constraints);
289}
290
291void Applet::constraintsEvent(Constraints constraints)
292{
293 // NOTE: do NOT put any code in here that reacts to constraints updates
294 // as it will not get called for any applet that reimplements constraintsEvent
295 // without calling the Applet:: version as well, which it shouldn't need to.
296 // INSTEAD put such code into flushPendingConstraintsEvents
297 Q_UNUSED(constraints)
298 // qCDebug(LOG_PLASMA) << constraints << "constraints are FormFactor: " << formFactor()
299 // << ", Location: " << location();
300}
303{
304 if (!d->customTitle.isEmpty()) {
305 return d->customTitle;
306 }
307
308 if (d->appletDescription.isValid()) {
309 return d->appletDescription.name();
310 }
311
312 return i18n("Unknown");
313}
315void Applet::setTitle(const QString &title)
316{
317 if (title == d->customTitle) {
318 return;
319 }
320
321 d->customTitle = title;
323}
325QString Applet::icon() const
326{
327 return d->icon;
328}
330void Applet::setIcon(const QString &icon)
331{
332 if (icon == d->icon) {
333 return;
334 }
335
336 d->icon = icon;
338}
340bool Applet::isBusy() const
341{
342 return d->busy;
343}
345void Applet::setBusy(bool busy)
346{
347 if (busy == d->busy) {
348 return;
349 }
350
351 d->busy = busy;
353}
356{
357 return d->backgroundHints;
358}
361{
362 if (d->backgroundHints == hint) {
363 return;
364 }
365
367
368 d->backgroundHints = hint;
370
371 if (oldeffectiveHints != effectiveBackgroundHints()) {
373 }
374}
377{
378 if (d->userBackgroundHintsInitialized && (d->backgroundHints & Plasma::Types::ConfigurableBackground)) {
379 return d->userBackgroundHints;
380 } else {
381 return d->backgroundHints;
382 }
383}
386{
387 return d->userBackgroundHints;
388}
391{
392 if (d->userBackgroundHints == hint && d->userBackgroundHintsInitialized) {
393 return;
394 }
395
396 d->userBackgroundHints = hint;
397 d->userBackgroundHintsInitialized = true;
399 config().writeEntry("UserBackgroundHints", hintEnum.valueToKey(d->userBackgroundHints));
400 if (containment() && containment()->corona()) {
401 containment()->corona()->requestConfigSync();
402 }
403
405
406 if (d->backgroundHints & Plasma::Types::ConfigurableBackground) {
408 }
409}
412{
413 return d->appletDescription;
414}
417{
418 return d->appletDescription.isValid() ? d->appletDescription.pluginId() : QString();
419}
422{
423 // if this object is itself system immutable, then just return that; it's the most
424 // restrictive setting possible and will override anything that might be happening above it
425 // in the Corona->Containment->Applet hierarchy
426 if (d->transient || (d->mainConfig && d->mainConfig->isImmutable())) {
428 }
429
430 // Returning the more strict immutability between the applet immutability, Containment and Corona
431 Types::ImmutabilityType upperImmutability = Types::Mutable;
432
433 if (isContainment()) {
434 Corona *cor = static_cast<Containment *>(const_cast<Applet *>(this))->corona();
435 if (cor) {
436 upperImmutability = cor->immutability();
437 }
438 } else {
439 const Containment *cont = containment();
440 if (cont) {
441 if (cont->corona()) {
442 upperImmutability = cont->corona()->immutability();
443 } else {
444 upperImmutability = cont->immutability();
445 }
446 }
447 }
448
449 if (upperImmutability != Types::Mutable) {
450 // it's either system or user immutable, and we already check for local system immutability,
451 // so upperImmutability is guaranteed to be as or more severe as this object's immutability
452 return upperImmutability;
453 } else {
454 return d->immutability;
455 }
456}
459{
460 if (d->immutability == immutable || immutable == Types::SystemImmutable) {
461 // we do not store system immutability in d->immutability since that gets saved
462 // out to the config file; instead, we check with
463 // the config group itself for this information at all times. this differs from
464 // corona, where SystemImmutability is stored in d->immutability.
465 return;
466 }
467
468 d->immutability = immutable;
470}
472bool Applet::immutable() const
473{
474 return immutability() != Types::Mutable;
475}
478{
479 return d->launchErrorMessage;
480}
482bool Applet::failedToLaunch() const
483{
484 return d->failed;
485}
488{
489 return d->needsConfig;
490}
493{
494 return d->configurationRequiredReason;
495}
497void Applet::setConfigurationRequired(bool needsConfig, const QString &reason)
498{
499 if (d->needsConfig == needsConfig && reason == d->configurationRequiredReason) {
500 return;
501 }
502
503 d->needsConfig = needsConfig;
504 d->configurationRequiredReason = reason;
505
506 Q_EMIT configurationRequiredChanged(needsConfig, reason);
507}
510{
511 if (d->constraintHints == constraintHints) {
512 return;
513 }
514
515 d->constraintHints = constraintHints;
517}
519Applet::ConstraintHints Applet::constraintHints() const
520{
521 return d->constraintHints;
522}
524bool Applet::isUserConfiguring() const
525{
526 return d->userConfiguring;
527}
529void Applet::setUserConfiguring(bool configuring)
530{
531 if (configuring == d->userConfiguring) {
532 return;
533 }
534
535 d->userConfiguring = configuring;
536 Q_EMIT userConfiguringChanged(configuring);
537}
540{
541 return d->itemStatus;
542}
545{
546 if (status == d->itemStatus) {
547 return;
548 }
549 d->itemStatus = status;
551}
554{
555 if (d->pendingConstraints == NoConstraint) {
556 return;
557 }
558
559 if (d->constraintsTimer.isActive()) {
560 d->constraintsTimer.stop();
561 }
562
563 // qCDebug(LOG_PLASMA) << "flushing constraints: " << d->pendingConstraints << "!!!!!!!!!!!!!!!!!!!!!!!!!!!";
564 Constraints c = d->pendingConstraints;
565 d->pendingConstraints = NoConstraint;
566
567 if (c & UiReadyConstraint) {
568 d->setUiReady();
569 }
570
572 // common actions
573 bool unlocked = immutability() == Types::Mutable;
574 QAction *closeApplet = d->actions.value(QStringLiteral("remove"));
575 if (closeApplet) {
576 closeApplet->setEnabled(unlocked);
577 closeApplet->setVisible(unlocked);
578 connect(closeApplet, SIGNAL(triggered(bool)), this, SLOT(askDestroy()), Qt::UniqueConnection);
579 }
580
581 QAction *configAction = d->actions.value(QStringLiteral("configure"));
582 if (configAction) {
583 if (d->hasConfigurationInterface) {
584 bool canConfig = unlocked || KAuthorized::authorize(QStringLiteral("plasma/allow_configure_when_locked"));
585 configAction->setVisible(canConfig);
586 configAction->setEnabled(canConfig);
587 }
588 }
589 }
590
591 if (c & ImmutableConstraint) {
592 bool unlocked = immutability() == Types::Mutable;
593 QAction *action = d->actions.value(QStringLiteral("remove"));
594 if (action) {
595 action->setVisible(unlocked);
596 action->setEnabled(unlocked);
597 }
598
599 action = d->actions.value(QStringLiteral("configure"));
600 if (action && d->hasConfigurationInterface) {
601 bool canConfig = unlocked || KAuthorized::authorize(QStringLiteral("plasma/allow_configure_when_locked"));
602 action->setVisible(canConfig);
603 action->setEnabled(canConfig);
604 }
605
606 // an immutable constraint will always happen at startup
607 // make sure don't emit a change signal for nothing
608 if (d->oldImmutability != immutability()) {
610 }
611 d->oldImmutability = immutability();
612 }
613
614 // now take care of constraints in special subclass: Containment
616 if (containment) {
617 containment->d->containmentConstraintsEvent(c);
618 }
619
620 // pass the constraint on to the actual subclass
621 constraintsEvent(c);
622
624 // start up is done, we can now go do a mod timer
625 if (d->modificationsTimer) {
626 if (d->modificationsTimer->isActive()) {
627 d->modificationsTimer->stop();
628 }
629 } else {
630 d->modificationsTimer = new QBasicTimer;
631 }
632 }
633
634 if (c & FormFactorConstraint) {
636 }
637
638 if (c & LocationConstraint) {
640 }
641}
642
644{
645 return d->contextualActions;
646}
647
648QQmlListProperty<QAction> Applet::qmlContextualActions()
649{
650 return QQmlListProperty<QAction>(this,
651 nullptr,
652 AppletPrivate::contextualActions_append,
653 AppletPrivate::contextualActions_count,
654 AppletPrivate::contextualActions_at,
655 AppletPrivate::contextualActions_clear,
656 AppletPrivate::contextualActions_replace,
657 AppletPrivate::contextualActions_removeLast);
658}
660void Applet::setInternalAction(const QString &name, QAction *action)
661{
662 if (name.isEmpty()) {
663 return;
664 }
665
666 action->setObjectName(name);
667 QAction *oldAction = d->actions.value(name);
668 if (oldAction && QJSEngine::objectOwnership(oldAction) == QJSEngine::CppOwnership) {
669 delete oldAction;
670 }
671
672 d->actions[name] = action;
673
674 QObject::connect(action, &QObject::destroyed, this, [this, name]() {
675 d->actions.remove(name);
676 Q_EMIT internalActionsChanged(d->actions.values());
677 });
678
679 Q_EMIT internalActionsChanged(d->actions.values());
680}
682QAction *Applet::internalAction(const QString &name) const
683{
684 return d->actions.value(name);
685}
688{
689 QAction *action = d->actions.value(name);
690
691 if (action && QJSEngine::objectOwnership(action) == QJSEngine::CppOwnership) {
692 disconnect(action, &QObject::destroyed, this, nullptr); // Avoid emitting signal again
693 delete action;
694 }
695
696 d->actions.remove(name);
697
698 Q_EMIT internalActionsChanged(d->actions.values());
699}
702{
703 return d->actions.values();
704}
707{
708 Containment *c = containment();
709
710 if (!c) {
712 }
713
714 // Let's try to return the higher level formfactor in case of
715 // nested containments.
716 // c->containment() is guaranteed to exist except during teardown.
717 // if c is a toplevel containment,
718 // c == c->containment() else if is a nested one, it will be containment's
719 // containment
720 Containment *topC = c->containment();
721 if (topC) {
722 return topC->d->formFactor;
723 }
724 return c->d->formFactor;
725}
727Types::ContainmentDisplayHints Applet::containmentDisplayHints() const
728{
729 Containment *c = containment();
730
731 return c ? c->d->containmentDisplayHints : Plasma::Types::NoContainmentDisplayHint;
732}
734Containment *Applet::containment() const
735{
736 Containment *c = qobject_cast<Containment *>(const_cast<Applet *>(this));
738 return c;
739 } else {
740 c = nullptr;
741 }
742
743 QObject *parent = this->parent();
744
745 while (parent) {
746 Containment *possibleC = qobject_cast<Containment *>(parent);
747
748 if (possibleC && possibleC->isContainment()) {
749 c = possibleC;
750 break;
751 }
752 parent = parent->parent();
753 }
754
755 return c;
756}
758void Applet::setGlobalShortcut(const QKeySequence &shortcut)
759{
760 if (!d->activationAction) {
761 d->activationAction = new QAction(this);
762 d->activationAction->setText(i18n("Activate %1 Widget", title()));
763 d->activationAction->setObjectName(QStringLiteral("activate widget %1").arg(id())); // NO I18N
764 connect(d->activationAction, &QAction::triggered, this, &Applet::activated);
765 connect(KGlobalAccel::self(), &KGlobalAccel::globalShortcutChanged, this, [this](QAction *action, const QKeySequence &shortcut) {
766 if (action == d->activationAction) {
767 d->activationAction->setShortcut(shortcut);
768 d->globalShortcutChanged();
769 }
770 });
771 } else if (d->activationAction->shortcut() == shortcut) {
772 return;
773 }
774
775 d->activationAction->setShortcut(shortcut);
776 d->globalShortcutEnabled = true;
777 QList<QKeySequence> seqs{shortcut};
778 KGlobalAccel::self()->setShortcut(d->activationAction, seqs, KGlobalAccel::NoAutoloading);
779 d->globalShortcutChanged();
780
782}
785{
786 if (d->activationAction) {
787 QList<QKeySequence> shortcuts = KGlobalAccel::self()->shortcut(d->activationAction);
788 if (!shortcuts.isEmpty()) {
789 return shortcuts.first();
790 }
791 }
792
793 return QKeySequence();
794}
797{
798 Containment *c = containment();
799
800 if (!c) {
802 }
803
804 // Let's try to return the higher level location in case of
805 // nested containments.
806 // c->containment() is guaranteed to exist except during teardown.
807 // if c is a toplevel containment,
808 // c == c->containment() else if is a nested one, it will be containment's
809 // containment
810 Containment *topC = c->containment();
811 if (topC) {
812 return topC->d->location;
813 }
814 return c->d->location;
815}
818{
819 return d->hasConfigurationInterface;
820}
822void Applet::setHasConfigurationInterface(bool hasInterface)
823{
824 if (hasInterface == d->hasConfigurationInterface) {
825 return;
826 }
827
828 QAction *configAction = d->actions.value(QStringLiteral("configure"));
829 if (configAction) {
830 bool enable = hasInterface;
831 if (enable) {
832 const bool unlocked = immutability() == Types::Mutable;
833 enable = unlocked || KAuthorized::authorize(QStringLiteral("plasma/allow_configure_when_locked"));
834 }
835 configAction->setEnabled(enable);
836 }
837
838 d->hasConfigurationInterface = hasInterface;
840}
843{
844 if (d->configLoader) {
845 d->configLoader->load();
846 }
847}
848
849QUrl Applet::fileUrl(const QByteArray &key, const QString &filename) const
850{
851 if (d->package.isValid()) {
852 return d->package.fileUrl(key, filename);
853 } else {
854 return QUrl(QLatin1String("qrc") + qrcPath() + filename);
855 }
856}
857
858QUrl Applet::mainScript() const
859{
860 const QString path = qrcPath() + QLatin1String("main.qml");
861
862 if (QFile::exists(path)) {
863 return QUrl(QLatin1String("qrc") + path);
864 }
865
866 if (d->package.isValid()) {
867 return d->package.fileUrl("mainscript");
868 }
869 return QUrl();
870}
871
872QUrl Applet::configModel() const
873{
874 if (d->package.isValid()) {
875 return d->package.fileUrl("configmodel");
876 } else {
877 const QString path = qrcPath() + QLatin1String("config.qml");
878 if (QFile::exists(path)) {
879 return QUrl(QLatin1String("qrc") + path);
880 }
881 }
882
883 return QUrl();
884}
885
886bool Applet::sourceValid() const
887{
888 if (QFile::exists(qrcPath())) {
889 return QFile::exists(qrcPath() + QLatin1String("main.qml"));
890 }
891
892 return d->package.isValid();
893}
896{
897 if (d->transient) {
898 d->constraintsTimer.stop();
899 if (d->modificationsTimer) {
900 d->modificationsTimer->stop();
901 }
902 return;
903 }
904
905 if (event->timerId() == d->constraintsTimer.timerId()) {
906 d->constraintsTimer.stop();
907
908 // Don't flushPendingConstraints if we're just starting up
909 // flushPendingConstraints will be called by Corona
910 if (!(d->pendingConstraints & StartupCompletedConstraint)) {
912 }
913 } else if (d->modificationsTimer && event->timerId() == d->modificationsTimer->timerId()) {
914 d->modificationsTimer->stop();
915 // invalid group, will result in save using the default group
916 KConfigGroup cg;
917
918 save(cg);
920 }
921}
923bool Applet::isContainment() const
924{
925 // normal "acting as a containment" condition
926 const Containment *cont = qobject_cast<const Containment *>(this);
927 if (!cont) {
928 return false;
929 }
930 return qobject_cast<Corona *>(parent()) || cont->containmentType() == Containment::CustomEmbedded;
931}
934{
935 const QString rootPath = d->appletDescription.value(u"X-Plasma-RootPath");
936 if (!rootPath.isEmpty()) {
937 return QLatin1String("plasma_applet_") + rootPath;
938 } else {
939 return QLatin1String("plasma_applet_") + d->appletDescription.pluginId();
940 }
941}
942
943QString Applet::qrcPath() const
944{
945 return QLatin1String(":/qt/qml/plasma/applet/") + pluginName().replace(QLatin1Char('.'), QLatin1Char('/')) + QLatin1String("/");
946}
947
948} // Plasma namespace
949
950#include "moc_applet.cpp"
static Q_INVOKABLE bool authorize(const QString &action)
QString readEntryUntranslated(const char *key, const QString &aDefault=QString()) const
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
bool isValid() const
KConfig * config()
QString readEntry(const char *key, const char *aDefault=nullptr) const
void copyTo(KConfigBase *other, WriteConfigFlags pFlags=Normal) const
QString name() const
static KGlobalAccel * self()
bool setShortcut(QAction *action, const QList< QKeySequence > &shortcut, GlobalShortcutLoading loadFlag=Autoloading)
QList< QKeySequence > shortcut(const QAction *action) const
void globalShortcutChanged(QAction *action, const QKeySequence &seq)
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
bool isUserConfiguring() const
Definition applet.cpp:523
uint id
Applet id: is unique in the whole Plasma session and will never change across restarts.
Definition applet.h:69
void updateConstraints(Constraints constraints=AllConstraints)
Called when any of the geometry constraints have been updated.
Definition applet.cpp:285
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:102
Plasma::Types::ContainmentDisplayHints containmentDisplayHints
Display hints that come from the containment that suggest the applet how to look and behave.
Definition applet.h:119
QQmlListProperty< QAction > contextualActions
Actions to be added in the plasmoid context menu.
Definition applet.h:195
QKeySequence globalShortcut
The global shortcut to activate the plasmoid.
Definition applet.h:162
void setHasConfigurationInterface(bool hasInterface)
Sets whether or not this applet provides a user interface for configuring the applet.
Definition applet.cpp:821
Plasma::Types::Location location
The location of the scene which is displaying applet.
Definition applet.h:95
Q_INVOKABLE void removeInternalAction(const QString &name)
Removes an action from the internal actions.
Definition applet.cpp:686
void setStatus(const Types::ItemStatus stat)
sets the status for this applet
Definition applet.cpp:543
Q_INVOKABLE QAction * internalAction(const QString &name) const
Definition applet.cpp:681
KConfigGroup config() const
Returns the KConfigGroup to access the applets configuration.
Definition applet.cpp:189
bool failedToLaunch() const
If for some reason, the applet fails to get up on its feet (the library couldn't be loaded,...
Definition applet.cpp:481
void titleChanged(const QString &title)
Emitted when the title has changed.
Plasma::Types::BackgroundHints backgroundHints
How the applet wants its background to be drawn.
Definition applet.h:135
void constraintHintsChanged(Plasma::Applet::ConstraintHints constraintHints)
Emitted when the constraint hints changed.
Plasma::Types::BackgroundHints userBackgroundHints
The containment (and/or the user) may decide to use another kind of background instead (if supported ...
Definition applet.h:140
void setUserBackgroundHints(Plasma::Types::BackgroundHints hint)
Sets the hints the user wished the background style for the applet to be.
Definition applet.cpp:389
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:496
void internalActionsChanged(const QList< QAction * > &actions)
Emitted when the list of internal actions has changed.
@ NoConstraint
No constraint; never passed in to Applet::constraintsEvent on its own.
Definition applet.h:214
@ StartupCompletedConstraint
application startup has completed
Definition applet.h:219
@ UiReadyConstraint
The ui has been completely loaded.
Definition applet.h:220
@ ImmutableConstraint
the immutability (locked) nature of the applet changed
Definition applet.h:218
@ FormFactorConstraint
The FormFactor for an object.
Definition applet.h:215
@ LocationConstraint
The Location of an object.
Definition applet.h:216
void destroy()
Destroys the applet; it will be removed nicely and deleted.
Definition applet.cpp:222
Applet::ConstraintHints constraintHints
The hints that the applet gives to its constraint, such as asking to fill all the available space ign...
Definition applet.h:179
bool isContainment
True if this applet is a Containment and is acting as one, such as a desktop or a panel.
Definition applet.h:200
Plasma::Types::ImmutabilityType immutability
The immutability of the Corona.
Definition applet.h:106
QString translationDomain() const
The translation domain for this applet.
Definition applet.cpp:932
void globalShortcutChanged(const QKeySequence &sequence)
Emitted when the global shortcut to activate this applet has chanaged.
void effectiveBackgroundHintsChanged()
Emitted when the effective background hints have changed.
void setTitle(const QString &title)
Sets a custom title for this instance of the applet.
Definition applet.cpp:314
void configNeedsSaving()
Emitted when an applet has changed values in its configuration and wishes for them to be saved at the...
void activated()
Emitted when activation is requested due to, for example, a global keyboard shortcut.
virtual void init()
This method is called once the applet is loaded and added to a Corona.
Definition applet.cpp:87
void setIcon(const QString &icon)
Sets an icon name for this applet.
Definition applet.cpp:329
virtual void configChanged()
Called when applet configuration values have changed.
Definition applet.cpp:841
void setUserConfiguring(bool configuring)
Tells the applet the user is configuring.
Definition applet.cpp:528
void hasConfigurationInterfaceChanged(bool hasConfiguration)
Emitted when the applet gains or loses the ability to show a configuration interface.
void setGlobalShortcut(const QKeySequence &shortcut=QKeySequence())
Sets the global shortcut to associate with this widget.
Definition applet.cpp:757
QString icon
Icon to represent the plasmoid.
Definition applet.h:79
void setConstraintHints(ConstraintHints constraintHints)
Sets the constraint hits which give a more granular control over sizing in constrained layouts such a...
Definition applet.cpp:508
void statusChanged(Plasma::Types::ItemStatus status)
Emitted when the applet status changes.
bool immutable
Whether the Corona is immutable.
Definition applet.h:113
void timerEvent(QTimerEvent *event) override
Reimplemented from QObject.
Definition applet.cpp:894
bool busy
True if the applet should show a busy status, for instance doing some network operation.
Definition applet.h:125
KConfigPropertyMap * configuration
A KConfigPropertyMap instance that represents the configuration which is usable from QML to read and ...
Definition applet.h:154
Plasma::Types::FormFactor formFactor
The current form factor the applet is being displayed in.
Definition applet.h:88
KConfigGroup globalConfig() const
Returns a KConfigGroup object to be shared by all applets of this type.
Definition applet.cpp:202
bool isBusy() const
Definition applet.cpp:339
void setLaunchErrorMessage(const QString &reason=QString())
Call this method when the applet fails to launch properly.
Definition applet.cpp:169
QString configurationRequiredReason() const
Definition applet.cpp:491
Q_INVOKABLE void setInternalAction(const QString &name, QAction *action)
Add a new internal action.
Definition applet.cpp:659
void iconChanged(const QString &icon)
Emitted when the icon name for the applet has changed.
QString pluginName
Plugin name for the applet.
Definition applet.h:205
void busyChanged(bool busy)
Emitted when the busy status has changed.
QList< QAction * > internalActions() const
Definition applet.cpp:700
bool destroyed() const
Definition applet.cpp:243
virtual void saveState(KConfigGroup &config) const
When called, the Applet should write any information needed as part of the Applet's running state to ...
Definition applet.cpp:179
Plasma::Types::ItemStatus status
Status of the plasmoid: useful to instruct the shell if this plasmoid is requesting attention,...
Definition applet.h:100
QString title
User friendly title for the plasmoid: it's the localized applet name by default.
Definition applet.h:74
void immutabilityChanged(Plasma::Types::ImmutabilityType immutable)
Emitted when the immutability changes.
void setBusy(bool busy)
Sets the Applet to have a busy status hint, for instance the applet doing some network operation.
Definition applet.cpp:344
void setImmutability(const Types::ImmutabilityType immutable)
Sets the immutability type for this applet (not immutable, user immutable or system immutable)
Definition applet.cpp:457
void setBackgroundHints(Plasma::Types::BackgroundHints hint)
Sets the applet background hints.
Definition applet.cpp:359
Plasma::Containment * containment
The Containment managing this applet.
Definition applet.h:189
void backgroundHintsChanged()
Emitted when the background hints have changed.
void configurationRequiredChanged(bool needsConfig, const QString &reason)
Emitted when setConfigurationRequired was called.
Plasma::Types::BackgroundHints effectiveBackgroundHints
The effective background hints the applet has, internally decided how to mix with userBackgroundHints...
Definition applet.h:145
void formFactorChanged(Plasma::Types::FormFactor formFactor)
Emitted when the formfactor changes.
QVariantList startupArguments() const
Definition applet.cpp:97
void flushPendingConstraintsEvents()
Sends all pending constraints updates to the applet.
Definition applet.cpp:552
Applet(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args)
This constructor can be used with the KCoreAddons plugin loading system.
Definition applet.cpp:41
void locationChanged(Plasma::Types::Location location)
Emitted when the location changes.
void userConfiguringChanged(bool configuring)
emitted when the config ui appears or disappears
KPluginMetaData pluginMetaData() const
Definition applet.cpp:410
bool configurationRequired
If true the applet requires manual configuration from the user TODO KF6: having just a reason propert...
Definition applet.h:168
KConfigLoader * configScheme() const
Returns the config skeleton object from this applet's package, if any.
Definition applet.cpp:248
bool hasConfigurationInterface
True if this applet will provide a UI for its configuration.
Definition applet.h:173
void userBackgroundHintsChanged()
Emitted when the user background hints have changed.
QString launchErrorMessage() const
If for some reason, the applet fails to get up on its feet (the library couldn't be loaded,...
Definition applet.cpp:476
virtual void restore(KConfigGroup &group)
Restores state information about this applet saved previously in save(KConfigGroup&).
Definition applet.cpp:135
@ CustomEmbedded
A customized containment embedded in another applet.
Plasma::Containment::Type containmentType
Type of this containment.
Definition containment.h:64
KSharedConfig::Ptr config() const
Returns the config file used to store the configuration for this Corona.
Definition corona.cpp:230
Types::ImmutabilityType immutability() const
Definition corona.cpp:282
ImmutabilityType
Defines the immutability of items like applets, corona and containments they can be free to modify,...
Definition plasma.h:99
@ SystemImmutable
the item is locked down by the system, the user can't unlock it
Definition plasma.h:103
@ Mutable
The item can be modified in any way.
Definition plasma.h:100
ItemStatus
Status of an applet.
Definition plasma.h:112
BackgroundHints
Description on how draw a background for the applet.
Definition plasma.h:127
Location
The Location enumeration describes where on screen an element, such as an Applet or its managing cont...
Definition plasma.h:81
@ Desktop
On the planar desktop layer, extending across the full screen from edge to edge.
Definition plasma.h:84
FormFactor
The FormFactor enumeration describes how a Plasma::Applet should arrange itself.
Definition plasma.h:40
@ Planar
The applet lives in a plane and has two degrees of freedom to grow.
Definition plasma.h:41
QString i18n(const char *text, const TYPE &arg...)
QString path(const QString &relativePath)
Namespace for everything in libplasma.
void setEnabled(bool)
void triggered(bool checked)
void setVisible(bool)
const char * constData() const const
bool exists(const QString &fileName)
bool exists() const const
ObjectOwnership objectOwnership(QObject *object)
T & first()
bool isEmpty() const const
QMetaEnum fromType()
int keyToValue(const char *key, bool *ok) const const
const char * valueToKey(int value) const const
QObject(QObject *parent)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
bool disconnect(const QMetaObject::Connection &connection)
virtual bool event(QEvent *e)
QObject * parent() const const
T qobject_cast(QObject *object)
void setObjectName(QAnyStringView name)
void valueChanged(const QString &key, const QVariant &value)
bool isEmpty() const const
UniqueConnection
QVariant fromValue(T &&value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri May 2 2025 11:55:47 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.