1
/***************************************************************************
2
* Copyright 2007 by Anne-Marie Mahfouf <annma@kde.org> *
3
* Copyright 2007 by Antonio Vinci <mercurio@personellarete.it> *
4
* Copyright 2008 by Thomas Coopman <thomas.coopman@gmail.com> *
6
* This program is free software; you can redistribute it and/or modify *
7
* it under the terms of the GNU General Public License as published by *
8
* the Free Software Foundation; either version 2 of the License, or *
9
* (at your option) any later version. *
11
* This program is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU General Public License for more details. *
16
* You should have received a copy of the GNU General Public License *
17
* along with this program; if not, write to the *
18
* Free Software Foundation, Inc., *
19
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
20
***************************************************************************/
26
#include <QStyleOptionGraphicsItem>
27
#include <QGraphicsSceneDragDropEvent>
28
#include <QGraphicsLinearLayout>
32
#include <QStandardItemModel>
33
#include <QThreadPool>
36
#include <KConfigDialog>
37
#include <KSharedConfig>
40
#include <KDirSelectDialog>
41
#include <KServiceTypeTrader>
42
#include <kglobalsettings.h>
44
#include <Plasma/PaintUtils>
45
#include <Plasma/DataEngine>
46
#include <Plasma/ToolButton>
47
#include <Plasma/Frame>
48
#include <Plasma/ToolTipContent>
49
#include <Plasma/ToolTipManager>
53
#include "configdialog.h"
55
#include "slideshow.h"
56
#include "imagescaler.h"
58
Frame::Frame(QObject *parent, const QVariantList &args)
59
: Plasma::Applet(parent, args),
63
setHasConfigurationInterface(true);
65
setAcceptsHoverEvents(true);
66
setCacheMode(QGraphicsItem::DeviceCoordinateCache);
68
//make size()==contentssize(), resolves auto-shrinking once for all
69
setContentsMargins(0, 0, 0, 0);
70
m_mySlideShow = new SlideShow(this);
72
m_currentUrl = args.value(0).toString();
74
m_currentUrl = KUrl();
76
setAssociatedApplicationUrls(m_currentUrl);
78
m_updateTimer = new QTimer(this);
79
m_updateTimer->setSingleShot(true);
80
connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(delayedUpdateSize()));
82
m_autoUpdateTimer = new QTimer(this);
83
m_autoUpdateTimer->setSingleShot(true);
84
connect(m_autoUpdateTimer, SIGNAL(timeout()), this, SLOT(reloadImage()));
89
m_autoUpdateTimer->stop();
94
bool frameReceivedUrlArgs = false;
95
if (!m_currentUrl.isEmpty()) {
96
frameReceivedUrlArgs = true;
99
m_currentDay = QDate::currentDate();
103
// Frame & Shadow dimensions
107
// Initialize the slideshow timer
108
connect(m_mySlideShow, SIGNAL(pictureUpdated()), this, SLOT(scalePictureAndUpdate()));
110
connect(&m_waitForResize, SIGNAL(timeout()), this, SLOT(scalePictureAndUpdate()));
111
m_waitForResize.setSingleShot(true);
112
m_waitForResize.setInterval(200);
117
KConfigGroup cg = config();
118
if (frameReceivedUrlArgs) {
119
cg.writeEntry("url", m_currentUrl);
120
emit configNeedsSaving();
123
m_menuPresent = false;
125
QAction *openAction = action("run associated application");
126
openAction->setIcon(SmallIcon("image-x-generic"));
127
openAction->setText(i18n("&Open Picture..."));
130
void Frame::configChanged()
133
KConfigGroup cg = config();
134
m_frameColor = cg.readEntry("frameColor", QColor(70, 90, 130)); //theme?
135
m_frame = cg.readEntry("frame", false);
136
m_shadow = cg.readEntry("shadow", true);
137
m_roundCorners = cg.readEntry("roundCorners", false);
138
m_slideShow = cg.readEntry("slideshow", false);
139
m_random = cg.readEntry("random", false);
140
m_recursiveSlideShow = cg.readEntry("recursive slideshow", false);
141
m_slideShowPaths = cg.readEntry("slideshow paths", QStringList());
142
m_slideshowTime = cg.readEntry("slideshow time", 60); // default to 1 minute
143
m_currentUrl = cg.readEntry("url", m_currentUrl);
144
setAssociatedApplicationUrls(m_currentUrl);
145
m_potdProvider = cg.readEntry("potdProvider", QString());
146
m_potd = cg.readEntry("potd", false);
147
m_autoUpdateIntervall = cg.readEntry("autoupdate time", 0);
150
void Frame::slotOpenPicture()
152
if (!hasAuthorization("LaunchApp")) {
158
url = m_mySlideShow->currentUrl();
163
if (!url.path().isEmpty()) {
168
void Frame::constraintsEvent(Plasma::Constraints constraints)
170
if (constraints & Plasma::FormFactorConstraint) {
171
setBackgroundHints(Plasma::Applet::NoBackground);
172
if (formFactor() == Plasma::Horizontal) {
175
} else if (formFactor() == Plasma::Vertical) {
181
//Restore widget geometry to image proportions
182
QSizeF sizeHint = contentSizeHint();
183
if (sizeHint != geometry().size()) {
185
emit appletTransformedItself();
188
m_updateTimer->start(400);
191
if (constraints & Plasma::SizeConstraint) {
192
//If on panel, keep geometry to 4:3 ratio
193
if (formFactor() == Plasma::Vertical) {
194
setMinimumSize(QSizeF(0, contentsRect().width()/1.33));
195
setMaximumSize(QSizeF(-1, contentsRect().width()/1.33));
196
} else if (formFactor() == Plasma::Horizontal) {
197
setMinimumSize(QSizeF(contentsRect().height()*1.33,0));
198
setMaximumSize(QSizeF(contentsRect().height()*1.33,-1));
205
min += m_frameOutline;
207
setMinimumSize(QSizeF(min, min));
208
setMaximumSize(QSizeF());
214
int x = contentsRect().center().x() - (m_slideFrame->size().width() / 2);
215
int y = contentsRect().bottom() - m_slideFrame->size().height() - 5;
216
m_slideFrame->setPos(x, y);
219
m_waitForResize.start();
220
m_updateTimer->start(400);
224
QSizeF Frame::contentSizeHint() const
226
if (!m_pictureSize.isEmpty() && (formFactor() == Plasma::Planar || formFactor() == Plasma::MediaCenter)) {
227
const qreal maxSize = qMax(contentsRect().width(), contentsRect().height());
228
QSize size = m_pictureSize;
229
size.scale(maxSize, maxSize, Qt::KeepAspectRatio);
232
return contentsRect().size();
236
QSizeF Frame::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
238
if (which != Qt::PreferredSize) {
239
return Applet::sizeHint(which, constraint);
241
return m_pictureSize;
245
void Frame::scalePictureAndUpdate()
247
QImage img = m_mySlideShow->image();
248
ImageScaler *scaler = new ImageScaler(img, contentSizeHint().toSize());
249
connect(scaler, SIGNAL(scaled(const QImage&)), this, SLOT(imageScaled(const QImage&)));
250
QThreadPool::globalInstance()->start(scaler);
253
void Frame::imageScaled(const QImage &img)
259
void Frame::updatePicture()
261
m_pictureSize = m_mySlideShow->image().size();
262
QSizeF sizeHint = contentSizeHint();
263
int frameLines = qMin(m_frameOutline, (int)(sizeHint.height()/10));
264
const QSize contentsSize = sizeHint.toSize();
266
if (m_currentUrl.url().isEmpty() && m_mySlideShow->currentUrl().isEmpty()) {
267
setAssociatedApplicationUrls(KUrl::List());
269
setAssociatedApplicationUrls(m_mySlideShow->currentUrl());
272
if (sizeHint != geometry().size()) {
273
emit sizeHintChanged(Qt::PreferredSize);
277
kDebug() << "Rendering picture";
278
Plasma::ToolTipContent toolTipData;
279
toolTipData.setSubText(m_mySlideShow->currentUrl().fileName());
280
Plasma::ToolTipManager::self()->setContent(this, toolTipData);
282
// create a QPixmap which can be drawn in paintInterface()
283
QPixmap picture = QPixmap::fromImage(m_scaledImage);
285
if (picture.isNull()) {
289
m_pixmap = QPixmap(contentsSize);
290
m_pixmap.fill(Qt::transparent);
291
QPainter *p = new QPainter();
294
int roundingFactor = qMin(qreal(sizeHint.height() / 10), qreal(12.0)) * m_roundCorners;
295
int swRoundness = roundingFactor + frameLines / 2 * m_frame * m_roundCorners;
297
QRectF frameRect(QPoint(0, 0), contentsSize);
298
frameRect.adjust(m_swOutline, m_swOutline, -m_swOutline, -m_swOutline); //Pretty useless.
300
QSizeF scaledSize = frameRect.size();
301
scaledSize.scale(frameRect.size(), Qt::KeepAspectRatio);
302
frameRect = QRectF(QPoint(frameRect.x() + (frameRect.width() - scaledSize.width()) / 2,
303
frameRect.y() + (frameRect.height() - scaledSize.height()) / 2), scaledSize);
307
shadowRect = frameRect.adjusted(-frameLines, -frameLines,
308
frameLines, frameLines);
310
shadowRect = frameRect;
313
// The frame path. It will be used to draw the frame and clip the image.
314
QPainterPath framePath = Plasma::PaintUtils::roundedRectangle(frameRect, roundingFactor);
316
p->setRenderHint(QPainter::SmoothPixmapTransform, true);
317
p->setRenderHint(QPainter::Antialiasing, true);
321
// The shadow is a couple of lines with decreasing opacity painted around the path
322
p->setBrush(Qt::NoBrush);
323
QPen pen = QPen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin);
324
int shadowLines = qMin((int)(sizeHint.height() / 6), m_swOutline);
326
// The shadow is drawn from inside to the outside
327
shadowRect.adjust(+shadowLines, +shadowLines, -shadowLines, -shadowLines);
329
// Make the path to paint the frame in a bit smaller so it's inside the shadow
330
frameRect.adjust(+shadowLines, +shadowLines, -shadowLines, -shadowLines);
331
framePath = Plasma::PaintUtils::roundedRectangle(frameRect, roundingFactor);
333
// Paint the shadow's lines around the picture
334
for (int i = m_swOutline - shadowLines; i <= m_swOutline; i += 1) {
335
// It's important to change the opacity using the QColor, as
336
// QPainter->setOpacity() kills performance
337
qreal opacity = 0.7 * exp(-(i / (double)(m_swOutline / 3)));
338
pen.setColor(QColor(0, 0, 0, opacity * 254));
340
QPainterPath tr = Plasma::PaintUtils::roundedRectangle(shadowRect, swRoundness + i);
342
shadowRect.adjust(-1, -1, + 1, + 1);
346
p->setBrush(Qt::NoBrush);
350
m_frameColor.setAlphaF(0.5);
351
// The frame is painted twice as thick, the inner half lies behind the picture
352
// This is important to not make the corners look "cut out" when rounded
353
p->setPen(QPen(m_frameColor, frameLines * 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
354
p->drawPath(framePath);
358
// We save the painter here so the clipping only happens on the pixmap,
359
// not on pixmap, frame, shadow, etc
361
if (m_roundCorners) {
362
p->setClipPath(framePath);
365
// Respect the smoothScaling setting
366
p->setRenderHint(QPainter::SmoothPixmapTransform, true);
367
// draw our pixmap into the computed rectangle
368
p->drawPixmap(frameRect.toRect(), picture);
373
p->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
374
p->drawPath(framePath);
375
} else if (m_roundCorners) {
376
p->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
377
p->drawPath(framePath);
380
// Paint status text on top of it all
381
if (!m_mySlideShow->message().isEmpty()) {
382
int dist = frameRect.width() / 10;
383
QRect bgRect = frameRect.adjusted(dist-1, dist-1, -dist, -dist).toRect();
385
// The text's background rounded rectangle
386
QPainterPath bgPath = Plasma::PaintUtils::roundedRectangle(bgRect, bgRect.height()/15);
388
QColor c = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor);
390
QColor outline = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
391
outline.setAlphaF(.5);
394
p->setPen(QPen(outline, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
396
QString message = m_mySlideShow->message();
398
// Set the font and draw text
399
p->setRenderHint(QPainter::Antialiasing);
400
QFont textFont = Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont);
401
textFont.setPointSize(qMax(KGlobalSettings::smallestReadableFont().pointSize(), bgRect.height() / 6));
402
p->setFont(textFont);
405
option.setAlignment(Qt::AlignCenter);
406
option.setWrapMode(QTextOption::WordWrap);
408
preparePainter(p, bgRect, textFont, message);
410
p->setPen(QPen(Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
411
p->drawText(bgRect, message, option);
418
if (m_doAutoUpdate && !m_autoUpdateTimer->isActive()) {
419
kDebug() << "Autoupdate timer restarted:" << m_autoUpdateIntervall << "s";
420
m_autoUpdateTimer->start(m_autoUpdateIntervall * 1000);
424
QRect Frame::preparePainter(QPainter *p, const QRect &rect, const QFont &font, const QString &text)
427
QFont tmpFont = font;
430
// Starting with the given font, decrease its size until it'll fit in the
431
// given rect allowing wrapping where possible
436
tmpFont.setPointSize(qMax(KGlobalSettings::smallestReadableFont().pointSize(), tmpFont.pointSize() - 1));
439
const QFontMetrics fm(tmpFont);
440
int flags = Qt::TextWordWrap;
442
tmpRect = fm.boundingRect(rect, flags, text);
443
} while (tmpFont.pointSize() > KGlobalSettings::smallestReadableFont().pointSize() &&
444
(tmpRect.width() > rect.width() || tmpRect.height() > rect.height()));
451
void Frame::nextPicture()
453
m_mySlideShow->setUpdateInterval(0);
454
m_mySlideShow->nextPicture();
455
m_mySlideShow->setUpdateInterval(m_slideshowTime * 1000);
458
void Frame::previousPicture()
460
m_mySlideShow->setUpdateInterval(0);
461
m_mySlideShow->previousPicture();
462
m_mySlideShow->setUpdateInterval(m_slideshowTime * 1000);
467
QPointer<KDirSelectDialog> dialog = new KDirSelectDialog(KUrl(), true);
468
if (dialog->exec()) {
469
QString path = dialog->url().url();
470
if (!m_slideShowPaths.contains(path)) {
471
m_configDialog->imageUi.slideShowDirList->addItem(path);
478
void Frame::removeDir()
480
int row = m_configDialog->imageUi.slideShowDirList->currentRow();
482
m_configDialog->imageUi.slideShowDirList->takeItem(row);
487
void Frame::updateButtons()
489
int row = m_configDialog->imageUi.slideShowDirList->currentRow();
490
m_configDialog->imageUi.removeDirButton->setEnabled(row != -1);
493
void Frame::createConfigurationInterface(KConfigDialog *parent)
495
m_configDialog = new ConfigDialog(parent);
497
KService::List services = KServiceTypeTrader::self()->query("PlasmaPoTD/Plugin");
498
foreach(const KService::Ptr &service, services) {
499
const QString service_name(service->name());
500
const QVariant service_identifier(service->property("X-KDE-PlasmaPoTDProvider-Identifier", QVariant::String).toString());
501
m_configDialog->imageUi.potdComboBox->insertItem(m_configDialog->imageUi.potdComboBox->count(), service_name, service_identifier);
504
QStandardItemModel* model = static_cast<QStandardItemModel*>(m_configDialog->imageUi.pictureComboBox->model());
505
QStandardItem* item = model->item(2);
508
if (services.isEmpty())
509
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
511
item->setFlags(item->flags() | Qt::ItemIsEnabled);
514
parent->addPage(m_configDialog->imageSettings, i18n("Image"), icon());
515
parent->addPage(m_configDialog->appearanceSettings, i18n("Appearance"), "preferences-desktop-theme");
516
parent->setDefaultButton(KDialog::Ok);
517
parent->showButtonSeparator(true);
518
connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
519
connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
521
connect(m_configDialog->imageUi.removeDirButton, SIGNAL(clicked()), this, SLOT(removeDir()));
522
connect(m_configDialog->imageUi.addDirButton, SIGNAL(clicked()), this, SLOT(addDir()));
523
connect(m_configDialog->imageUi.slideShowDirList, SIGNAL(currentRowChanged(int)), this, SLOT(updateButtons()));
525
m_configDialog->setRoundCorners(m_roundCorners);
526
m_configDialog->setShadow(m_shadow);
527
m_configDialog->setShowFrame(m_frame);
528
m_configDialog->setFrameColor(m_frameColor);
531
m_configDialog->imageUi.pictureComboBox->setCurrentIndex(1);
533
m_configDialog->imageUi.pictureComboBox->setCurrentIndex(2);
535
m_configDialog->imageUi.pictureComboBox->setCurrentIndex(0);
538
m_configDialog->imageUi.randomCheckBox->setCheckState(m_random ? Qt::Checked : Qt::Unchecked);
539
m_configDialog->imageUi.recursiveCheckBox->setCheckState(m_recursiveSlideShow ? Qt::Checked : Qt::Unchecked);
541
if (!m_potdProvider.isEmpty())
542
m_configDialog->imageUi.potdComboBox->setCurrentIndex(m_configDialog->imageUi.potdComboBox->findData(m_potdProvider));
544
m_configDialog->imageUi.potdComboBox->setCurrentIndex(0);
546
m_configDialog->setCurrentUrl(m_currentUrl);
547
m_configDialog->imageUi.slideShowDirList->clear();
548
m_configDialog->imageUi.slideShowDirList->addItems(m_slideShowPaths);
549
m_configDialog->imageUi.removeDirButton->setEnabled(!m_slideShowPaths.isEmpty());
550
m_configDialog->imageUi.slideShowDelay->setTime(QTime(m_slideshowTime / 3600, (m_slideshowTime / 60) % 60, m_slideshowTime % 60));
551
m_configDialog->previewPicture(m_mySlideShow->image());
552
m_configDialog->imageUi.autoUpdateTime->setTime(QTime(m_autoUpdateIntervall / 3600, (m_autoUpdateIntervall / 60) % 60));
555
void Frame::configAccepted()
557
KConfigGroup cg = config();
559
m_roundCorners = m_configDialog->roundCorners();
560
cg.writeEntry("roundCorners", m_roundCorners);
561
m_shadow = m_configDialog->shadow();
562
cg.writeEntry("shadow", m_shadow);
563
m_frame = m_configDialog->showFrame();
564
cg.writeEntry("frame", m_frame);
565
m_frameColor = m_configDialog->frameColor();
566
cg.writeEntry("frameColor", m_frameColor);
568
bool wasPotd = m_potd;
570
if (m_configDialog->imageUi.pictureComboBox->currentIndex() == 1) {
573
} else if (m_configDialog->imageUi.pictureComboBox->currentIndex() == 2) {
581
m_random = m_configDialog->random();
582
cg.writeEntry("random", m_random);
583
m_currentUrl = m_configDialog->currentUrl();
584
setAssociatedApplicationUrls(m_currentUrl);
585
cg.writeEntry("url", m_currentUrl);
586
cg.writeEntry("slideshow", m_slideShow);
587
m_recursiveSlideShow = m_configDialog->imageUi.recursiveCheckBox->checkState() == Qt::Checked ? true : false;
588
cg.writeEntry("recursive slideshow", m_recursiveSlideShow);
589
m_slideShowPaths.clear();
591
for (int i = 0; i < m_configDialog->imageUi.slideShowDirList->count(); i++) {
592
m_slideShowPaths << m_configDialog->imageUi.slideShowDirList->item(i)->text();
594
cg.writeEntry("slideshow paths", m_slideShowPaths);
596
QTime timerTime = m_configDialog->imageUi.slideShowDelay->time();
597
m_slideshowTime = timerTime.second() + timerTime.minute() * 60 + timerTime.hour() * 3600;
598
cg.writeEntry("slideshow time", m_slideshowTime);
600
m_autoUpdateTimer->stop();
602
QTime AutoUpdateTimer = m_configDialog->imageUi.autoUpdateTime->time();
603
m_autoUpdateIntervall = AutoUpdateTimer.minute() * 60 + AutoUpdateTimer.hour() * 3600;
604
cg.writeEntry("autoupdate time", m_autoUpdateIntervall);
606
QString potdProvider = m_configDialog->imageUi.potdComboBox->itemData(m_configDialog->imageUi.potdComboBox->currentIndex()).toString();
608
if ((wasPotd && !m_potd) || (m_potd && potdProvider != m_potdProvider)) {
609
// if we go from potd to no potd, or if the provider changes, then we first want to
610
// stop the potd engine
614
m_potdProvider = potdProvider;
615
cg.writeEntry("potdProvider", m_potdProvider);
616
cg.writeEntry("potd", m_potd);
620
emit configNeedsSaving();
623
void Frame::stopPotd()
625
Plasma::DataEngine *engine = dataEngine("potd");
626
const QString identifier = m_potdProvider + ':' + m_currentDay.toString(Qt::ISODate);
627
engine->disconnectSource(identifier, m_mySlideShow);
628
m_autoUpdateTimer->stop();
631
void Frame::initSlideShow()
633
m_mySlideShow->setUpdateInterval(0);
634
m_doAutoUpdate = false;
637
m_mySlideShow->setRandom(m_random);
638
m_mySlideShow->setDirs(m_slideShowPaths, m_recursiveSlideShow);
639
m_mySlideShow->setUpdateInterval(m_slideshowTime * 1000);
641
m_dateChangedTimer = new QTimer( this );//change picture at midnight
642
connect( m_dateChangedTimer, SIGNAL( timeout() ), this, SLOT( checkDayChanged() ) );
643
m_dateChangedTimer->start( 60 * 60 * 1000 ); // every hour
644
Plasma::DataEngine *engine = dataEngine("potd");
645
const QString identifier = m_potdProvider + ':' + m_currentDay.toString(Qt::ISODate);
646
engine->connectSource(identifier, m_mySlideShow);
647
} else { //no slideshow so no random stuff
648
m_mySlideShow->setRandom(false);
649
m_mySlideShow->setImage(m_currentUrl.url());
651
if (m_autoUpdateIntervall > 0) {
652
m_doAutoUpdate = true;
656
scalePictureAndUpdate();
659
void Frame::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
661
// kDebug() << event->mimeData()->formats();
662
if (event->mimeData()->hasUrls()) {
663
event->acceptProposedAction();
669
void Frame::dropEvent(QGraphicsSceneDragDropEvent *event)
672
m_slideFrame->hide();
674
KUrl droppedUrl = (KUrl::List::fromMimeData(event->mimeData())).at(0);
675
kDebug() << "dropped URL" << droppedUrl.url();
676
if (droppedUrl.protocol() == "desktop") {
677
KUrl tmpUrl = KGlobalSettings::desktopPath() + droppedUrl.path();
680
// If the url is a local directory start slideshowmode
681
if (droppedUrl.isLocalFile() && QFileInfo(droppedUrl.path()).isDir()) {
682
m_slideShowPaths.clear();
683
m_slideShowPaths.append(droppedUrl.path());
686
kDebug() << "Remote URL" << droppedUrl.url();
687
m_currentUrl = droppedUrl;
688
setAssociatedApplicationUrls(m_currentUrl);
696
KConfigGroup cg = config();
697
cg.writeEntry("url", m_currentUrl);
698
cg.writeEntry("slideshow", m_slideShow);
699
cg.writeEntry("slideshow paths", m_slideShowPaths);
700
emit configNeedsSaving();
703
void Frame::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
707
m_slideFrame->show();
709
Applet::hoverEnterEvent(event);
712
void Frame::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
716
m_slideFrame->hide();
718
Applet::hoverLeaveEvent( event );
721
void Frame::checkSlideFrame()
724
m_slideFrame->hide();
727
m_slideFrame = new Plasma::Frame( this );
728
m_slideFrame->setZValue( 10 );
730
m_backButton = new Plasma::ToolButton(m_slideFrame);
731
m_backButton->setImage("widgets/arrows", "left-arrow");
732
m_backButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
733
m_backButton->setMaximumSize(IconSize(KIconLoader::MainToolbar), IconSize(KIconLoader::MainToolbar));
734
connect(m_backButton, SIGNAL(clicked()), this , SLOT(previousPicture()));
736
m_nextButton = new Plasma::ToolButton(m_slideFrame);
737
m_nextButton->setImage("widgets/arrows", "right-arrow");
738
m_nextButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
739
m_nextButton->setMaximumSize(IconSize(KIconLoader::MainToolbar), IconSize(KIconLoader::MainToolbar));
740
connect(m_nextButton, SIGNAL(clicked()), this , SLOT(nextPicture()));
742
QGraphicsLinearLayout *buttonsLayout = new QGraphicsLinearLayout();
743
buttonsLayout->addItem(m_backButton);
744
buttonsLayout->addItem(m_nextButton);
745
m_slideFrame->setLayout(buttonsLayout);
746
buttonsLayout->activate();
748
m_slideFrame->setFrameShadow( Plasma::Frame::Raised );
749
m_slideFrame->hide();
751
constraintsEvent(Plasma::SizeConstraint);
754
void Frame::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &rect)
758
// temporarily suspend the slideshow to allow time for loading the image
759
m_mySlideShow->setUpdateInterval(0);
762
p->drawPixmap(rect, m_pixmap);
765
// unsuspend the slideshow to allow time for loading the image
766
m_mySlideShow->setUpdateInterval(m_slideshowTime * 1000);
770
void Frame::delayedUpdateSize()
772
QSizeF sizeHint = contentSizeHint();
773
if (sizeHint != geometry().size()) {
775
emit appletTransformedItself();
779
void Frame::checkDayChanged()
781
if ( ( m_currentDay != QDate::currentDate() ) ) {
783
//keep after reloadImage()
784
m_currentDay = QDate::currentDate();
788
void Frame::reloadImage()
791
Plasma::DataEngine *engine = dataEngine("potd");
792
//disconnect yesterday's source
793
QString identifier = m_potdProvider + ':' + m_currentDay.toString(Qt::ISODate);
794
engine->disconnectSource(identifier, m_mySlideShow);
795
//connect today's source
796
identifier = m_potdProvider + ':' + QDate::currentDate().toString(Qt::ISODate);
797
engine->connectSource(identifier, m_mySlideShow);
799
m_mySlideShow->updateImage(m_currentUrl.url());