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

Plasma

wallpaper.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2008 by Aaron Seigo <aseigo@kde.org>
00003  *   Copyright 2008 by Petri Damsten <damu@iki.fi>
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU Library General Public License as
00007  *   published by the Free Software Foundation; either version 2, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details
00014  *
00015  *   You should have received a copy of the GNU Library General Public
00016  *   License along with this program; if not, write to the
00017  *   Free Software Foundation, Inc.,
00018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019  */
00020 
00021 #include "wallpaper.h"
00022 
00023 #include <QColor>
00024 #include <QFile>
00025 #include <QFileInfo>
00026 #include <QImage>
00027 #include <QQueue>
00028 
00029 #include <kdebug.h>
00030 #include <kglobal.h>
00031 #include <kservicetypetrader.h>
00032 #include <kstandarddirs.h>
00033 
00034 #include <kio/job.h>
00035 
00036 #include <version.h>
00037 
00038 #include "plasma/private/dataengineconsumer_p.h"
00039 #include "plasma/private/packages_p.h"
00040 #include "plasma/private/wallpaper_p.h"
00041 
00042 namespace Plasma
00043 {
00044 
00045 PackageStructure::Ptr WallpaperPrivate::s_packageStructure(0);
00046 
00047 Wallpaper::Wallpaper(QObject * parentObject)
00048     : d(new WallpaperPrivate(KService::serviceByStorageId(QString()), this))
00049 {
00050     setParent(parentObject);
00051 }
00052 
00053 Wallpaper::Wallpaper(QObject *parentObject, const QVariantList &args)
00054     : d(new WallpaperPrivate(KService::serviceByStorageId(args.count() > 0 ?
00055                              args[0].toString() : QString()), this))
00056 {
00057     // now remove first item since those are managed by Wallpaper and subclasses shouldn't
00058     // need to worry about them. yes, it violates the constness of this var, but it lets us add
00059     // or remove items later while applets can just pretend that their args always start at 0
00060     QVariantList &mutableArgs = const_cast<QVariantList &>(args);
00061     if (!mutableArgs.isEmpty()) {
00062         mutableArgs.removeFirst();
00063     }
00064 
00065     setParent(parentObject);
00066 }
00067 
00068 Wallpaper::~Wallpaper()
00069 {
00070     delete d;
00071 }
00072 
00073 KPluginInfo::List Wallpaper::listWallpaperInfo(const QString &formFactor)
00074 {
00075     QString constraint;
00076 
00077     if (!formFactor.isEmpty()) {
00078         constraint.append("[X-Plasma-FormFactors] ~~ '").append(formFactor).append("'");
00079     }
00080 
00081     KService::List offers = KServiceTypeTrader::self()->query("Plasma/Wallpaper", constraint);
00082     return KPluginInfo::fromServices(offers);
00083 }
00084 
00085 Wallpaper *Wallpaper::load(const QString &wallpaperName, const QVariantList &args)
00086 {
00087     if (wallpaperName.isEmpty()) {
00088         return 0;
00089     }
00090 
00091     QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(wallpaperName);
00092     KService::List offers = KServiceTypeTrader::self()->query("Plasma/Wallpaper", constraint);
00093 
00094     if (offers.isEmpty()) {
00095         kDebug() << "offers is empty for " << wallpaperName;
00096         return 0;
00097     }
00098 
00099     KService::Ptr offer = offers.first();
00100     KPluginLoader plugin(*offer);
00101 
00102     if (!Plasma::isPluginVersionCompatible(plugin.pluginVersion())) {
00103         return 0;
00104     }
00105 
00106     QVariantList allArgs;
00107     allArgs << offer->storageId() << args;
00108     QString error;
00109     Wallpaper *wallpaper = offer->createInstance<Plasma::Wallpaper>(0, allArgs, &error);
00110 
00111     if (!wallpaper) {
00112         kDebug() << "Couldn't load wallpaper \"" << wallpaperName << "\"! reason given: " << error;
00113     }
00114 
00115     return wallpaper;
00116 }
00117 
00118 Wallpaper *Wallpaper::load(const KPluginInfo &info, const QVariantList &args)
00119 {
00120     if (!info.isValid()) {
00121         return 0;
00122     }
00123     return load(info.pluginName(), args);
00124 }
00125 
00126 PackageStructure::Ptr Wallpaper::packageStructure(Wallpaper *paper)
00127 {
00128     if (paper) {
00129         PackageStructure::Ptr package(new WallpaperPackage(paper));
00130         return package;
00131     }
00132 
00133     if (!WallpaperPrivate::s_packageStructure) {
00134         WallpaperPrivate::s_packageStructure = new WallpaperPackage();
00135     }
00136 
00137     return WallpaperPrivate::s_packageStructure;
00138 }
00139 
00140 QString Wallpaper::name() const
00141 {
00142     if (!d->wallpaperDescription.isValid()) {
00143         return i18n("Unknown Wallpaper");
00144     }
00145 
00146     return d->wallpaperDescription.name();
00147 }
00148 
00149 QString Wallpaper::icon() const
00150 {
00151     if (!d->wallpaperDescription.isValid()) {
00152         return QString();
00153     }
00154 
00155     return d->wallpaperDescription.icon();
00156 }
00157 
00158 QString Wallpaper::pluginName() const
00159 {
00160     if (!d->wallpaperDescription.isValid()) {
00161         return QString();
00162     }
00163 
00164     return d->wallpaperDescription.pluginName();
00165 }
00166 
00167 KServiceAction Wallpaper::renderingMode() const
00168 {
00169     return d->mode;
00170 }
00171 
00172 QList<KServiceAction> Wallpaper::listRenderingModes() const
00173 {
00174     if (!d->wallpaperDescription.isValid()) {
00175         return QList<KServiceAction>();
00176     }
00177 
00178     return d->wallpaperDescription.service()->actions();
00179 }
00180 
00181 QRectF Wallpaper::boundingRect() const
00182 {
00183     return d->boundingRect;
00184 }
00185 
00186 bool Wallpaper::isInitialized() const
00187 {
00188     return d->initialized;
00189 }
00190 
00191 void Wallpaper::setBoundingRect(const QRectF &boundingRect)
00192 {
00193     QSizeF oldBoundingRectSize = d->boundingRect.size();
00194     d->boundingRect = boundingRect;
00195 
00196     if (!d->targetSize.isValid() || d->targetSize == oldBoundingRectSize)  {
00197         d->targetSize = boundingRect.size();
00198         emit renderHintsChanged();
00199     }
00200 }
00201 
00202 void Wallpaper::setRenderingMode(const QString &mode)
00203 {
00204     if (d->mode.name() == mode) {
00205         return;
00206     }
00207 
00208     d->mode = KServiceAction();
00209     if (!mode.isEmpty()) {
00210         QList<KServiceAction> modes = listRenderingModes();
00211 
00212         foreach (const KServiceAction &action, modes) {
00213             if (action.name() == mode) {
00214                 d->mode = action;
00215                 break;
00216             }
00217         }
00218     }
00219 }
00220 
00221 void Wallpaper::restore(const KConfigGroup &config)
00222 {
00223     init(config);
00224     d->initialized = true;
00225 }
00226 
00227 void Wallpaper::init(const KConfigGroup &config)
00228 {
00229     Q_UNUSED(config);
00230 }
00231 
00232 void Wallpaper::save(KConfigGroup &config)
00233 {
00234     Q_UNUSED(config);
00235 }
00236 
00237 QWidget *Wallpaper::createConfigurationInterface(QWidget *parent)
00238 {
00239     Q_UNUSED(parent);
00240     return 0;
00241 }
00242 
00243 void Wallpaper::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00244 {
00245     Q_UNUSED(event)
00246 }
00247 
00248 void Wallpaper::mousePressEvent(QGraphicsSceneMouseEvent *event)
00249 {
00250     Q_UNUSED(event)
00251 }
00252 
00253 void Wallpaper::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
00254 {
00255     Q_UNUSED(event)
00256 }
00257 
00258 void Wallpaper::wheelEvent(QGraphicsSceneWheelEvent *event)
00259 {
00260     Q_UNUSED(event)
00261 }
00262 
00263 DataEngine *Wallpaper::dataEngine(const QString &name) const
00264 {
00265     return d->dataEngine(name);
00266 }
00267 
00268 bool Wallpaper::configurationRequired() const
00269 {
00270     return d->needsConfig;
00271 }
00272 
00273 void Wallpaper::setConfigurationRequired(bool needsConfig, const QString &reason)
00274 {
00275     //TODO: implement something for reason. first, we need to decide where/how
00276     //      to communicate it to the user
00277     Q_UNUSED(reason)
00278 
00279     if (d->needsConfig == needsConfig) {
00280         return;
00281     }
00282 
00283     d->needsConfig = needsConfig;
00284     emit configurationRequired(needsConfig);
00285 }
00286 
00287 bool Wallpaper::isUsingRenderingCache() const
00288 {
00289     return d->cacheRendering;
00290 }
00291 
00292 void Wallpaper::setUsingRenderingCache(bool useCache)
00293 {
00294     d->cacheRendering = useCache;
00295 }
00296 
00297 void Wallpaper::setResizeMethodHint(Wallpaper::ResizeMethod resizeMethod)
00298 {
00299     d->lastResizeMethod = resizeMethod;
00300     emit renderHintsChanged();
00301 }
00302 
00303 void Wallpaper::setTargetSizeHint(const QSizeF &targetSize)
00304 {
00305     d->targetSize = targetSize;
00306     emit renderHintsChanged();
00307 }
00308 
00309 void Wallpaper::render(const QString &sourceImagePath, const QSize &size,
00310                        Wallpaper::ResizeMethod resizeMethod, const QColor &color)
00311 {
00312     if (sourceImagePath.isEmpty() || !QFile::exists(sourceImagePath)) {
00313         //kDebug() << "failed on:" << sourceImagePath;
00314         return;
00315     }
00316 
00317     if (d->lastResizeMethod != resizeMethod) {
00318         d->lastResizeMethod = resizeMethod;
00319         emit renderHintsChanged();
00320     }
00321 
00322     if (d->cacheRendering) {
00323         QFileInfo info(sourceImagePath);
00324         QString cache = d->cacheKey(sourceImagePath, size, resizeMethod, color);
00325         QImage img;
00326         if (findInCache(cache, img, info.lastModified().toTime_t())) {
00327             emit renderCompleted(img);
00328             return;
00329         }
00330     }
00331 
00332     WallpaperRenderRequest request;
00333     d->renderToken = request.token;
00334     request.requester = this;
00335     request.file = sourceImagePath;
00336     request.size = size;
00337     request.resizeMethod = resizeMethod;
00338     request.color = color;
00339     WallpaperRenderThread::render(request);
00340     //kDebug() << "rendering" << sourceImagePath << ", token is" << d->renderToken;
00341 }
00342 
00343 QString WallpaperPrivate::cacheKey(const QString &sourceImagePath, const QSize &size,
00344                                    int resizeMethod, const QColor &color) const
00345 {
00346     const QString id = QString("%5_%3_%4_%1x%2")
00347                               .arg(size.width()).arg(size.height()).arg(color.name())
00348                               .arg(resizeMethod).arg(sourceImagePath);
00349     return id;
00350 }
00351 
00352 QString WallpaperPrivate::cachePath(const QString &key) const
00353 {
00354     return KGlobal::dirs()->locateLocal("cache", "plasma-wallpapers/" + key + ".png");
00355 }
00356 
00357 void WallpaperPrivate::newRenderCompleted(const WallpaperRenderRequest &request, const QImage &image)
00358 {
00359     kDebug() << request.token << renderToken;
00360     if (request.token != renderToken) {
00361         //kDebug() << "render token mismatch" << token << renderToken;
00362         return;
00363     }
00364 
00365     if (cacheRendering) {
00366         q->insertIntoCache(cacheKey(request.file, request.size, request.resizeMethod, request.color), image);
00367     }
00368 
00369     //kDebug() << "rendering complete!";
00370     emit q->renderCompleted(image);
00371 }
00372 
00373 bool Wallpaper::findInCache(const QString &key, QImage &image, unsigned int lastModified)
00374 {
00375     if (d->cacheRendering) {
00376         QString cache = d->cachePath(key);
00377         if (QFile::exists(cache)) {
00378             if (lastModified > 0) {
00379                 QFileInfo info(cache);
00380                 if (info.lastModified().toTime_t() < lastModified) {
00381                     return false;
00382                 }
00383             }
00384 
00385             image.load(cache);
00386             return true;
00387         }
00388     }
00389 
00390     return false;
00391 }
00392 
00393 void Wallpaper::insertIntoCache(const QString& key, const QImage &image)
00394 {
00395     //TODO: cache limits?
00396     if (key.isEmpty()) {
00397         return;
00398     }
00399 
00400     if (d->cacheRendering) {
00401         if (image.isNull()) {
00402             KIO::file_delete(d->cachePath(key));
00403         } else {
00404             image.save(d->cachePath(key));
00405         }
00406     }
00407 }
00408 
00409 } // Plasma namespace
00410 
00411 #include "wallpaper.moc"

Plasma

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal