23#include "config-plasma.h"
37#include <kservicetypetrader.h>
38#include <kstandarddirs.h>
47#include "plasma/private/dataengineconsumer_p.h"
48#include "plasma/private/packages_p.h"
49#include "plasma/private/wallpaper_p.h"
54class SaveImageThread :
public QRunnable
60 SaveImageThread(
const QImage &image,
const QString &filePath)
63 m_filePath = filePath;
68 m_image.save(m_filePath);
72LoadImageThread::LoadImageThread(
const QString &filePath)
74 m_filePath = filePath;
77void LoadImageThread::run()
80 image.load(m_filePath);
84class WallpaperWithPaint :
public Wallpaper
92 virtual void paint(QPainter *painter,
const QRectF &exposedRect)
95 d->script->paint(painter, exposedRect);
100PackageStructure::Ptr WallpaperPrivate::s_packageStructure(0);
103 : d(new WallpaperPrivate(KService::serviceByStorageId(QString()), this))
105 setParent(parentObject);
108Wallpaper::Wallpaper(
QObject *parentObject,
const QVariantList &args)
109 : d(new WallpaperPrivate(KService::serviceByStorageId(args.count() > 0 ?
110 args[0].toString() : QString()), this))
115 QVariantList &mutableArgs =
const_cast<QVariantList &
>(args);
116 if (!mutableArgs.isEmpty()) {
117 mutableArgs.removeFirst();
120 setParent(parentObject);
123Wallpaper::~Wallpaper()
128void Wallpaper::addUrls(
const KUrl::List &urls)
131 d->script->setUrls(urls);
134 foreach (
const KUrl &url, urls) {
140void Wallpaper::setUrls(
const KUrl::List &urls)
142 if (!d->initialized) {
143 d->pendingUrls = urls;
144 }
else if (d->script) {
145 d->script->setUrls(urls);
147 QMetaObject::invokeMethod(
this,
"addUrls", Q_ARG(KUrl::List, urls));
151KPluginInfo::List Wallpaper::listWallpaperInfo(
const QString &formFactor)
154 if (!formFactor.isEmpty()) {
155 constraint.append(
"[X-Plasma-FormFactors] ~~ '").append(formFactor).append(
"'");
158 KService::List offers = KServiceTypeTrader::self()->query(
"Plasma/Wallpaper", constraint);
159 return KPluginInfo::fromServices(offers);
162KPluginInfo::List Wallpaper::listWallpaperInfoForMimetype(
const QString &mimetype,
const QString &formFactor)
164 QString constraint = QString(
"'%1' in [X-Plasma-DropMimeTypes]").arg(mimetype);
165 if (!formFactor.isEmpty()) {
166 constraint.append(
"[X-Plasma-FormFactors] ~~ '").append(formFactor).append(
"'");
169 KService::List offers = KServiceTypeTrader::self()->query(
"Plasma/Wallpaper", constraint);
170 kDebug() << offers.count() << constraint;
171 return KPluginInfo::fromServices(offers);
174bool Wallpaper::supportsMimetype(
const QString &mimetype)
const
176 return d->wallpaperDescription.isValid() &&
177 d->wallpaperDescription.service()->hasMimeType(mimetype);
180Wallpaper *Wallpaper::load(
const QString &wallpaperName,
const QVariantList &args)
182 if (wallpaperName.isEmpty()) {
186 QString constraint = QString(
"[X-KDE-PluginInfo-Name] == '%1'").arg(wallpaperName);
187 KService::List offers = KServiceTypeTrader::self()->query(
"Plasma/Wallpaper", constraint);
189 if (offers.isEmpty()) {
190 kDebug() <<
"offers is empty for " << wallpaperName;
194 KService::Ptr offer = offers.first();
195 QVariantList allArgs;
196 allArgs << offer->storageId() << args;
198 if (!offer->property(
"X-Plasma-API").toString().isEmpty()) {
199 kDebug() <<
"we have a script using the"
200 << offer->property(
"X-Plasma-API").toString() <<
"API";
204 KPluginLoader plugin(*offer);
214 kDebug() <<
"Couldn't load wallpaper \"" << wallpaperName <<
"\"! reason given: " << error;
220Wallpaper *Wallpaper::load(
const KPluginInfo &info,
const QVariantList &args)
222 if (!info.isValid()) {
225 return load(info.pluginName(), args);
235 if (!WallpaperPrivate::s_packageStructure) {
236 WallpaperPrivate::s_packageStructure =
new WallpaperPackage();
239 return WallpaperPrivate::s_packageStructure;
242QString Wallpaper::name()
const
244 if (!d->wallpaperDescription.isValid()) {
245 return i18n(
"Unknown Wallpaper");
248 return d->wallpaperDescription.name();
251QString Wallpaper::icon()
const
253 if (!d->wallpaperDescription.isValid()) {
257 return d->wallpaperDescription.icon();
260QString Wallpaper::pluginName()
const
262 if (!d->wallpaperDescription.isValid()) {
266 return d->wallpaperDescription.pluginName();
269KServiceAction Wallpaper::renderingMode()
const
274QList<KServiceAction> Wallpaper::listRenderingModes()
const
276 if (!d->wallpaperDescription.isValid()) {
277 return QList<KServiceAction>();
280 return d->wallpaperDescription.service()->actions();
283QRectF Wallpaper::boundingRect()
const
285 return d->boundingRect;
288bool Wallpaper::isInitialized()
const
290 return d->initialized;
293void Wallpaper::setBoundingRect(
const QRectF &boundingRect)
303void Wallpaper::setRenderingMode(
const QString &mode)
305 if (d->mode.name() == mode) {
309 d->mode = KServiceAction();
310 if (!mode.isEmpty()) {
313 foreach (
const KServiceAction &action, modes) {
314 if (action.name() == mode) {
322void Wallpaper::restore(
const KConfigGroup &config)
325 d->initialized =
true;
326 if (!d->pendingUrls.isEmpty()) {
328 d->pendingUrls.clear();
332void Wallpaper::init(
const KConfigGroup &config)
336 d->script->initWallpaper(config);
340void Wallpaper::save(KConfigGroup &config)
343 d->script->save(config);
350 return d->script->createConfigurationInterface(parent);
356void Wallpaper::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
359 return d->script->mouseMoveEvent(event);
363void Wallpaper::mousePressEvent(QGraphicsSceneMouseEvent *event)
366 return d->script->mousePressEvent(event);
370void Wallpaper::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
373 return d->script->mouseReleaseEvent(event);
377void Wallpaper::wheelEvent(QGraphicsSceneWheelEvent *event)
380 return d->script->wheelEvent(event);
386 return d->dataEngine(
name);
389bool Wallpaper::configurationRequired()
const
391 return d->needsConfig;
394void Wallpaper::setConfigurationRequired(
bool needsConfig,
const QString &reason)
400 if (d->needsConfig == needsConfig) {
404 d->needsConfig = needsConfig;
408bool Wallpaper::isUsingRenderingCache()
const
410 return d->cacheRendering;
413void Wallpaper::setUsingRenderingCache(
bool useCache)
415 d->cacheRendering = useCache;
421 if (method != d->lastResizeMethod) {
422 d->lastResizeMethod = method;
429 return d->lastResizeMethod;
432void Wallpaper::setTargetSizeHint(
const QSizeF &targetSize)
440QSizeF Wallpaper::targetSizeHint()
const
442 return d->targetSize;
445void Wallpaper::render(
const QImage &image,
const QSize &size,
448 if (image.isNull()) {
452 d->renderWallpaper(QString(), image, size,
resizeMethod, color);
455void Wallpaper::render(
const QString &sourceImagePath,
const QSize &size,
458 if (sourceImagePath.isEmpty() || !QFile::exists(sourceImagePath)) {
463 d->renderWallpaper(sourceImagePath, QImage(), size,
resizeMethod, color);
466void WallpaperPrivate::renderWallpaper(
const QString &sourceImagePath,
const QImage &image,
const QSize &size,
469 resizeMethod = qBound(Wallpaper::ScaledResize, resizeMethod, Wallpaper::LastResizeMethod);
470 if (lastResizeMethod != resizeMethod) {
471 lastResizeMethod = resizeMethod;
472 emit q->renderHintsChanged();
475 if (cacheRendering) {
476 QFileInfo info(sourceImagePath);
477 QString cache = cacheKey(sourceImagePath, size, resizeMethod, color);
478 if (findInCache(cache, info.lastModified().toTime_t())) {
483 WallpaperRenderRequest request;
484 renderToken = request.token;
485 request.requester = q;
486 request.providedImage = image;
487 request.file = sourceImagePath;
489 request.resizeMethod = resizeMethod;
490 request.color = color;
491 WallpaperRenderThread::render(request);
495WallpaperPrivate::WallpaperPrivate(KService::Ptr service, Wallpaper *wallpaper) :
497 wallpaperDescription(service),
500 lastResizeMethod(Wallpaper::ScaledResize),
502 cacheRendering(false),
505 scriptInitialized(false),
507 needsPreviewDuringConfiguration(false)
509 if (wallpaperDescription.isValid()) {
510 QString api = wallpaperDescription.property(
"X-Plasma-API").toString();
512 if (!api.isEmpty()) {
513 const QString path = KStandardDirs::locate(
"data",
514 "plasma/wallpapers/" + wallpaperDescription.pluginName() +
'/');
517 structure->setPath(path);
518 package = new Package(path, structure);
522 kDebug() <<
"Could not create a" << api <<
"ScriptEngine for the"
523 << wallpaperDescription.name() <<
"Wallpaper.";
531QString WallpaperPrivate::cacheKey(
const QString &sourceImagePath,
const QSize &size,
534 const QString
id = QString(
"%5_%3_%4_%1x%2")
535 .arg(size.width()).arg(size.height()).arg(color.name())
540QString WallpaperPrivate::cachePath(
const QString &key)
const
542 return KGlobal::dirs()->locateLocal(
"cache",
"plasma-wallpapers/" + key +
".png");
545void WallpaperPrivate::newRenderCompleted(
const WallpaperRenderRequest &request,
const QImage &image)
547 kDebug() << request.token << renderToken;
548 if (request.token != renderToken) {
553 if (cacheRendering) {
554 q->insertIntoCache(cacheKey(request.file, request.size, request.resizeMethod, request.color), image);
558 emit q->renderCompleted(image);
563void WallpaperPrivate::setupScriptSupport()
566 kDebug() <<
"setting up script support, package is in" <<
package->
path()
571 if (!translationsPath.isEmpty()) {
574 KGlobal::dirs()->addResourceDir(
"locale", translationsPath);
579void WallpaperPrivate::initScript()
581 if (script && !scriptInitialized) {
582 setupScriptSupport();
584 scriptInitialized =
true;
588bool WallpaperPrivate::findInCache(
const QString &key,
unsigned int lastModified)
590 if (cacheRendering) {
591 QString cache = cachePath(key);
592 if (QFile::exists(cache)) {
593 if (lastModified > 0) {
594 QFileInfo info(cache);
595 if (info.lastModified().toTime_t() < lastModified) {
600 LoadImageThread *loadImageT =
new LoadImageThread(cache);
601 q->connect(loadImageT, SIGNAL(done(QImage)), q, SIGNAL(
renderCompleted(QImage)));
602 QThreadPool::globalInstance()->start(loadImageT);
613 if (d->cacheRendering) {
614 QString cache = d->cachePath(key);
615 if (QFile::exists(cache)) {
616 if (lastModified > 0) {
617 QFileInfo info(cache);
618 if (info.lastModified().toTime_t() < lastModified) {
638 if (d->cacheRendering) {
639 if (image.isNull()) {
641 KIO::file_delete(d->cachePath(key));
643 QFile f(d->cachePath(key));
647 QThreadPool::globalInstance()->start(
new SaveImageThread(image, d->cachePath(key)));
664 return d->previewing;
674 return d->needsPreviewDuringConfiguration;
679 d->needsPreviewDuringConfiguration = preview;
689#include "wallpaper.moc"
690#include "private/wallpaper_p.moc"
Data provider for plasmoids (Plasma plugins)
KSharedPtr< PackageStructure > Ptr
object representing an installed Plasmagik package
PackageMetadata metadata() const
const PackageStructure::Ptr structure() const
QString filePath(const char *fileType, const QString &filename) const
Get the path to a given file.
const QString path() const
The base Wallpaper class.
virtual void init(const KConfigGroup &config)
This method is called once the wallpaper is loaded or mode is changed.
friend class WallpaperWithPaint
bool isPreviewing() const
bool findInCache(const QString &key, QImage &image, unsigned int lastModified=0)
Tries to load pixmap with the specified key from cache.
QList< KServiceAction > listRenderingModes
QList< QAction * > contextualActions() const
Returns a list of wallpaper contextual actions (nothing by default)
ResizeMethod resizeMethod
void renderHintsChanged()
ResizeMethod
Various resize modes supported by the built in image renderer.
@ ScaledResize
Scales the image to fit the full area.
bool needsPreviewDuringConfiguration() const
QList< QAction * > contextActions
static Wallpaper * load(const QString &name, const QVariantList &args=QVariantList())
Attempts to load a wallpaper.
void setContextualActions(const QList< QAction * > &actions)
Sets the contextual actions for this wallpaper.
void renderCompleted(const QImage &image)
Emitted when a wallpaper image render is completed.
bool configurationRequired() const
void urlDropped(const KUrl &url)
Emitted when a URL matching X-Plasma-DropMimeTypes is dropped on the wallpaper.
void setPreviewing(bool previewing)
Puts the wallpaper into preview mode.
void setPreviewDuringConfiguration(const bool preview)
Sets whether the configuration user interface of the wallpaper should have a live preview rendered by...
const Package * package() const
Accessor for the associated Package object if any.
void insertIntoCache(const QString &key, const QImage &image)
Insert specified pixmap into the cache if usingRenderingCache.
void setUrls(const KUrl::List &urls)
Sets the urls for the wallpaper.
Wallpaper(QObject *parent=0)
Default constructor for an empty or null wallpaper.
Namespace for everything in libplasma.
PackageStructure::Ptr packageStructure(const QString &language, ComponentType type)
Loads an appropriate PackageStructure for the given language and type.
bool isPluginVersionCompatible(unsigned int version)
Verifies that a plugin is compatible with plasma.
AppletScript * loadScriptEngine(const QString &language, Applet *applet)
Loads an Applet script engine for the given language.
@ WallpaperComponent
Plasma::Wallpaper based plugins.