1/*
2 * Copyright 2008 by Aaron Seigo <aseigo@kde.org>
3 * Copyright 2008 by Petri Damsten <damu@iki.fi>
4
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Library General Public License as
7 * published by the Free Software Foundation; either version 2, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef PLASMA_WALLPAPER_H
22#define PLASMA_WALLPAPER_H
23
24#include <kmimetype.h>
25#include <kplugininfo.h>
26
27#include <plasma/plasma.h>
28#include <plasma/packagestructure.h>
29#include <plasma/version.h>
30
31namespace Plasma
32{
33
34class DataEngine;
35class WallpaperPrivate;
36class Package;
37
38/**
39 * @class Wallpaper plasma/wallpaper.h <Plasma/Wallpaper>
40 *
41 * @short The base Wallpaper class
42 *
43 * "Wallpapers" are components that paint the background for Containments that
44 * do not provide their own background rendering.
45 *
46 * Wallpaper plugins are registered using .desktop files. These files should be
47 * named using the following naming scheme:
48 *
49 * plasma-wallpaper-\<pluginname\>.desktop
50 *
51 * If a wallpaper plugin provides more than on mode (e.g. Single Image, Wallpaper)
52 * it should include a Actions= entry in the .desktop file, listing the possible
53 * actions. An actions group should be included to provide for translatable names.
54 */
55
56class PLASMA_EXPORT Wallpaper : public QObject
57{
58 Q_OBJECT
59 Q_PROPERTY(QRectF boundingRect READ boundingRect WRITE setBoundingRect)
60 Q_PROPERTY(QString name READ name)
61 Q_PROPERTY(QString pluginName READ pluginName)
62 Q_PROPERTY(QString icon READ icon)
63 Q_PROPERTY(KServiceAction renderingMode READ renderingMode)
64 Q_PROPERTY(QList<KServiceAction> listRenderingModes READ listRenderingModes)
65 Q_PROPERTY(bool usingRenderingCache READ isUsingRenderingCache WRITE setUsingRenderingCache)
66 Q_PROPERTY(bool previewing READ isPreviewing WRITE setPreviewing)
67 Q_PROPERTY(ResizeMethod resizeMethod READ resizeMethodHint WRITE setResizeMethodHint)
68 Q_PROPERTY(QSizeF targetSize READ targetSizeHint WRITE setTargetSizeHint)
69
70 public:
71 /**
72 * Various resize modes supported by the built in image renderer
73 */
74 enum ResizeMethod {
75 ScaledResize /**< Scales the image to fit the full area*/,
76 CenteredResize /**< Centers the image within the area */,
77 ScaledAndCroppedResize /**< Scales and crops the image, preserving the aspect ratio */,
78 TiledResize /**< Tiles the image to fill the area */,
79 CenterTiledResize /**< Tiles the image to fill the area, starting with a centered tile */,
80 MaxpectResize /**< Best fit resize */,
81 LastResizeMethod = MaxpectResize
82 };
83 Q_ENUMS(ResizeMethod)
84
85 /**
86 * Default constructor for an empty or null wallpaper
87 */
88 explicit Wallpaper(QObject * parent = 0);
89
90 ~Wallpaper();
91
92 /**
93 * Sets the urls for the wallpaper
94 * @param urls Urls of the selected images
95 * @since 4.7
96 */
97 void setUrls(const KUrl::List &urls);
98
99
100 /**
101 * Returns a list of all known wallpapers.
102 *
103 * @param formFactor the format of the wallpaper being search for (e.g. desktop)
104 * @return list of wallpapers
105 **/
106 static KPluginInfo::List listWallpaperInfo(const QString &formFactor = QString());
107
108 /**
109 * Returns a list of all known wallpapers that can accept the given mimetype
110 * @param mimetype the mimetype to search for
111 * @param formFactor the format of the wallpaper being search for (e.g. desktop)
112 * @return list of wallpapers
113 */
114 static KPluginInfo::List listWallpaperInfoForMimetype(const QString &mimetype,
115 const QString &formFactor = QString());
116
117 /**
118 * Attempts to load a wallpaper
119 *
120 * Returns a pointer to the wallpaper if successful.
121 * The caller takes responsibility for the wallpaper, including
122 * deleting it when no longer needed.
123 *
124 * @param name the plugin name, as returned by KPluginInfo::pluginName()
125 * @param args to send the wallpaper extra arguments
126 * @return a pointer to the loaded wallpaper, or 0 on load failure
127 **/
128 static Wallpaper *load(const QString &name, const QVariantList &args = QVariantList());
129
130 /**
131 * Attempts to load a wallpaper
132 *
133 * Returns a pointer to the wallpaper if successful.
134 * The caller takes responsibility for the wallpaper, including
135 * deleting it when no longer needed.
136 *
137 * @param info KPluginInfo object for the desired wallpaper
138 * @param args to send the wallpaper extra arguments
139 * @return a pointer to the loaded wallpaper, or 0 on load failure
140 **/
141 static Wallpaper *load(const KPluginInfo &info, const QVariantList &args = QVariantList());
142
143 /**
144 * Returns the Package specialization for wallpapers. May be queried for 'preferred'
145 * which will return the preferred wallpaper image path given the associated Wallpaper
146 * object, if any.
147 *
148 * @param paper the Wallpaper object to associated the PackageStructure with,
149 * which will then use the Wallpaper object to define things such as
150 * default size and resize methods.
151 */
152 static PackageStructure::Ptr packageStructure(Wallpaper *paper = 0);
153
154 /**
155 * Returns the user-visible name for the wallpaper, as specified in the
156 * .desktop file.
157 *
158 * @return the user-visible name for the wallpaper.
159 **/
160 QString name() const;
161
162 /**
163 * Accessor for the associated Package object if any.
164 *
165 * @return the Package object, or 0 if none
166 **/
167 const Package *package() const;
168
169 /**
170 * Returns the plugin name for the wallpaper
171 */
172 QString pluginName() const;
173
174 /**
175 * Returns the icon related to this wallpaper
176 **/
177 QString icon() const;
178
179 /**
180 * @return the currently active rendering mode
181 */
182 KServiceAction renderingMode() const;
183
184 /**
185 * @return true if the mimetype is supported by this wallpaper and
186 * can be used in renderering. Uses the MimeType= entry from
187 * the .desktop file, and can include mimetypes that may not be
188 * suitable for drag-and-drop purposes.
189 * @since 4.7
190 */
191 bool supportsMimetype(const QString &mimetype) const;
192
193 /**
194 * Sets the rendering mode for this wallpaper.
195 * @param mode One of the modes supported by the plugin,
196 * or an empty string for the default mode.
197 */
198 void setRenderingMode(const QString &mode);
199
200 /**
201 * Returns modes the wallpaper has, as specified in the
202 * .desktop file.
203 */
204 QList<KServiceAction> listRenderingModes() const;
205
206 /**
207 * @return true if initialized (usually by calling restore), false otherwise
208 */
209 bool isInitialized() const;
210
211 /**
212 * Returns bounding rectangle
213 */
214 QRectF boundingRect() const;
215
216 /**
217 * Sets bounding rectangle
218 */
219 void setBoundingRect(const QRectF &boundingRect);
220
221 /**
222 * This method is called when the wallpaper should be painted.
223 *
224 * @param painter the QPainter to use to do the painting
225 * @param exposedRect the rect to paint within
226 **/
227 virtual void paint(QPainter *painter, const QRectF &exposedRect) = 0;
228
229 /**
230 * This method should be called once the wallpaper is loaded or mode is changed.
231 * @param config Config group to load settings
232 * @see init
233 **/
234 void restore(const KConfigGroup &config);
235
236 /**
237 * This method is called when settings need to be saved.
238 * @param config Config group to save settings
239 **/
240 virtual void save(KConfigGroup &config);
241
242 /**
243 * Returns a widget that can be used to configure the options (if any)
244 * associated with this wallpaper. It will be deleted by the caller
245 * when it complete. The default implementation returns a null pointer.
246 *
247 * To signal that settings have changed connect to
248 * settingsChanged(bool modified) in @p parent.
249 *
250 * @code connect(this, SIGNAL(settingsChanged(bool), parent, SLOT(settingsChanged(bool)))
251 * @endcode
252 *
253 * Emit settingsChanged(true) when the settings are changed and false when the original state is restored.
254 *
255 * Implementation detail note: for best visual results, use a QGridLayout with two columns,
256 * with the option labels in column 0
257 */
258 virtual QWidget *createConfigurationInterface(QWidget *parent);
259
260 /**
261 * Mouse move event. To prevent further propagation of the event,
262 * the event must be accepted.
263 *
264 * @param event the mouse event object
265 */
266 virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
267
268 /**
269 * Mouse press event. To prevent further propagation of the even,
270 * and to receive mouseMoveEvents, the event must be accepted.
271 *
272 * @param event the mouse event object
273 */
274 virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
275
276 /**
277 * Mouse release event. To prevent further propagation of the event,
278 * the event must be accepted.
279 *
280 * @param event the mouse event object
281 */
282 virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
283
284 /**
285 * Mouse wheel event. To prevent further propagation of the event,
286 * the event must be accepted.
287 *
288 * @param event the wheel event object
289 */
290 virtual void wheelEvent(QGraphicsSceneWheelEvent *event);
291
292 /**
293 * Loads the given DataEngine
294 *
295 * Tries to load the data engine given by @p name. Each engine is
296 * only loaded once, and that instance is re-used on all subsequent
297 * requests.
298 *
299 * If the data engine was not found, an invalid data engine is returned
300 * (see DataEngine::isValid()).
301 *
302 * Note that you should <em>not</em> delete the returned engine.
303 *
304 * @param name Name of the data engine to load
305 * @return pointer to the data engine if it was loaded,
306 * or an invalid data engine if the requested engine
307 * could not be loaded
308 *
309 * @since 4.3
310 */
311 Q_INVOKABLE DataEngine *dataEngine(const QString &name) const;
312
313 /**
314 * @return true if the wallpaper currently needs to be configured,
315 * otherwise, false
316 * @since 4.3
317 */
318 bool configurationRequired() const;
319
320 /**
321 * @return true if disk caching is turned on.
322 * @since 4.3
323 */
324 bool isUsingRenderingCache() const;
325
326 /**
327 * Allows one to set rendering hints that may differ from the actualities of the
328 * Wallpaper's current state, allowing for better selection of papers from packages,
329 * for instance.
330 *
331 * @param resizeMethod The resize method to assume will be used for future wallpaper
332 * scaling; may later be changed by calls to render()
333 *
334 * @since 4.3
335 */
336 void setResizeMethodHint(Wallpaper::ResizeMethod resizeMethod);
337
338 /**
339 * @return the current resize method hint
340 * @since 4.7.2
341 */
342 Wallpaper::ResizeMethod resizeMethodHint() const;
343
344 /**
345 * Allows one to set rendering hints that may differ from the actualities of the
346 * Wallpaper's current state, allowing for better selection of papers from packages,
347 * for instance.
348 *
349 * @param targetSize The size to assume will be used for future wallpaper scaling
350 *
351 * @since 4.3
352 */
353 void setTargetSizeHint(const QSizeF &targetSize);
354
355 /**
356 * @return the current target size method hint
357 * @since 4.7.2
358 */
359 QSizeF targetSizeHint() const;
360
361 /**
362 * Returns a list of wallpaper contextual actions (nothing by default)
363 */
364 QList<QAction*> contextualActions() const;
365
366 /**
367 * @return true if in preview mode, such as in a configuation dialog
368 * @since 4.5
369 */
370 bool isPreviewing() const;
371
372 /**
373 * Puts the wallpaper into preview mode
374 * @since 4.5
375 */
376 void setPreviewing(bool previewing);
377
378 /**
379 * @return true if the wallpaper needs a live preview in the configuration UI
380 * @since 4.6
381 */
382 bool needsPreviewDuringConfiguration() const;
383
384
385 Q_SIGNALS:
386 /**
387 * This signal indicates that wallpaper needs to be repainted.
388 */
389 void update(const QRectF &exposedArea);
390
391 /**
392 * Emitted when the user wants to configure/change the wallpaper.
393 * @since 4.3
394 */
395 void configureRequested();
396
397 /**
398 * Emitted when the state of the wallpaper requiring configuration
399 * changes.
400 * @since 4.3
401 */
402 void configurationRequired(bool needsConfig);
403
404 /**
405 * Emitted when the configuration of the wallpaper needs to be saved
406 * to disk.
407 * @since 4.3
408 */
409 void configNeedsSaving();
410
411 /**
412 * Emitted when a wallpaper image render is completed.
413 * @since 4.3
414 */
415 void renderCompleted(const QImage &image);
416
417 /**
418 * Emitted when a URL matching X-Plasma-DropMimeTypes is dropped on the wallpaper
419 *
420 * @param url the URL of the dropped file
421 * @since 4.4
422 */
423 KDE_DEPRECATED void urlDropped(const KUrl &url);
424
425 /**
426 * @internal
427 */
428 void renderHintsChanged();
429
430 protected Q_SLOTS:
431 /**
432 * This method is invoked by setUrls(KUrl::List)
433 * Can be Overriden by Plugins which want to support setting Image URLs
434 * Will be changed to virtual method in libplasma2/KDE5
435 * @since 4.7
436 */
437 void addUrls(const KUrl::List &urls);
438
439 protected:
440 /**
441 * This constructor is to be used with the plugin loading systems
442 * found in KPluginInfo and KService. The argument list is expected
443 * to have one element: the KService service ID for the desktop entry.
444 *
445 * @param parent a QObject parent; you probably want to pass in 0
446 * @param args a list of strings containing one entry: the service id
447 */
448 Wallpaper(QObject *parent, const QVariantList &args);
449
450 /**
451 * This method is called once the wallpaper is loaded or mode is changed.
452 *
453 * The mode can be retrieved using the renderingMode() method.
454 *
455 * @param config Config group to load settings
456 **/
457 virtual void init(const KConfigGroup &config);
458
459 /**
460 * When the wallpaper needs to be configured before being usable, this
461 * method can be called to denote that action is required
462 *
463 * @param needsConfiguring true if the applet needs to be configured,
464 * or false if it doesn't
465 * @param reason a translated message for the user explaining that the
466 * applet needs configuring; this should note what needs
467 * to be configured
468 * @since 4.3
469 */
470 void setConfigurationRequired(bool needsConfiguring, const QString &reason = QString());
471
472 /**
473 * Renders the wallpaper asyncronously with the given parameters. When the rendering is
474 * complete, the renderCompleted signal is emitted.
475 *
476 * @param sourceImagePath the path to the image file on disk. Common image formats such as
477 * PNG, JPEG and SVG are supported
478 * @param size the size to render the image as
479 * @param resizeMethod the method to use when resizing the image to fit size, @see
480 * ResizeMethod
481 * @param color the color to use to pad the rendered image if it doesn't take up the
482 * entire size with the given ResizeMethod
483 * @since 4.3
484 */
485 void render(const QString &sourceImagePath, const QSize &size,
486 Wallpaper::ResizeMethod resizeMethod = ScaledResize,
487 const QColor &color = QColor(0, 0, 0));
488
489 /**
490 * Renders the wallpaper asyncronously with the given parameters. When the rendering is
491 * complete, the renderCompleted signal is emitted.
492 *
493 * @param image the raw QImage
494 * @param size the size to render the image as
495 * @param resizeMethod the method to use when resizing the image to fit size, @see
496 * ResizeMethod
497 * @param color the color to use to pad the rendered image if it doesn't take up the
498 * entire size with the given ResizeMethod
499 * @since 4.7.4
500 */
501 void render(const QImage &image, const QSize &size,
502 Wallpaper::ResizeMethod resizeMethod = ScaledResize,
503 const QColor &color = QColor(0, 0, 0));
504
505 /**
506 * Sets whether or not to cache on disk the results of calls to render. If the wallpaper
507 * changes often or is innexpensive to render, then it's probably best not to cache them.
508 *
509 * The default is not to cache.
510 *
511 * @see render
512 * @param useCache true to cache rendered papers on disk, false not to cache
513 * @since 4.3
514 */
515 void setUsingRenderingCache(bool useCache);
516
517 /**
518 * Tries to load pixmap with the specified key from cache.
519 *
520 * @param key the name to use in the cache for this image
521 * @param image the image object to populate with the resulting data if found
522 * @param lastModified if non-zero, the time stamp is also checked on the file,
523 * and must be newer than the timestamp to be loaded
524 *
525 * @return true when pixmap was found and loaded from cache, false otherwise
526 * @since 4.3
527 **/
528 bool findInCache(const QString &key, QImage &image, unsigned int lastModified = 0);
529
530 /**
531 * Insert specified pixmap into the cache if usingRenderingCache.
532 * If the cache already contains pixmap with the specified key then it is
533 * overwritten.
534 *
535 * @param key the name use in the cache for this image; if the image is specific
536 * to this wallpaper plugin, consider including the name() as part of
537 * the cache key to avoid collisions with other plugins.
538 * @param image the image to store in the cache; passing in a null image will cause
539 * the cached image to be removed from the cache
540 *
541 * @since 4.3
542 **/
543 void insertIntoCache(const QString& key, const QImage &image);
544
545 /**
546 * Sets the contextual actions for this wallpaper.
547 *
548 * @param actions A list of contextual actions for this wallpaper
549 *
550 * @since 4.4
551 **/
552 void setContextualActions(const QList<QAction*> &actions);
553
554 //FIXME: KDE5, this must be moved to the dptr
555 QList<QAction*> contextActions;
556
557 /**
558 * Sets whether the configuration user interface of the wallpaper should have
559 * a live preview rendered by a Wallpaper instance. note: this is just an
560 * hint, the configuration user interface can choose to ignore it
561 *
562 * @param preview true if a preview should be shown
563 * @since 4.6
564 */
565 void setPreviewDuringConfiguration(const bool preview);
566
567 private:
568 Q_PRIVATE_SLOT(d, void newRenderCompleted(const WallpaperRenderRequest &request,
569 const QImage &image))
570 Q_PRIVATE_SLOT(d, void initScript())
571
572 friend class WallpaperPackage;
573 friend class WallpaperPrivate;
574 friend class WallpaperScript;
575 friend class WallpaperWithPaint;
576 friend class ContainmentPrivate;
577 WallpaperPrivate *const d;
578};
579
580} // Plasma namespace
581
582/**
583 * Register a wallpaper when it is contained in a loadable module
584 */
585#define K_EXPORT_PLASMA_WALLPAPER(libname, classname) \
586K_PLUGIN_FACTORY(factory, registerPlugin<classname>();) \
587K_EXPORT_PLUGIN(factory("plasma_wallpaper_" #libname)) \
588K_EXPORT_PLUGIN_VERSION(PLASMA_VERSION)
589
590#endif // multiple inclusion guard
591