2008-11-03 23:08:39 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2007 by Aaron Seigo <aseigo@kde.org>
|
|
|
|
* Copyright 2008 by Ménard Alexis <darktears31@gmail.com>
|
2009-08-17 22:31:18 +00:00
|
|
|
* Copyright 2009 Chani Armitage <chani@kde.org>
|
2012-07-17 14:21:45 +02:00
|
|
|
* Copyright 2012 Marco Martin <notmart@kde.org>
|
2008-11-03 23:08:39 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Library General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this program; if not, write to the
|
|
|
|
* Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "containment.h"
|
|
|
|
#include "private/containment_p.h"
|
|
|
|
|
2010-10-14 12:27:15 +00:00
|
|
|
#include "config-plasma.h"
|
|
|
|
|
2009-05-05 05:19:35 +00:00
|
|
|
#include <QClipboard>
|
2013-03-07 21:25:30 +01:00
|
|
|
#include <QDebug>
|
2008-11-03 23:08:39 +00:00
|
|
|
#include <QFile>
|
2012-09-25 21:35:53 +02:00
|
|
|
#include <QContextMenuEvent>
|
2008-11-03 23:08:39 +00:00
|
|
|
#include <QMimeData>
|
|
|
|
#include <QPainter>
|
2011-10-04 16:50:44 +02:00
|
|
|
#include <qtemporaryfile.h>
|
2013-02-19 13:00:57 +01:00
|
|
|
#include <qmimedatabase.h>
|
2008-11-03 23:08:39 +00:00
|
|
|
|
2013-07-29 19:05:59 +02:00
|
|
|
#include <QDebug>
|
2013-09-16 16:16:21 +02:00
|
|
|
#include <kauthorized.h>
|
2013-02-11 21:38:18 +01:00
|
|
|
#include <klocalizedstring.h>
|
2014-04-26 14:29:54 +02:00
|
|
|
#include <KConfigSkeleton>
|
|
|
|
#include <KConfigLoader>
|
2012-06-12 12:59:34 +02:00
|
|
|
|
2012-08-24 03:16:04 +02:00
|
|
|
#if !PLASMA_NO_KIO
|
Make dropping remote content onto Plasma work
The idea is that you drop a file from a webpage, or basically a URL onto Plasma and Plasma creates a suitable applet to display this URL. For example an image frame for picture, or a previewer for pdf files. Downloading the data itself (and possibly saving it) is left to the applets. The mimetype needs to be retrieved as it cannot be determined from the URL.
The code pathes I've changed or added are, roughly:
- "something" is dropped onto Plasma
- if it's a remote URL, we don't know the mimetype of the object behind the URL yet
- a KIO::TransferJob is used to retrieve the mimetype asynchronously, and will call back
- we open a QMenu that says "Fetching file type..."
- If the user closes the menu while the mimetype is being retrieved, we will open a new one
- When the TransferJob calls back, and we have our mimetype, we offer a list of applets suitable for this kind of content
- If the user chooses to create an applet, we put the transfer job on hold to make it available for recycling by the applet
- If the user dismisses the offering, we kill the job
Thanks to marco for reviewing and everybody else for the input :)
Next steps are making some more applets work with this.
CCMAIL:plasma-devel@kde.org
svn path=/trunk/KDE/kdelibs/; revision=1009004
2009-08-08 22:01:16 +00:00
|
|
|
#include "kio/jobclasses.h" // for KIO::JobFlags
|
|
|
|
#include "kio/job.h"
|
|
|
|
#include "kio/scheduler.h"
|
2010-10-14 12:27:15 +00:00
|
|
|
#endif
|
2008-11-03 23:08:39 +00:00
|
|
|
|
2009-08-17 22:31:32 +00:00
|
|
|
#include "containmentactions.h"
|
2008-11-03 23:08:39 +00:00
|
|
|
#include "corona.h"
|
2011-07-19 21:40:57 +02:00
|
|
|
#include "pluginloader.h"
|
2015-12-15 16:56:40 -05:00
|
|
|
#include "debug_p.h"
|
2008-11-03 23:08:39 +00:00
|
|
|
|
|
|
|
#include "private/applet_p.h"
|
|
|
|
|
2009-12-16 22:33:30 +00:00
|
|
|
#include "plasma/plasma.h"
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
namespace Plasma
|
|
|
|
{
|
|
|
|
|
2012-09-24 17:18:55 +02:00
|
|
|
Containment::Containment(QObject *parent,
|
2008-11-03 23:08:39 +00:00
|
|
|
const QString &serviceId,
|
|
|
|
uint containmentId)
|
|
|
|
: Applet(parent, serviceId, containmentId),
|
|
|
|
d(new ContainmentPrivate(this))
|
|
|
|
{
|
|
|
|
// WARNING: do not access config() OR globalConfig() in this method!
|
|
|
|
// that requires a scene, which is not available at this point
|
2013-05-10 19:29:13 +02:00
|
|
|
setContainmentType(Types::CustomContainment);
|
2013-02-28 16:33:44 +01:00
|
|
|
setHasConfigurationInterface(true);
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Containment::Containment(QObject *parent, const QVariantList &args)
|
|
|
|
: Applet(parent, args),
|
|
|
|
d(new ContainmentPrivate(this))
|
|
|
|
{
|
|
|
|
// WARNING: do not access config() OR globalConfig() in this method!
|
|
|
|
// that requires a scene, which is not available at this point
|
2013-02-28 16:33:44 +01:00
|
|
|
setHasConfigurationInterface(true);
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-02-25 17:20:29 +01:00
|
|
|
Containment::Containment(const QString &packagePath, uint appletId)
|
|
|
|
: Applet(packagePath, appletId),
|
2009-10-23 13:48:29 +00:00
|
|
|
d(new ContainmentPrivate(this))
|
|
|
|
{
|
|
|
|
// WARNING: do not access config() OR globalConfig() in this method!
|
|
|
|
// that requires a scene, which is not available at this point
|
2013-02-28 16:33:44 +01:00
|
|
|
setHasConfigurationInterface(true);
|
2009-10-23 13:48:29 +00:00
|
|
|
}
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
Containment::~Containment()
|
|
|
|
{
|
2014-07-17 17:30:03 +02:00
|
|
|
qDeleteAll(d->localActionPlugins);
|
2012-10-10 19:09:29 +02:00
|
|
|
delete d;
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Containment::init()
|
|
|
|
{
|
2010-05-04 03:50:11 +00:00
|
|
|
Applet::init();
|
2016-06-15 11:00:57 +02:00
|
|
|
static_cast<Applet *>(this)->d->setupScripting();
|
2008-11-03 23:08:39 +00:00
|
|
|
|
2013-05-10 19:29:13 +02:00
|
|
|
if (d->type == Types::NoContainmentType) {
|
|
|
|
//setContainmentType(Plasma::Types::DesktopContainment);
|
2013-03-07 21:25:30 +01:00
|
|
|
//Try to determine the containment type. It must be done as soon as possible
|
2016-02-29 00:08:05 +01:00
|
|
|
QString type = pluginInfo().property(QStringLiteral("X-Plasma-ContainmentType")).toString();
|
2013-03-07 21:25:30 +01:00
|
|
|
|
2015-11-27 20:03:48 +00:00
|
|
|
if (type == QLatin1String("Panel")) {
|
2013-05-10 19:29:13 +02:00
|
|
|
setContainmentType(Plasma::Types::PanelContainment);
|
2015-11-27 20:03:48 +00:00
|
|
|
} else if (type == QLatin1String("Custom")) {
|
2013-05-10 19:29:13 +02:00
|
|
|
setContainmentType(Plasma::Types::CustomContainment);
|
2015-11-27 20:03:48 +00:00
|
|
|
} else if (type == QLatin1String("CustomPanel")) {
|
2013-05-10 19:29:13 +02:00
|
|
|
setContainmentType(Plasma::Types::CustomPanelContainment);
|
2014-04-26 01:45:47 +02:00
|
|
|
//default to desktop
|
2013-03-07 21:25:30 +01:00
|
|
|
} else {
|
2013-05-10 19:29:13 +02:00
|
|
|
setContainmentType(Plasma::Types::DesktopContainment);
|
2013-03-07 21:25:30 +01:00
|
|
|
}
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2009-05-03 20:22:14 +00:00
|
|
|
//connect actions
|
2013-02-25 16:31:26 +01:00
|
|
|
ContainmentPrivate::addDefaultActions(actions(), this);
|
2013-05-10 19:29:13 +02:00
|
|
|
bool unlocked = immutability() == Types::Mutable;
|
2008-11-03 23:08:39 +00:00
|
|
|
|
2013-02-12 11:30:25 +01:00
|
|
|
//fix the text of the actions that need title()
|
|
|
|
//btw, do we really want to use title() when it's a desktopcontainment?
|
2015-11-27 20:03:48 +00:00
|
|
|
QAction *closeApplet = actions()->action(QStringLiteral("remove"));
|
2009-06-10 04:51:24 +00:00
|
|
|
if (closeApplet) {
|
2013-02-12 11:30:25 +01:00
|
|
|
closeApplet->setText(i18nc("%1 is the name of the applet", "Remove this %1", title()));
|
2009-06-10 04:51:24 +00:00
|
|
|
}
|
|
|
|
|
2015-11-27 20:03:48 +00:00
|
|
|
QAction *configAction = actions()->action(QStringLiteral("configure"));
|
2009-06-10 04:51:24 +00:00
|
|
|
if (configAction) {
|
2013-02-12 11:30:25 +01:00
|
|
|
configAction->setText(i18nc("%1 is the name of the applet", "%1 Settings", title()));
|
2009-06-10 04:51:24 +00:00
|
|
|
}
|
2009-05-03 20:22:14 +00:00
|
|
|
|
2015-11-27 20:03:48 +00:00
|
|
|
QAction *appletBrowserAction = actions()->action(QStringLiteral("add widgets"));
|
2009-06-10 04:51:24 +00:00
|
|
|
if (appletBrowserAction) {
|
|
|
|
appletBrowserAction->setVisible(unlocked);
|
|
|
|
appletBrowserAction->setEnabled(unlocked);
|
|
|
|
connect(appletBrowserAction, SIGNAL(triggered()), this, SLOT(triggerShowAddWidgets()));
|
|
|
|
}
|
2008-11-03 23:08:39 +00:00
|
|
|
|
2013-05-10 19:29:13 +02:00
|
|
|
if (immutability() != Types::SystemImmutable && corona()) {
|
2015-11-27 20:03:48 +00:00
|
|
|
QAction *lockDesktopAction = corona()->actions()->action(QStringLiteral("lock widgets"));
|
2009-03-10 19:52:50 +00:00
|
|
|
//keep a pointer so nobody notices it moved to corona
|
|
|
|
if (lockDesktopAction) {
|
2016-02-29 00:08:05 +01:00
|
|
|
actions()->addAction(QStringLiteral("lock widgets"), lockDesktopAction);
|
2009-03-10 19:52:50 +00:00
|
|
|
}
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
2014-05-07 13:08:55 +02:00
|
|
|
|
|
|
|
//HACK: this is valid only in the systray case
|
|
|
|
connect(this, &Containment::configureRequested, [=] (Plasma::Applet *a) {
|
|
|
|
if (Plasma::Applet *p = qobject_cast<Plasma::Applet *>(parent())) {
|
|
|
|
emit p->containment()->configureRequested(a);
|
|
|
|
}
|
|
|
|
});
|
2009-05-03 20:22:14 +00:00
|
|
|
}
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
// helper function for sorting the list of applets
|
|
|
|
bool appletConfigLessThan(const KConfigGroup &c1, const KConfigGroup &c2)
|
|
|
|
{
|
2013-02-19 14:19:08 +01:00
|
|
|
int i1 = c1.readEntry("id", 0);
|
|
|
|
int i2 = c2.readEntry("id", 0);
|
2008-11-14 04:01:01 +00:00
|
|
|
|
2013-02-19 14:19:08 +01:00
|
|
|
return (i1 < i2);
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Containment::restore(KConfigGroup &group)
|
|
|
|
{
|
2011-07-29 15:46:52 +02:00
|
|
|
/*
|
2014-04-26 01:45:47 +02:00
|
|
|
#ifndef NDEBUG
|
2015-12-15 16:56:40 -05:00
|
|
|
// qCDebug(LOG_PLASMA) << "!!!!!!!!!!!!initConstraints" << group.name() << d->type;
|
|
|
|
// qCDebug(LOG_PLASMA) << " location:" << group.readEntry("location", (int)d->location);
|
|
|
|
// qCDebug(LOG_PLASMA) << " geom:" << group.readEntry("geometry", geometry());
|
|
|
|
// qCDebug(LOG_PLASMA) << " formfactor:" << group.readEntry("formfactor", (int)d->formFactor);
|
|
|
|
// qCDebug(LOG_PLASMA) << " screen:" << group.readEntry("screen", d->screen);
|
2014-04-26 01:45:47 +02:00
|
|
|
#endif
|
|
|
|
*/
|
2013-05-14 18:19:33 +02:00
|
|
|
setLocation((Plasma::Types::Location)group.readEntry("location", (int)d->location));
|
|
|
|
setFormFactor((Plasma::Types::FormFactor)group.readEntry("formfactor", (int)d->formFactor));
|
2013-10-16 21:01:39 +02:00
|
|
|
d->lastScreen = group.readEntry("lastScreen", d->lastScreen);
|
2013-08-08 17:59:30 +02:00
|
|
|
|
|
|
|
setWallpaper(group.readEntry("wallpaperplugin", ContainmentPrivate::defaultWallpaper));
|
2014-04-26 01:45:47 +02:00
|
|
|
|
2011-05-20 09:41:19 +02:00
|
|
|
d->activityId = group.readEntry("activityId", QString());
|
2008-11-03 23:08:39 +00:00
|
|
|
|
|
|
|
flushPendingConstraintsEvents();
|
|
|
|
restoreContents(group);
|
2013-05-14 20:27:32 +02:00
|
|
|
setImmutability((Types::ImmutabilityType)group.readEntry("immutability", (int)Types::Mutable));
|
2008-11-03 23:08:39 +00:00
|
|
|
|
2014-04-14 14:03:49 +02:00
|
|
|
if (isContainment()) {
|
|
|
|
KConfigGroup cfg = KConfigGroup(corona()->config(), "ActionPlugins");
|
|
|
|
cfg = KConfigGroup(&cfg, QString::number(containmentType()));
|
|
|
|
|
2015-12-15 16:56:40 -05:00
|
|
|
//qCDebug(LOG_PLASMA) << cfg.keyList();
|
2014-04-14 14:03:49 +02:00
|
|
|
if (cfg.exists()) {
|
|
|
|
foreach (const QString &key, cfg.keyList()) {
|
2015-12-15 16:56:40 -05:00
|
|
|
//qCDebug(LOG_PLASMA) << "loading" << key;
|
2014-04-14 14:03:49 +02:00
|
|
|
setContainmentActions(key, cfg.readEntry(key, QString()));
|
|
|
|
}
|
|
|
|
} else { //shell defaults
|
|
|
|
KConfigGroup defaultActionsCfg;
|
|
|
|
if (d->type == Plasma::Types::PanelContainment) {
|
|
|
|
defaultActionsCfg = KConfigGroup(KSharedConfig::openConfig(corona()->package().filePath("defaults")), "Panel");
|
2014-04-26 01:45:47 +02:00
|
|
|
//Plasma::Types::DesktopContainment
|
2014-04-14 14:03:49 +02:00
|
|
|
} else {
|
|
|
|
defaultActionsCfg = KConfigGroup(KSharedConfig::openConfig(corona()->package().filePath("defaults")), "Desktop");
|
|
|
|
}
|
|
|
|
defaultActionsCfg = KConfigGroup(&defaultActionsCfg, "ContainmentActions");
|
|
|
|
|
|
|
|
foreach (const QString &key, defaultActionsCfg.keyList()) {
|
|
|
|
setContainmentActions(key, defaultActionsCfg.readEntry(key, QString()));
|
|
|
|
}
|
2010-11-11 22:22:39 +00:00
|
|
|
}
|
2009-08-17 22:30:42 +00:00
|
|
|
}
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
/*
|
2014-04-26 01:45:47 +02:00
|
|
|
#ifndef NDEBUG
|
2015-12-15 16:56:40 -05:00
|
|
|
// qCDebug(LOG_PLASMA) << "Containment" << id() <<
|
2014-04-26 01:45:47 +02:00
|
|
|
#endif
|
2008-11-03 23:08:39 +00:00
|
|
|
"screen" << screen() <<
|
|
|
|
"geometry is" << geometry() <<
|
|
|
|
"config entries" << group.entryMap();
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void Containment::save(KConfigGroup &g) const
|
|
|
|
{
|
2009-01-22 00:00:16 +00:00
|
|
|
if (Applet::d->transient) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
KConfigGroup group = g;
|
|
|
|
if (!group.isValid()) {
|
|
|
|
group = config();
|
|
|
|
}
|
|
|
|
|
|
|
|
// locking is saved in Applet::save
|
|
|
|
Applet::save(group);
|
2010-05-13 21:40:02 +00:00
|
|
|
|
2013-12-12 17:10:36 +01:00
|
|
|
// group.writeEntry("screen", d->screen);
|
2013-10-16 21:01:39 +02:00
|
|
|
group.writeEntry("lastScreen", d->lastScreen);
|
2008-11-03 23:08:39 +00:00
|
|
|
group.writeEntry("formfactor", (int)d->formFactor);
|
|
|
|
group.writeEntry("location", (int)d->location);
|
2011-05-20 09:41:19 +02:00
|
|
|
group.writeEntry("activityId", d->activityId);
|
2010-07-31 13:02:07 +00:00
|
|
|
|
2012-11-21 15:26:59 +01:00
|
|
|
group.writeEntry("wallpaperplugin", d->wallpaper);
|
2008-11-03 23:08:39 +00:00
|
|
|
|
|
|
|
saveContents(group);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Containment::saveContents(KConfigGroup &group) const
|
|
|
|
{
|
|
|
|
KConfigGroup applets(&group, "Applets");
|
|
|
|
foreach (const Applet *applet, d->applets) {
|
|
|
|
KConfigGroup appletConfig(&applets, QString::number(applet->id()));
|
|
|
|
applet->save(appletConfig);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Containment::restoreContents(KConfigGroup &group)
|
|
|
|
{
|
|
|
|
KConfigGroup applets(&group, "Applets");
|
|
|
|
|
2014-09-15 17:55:36 +02:00
|
|
|
//restore the applets ordered by id
|
|
|
|
QStringList groups = applets.groupList();
|
|
|
|
qSort(groups.begin(), groups.end());
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
// Sort the applet configs in order of geometry to ensure that applets
|
|
|
|
// are added from left to right or top to bottom for a panel containment
|
|
|
|
QList<KConfigGroup> appletConfigs;
|
2014-09-15 17:55:36 +02:00
|
|
|
foreach (const QString &appletGroup, groups) {
|
2015-12-15 16:56:40 -05:00
|
|
|
//qCDebug(LOG_PLASMA) << "reading from applet group" << appletGroup;
|
2008-11-03 23:08:39 +00:00
|
|
|
KConfigGroup appletConfig(&applets, appletGroup);
|
|
|
|
appletConfigs.append(appletConfig);
|
|
|
|
}
|
2008-11-14 04:01:01 +00:00
|
|
|
qStableSort(appletConfigs.begin(), appletConfigs.end(), appletConfigLessThan);
|
2008-11-03 23:08:39 +00:00
|
|
|
|
2008-11-05 23:14:47 +00:00
|
|
|
QMutableListIterator<KConfigGroup> it(appletConfigs);
|
|
|
|
while (it.hasNext()) {
|
|
|
|
KConfigGroup &appletConfig = it.next();
|
2008-11-03 23:08:39 +00:00
|
|
|
int appId = appletConfig.name().toUInt();
|
|
|
|
QString plugin = appletConfig.readEntry("plugin", QString());
|
|
|
|
|
|
|
|
if (plugin.isEmpty()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-02-28 13:32:47 +01:00
|
|
|
d->createApplet(plugin, QVariantList(), appId);
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
2014-07-15 10:16:10 +02:00
|
|
|
|
2016-02-29 00:08:05 +01:00
|
|
|
foreach (Applet *applet, Containment::applets()) {
|
2014-07-15 10:16:10 +02:00
|
|
|
if (!applet->pluginInfo().isValid()) {
|
|
|
|
applet->updateConstraints(Plasma::Types::UiReadyConstraint);
|
|
|
|
}
|
|
|
|
}
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-05-14 18:34:40 +02:00
|
|
|
Plasma::Types::ContainmentType Containment::containmentType() const
|
2008-11-03 23:08:39 +00:00
|
|
|
{
|
|
|
|
return d->type;
|
|
|
|
}
|
|
|
|
|
2013-05-14 18:34:40 +02:00
|
|
|
void Containment::setContainmentType(Plasma::Types::ContainmentType type)
|
2008-11-03 23:08:39 +00:00
|
|
|
{
|
|
|
|
if (d->type == type) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->type = type;
|
2013-09-10 12:43:25 +02:00
|
|
|
emit containmentTypeChanged();
|
2010-04-13 18:36:38 +00:00
|
|
|
}
|
2008-11-03 23:08:39 +00:00
|
|
|
|
|
|
|
Corona *Containment::corona() const
|
|
|
|
{
|
2014-06-17 16:02:08 +02:00
|
|
|
if(Plasma::Corona* corona = qobject_cast<Corona *>(parent())) {
|
|
|
|
return corona;
|
|
|
|
//case in which this containment is child of an applet, hello systray :)
|
|
|
|
} else {
|
|
|
|
Plasma::Applet *parentApplet = qobject_cast<Plasma::Applet *>(parent());
|
2016-08-25 17:48:56 +01:00
|
|
|
if (parentApplet && parentApplet->containment()) {
|
2014-06-17 16:02:08 +02:00
|
|
|
return parentApplet->containment()->corona();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-05-14 18:19:33 +02:00
|
|
|
void Containment::setFormFactor(Types::FormFactor formFactor)
|
2008-11-03 23:08:39 +00:00
|
|
|
{
|
|
|
|
if (d->formFactor == formFactor) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-15 16:56:40 -05:00
|
|
|
//qCDebug(LOG_PLASMA) << "switching FF to " << formFactor;
|
2008-11-03 23:08:39 +00:00
|
|
|
d->formFactor = formFactor;
|
|
|
|
|
2013-05-10 19:29:13 +02:00
|
|
|
updateConstraints(Plasma::Types::FormFactorConstraint);
|
2008-11-03 23:08:39 +00:00
|
|
|
|
|
|
|
KConfigGroup c = config();
|
|
|
|
c.writeEntry("formfactor", (int)formFactor);
|
|
|
|
emit configNeedsSaving();
|
2013-02-21 17:49:52 +01:00
|
|
|
emit formFactorChanged(formFactor);
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-05-14 18:19:33 +02:00
|
|
|
void Containment::setLocation(Types::Location location)
|
2008-11-03 23:08:39 +00:00
|
|
|
{
|
|
|
|
if (d->location == location) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->location = location;
|
|
|
|
|
|
|
|
foreach (Applet *applet, d->applets) {
|
2013-05-10 19:29:13 +02:00
|
|
|
applet->updateConstraints(Plasma::Types::LocationConstraint);
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-05-10 19:29:13 +02:00
|
|
|
updateConstraints(Plasma::Types::LocationConstraint);
|
2008-11-03 23:08:39 +00:00
|
|
|
|
|
|
|
KConfigGroup c = config();
|
|
|
|
c.writeEntry("location", (int)location);
|
|
|
|
emit configNeedsSaving();
|
2013-02-21 17:49:52 +01:00
|
|
|
emit locationChanged(location);
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-02-28 13:32:47 +01:00
|
|
|
Applet *Containment::createApplet(const QString &name, const QVariantList &args)
|
2008-11-03 23:08:39 +00:00
|
|
|
{
|
2015-10-13 14:24:29 +02:00
|
|
|
Plasma::Applet *applet = d->createApplet(name, args);
|
2015-12-21 14:58:14 +01:00
|
|
|
if (applet) {
|
|
|
|
emit appletCreated(applet);
|
|
|
|
}
|
2015-10-13 14:24:29 +02:00
|
|
|
return applet;
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-02-18 17:28:29 +01:00
|
|
|
void Containment::addApplet(Applet *applet)
|
2008-11-03 23:08:39 +00:00
|
|
|
{
|
|
|
|
if (!applet) {
|
2011-07-29 15:46:52 +02:00
|
|
|
#ifndef NDEBUG
|
2015-12-15 16:56:40 -05:00
|
|
|
// qCDebug(LOG_PLASMA) << "adding null applet!?!";
|
2011-07-29 15:46:52 +02:00
|
|
|
#endif
|
2008-11-03 23:08:39 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-03-20 22:04:53 +01:00
|
|
|
if (immutability() != Types::Mutable && !applet->property("org.kde.plasma:force-create").toBool()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
if (d->applets.contains(applet)) {
|
2011-07-29 15:46:52 +02:00
|
|
|
#ifndef NDEBUG
|
2015-12-15 16:56:40 -05:00
|
|
|
// qCDebug(LOG_PLASMA) << "already have this applet!";
|
2011-07-29 15:46:52 +02:00
|
|
|
#endif
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Containment *currentContainment = applet->containment();
|
|
|
|
|
|
|
|
if (currentContainment && currentContainment != this) {
|
|
|
|
emit currentContainment->appletRemoved(applet);
|
2009-05-13 18:11:08 +00:00
|
|
|
|
2008-11-25 03:07:18 +00:00
|
|
|
disconnect(applet, 0, currentContainment, 0);
|
2008-11-03 23:08:39 +00:00
|
|
|
KConfigGroup oldConfig = applet->config();
|
|
|
|
currentContainment->d->applets.removeAll(applet);
|
2010-12-16 20:08:16 +00:00
|
|
|
applet->setParent(this);
|
2008-11-03 23:08:39 +00:00
|
|
|
|
|
|
|
// now move the old config to the new location
|
2009-01-23 07:32:11 +00:00
|
|
|
//FIXME: this doesn't seem to get the actual main config group containing plugin=, etc
|
2008-11-03 23:08:39 +00:00
|
|
|
KConfigGroup c = config().group("Applets").group(QString::number(applet->id()));
|
|
|
|
oldConfig.reparent(&c);
|
|
|
|
applet->d->resetConfigurationObject();
|
2009-01-24 10:47:35 +00:00
|
|
|
|
2014-02-14 14:40:53 +01:00
|
|
|
disconnect(applet, SIGNAL(activated()), currentContainment, SIGNAL(activated()));
|
2014-04-10 20:41:34 +02:00
|
|
|
//change the group to its configloader, if any
|
|
|
|
//FIXME: this is very, very brutal
|
|
|
|
if (applet->configScheme()) {
|
|
|
|
const QString oldGroupPrefix = QString("Containments" + QString::number(currentContainment->id()) + "Applets");
|
|
|
|
const QString newGroupPrefix = QString("Containments" + QString::number(id()) + "Applets");
|
|
|
|
|
|
|
|
applet->configScheme()->setCurrentGroup(applet->configScheme()->currentGroup().replace(0, oldGroupPrefix.length(), newGroupPrefix));
|
|
|
|
|
|
|
|
foreach (KConfigSkeletonItem *item, applet->configScheme()->items()) {
|
|
|
|
item->setGroup(item->group().replace(0, oldGroupPrefix.length(), newGroupPrefix));
|
|
|
|
}
|
|
|
|
}
|
2008-11-03 23:08:39 +00:00
|
|
|
} else {
|
2010-12-16 20:08:16 +00:00
|
|
|
applet->setParent(this);
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2014-09-15 17:55:36 +02:00
|
|
|
//make sure the applets are sorted by id
|
|
|
|
auto position = std::lower_bound(d->applets.begin(), d->applets.end(), applet, [](Plasma::Applet *a1, Plasma::Applet *a2) {
|
|
|
|
return a1->id() < a2->id();
|
|
|
|
});
|
|
|
|
d->applets.insert(position, applet);
|
2008-11-03 23:08:39 +00:00
|
|
|
|
2014-07-14 13:23:20 +02:00
|
|
|
if (!d->uiReady) {
|
2013-08-09 21:51:13 +02:00
|
|
|
d->loadingApplets << applet;
|
|
|
|
}
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
connect(applet, SIGNAL(configNeedsSaving()), this, SIGNAL(configNeedsSaving()));
|
2013-02-15 18:07:38 +01:00
|
|
|
connect(applet, SIGNAL(appletDeleted(Plasma::Applet*)), this, SLOT(appletDeleted(Plasma::Applet*)));
|
2013-05-14 20:49:50 +02:00
|
|
|
connect(applet, SIGNAL(statusChanged(Plasma::Types::ItemStatus)), this, SLOT(checkStatus(Plasma::Types::ItemStatus)));
|
2014-02-14 14:40:53 +01:00
|
|
|
connect(applet, SIGNAL(activated()), this, SIGNAL(activated()));
|
2008-11-03 23:08:39 +00:00
|
|
|
|
2013-02-05 16:00:12 +01:00
|
|
|
if (!currentContainment) {
|
2013-02-13 21:38:47 +01:00
|
|
|
const bool isNew = applet->d->mainConfigGroup()->entryMap().isEmpty();
|
|
|
|
|
|
|
|
if (!isNew) {
|
|
|
|
applet->restore(*applet->d->mainConfigGroup());
|
|
|
|
}
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
applet->init();
|
2016-06-15 11:00:57 +02:00
|
|
|
applet->d->setupScripting();
|
2013-02-13 21:38:47 +01:00
|
|
|
|
|
|
|
if (isNew) {
|
|
|
|
applet->save(*applet->d->mainConfigGroup());
|
|
|
|
emit configNeedsSaving();
|
|
|
|
}
|
2011-11-17 14:40:53 +01:00
|
|
|
//FIXME: an on-appear animation would be nice to have again
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-05-10 19:29:13 +02:00
|
|
|
applet->updateConstraints(Plasma::Types::AllConstraints);
|
2013-02-05 16:00:12 +01:00
|
|
|
applet->flushPendingConstraintsEvents();
|
|
|
|
|
2013-02-18 17:28:29 +01:00
|
|
|
emit appletAdded(applet);
|
2008-12-12 01:05:00 +00:00
|
|
|
|
|
|
|
if (!currentContainment) {
|
2013-05-10 19:29:13 +02:00
|
|
|
applet->updateConstraints(Plasma::Types::StartupCompletedConstraint);
|
2013-02-05 16:00:12 +01:00
|
|
|
applet->flushPendingConstraintsEvents();
|
2008-12-12 01:05:00 +00:00
|
|
|
}
|
2010-03-06 01:41:18 +00:00
|
|
|
|
2013-02-05 16:00:12 +01:00
|
|
|
applet->d->scheduleModificationNotification();
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-02-12 11:02:22 +01:00
|
|
|
QList<Applet *> Containment::applets() const
|
2008-11-03 23:08:39 +00:00
|
|
|
{
|
|
|
|
return d->applets;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Containment::screen() const
|
|
|
|
{
|
2014-06-17 16:02:08 +02:00
|
|
|
Q_ASSERT(corona());
|
|
|
|
if (Corona* c = corona()) {
|
|
|
|
return c->screenForContainment(this);
|
2014-02-21 11:12:27 +01:00
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-10-16 21:01:39 +02:00
|
|
|
int Containment::lastScreen() const
|
|
|
|
{
|
|
|
|
return d->lastScreen;
|
|
|
|
}
|
|
|
|
|
2013-02-06 15:23:48 +01:00
|
|
|
void Containment::setWallpaper(const QString &pluginName)
|
2008-11-03 23:08:39 +00:00
|
|
|
{
|
2013-02-06 15:23:48 +01:00
|
|
|
if (pluginName != d->wallpaper) {
|
2012-11-21 15:26:59 +01:00
|
|
|
d->wallpaper = pluginName;
|
2008-11-03 23:08:39 +00:00
|
|
|
|
2013-02-06 15:23:48 +01:00
|
|
|
KConfigGroup cfg = config();
|
|
|
|
cfg.writeEntry("wallpaperplugin", d->wallpaper);
|
2008-11-03 23:08:39 +00:00
|
|
|
emit configNeedsSaving();
|
2013-02-06 15:23:48 +01:00
|
|
|
emit wallpaperChanged();
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-21 15:26:59 +01:00
|
|
|
QString Containment::wallpaper() const
|
2008-11-03 23:08:39 +00:00
|
|
|
{
|
|
|
|
return d->wallpaper;
|
|
|
|
}
|
|
|
|
|
2013-08-26 17:50:17 +02:00
|
|
|
void Containment::setContainmentActions(const QString &trigger, const QString &pluginName)
|
2009-08-17 22:30:34 +00:00
|
|
|
{
|
2013-02-18 20:12:31 +01:00
|
|
|
KConfigGroup cfg = d->containmentActionsConfig();
|
2009-08-17 22:31:32 +00:00
|
|
|
ContainmentActions *plugin = 0;
|
2009-08-17 22:30:34 +00:00
|
|
|
|
2015-03-24 12:05:21 +01:00
|
|
|
plugin = containmentActions().value(trigger);
|
|
|
|
if (plugin && plugin->pluginInfo().pluginName() != pluginName) {
|
|
|
|
containmentActions().remove(trigger);
|
|
|
|
delete plugin;
|
|
|
|
plugin = 0;
|
2009-08-17 22:30:34 +00:00
|
|
|
}
|
2012-11-09 18:55:03 +01:00
|
|
|
|
2009-08-17 22:30:34 +00:00
|
|
|
if (pluginName.isEmpty()) {
|
|
|
|
cfg.deleteEntry(trigger);
|
2009-08-17 22:31:32 +00:00
|
|
|
} else if (plugin) {
|
2013-08-26 21:22:06 +02:00
|
|
|
//it already existed, just reload config
|
|
|
|
plugin->setContainment(this); //to be safe
|
|
|
|
//FIXME make a truly unique config group
|
|
|
|
KConfigGroup pluginConfig = KConfigGroup(&cfg, trigger);
|
|
|
|
plugin->restore(pluginConfig);
|
|
|
|
|
2009-08-17 22:31:08 +00:00
|
|
|
} else {
|
2013-02-25 16:53:58 +01:00
|
|
|
plugin = PluginLoader::self()->loadContainmentActions(this, pluginName);
|
2012-11-09 18:55:03 +01:00
|
|
|
|
2009-08-17 22:31:32 +00:00
|
|
|
if (plugin) {
|
2009-08-17 22:31:08 +00:00
|
|
|
cfg.writeEntry(trigger, pluginName);
|
2013-02-19 12:03:53 +01:00
|
|
|
containmentActions().insert(trigger, plugin);
|
2013-08-14 15:13:35 +02:00
|
|
|
plugin->setContainment(this);
|
2013-08-26 21:22:06 +02:00
|
|
|
KConfigGroup pluginConfig = KConfigGroup(&cfg, trigger);
|
|
|
|
plugin->restore(pluginConfig);
|
2009-08-17 22:31:08 +00:00
|
|
|
} else {
|
|
|
|
//bad plugin... gets removed. is this a feature or a bug?
|
|
|
|
cfg.deleteEntry(trigger);
|
2009-08-17 22:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-17 22:30:42 +00:00
|
|
|
emit configNeedsSaving();
|
2009-08-17 22:30:34 +00:00
|
|
|
}
|
|
|
|
|
2014-04-26 01:45:47 +02:00
|
|
|
QHash<QString, ContainmentActions *> &Containment::containmentActions()
|
2009-08-17 22:30:38 +00:00
|
|
|
{
|
2013-02-25 15:58:31 +01:00
|
|
|
return d->localActionPlugins;
|
2009-08-17 22:30:38 +00:00
|
|
|
}
|
|
|
|
|
2013-08-09 21:51:13 +02:00
|
|
|
bool Containment::isUiReady() const
|
|
|
|
{
|
2014-07-15 10:16:10 +02:00
|
|
|
return d->uiReady && d->appletsUiReady && Applet::d->started;
|
2013-08-09 21:51:13 +02:00
|
|
|
}
|
|
|
|
|
2011-05-20 09:41:19 +02:00
|
|
|
void Containment::setActivity(const QString &activityId)
|
2008-11-03 23:08:39 +00:00
|
|
|
{
|
2013-02-18 18:54:44 +01:00
|
|
|
if (activityId.isEmpty() || d->activityId == activityId) {
|
2011-05-20 09:41:19 +02:00
|
|
|
return;
|
2010-05-11 19:02:24 +00:00
|
|
|
}
|
2010-05-10 01:43:06 +00:00
|
|
|
|
2011-05-20 09:41:19 +02:00
|
|
|
d->activityId = activityId;
|
|
|
|
KConfigGroup c = config();
|
|
|
|
c.writeEntry("activityId", activityId);
|
2010-05-10 01:43:06 +00:00
|
|
|
|
2011-05-20 09:41:19 +02:00
|
|
|
emit configNeedsSaving();
|
2013-02-18 18:54:44 +01:00
|
|
|
emit activityChanged(activityId);
|
2010-05-10 01:43:06 +00:00
|
|
|
}
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
QString Containment::activity() const
|
|
|
|
{
|
2011-05-20 09:41:19 +02:00
|
|
|
return d->activityId;
|
2008-11-03 23:08:39 +00:00
|
|
|
}
|
|
|
|
|
2013-12-12 17:10:36 +01:00
|
|
|
void Containment::reactToScreenChange()
|
|
|
|
{
|
|
|
|
int newScreen = screen();
|
|
|
|
|
|
|
|
if (newScreen >= 0) {
|
|
|
|
d->lastScreen = newScreen;
|
2014-07-08 01:47:26 +02:00
|
|
|
KConfigGroup c = config();
|
2013-12-12 17:10:36 +01:00
|
|
|
c.writeEntry("lastScreen", d->lastScreen);
|
2014-07-08 01:47:26 +02:00
|
|
|
emit configNeedsSaving();
|
2013-12-12 17:10:36 +01:00
|
|
|
}
|
2014-04-08 19:47:50 +02:00
|
|
|
|
2013-12-12 17:10:36 +01:00
|
|
|
emit screenChanged(newScreen);
|
|
|
|
}
|
|
|
|
|
2008-11-03 23:08:39 +00:00
|
|
|
} // Plasma namespace
|
|
|
|
|
2012-02-08 23:33:03 +01:00
|
|
|
#include "moc_containment.cpp"
|