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