OSDN Git Service

c0eab6ba450dd6493e9d2f5674c4dfdac3f5899b
[kde/kde-extraapps.git] / kdeplasma-addons / wallpapers / weather / weatherwallpaper.cpp
1 /***************************************************************************
2  *   Copyright (C) 2009 by Jonathan Thomas <echidnaman@kubuntu.org>        *
3  *   Copyright (C) 2007-2009 by Shawn Starr <shawn.starr@rogers.com>       *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or         *
6  *   modify it under the terms of the GNU General Public License as        *
7  *   published by the Free Software Foundation; either version 2 of        *
8  *   the License or (at your option) version 3 or any later version        *
9  *   accepted by the membership of KDE e.V. (or its successor approved     *
10  *   by the membership of KDE e.V.), which shall act as a proxy            *
11  *   defined in Section 14 of version 3 of the license.                    *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
20  ***************************************************************************/
21
22 #include "weatherwallpaper.h"
23
24 // Qt includes
25 #include <QPainter>
26 #include <QEasingCurve>
27 #include <QPropertyAnimation>
28
29 // KDE includes
30 #include <KFileDialog>
31 #include <KLocalizedString>
32 #include <KPushButton>
33 #include <KStandardDirs>
34 #include <KImageIO>
35 #include <Plasma/Animator>
36 #include <Plasma/Theme>
37
38 // Libplasmaweather includes
39 #include "plasmaweather/weatherconfig.h"
40 #include "plasmaweather/weatherlocation.h"
41
42 // Own includes
43 #include "backgroundlistmodel.h"
44 #include "backgrounddelegate.h"
45
46 K_EXPORT_PLASMA_WALLPAPER(weather, WeatherWallpaper)
47
48 WeatherWallpaper::WeatherWallpaper(QObject * parent, const QVariantList & args )
49     : Plasma::Wallpaper(parent, args)
50     , m_configWidget(0)
51     , m_weatherLocation(0)
52     , m_advancedDialog(0)
53     , m_fileDialog(0)
54     , m_fadeValue(0)
55     , m_animation(0)
56     , m_model(0)
57 {
58     connect(this, SIGNAL(renderHintsChanged()), this, SLOT(calculateGeometry()));
59     connect(this, SIGNAL(renderCompleted(QImage)), this, SLOT(updateBackground(QImage)));
60 }
61
62 WeatherWallpaper::~WeatherWallpaper()
63 {
64     delete m_animation;
65 }
66
67 void WeatherWallpaper::init(const KConfigGroup & config)
68 {
69     locationEngine = dataEngine(QLatin1String("geolocation"));
70     // Connect to weather engine.
71     weatherEngine = dataEngine(QLatin1String("weather"));
72
73     // Set custom weather options
74     m_source = config.readEntry("source");
75     m_weatherUpdateTime = config.readEntry("updateWeather", 30);
76
77     m_color = config.readEntry("wallpapercolor", QColor(56, 111, 150));
78     m_usersWallpapers = config.readEntry("userswallpapers", QStringList());
79     m_resizeMethod = (ResizeMethod)config.readEntry("wallpaperposition", (int)ScaledResize);
80
81     m_animation = new QPropertyAnimation(this, "fadeValue");
82     m_animation->setProperty("easingCurve", QEasingCurve::InQuad);
83     m_animation->setProperty("duration", 1000);
84     m_animation->setProperty("startValue", 0.0);
85     m_animation->setProperty("endValue", 1.0);
86
87     const QString defaultWallpaper = Plasma::Theme::defaultTheme()->wallpaperPath();
88     m_weatherMap[QLatin1String("weather-clear")] = config.readEntry("clearPaper", defaultWallpaper);
89     m_weatherMap[QLatin1String("weather-few-clouds")] = config.readEntry("partlyCloudyPaper", defaultWallpaper);
90     m_weatherMap[QLatin1String("weather-clouds")] = config.readEntry("cloudyPaper", defaultWallpaper);
91     m_weatherMap[QLatin1String("weather-many-clouds")] = config.readEntry("manyCloudsPaper", defaultWallpaper);
92     m_weatherMap[QLatin1String("weather-showers")] = config.readEntry("showersPaper", defaultWallpaper);
93     m_weatherMap[QLatin1String("weather-showers-scattered")] = config.readEntry("showersScatteredPaper", defaultWallpaper);
94     m_weatherMap[QLatin1String("weather-rain")] = config.readEntry("rainPaper", defaultWallpaper);
95     m_weatherMap[QLatin1String("weather-mist")] = config.readEntry("mistPaper", defaultWallpaper);
96     m_weatherMap[QLatin1String("weather-storm")] = config.readEntry("stormPaper", defaultWallpaper);
97     m_weatherMap[QLatin1String("weather-scattered-storms")] = m_weatherMap[QLatin1String("weather-storm")];
98     m_weatherMap[QLatin1String("weather-hail")] = config.readEntry("hailPaper", defaultWallpaper);
99     m_weatherMap[QLatin1String("weather-snow")] = config.readEntry("snowPaper", defaultWallpaper);
100     m_weatherMap[QLatin1String("weather-snow-scattered")] = config.readEntry("snowScatteredPaper", defaultWallpaper);
101     m_weatherMap[QLatin1String("weather-few-clouds-night")] = config.readEntry("partlyCloudyNightPaper", defaultWallpaper);
102     m_weatherMap[QLatin1String("weather-clouds-night")] = config.readEntry("cloudyNightPaper", defaultWallpaper);
103     m_weatherMap[QLatin1String("weather-clear-night")] = config.readEntry("clearNightPaper", defaultWallpaper);
104     m_weatherMap[QLatin1String("weather-freezing-rain")] = config.readEntry("freezingRainPaper", defaultWallpaper);
105     m_weatherMap[QLatin1String("weather-snow-rain")] = config.readEntry("snowRainPaper", defaultWallpaper);
106
107     calculateGeometry();
108     connectWeatherSource();
109 }
110
111 void WeatherWallpaper::save(KConfigGroup & config)
112 {
113     QString oldSource(m_source);
114     int oldInterval = m_weatherUpdateTime;
115
116     if (m_configWidget) {
117         m_source = m_configWidget->source();
118         m_weatherUpdateTime = m_configWidget->updateInterval();
119     }
120     if (m_source != oldSource || m_weatherUpdateTime != oldInterval) {
121         if (!oldSource.isEmpty()) {
122             weatherEngine->disconnectSource(oldSource, this);
123         }
124         if (!m_source.isEmpty()) {
125             connectWeatherSource();
126         }
127     }
128     config.writeEntry("source", m_source);
129     config.writeEntry("updateWeather", m_weatherUpdateTime);
130     config.writeEntry("wallpaperposition", (int)m_resizeMethod);
131     config.writeEntry("wallpapercolor", m_color);
132     config.writeEntry("userswallpapers", m_usersWallpapers);
133     // Save custom wallpaper/weather pairings
134     config.writeEntry("clearPaper", m_weatherMap[QLatin1String("weather-clear")]);
135     config.writeEntry("partlyCloudyPaper", m_weatherMap[QLatin1String("weather-few-clouds")]);
136     config.writeEntry("cloudyPaper", m_weatherMap[QLatin1String("weather-clouds")]);
137     config.writeEntry("manyCloudsPaper", m_weatherMap[QLatin1String("weather-many-clouds")]);
138     config.writeEntry("showersPaper", m_weatherMap[QLatin1String("weather-showers")]);
139     config.writeEntry("showersScatteredPaper", m_weatherMap[QLatin1String("weather-showers-scattered")]);
140     config.writeEntry("rainPaper", m_weatherMap[QLatin1String("weather-rain")]);
141     config.writeEntry("mistPaper", m_weatherMap[QLatin1String("weather-mist")]);
142     config.writeEntry("stormPaper", m_weatherMap[QLatin1String("weather-storm")]);
143     config.writeEntry("hailPaper", m_weatherMap[QLatin1String("weather-hail")]);
144     config.writeEntry("snowPaper", m_weatherMap[QLatin1String("weather-snow")]);
145     config.writeEntry("snowScatteredPaper", m_weatherMap[QLatin1String("weather-snow-scattered")]);
146     config.writeEntry("partlyCloudyNightPaper", m_weatherMap[QLatin1String("weather-few-clouds-night")]);
147     config.writeEntry("cloudyNightPaper", m_weatherMap[QLatin1String("weather-clouds-night")]);
148     config.writeEntry("clearNightPaper", m_weatherMap[QLatin1String("weather-clear-night")]);
149     config.writeEntry("freezingRainPaper", m_weatherMap[QLatin1String("weather-freezing-rain")]);
150     config.writeEntry("snowRainPaper", m_weatherMap[QLatin1String("weather-snow-rain")]);
151 }
152
153 void WeatherWallpaper::configWidgetDestroyed()
154 {
155     m_configWidget = 0;
156 }
157
158 void WeatherWallpaper::advancedDialogDestroyed()
159 {
160     m_advancedDialog = 0;
161     m_model = 0;
162 }
163
164 QWidget * WeatherWallpaper::createConfigurationInterface(QWidget * parent)
165 {
166     QWidget *top = new QWidget(parent);
167     QVBoxLayout *layout = new QVBoxLayout(top);
168     layout->setMargin(0);
169     m_configWidget = new WeatherConfig(top);
170     connect(m_configWidget, SIGNAL(destroyed(QObject*)), this, SLOT(configWidgetDestroyed()));
171     m_configWidget->setDataEngines(locationEngine, weatherEngine);
172     m_configWidget->setSource(m_source);
173     m_configWidget->setIon("wettercom");
174     m_configWidget->setUpdateInterval(m_weatherUpdateTime);
175     m_configWidget->setConfigurableUnits(WeatherConfig::None);
176     m_configWidget->setHeadersVisible(false);
177     layout->addWidget(m_configWidget);
178
179     QHBoxLayout *buttonLayout = new QHBoxLayout;
180     KPushButton *buttonAdvanced = new KPushButton(m_configWidget);
181     buttonAdvanced->setText( i18n("&Advanced..."));
182     m_configWidget->layout()->addWidget(buttonAdvanced);
183     buttonLayout->addStretch();
184     buttonLayout->addWidget(buttonAdvanced);
185     layout->addLayout(buttonLayout);
186
187     connect(buttonAdvanced, SIGNAL(clicked()), this, SLOT(showAdvancedDialog()));
188     connect(this, SIGNAL(settingsChanged(bool)), parent, SLOT(settingsChanged(bool)));
189     connect(m_configWidget, SIGNAL(settingsChanged()), this, SIGNAL(settingsChanged()));
190
191     return top;
192 }
193
194 void WeatherWallpaper::calculateGeometry()
195 {
196     m_size = boundingRect().size().toSize();
197 }
198
199 void WeatherWallpaper::paint(QPainter * painter, const QRectF & exposedRect)
200 {
201     // Check if geometry changed
202     if (m_size != boundingRect().size().toSize()) {
203         calculateGeometry();
204         if (!m_size.isEmpty() && !m_img.isEmpty()) { // We have previous image
205             renderWallpaper();
206             return;
207         }
208     }
209
210     if (m_pixmap.isNull()) {
211         painter->fillRect(exposedRect, QBrush(m_color));
212         return;
213     }
214
215     if (painter->worldMatrix() == QMatrix()) {
216         // draw the background untransformed when possible;(saves lots of per-pixel-math)
217         painter->resetTransform();
218     }
219
220     // blit the background (saves all the per-pixel-products that blending does)
221     painter->setCompositionMode(QPainter::CompositionMode_Source);
222
223     // for pixmaps we draw only the exposed part (untransformed since the
224     // bitmapBackground already has the size of the viewport)
225     painter->drawPixmap(exposedRect, m_pixmap, exposedRect.translated(-boundingRect().topLeft()));
226
227     if (!m_oldFadedPixmap.isNull()) {
228         // Put old faded image on top.
229         painter->setCompositionMode(QPainter::CompositionMode_SourceAtop);
230         painter->drawPixmap(exposedRect, m_oldFadedPixmap,
231                             exposedRect.translated(-boundingRect().topLeft()));
232     }
233 }
234
235 void WeatherWallpaper::loadImage()
236 {
237     m_wallpaper = m_weatherMap.value(m_condition);
238
239     if (m_wallpaper.isEmpty()) {
240        QHashIterator<QString, QString> it(m_weatherMap);
241        while (it.hasNext()) {
242            it.next();
243            if (m_condition.startsWith(it.key())) {
244                m_wallpaper = it.value();
245                break;
246            }
247        }
248     }
249
250     if (m_wallpaper.isEmpty()) {
251         m_wallpaper = Plasma::Theme::defaultTheme()->wallpaperPath();
252     }
253
254     Plasma::Package b(m_wallpaper, packageStructure(this));
255     QString img = b.filePath("preferred");
256
257     if (img.isEmpty()) {
258         img = m_wallpaper;
259     }
260
261     if (!m_size.isEmpty()) {
262         renderWallpaper(img);
263     }
264 }
265
266 void WeatherWallpaper::showAdvancedDialog()
267 {
268     if (m_advancedDialog == 0) {
269         m_advancedDialog = new KDialog;
270         m_advancedUi.setupUi(m_advancedDialog->mainWidget());
271         m_advancedDialog->mainWidget()->layout()->setMargin(0);
272
273         m_advancedDialog->setCaption(i18n("Advanced Wallpaper Settings"));
274         m_advancedDialog->setButtons(KDialog::Ok | KDialog::Cancel);
275
276         qreal ratio = m_size.isEmpty() ? 1.0 : m_size.width() / qreal(m_size.height());
277         m_model = new BackgroundListModel(ratio, this, m_advancedDialog);
278         m_model->setResizeMethod(m_resizeMethod);
279         m_model->reload(m_usersWallpapers);
280         m_advancedUi.m_wallpaperView->setModel(m_model);
281         m_advancedUi.m_wallpaperView->setItemDelegate(new BackgroundDelegate(m_advancedUi.m_wallpaperView->view(),
282                                                                              ratio, m_advancedDialog));
283         m_advancedUi.m_wallpaperView->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
284
285         connect(m_advancedUi.m_conditionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(conditionChanged(int)));
286         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-clear")), i18nc("weather condition", "Clear"), QLatin1String("weather-clear"));
287         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-few-clouds")), i18n("Partly Cloudy"), QLatin1String("weather-few-clouds"));
288         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-clouds")), i18n("Cloudy"), QLatin1String("weather-clouds"));
289         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-many-clouds")), i18n("Very Cloudy"), QLatin1String("weather-many-clouds"));
290         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-showers")), i18n("Showering"), QLatin1String("weather-showers"));
291         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-showers-scattered")), i18n("Scattered Showers"), QLatin1String("weather-showers-scattered"));
292         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-showers")), i18n("Rainy"), QLatin1String("weather-rain"));
293         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-mist")), i18n("Misty"), QLatin1String("weather-mist"));
294         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-storm")), i18n("Storming"), QLatin1String("weather-storm"));
295         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-hail")), i18n("Hailing"), QLatin1String("weather-hail"));
296         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-snow")), i18n("Snowing"), QLatin1String("weather-snow"));
297         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-snow-scattered")), i18n("Scattered Snow"), QLatin1String("weather-snow-scattered"));
298         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-few-clouds-night")), i18n("Partly Cloudy Night"), QLatin1String("weather-few-clouds-night"));
299         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-clouds-night")), i18n("Cloudy Night"), QLatin1String("weather-clouds-night"));
300         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-clear-night")), i18n("Clear Night"), QLatin1String("weather-clear-night"));
301         m_advancedUi.m_conditionCombo->addItem(KIcon(QLatin1String("weather-snow-rain")), i18n("Mixed Precipitation"), QLatin1String("weather-snow-rain"));
302         // Set to the current weather condition
303         m_advancedUi.m_conditionCombo->setCurrentIndex(m_advancedUi.m_conditionCombo->findData(m_condition));
304
305
306         connect(m_advancedUi.m_wallpaperView, SIGNAL(currentIndexChanged(int)), this, SLOT(pictureChanged(int)));
307
308         m_advancedUi.m_pictureUrlButton->setIcon(KIcon(QLatin1String("document-open")));
309         connect(m_advancedUi.m_pictureUrlButton, SIGNAL(clicked()), this, SLOT(showFileDialog()));
310
311         m_advancedUi.m_emailLine->setTextInteractionFlags(Qt::TextSelectableByMouse);
312
313         m_advancedUi.m_resizeMethod->addItem(i18n("Scaled & Cropped"), ScaledAndCroppedResize);
314         m_advancedUi.m_resizeMethod->addItem(i18n("Scaled"), ScaledResize);
315         m_advancedUi.m_resizeMethod->addItem(i18n("Scaled, keep proportions"), MaxpectResize);
316         m_advancedUi.m_resizeMethod->addItem(i18n("Centered"), CenteredResize);
317         m_advancedUi.m_resizeMethod->addItem(i18n("Tiled"), TiledResize);
318         m_advancedUi.m_resizeMethod->addItem(i18n("Center Tiled"), CenterTiledResize);
319         for (int i = 0; i < m_advancedUi.m_resizeMethod->count(); ++i) {
320             if (m_resizeMethod == m_advancedUi.m_resizeMethod->itemData(i).value<int>()) {
321                 m_advancedUi.m_resizeMethod->setCurrentIndex(i);
322                 break;
323             }
324         }
325         connect(m_advancedUi.m_resizeMethod, SIGNAL(currentIndexChanged(int)),
326                 this, SLOT(positioningChanged(int)));
327
328         m_advancedUi.m_color->setColor(m_color);
329         connect(m_advancedUi.m_color, SIGNAL(changed(QColor)), this, SLOT(colorChanged(QColor)));
330     }
331     KDialog::centerOnScreen(m_advancedDialog);
332     connect(m_advancedDialog, SIGNAL(destroyed(QObject*)), this, SLOT(advancedDialogDestroyed()));
333     m_advancedDialog->show();
334 }
335
336 void WeatherWallpaper::colorChanged(const QColor& color)
337 {
338     m_color = color;
339
340     emit settingsChanged(true);
341
342     loadImage();
343 }
344
345 void WeatherWallpaper::pictureChanged(int index)
346 {
347     if (index == -1 || !m_model) {
348         return;
349     }
350
351     Plasma::Package *b = m_model->package(index);
352     if (!b) {
353         return;
354     }
355
356     QString conditionIndexValue = m_advancedUi.m_conditionCombo->itemData(m_advancedUi.m_conditionCombo->currentIndex()).toString();
357     fillMetaInfo(b);
358     if (b->structure()->contentsPrefix().isEmpty()) {
359         // it's not a full package, but a single paper
360         m_weatherMap[conditionIndexValue] = b->filePath("preferred");
361     } else {
362         m_weatherMap[conditionIndexValue] = b->path();
363     }
364
365     emit settingsChanged(true);
366
367     loadImage();
368 }
369
370 void WeatherWallpaper::conditionChanged(int index)
371 {
372     if (index == -1) {
373         return;
374     }
375     QString conditionIndexValue = m_advancedUi.m_conditionCombo->itemData(index).toString();
376     QString paper = m_weatherMap[conditionIndexValue];
377
378     int modelIndex = m_model->indexOf(paper);
379     if (modelIndex != -1) {
380         m_advancedUi.m_wallpaperView->setCurrentIndex(modelIndex);
381         Plasma::Package *b = m_model->package(modelIndex);
382         if (b) {
383             fillMetaInfo(b);
384         }
385     }
386
387     emit settingsChanged(true);
388 }
389
390 void WeatherWallpaper::positioningChanged(int index)
391 {
392     m_resizeMethod = (ResizeMethod)m_advancedUi.m_resizeMethod->itemData(index).value<int>();
393     loadImage();
394
395     setResizeMethodHint(m_resizeMethod);
396
397     if (m_model) {
398         m_model->setResizeMethod(m_resizeMethod);
399     }
400
401     emit settingsChanged(true);
402 }
403
404 void WeatherWallpaper::fillMetaInfo(Plasma::Package *b)
405 {
406     // Prepare more user-friendly forms of some pieces of data.
407     // - license by config is more a of a key value,
408     //   try to get the proper name if one of known licenses.
409
410     // not needed for now...
411     //QString license = b->license();
412     /*
413     KAboutLicense knownLicense = KAboutLicense::byKeyword(license);
414     if (knownLicense.key() != KAboutData::License_Custom) {
415         license = knownLicense.name(KAboutData::ShortName);
416     }
417     */
418     // - last ditch attempt to localize author's name, if not such by config
419     //   (translators can "hook" names from outside if resolute enough).
420     QString author = b->metadata().author();
421     if (author.isEmpty()) {
422         setMetadata(m_advancedUi.m_authorLine, QString());
423         m_advancedUi.m_authorLabel->setAlignment(Qt::AlignLeft);
424     } else {
425         QString authorIntl = i18nc("Wallpaper info, author name", "%1", author);
426         m_advancedUi.m_authorLabel->setAlignment(Qt::AlignRight);
427         setMetadata(m_advancedUi.m_authorLine, authorIntl);
428     }
429     setMetadata(m_advancedUi.m_licenseLine, QString());
430     setMetadata(m_advancedUi.m_emailLine, QString());
431     m_advancedUi.m_emailLabel->hide();
432     m_advancedUi.m_licenseLabel->hide();
433 }
434
435 bool WeatherWallpaper::setMetadata(QLabel *label, const QString &text)
436 {
437     if (text.isEmpty()) {
438         label->hide();
439         return false;
440     }
441     else {
442         label->show();
443         label->setText(text);
444         return true;
445     }
446 }
447
448 void WeatherWallpaper::showFileDialog()
449 {
450     if (!m_fileDialog) {
451         m_fileDialog = new KFileDialog(KUrl(), KImageIO::pattern(KImageIO::Reading), m_advancedDialog);
452         m_fileDialog->setOperationMode(KFileDialog::Opening);
453         m_fileDialog->setInlinePreviewShown(true);
454         m_fileDialog->setCaption(i18n("Select Wallpaper Image File"));
455         m_fileDialog->setModal(false);
456     }
457
458     m_fileDialog->show();
459     m_fileDialog->raise();
460     m_fileDialog->activateWindow();
461
462     connect(m_fileDialog, SIGNAL(okClicked()), this, SLOT(wallpaperBrowseCompleted()));
463     connect(m_fileDialog, SIGNAL(destroyed(QObject*)), this, SLOT(fileDialogFinished()));
464 }
465
466 void WeatherWallpaper::fileDialogFinished()
467 {
468     m_fileDialog = 0;
469 }
470
471 void WeatherWallpaper::wallpaperBrowseCompleted()
472 {
473     Q_ASSERT(m_model);
474
475     const QFileInfo info(m_fileDialog->selectedFile());
476
477     //the full file path, so it isn't broken when dealing with symlinks
478     const QString wallpaper = info.canonicalFilePath();
479
480     if (wallpaper.isEmpty()) {
481         return;
482     }
483
484     if (m_model->contains(wallpaper)) {
485         m_advancedUi.m_wallpaperView->setCurrentIndex(m_model->indexOf(wallpaper));
486         return;
487     }
488
489     // add background to the model
490     m_model->addBackground(wallpaper);
491
492     // select it
493     int index = m_model->indexOf(wallpaper);
494     if (index != -1) {
495         m_advancedUi.m_wallpaperView->setCurrentIndex(index);
496     }
497     // save it
498     m_usersWallpapers << wallpaper;
499 }
500
501 void WeatherWallpaper::renderWallpaper(const QString& image)
502 {
503     if (!image.isEmpty()) {
504         m_img = image;
505     }
506
507     if (m_img.isEmpty()) {
508         return;
509     }
510
511     render(m_img, m_size, m_resizeMethod, m_color);
512 }
513
514 void WeatherWallpaper::connectWeatherSource()
515 {
516     if (m_source.isEmpty()) {
517         // A location probably hasn't been configured, so call loadImage to load
518         // the default wallpaper in case we can't guess later
519         loadImage();
520         // We can see if we can be nice and figure out where the user is
521         m_weatherLocation = new WeatherLocation(this);
522         connect(m_weatherLocation, SIGNAL(valid(QString)),
523                 this, SLOT(locationReady(QString)));
524         m_weatherLocation->setDataEngines(locationEngine, weatherEngine);
525         m_weatherLocation->getDefault("wettercom");
526     } else {
527         weatherEngine->connectSource(m_source, this, m_weatherUpdateTime * 60 * 1000);
528     }
529 }
530
531 void WeatherWallpaper::locationReady(const QString &source)
532 {
533     m_source = source;
534     if (!m_source.isEmpty()) {
535         if (m_configWidget) {
536             m_configWidget->setSource(m_source);
537         }
538         connectWeatherSource();
539     }
540 }
541
542 void WeatherWallpaper::updateBackground(const QImage &img)
543 {
544     m_oldPixmap = m_pixmap;
545     m_oldFadedPixmap = m_oldPixmap;
546     m_pixmap = QPixmap::fromImage(img);
547
548     if (!m_oldPixmap.isNull()) {
549         m_animation->start();
550     } else {
551         emit update(boundingRect());
552     }
553 }
554
555 void WeatherWallpaper::updateScreenshot(QPersistentModelIndex index)
556 {
557     if (m_advancedDialog) {
558         m_advancedUi.m_wallpaperView->view()->update(index);
559     }
560 }
561
562 qreal WeatherWallpaper::fadeValue()
563 {
564     return m_fadeValue;
565 }
566
567 void WeatherWallpaper::setFadeValue(qreal value)
568 {
569     m_fadeValue = value;
570
571     //If we are done, delete the pixmaps and don't draw.
572     if (qFuzzyCompare(m_fadeValue, qreal(1.0))) {
573         m_oldFadedPixmap = QPixmap();
574         m_oldPixmap = QPixmap();
575         emit update(boundingRect());
576         return;
577     }
578
579     //Create the faded image.
580     m_oldFadedPixmap.fill(Qt::transparent);
581
582     QPainter p;
583     p.begin(&m_oldFadedPixmap);
584     p.drawPixmap(0, 0, m_oldPixmap);
585
586     p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
587     p.fillRect(m_oldFadedPixmap.rect(), QColor(0, 0, 0, 254 * (1-m_fadeValue)));//255*((150 - m_fadeValue)/150)));
588
589     p.end();
590
591     emit update(boundingRect());
592 }
593
594 void WeatherWallpaper::dataUpdated(const QString &source, const Plasma::DataEngine::Data &data)
595 {
596     Q_UNUSED(source);
597     if (data.isEmpty()) {
598         return;
599     }
600
601     m_condition = data[QLatin1String("Condition Icon")].toString();
602
603     loadImage();
604 }
605
606 #include "moc_weatherwallpaper.cpp"