mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-23 18:32:53 +00:00
789 lines
27 KiB
C++
789 lines
27 KiB
C++
/***************************************************************************
|
|
* Copyright 2007 by Anne-Marie Mahfouf <annma@kde.org> *
|
|
* Copyright 2007 by Antonio Vinci <mercurio@personellarete.it> *
|
|
* Copyright 2008 by Thomas Coopman <thomas.coopman@gmail.com> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
|
|
***************************************************************************/
|
|
|
|
#include "frame.h"
|
|
|
|
#include <QPainter>
|
|
#include <QPixmap>
|
|
#include <QtGui/qstyleoption.h>
|
|
#include <QtGui/qgraphicssceneevent.h>
|
|
#include <QGraphicsLinearLayout>
|
|
#include <QPen>
|
|
#include <QCheckBox>
|
|
#include <QFileInfo>
|
|
#include <QStandardItemModel>
|
|
#include <Plasma/Corona>
|
|
#include <Plasma/Containment>
|
|
#include <Plasma/Wallpaper>
|
|
|
|
#include <KDebug>
|
|
#include <KConfigDialog>
|
|
#include <KSharedConfig>
|
|
#include <KToolInvocation>
|
|
#include <KUrl>
|
|
#include <KFileDialog>
|
|
#include <KServiceTypeTrader>
|
|
#include <kglobalsettings.h>
|
|
|
|
#include <Plasma/PaintUtils>
|
|
#include <Plasma/ToolButton>
|
|
#include <Plasma/Frame>
|
|
#include <Plasma/ToolTipContent>
|
|
#include <Plasma/ToolTipManager>
|
|
|
|
#include <math.h>
|
|
|
|
#include "configdialog.h"
|
|
#include "picture.h"
|
|
#include "slideshow.h"
|
|
|
|
void kSetContainmentWallpaper(Plasma::Containment *containment, const KUrl &url, const QString &urlMime)
|
|
{
|
|
|
|
if (containment->wallpaper() && containment->wallpaper()->supportsMimetype(urlMime)) {
|
|
containment->wallpaper()->setUrls(url);
|
|
} else {
|
|
KPluginInfo::List wallpaperList = Plasma::Wallpaper::listWallpaperInfoForMimetype(urlMime);
|
|
bool image = false;
|
|
foreach (const KPluginInfo &wallpaper, wallpaperList) {
|
|
if (wallpaper.pluginName() == "image") {
|
|
image = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (image) {
|
|
containment->setWallpaper("image");
|
|
} else if (!wallpaperList.isEmpty()) {
|
|
containment->setWallpaper(wallpaperList.at(0).name());
|
|
}
|
|
|
|
if (containment->wallpaper()) {
|
|
containment->wallpaper()->setUrls(url);
|
|
}
|
|
}
|
|
}
|
|
|
|
Frame::Frame(QObject *parent, const QVariantList &args)
|
|
: Plasma::Applet(parent, args),
|
|
m_configDialog(0),
|
|
m_slideFrame(0)
|
|
{
|
|
setHasConfigurationInterface(true);
|
|
setAcceptDrops(true);
|
|
setAcceptHoverEvents(true);
|
|
setCacheMode(QGraphicsItem::DeviceCoordinateCache);
|
|
resize(400, 300);
|
|
//make size()==contentssize(), resolves auto-shrinking once for all
|
|
setContentsMargins(0, 0, 0, 0);
|
|
m_mySlideShow = new SlideShow(this);
|
|
if (args.count()) {
|
|
m_currentUrl = args.value(0).toString();
|
|
} else {
|
|
m_currentUrl = KUrl();
|
|
}
|
|
setAssociatedApplicationUrls(m_currentUrl);
|
|
|
|
m_updateTimer = new QTimer(this);
|
|
m_updateTimer->setSingleShot(true);
|
|
connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(delayedUpdateSize()));
|
|
|
|
m_autoUpdateTimer = new QTimer(this);
|
|
m_autoUpdateTimer->setSingleShot(true);
|
|
connect(m_autoUpdateTimer, SIGNAL(timeout()), this, SLOT(reloadImage()));
|
|
}
|
|
|
|
Frame::~Frame()
|
|
{
|
|
m_autoUpdateTimer->stop();
|
|
}
|
|
|
|
void Frame::init()
|
|
{
|
|
Applet::init();
|
|
|
|
bool frameReceivedUrlArgs = false;
|
|
if (!m_currentUrl.isEmpty()) {
|
|
frameReceivedUrlArgs = true;
|
|
}
|
|
|
|
m_currentDay = QDate::currentDate();
|
|
|
|
m_slideNumber = 0;
|
|
|
|
// Frame & Shadow dimensions
|
|
m_frameOutline = 8;
|
|
m_swOutline = 8;
|
|
|
|
// Initialize the slideshow timer
|
|
connect(m_mySlideShow, SIGNAL(pictureUpdated()), this, SLOT(scalePictureAndUpdate()));
|
|
|
|
connect(&m_waitForResize, SIGNAL(timeout()), this, SLOT(scalePictureAndUpdate()));
|
|
m_waitForResize.setSingleShot(true);
|
|
m_waitForResize.setInterval(200);
|
|
|
|
configChanged();
|
|
|
|
KConfigGroup cg = config();
|
|
if (frameReceivedUrlArgs) {
|
|
cg.writeEntry("url", m_currentUrl);
|
|
emit configNeedsSaving();
|
|
}
|
|
|
|
m_menuPresent = false;
|
|
|
|
QAction *openAction = action("run associated application");
|
|
openAction->setIcon(SmallIcon("image-x-generic"));
|
|
openAction->setText(i18n("&Open Picture..."));
|
|
QAction *wallpaperAction = new QAction(KIcon("user-desktop"),i18n("Set as Wallpaper Image"), this);
|
|
actions.append(wallpaperAction);
|
|
connect(wallpaperAction, SIGNAL(triggered(bool)), this, SLOT(setImageAsWallpaper()));
|
|
}
|
|
|
|
QList<QAction*> Frame::contextualActions()
|
|
{
|
|
return actions;
|
|
}
|
|
|
|
void Frame::setImageAsWallpaper()
|
|
{
|
|
//setting current image of Picture frame as wallaper image
|
|
KUrl url;
|
|
|
|
if (m_slideShow) {
|
|
url = m_mySlideShow->currentUrl();
|
|
} else {
|
|
url = m_currentUrl;
|
|
}
|
|
|
|
const QString urlMime = KMimeType::findByUrl(url)->name();
|
|
kDebug() << urlMime;
|
|
|
|
foreach (Plasma::Containment *c, containment()->corona()->containments()) {
|
|
kSetContainmentWallpaper(c, url, urlMime);
|
|
}
|
|
}
|
|
|
|
void Frame::configChanged()
|
|
{
|
|
// Get config values
|
|
KConfigGroup cg = config();
|
|
m_frameColor = cg.readEntry("frameColor", QColor(70, 90, 130)); //theme?
|
|
m_frame = cg.readEntry("frame", false);
|
|
m_shadow = cg.readEntry("shadow", true);
|
|
m_roundCorners = cg.readEntry("roundCorners", true);
|
|
m_slideShow = cg.readEntry("slideshow", false);
|
|
m_random = cg.readEntry("random", false);
|
|
m_recursiveSlideShow = cg.readEntry("recursive slideshow", false);
|
|
m_slideShowPaths = cg.readEntry("slideshow paths", QStringList());
|
|
m_slideshowTime = cg.readEntry("slideshow time", 60); // default to 1 minute
|
|
m_currentUrl = cg.readEntry("url", m_currentUrl);
|
|
setAssociatedApplicationUrls(m_currentUrl);
|
|
m_autoUpdateIntervall = cg.readEntry("autoupdate time", 0);
|
|
|
|
initSlideShow();
|
|
}
|
|
|
|
void Frame::slotOpenPicture()
|
|
{
|
|
KUrl url;
|
|
|
|
if (m_slideShow) {
|
|
url = m_mySlideShow->currentUrl();
|
|
} else {
|
|
url = m_currentUrl;
|
|
}
|
|
|
|
if (!url.path().isEmpty()) {
|
|
KToolInvocation::self()->startServiceForUrl(url.url());
|
|
}
|
|
}
|
|
|
|
void Frame::constraintsEvent(Plasma::Constraints constraints)
|
|
{
|
|
if (constraints & Plasma::FormFactorConstraint) {
|
|
setBackgroundHints(Plasma::Applet::NoBackground);
|
|
if (formFactor() == Plasma::Horizontal) {
|
|
m_frameOutline = 0;
|
|
m_swOutline = 4;
|
|
} else if (formFactor() == Plasma::Vertical) {
|
|
m_frameOutline = 0;
|
|
m_swOutline = 4;
|
|
} else {
|
|
m_frameOutline = 8;
|
|
m_swOutline = 8;
|
|
//Restore widget geometry to image proportions
|
|
QSizeF sizeHint = contentSizeHint();
|
|
if (sizeHint != geometry().size()) {
|
|
resize(sizeHint);
|
|
emit appletTransformedItself();
|
|
}
|
|
}
|
|
m_updateTimer->start(400);
|
|
}
|
|
|
|
if (constraints & Plasma::SizeConstraint) {
|
|
//If on panel, keep geometry to 4:3 ratio
|
|
if (formFactor() == Plasma::Vertical) {
|
|
setMinimumSize(QSizeF(0, contentsRect().width()/1.33));
|
|
setMaximumSize(QSizeF(-1, contentsRect().width()/1.33));
|
|
} else if (formFactor() == Plasma::Horizontal) {
|
|
setMinimumSize(QSizeF(contentsRect().height()*1.33,0));
|
|
setMaximumSize(QSizeF(contentsRect().height()*1.33,-1));
|
|
} else {
|
|
int min = 48;
|
|
if (m_shadow) {
|
|
min += m_swOutline;
|
|
}
|
|
if (m_frame) {
|
|
min += m_frameOutline;
|
|
}
|
|
setMinimumSize(QSizeF(min, min));
|
|
setMaximumSize(QSizeF());
|
|
}
|
|
|
|
if (m_slideShow) {
|
|
checkSlideFrame();
|
|
|
|
int x = contentsRect().center().x() - (m_slideFrame->size().width() / 2);
|
|
int y = contentsRect().bottom() - m_slideFrame->size().height() - 5;
|
|
m_slideFrame->setPos(x, y);
|
|
}
|
|
|
|
m_waitForResize.start();
|
|
m_updateTimer->start(400);
|
|
}
|
|
}
|
|
|
|
QSizeF Frame::contentSizeHint() const
|
|
{
|
|
if (!m_pictureSize.isEmpty() && (formFactor() == Plasma::Planar || formFactor() == Plasma::MediaCenter)) {
|
|
const qreal maxSize = qMax(contentsRect().width(), contentsRect().height());
|
|
QSize size = m_pictureSize;
|
|
size.scale(maxSize, maxSize, Qt::KeepAspectRatio);
|
|
return size;
|
|
} else {
|
|
return contentsRect().size();
|
|
}
|
|
}
|
|
|
|
QSizeF Frame::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
|
|
{
|
|
if (which != Qt::PreferredSize) {
|
|
return Applet::sizeHint(which, constraint);
|
|
} else {
|
|
return m_pictureSize;
|
|
}
|
|
}
|
|
|
|
void Frame::scalePictureAndUpdate()
|
|
{
|
|
m_scaledImage = m_mySlideShow->image().scaled(contentSizeHint().toSize(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
updatePicture();
|
|
}
|
|
|
|
void Frame::updatePicture()
|
|
{
|
|
m_pictureSize = m_mySlideShow->image().size();
|
|
QSizeF sizeHint = contentSizeHint();
|
|
int frameLines = qMin(m_frameOutline, (int)(sizeHint.height()/10));
|
|
const QSize contentsSize = sizeHint.toSize();
|
|
|
|
if (m_currentUrl.url().isEmpty() && m_mySlideShow->currentUrl().isEmpty()) {
|
|
setAssociatedApplicationUrls(KUrl::List());
|
|
} else {
|
|
setAssociatedApplicationUrls(m_mySlideShow->currentUrl());
|
|
}
|
|
|
|
if (sizeHint != geometry().size()) {
|
|
emit sizeHintChanged(Qt::PreferredSize);
|
|
resize(sizeHint);
|
|
}
|
|
|
|
kDebug() << "Rendering picture";
|
|
Plasma::ToolTipContent toolTipData;
|
|
toolTipData.setSubText(m_mySlideShow->currentUrl().fileName());
|
|
Plasma::ToolTipManager::self()->setContent(this, toolTipData);
|
|
|
|
// create a QPixmap which can be drawn in paintInterface()
|
|
QPixmap picture = QPixmap::fromImage(m_scaledImage);
|
|
|
|
if (picture.isNull()) {
|
|
return;
|
|
}
|
|
|
|
m_pixmap = QPixmap(contentsSize);
|
|
m_pixmap.fill(Qt::transparent);
|
|
QPainter *p = new QPainter();
|
|
p->begin(&m_pixmap);
|
|
|
|
int roundingFactor = qMin(qreal(sizeHint.height() / 10), qreal(12.0)) * m_roundCorners;
|
|
int swRoundness = roundingFactor + frameLines / 2 * m_frame * m_roundCorners;
|
|
|
|
QRectF frameRect(QPoint(0, 0), contentsSize);
|
|
frameRect.adjust(m_swOutline, m_swOutline, -m_swOutline, -m_swOutline); //Pretty useless.
|
|
|
|
QSizeF scaledSize = frameRect.size();
|
|
scaledSize.scale(frameRect.size(), Qt::KeepAspectRatio);
|
|
frameRect = QRectF(QPoint(frameRect.x() + (frameRect.width() - scaledSize.width()) / 2,
|
|
frameRect.y() + (frameRect.height() - scaledSize.height()) / 2), scaledSize);
|
|
|
|
QRectF shadowRect;
|
|
if (m_frame) {
|
|
shadowRect = frameRect.adjusted(-frameLines, -frameLines,
|
|
frameLines, frameLines);
|
|
} else {
|
|
shadowRect = frameRect;
|
|
}
|
|
|
|
// The frame path. It will be used to draw the frame and clip the image.
|
|
QPainterPath framePath = Plasma::PaintUtils::roundedRectangle(frameRect, roundingFactor);
|
|
|
|
p->setRenderHint(QPainter::SmoothPixmapTransform, true);
|
|
p->setRenderHint(QPainter::Antialiasing, true);
|
|
|
|
// Shadow
|
|
if (m_shadow) {
|
|
// The shadow is a couple of lines with decreasing opacity painted around the path
|
|
p->setBrush(Qt::NoBrush);
|
|
QPen pen = QPen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin);
|
|
int shadowLines = qMin((int)(sizeHint.height() / 6), m_swOutline);
|
|
|
|
// The shadow is drawn from inside to the outside
|
|
shadowRect.adjust(+shadowLines, +shadowLines, -shadowLines, -shadowLines);
|
|
|
|
// Make the path to paint the frame in a bit smaller so it's inside the shadow
|
|
frameRect.adjust(+shadowLines, +shadowLines, -shadowLines, -shadowLines);
|
|
framePath = Plasma::PaintUtils::roundedRectangle(frameRect, roundingFactor);
|
|
|
|
// Paint the shadow's lines around the picture
|
|
for (int i = m_swOutline - shadowLines; i <= m_swOutline; i += 1) {
|
|
// It's important to change the opacity using the QColor, as
|
|
// QPainter->setOpacity() kills performance
|
|
qreal opacity = 0.7 * exp(-(i / (double)(m_swOutline / 3)));
|
|
pen.setColor(QColor(0, 0, 0, opacity * 254));
|
|
p->setPen(pen);
|
|
QPainterPath tr = Plasma::PaintUtils::roundedRectangle(shadowRect, swRoundness + i);
|
|
p->drawPath(tr);
|
|
shadowRect.adjust(-1, -1, + 1, + 1);
|
|
}
|
|
}
|
|
|
|
p->setBrush(Qt::NoBrush);
|
|
|
|
// Frame
|
|
if (m_frame) {
|
|
m_frameColor.setAlphaF(0.5);
|
|
// The frame is painted twice as thick, the inner half lies behind the picture
|
|
// This is important to not make the corners look "cut out" when rounded
|
|
p->setPen(QPen(m_frameColor, frameLines * 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
|
|
p->drawPath(framePath);
|
|
}
|
|
|
|
// Picture
|
|
// We save the painter here so the clipping only happens on the pixmap,
|
|
// not on pixmap, frame, shadow, etc
|
|
p->save();
|
|
if (m_roundCorners) {
|
|
p->setClipPath(framePath);
|
|
}
|
|
|
|
// Respect the smoothScaling setting
|
|
p->setRenderHint(QPainter::SmoothPixmapTransform, true);
|
|
// draw our pixmap into the computed rectangle
|
|
p->drawPixmap(frameRect.toRect(), picture);
|
|
p->restore();
|
|
|
|
// black frame
|
|
if (m_frame) {
|
|
p->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
|
p->drawPath(framePath);
|
|
} else if (m_roundCorners) {
|
|
p->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
|
p->drawPath(framePath);
|
|
}
|
|
|
|
// Paint status text on top of it all
|
|
if (!m_mySlideShow->message().isEmpty()) {
|
|
int dist = frameRect.width() / 10;
|
|
QRect bgRect = frameRect.adjusted(dist-1, dist-1, -dist, -dist).toRect();
|
|
|
|
// The text's background rounded rectangle
|
|
QPainterPath bgPath = Plasma::PaintUtils::roundedRectangle(bgRect, bgRect.height()/15);
|
|
|
|
QColor c = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor);
|
|
c.setAlphaF(.3);
|
|
QColor outline = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
|
|
outline.setAlphaF(.5);
|
|
p->setBrush(c);
|
|
p->setPen(outline);
|
|
p->setPen(QPen(outline, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
|
p->drawPath(bgPath);
|
|
QString message = m_mySlideShow->message();
|
|
|
|
// Set the font and draw text
|
|
p->setRenderHint(QPainter::Antialiasing);
|
|
QFont textFont = Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont);
|
|
textFont.setPointSize(qMax(KGlobalSettings::smallestReadableFont().pointSize(), bgRect.height() / 6));
|
|
p->setFont(textFont);
|
|
|
|
QTextOption option;
|
|
option.setAlignment(Qt::AlignCenter);
|
|
option.setWrapMode(QTextOption::WordWrap);
|
|
|
|
preparePainter(p, bgRect, textFont, message);
|
|
|
|
p->setPen(QPen(Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
|
p->drawText(bgRect, message, option);
|
|
}
|
|
|
|
p->end();
|
|
delete p;
|
|
update();
|
|
|
|
if (m_doAutoUpdate && !m_autoUpdateTimer->isActive()) {
|
|
kDebug() << "Autoupdate timer restarted:" << m_autoUpdateIntervall << "s";
|
|
m_autoUpdateTimer->start(m_autoUpdateIntervall * 1000);
|
|
}
|
|
}
|
|
|
|
QRect Frame::preparePainter(QPainter *p, const QRect &rect, const QFont &font, const QString &text)
|
|
{
|
|
QRect tmpRect;
|
|
QFont tmpFont = font;
|
|
bool first = true;
|
|
|
|
// Starting with the given font, decrease its size until it'll fit in the
|
|
// given rect allowing wrapping where possible
|
|
do {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
tmpFont.setPointSize(qMax(KGlobalSettings::smallestReadableFont().pointSize(), tmpFont.pointSize() - 1));
|
|
}
|
|
|
|
const QFontMetrics fm(tmpFont);
|
|
int flags = Qt::TextWordWrap;
|
|
|
|
tmpRect = fm.boundingRect(rect, flags, text);
|
|
} while (tmpFont.pointSize() > KGlobalSettings::smallestReadableFont().pointSize() &&
|
|
(tmpRect.width() > rect.width() || tmpRect.height() > rect.height()));
|
|
|
|
p->setFont(tmpFont);
|
|
return tmpRect;
|
|
}
|
|
|
|
|
|
void Frame::nextPicture()
|
|
{
|
|
m_mySlideShow->setUpdateInterval(0);
|
|
m_mySlideShow->nextPicture();
|
|
m_mySlideShow->setUpdateInterval(m_slideshowTime * 1000);
|
|
}
|
|
|
|
void Frame::previousPicture()
|
|
{
|
|
m_mySlideShow->setUpdateInterval(0);
|
|
m_mySlideShow->previousPicture();
|
|
m_mySlideShow->setUpdateInterval(m_slideshowTime * 1000);
|
|
}
|
|
|
|
void Frame::addDir()
|
|
{
|
|
const QString path = KFileDialog::getExistingDirectory();
|
|
if (!path.isEmpty()) {
|
|
if (!m_slideShowPaths.contains(path)) {
|
|
m_configDialog->imageUi.slideShowDirList->addItem(path);
|
|
}
|
|
updateButtons();
|
|
}
|
|
}
|
|
|
|
void Frame::removeDir()
|
|
{
|
|
int row = m_configDialog->imageUi.slideShowDirList->currentRow();
|
|
if (row != -1) {
|
|
m_configDialog->imageUi.slideShowDirList->takeItem(row);
|
|
updateButtons();
|
|
}
|
|
}
|
|
|
|
void Frame::updateButtons()
|
|
{
|
|
int row = m_configDialog->imageUi.slideShowDirList->currentRow();
|
|
m_configDialog->imageUi.removeDirButton->setEnabled(row != -1);
|
|
}
|
|
|
|
void Frame::createConfigurationInterface(KConfigDialog *parent)
|
|
{
|
|
m_configDialog = new ConfigDialog(parent);
|
|
|
|
parent->addPage(m_configDialog->imageSettings, i18n("Image"), icon());
|
|
parent->addPage(m_configDialog->appearanceSettings, i18n("Appearance"), "preferences-desktop-theme");
|
|
parent->setDefaultButton(KDialog::Ok);
|
|
parent->showButtonSeparator(true);
|
|
connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
|
|
connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
|
|
|
|
connect(m_configDialog->imageUi.removeDirButton, SIGNAL(clicked()), this, SLOT(removeDir()));
|
|
connect(m_configDialog->imageUi.addDirButton, SIGNAL(clicked()), this, SLOT(addDir()));
|
|
connect(m_configDialog->imageUi.slideShowDirList, SIGNAL(currentRowChanged(int)), this, SLOT(updateButtons()));
|
|
|
|
m_configDialog->setRoundCorners(m_roundCorners);
|
|
m_configDialog->setShadow(m_shadow);
|
|
m_configDialog->setShowFrame(m_frame);
|
|
m_configDialog->setFrameColor(m_frameColor);
|
|
|
|
if (m_slideShow) {
|
|
m_configDialog->imageUi.pictureComboBox->setCurrentIndex(1);
|
|
} else {
|
|
m_configDialog->imageUi.pictureComboBox->setCurrentIndex(0);
|
|
}
|
|
|
|
m_configDialog->imageUi.randomCheckBox->setCheckState(m_random ? Qt::Checked : Qt::Unchecked);
|
|
m_configDialog->imageUi.recursiveCheckBox->setCheckState(m_recursiveSlideShow ? Qt::Checked : Qt::Unchecked);
|
|
|
|
m_configDialog->setCurrentUrl(m_currentUrl);
|
|
m_configDialog->imageUi.slideShowDirList->clear();
|
|
m_configDialog->imageUi.slideShowDirList->addItems(m_slideShowPaths);
|
|
m_configDialog->imageUi.removeDirButton->setEnabled(!m_slideShowPaths.isEmpty());
|
|
m_configDialog->imageUi.slideShowDelay->setMinimumTime(QTime(0, 0, 1));
|
|
m_configDialog->imageUi.slideShowDelay->setTime(QTime(m_slideshowTime / 3600, (m_slideshowTime / 60) % 60, m_slideshowTime % 60));
|
|
m_configDialog->previewPicture(m_mySlideShow->image());
|
|
m_configDialog->imageUi.autoUpdateTime->setTime(QTime(m_autoUpdateIntervall / 3600, (m_autoUpdateIntervall / 60) % 60, m_autoUpdateIntervall % 60));
|
|
|
|
connect(m_configDialog->imageUi.slideShowDelay, SIGNAL(timeChanged(QTime)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->imageUi.pictureComboBox, SIGNAL(currentIndexChanged(int)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->imageUi.picRequester, SIGNAL(textChanged(QString)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->imageUi.autoUpdateTime, SIGNAL(timeChanged(QTime)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->imageUi.addDirButton, SIGNAL(clicked(bool)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->imageUi.removeDirButton, SIGNAL(clicked(bool)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->imageUi.randomCheckBox, SIGNAL(toggled(bool)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->imageUi.recursiveCheckBox, SIGNAL(toggled(bool)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->appearanceUi.roundCheckBox, SIGNAL(toggled(bool)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->appearanceUi.shadowCheckBox, SIGNAL(toggled(bool)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->appearanceUi.frameCheckBox, SIGNAL(toggled(bool)),
|
|
parent, SLOT(settingsModified()));
|
|
connect(m_configDialog->appearanceUi.changeFrameColor,SIGNAL(changed(QColor)),
|
|
parent, SLOT(settingsModified()));
|
|
}
|
|
|
|
void Frame::configAccepted()
|
|
{
|
|
KConfigGroup cg = config();
|
|
// Appearance
|
|
m_roundCorners = m_configDialog->roundCorners();
|
|
cg.writeEntry("roundCorners", m_roundCorners);
|
|
m_shadow = m_configDialog->shadow();
|
|
cg.writeEntry("shadow", m_shadow);
|
|
m_frame = m_configDialog->showFrame();
|
|
cg.writeEntry("frame", m_frame);
|
|
m_frameColor = m_configDialog->frameColor();
|
|
cg.writeEntry("frameColor", m_frameColor);
|
|
|
|
if (m_configDialog->imageUi.pictureComboBox->currentIndex() == 1) {
|
|
m_slideShow = true;
|
|
} else {
|
|
m_slideShow = false;
|
|
}
|
|
|
|
m_random = m_configDialog->random();
|
|
cg.writeEntry("random", m_random);
|
|
m_currentUrl = m_configDialog->currentUrl();
|
|
setAssociatedApplicationUrls(m_currentUrl);
|
|
cg.writeEntry("url", m_currentUrl);
|
|
cg.writeEntry("slideshow", m_slideShow);
|
|
m_recursiveSlideShow = m_configDialog->imageUi.recursiveCheckBox->checkState() == Qt::Checked ? true : false;
|
|
cg.writeEntry("recursive slideshow", m_recursiveSlideShow);
|
|
m_slideShowPaths.clear();
|
|
QStringList dirs;
|
|
for (int i = 0; i < m_configDialog->imageUi.slideShowDirList->count(); i++) {
|
|
m_slideShowPaths << m_configDialog->imageUi.slideShowDirList->item(i)->text();
|
|
}
|
|
cg.writeEntry("slideshow paths", m_slideShowPaths);
|
|
|
|
QTime timerTime = m_configDialog->imageUi.slideShowDelay->time();
|
|
m_slideshowTime = timerTime.second() + timerTime.minute() * 60 + timerTime.hour() * 3600;
|
|
cg.writeEntry("slideshow time", m_slideshowTime);
|
|
|
|
m_autoUpdateTimer->stop();
|
|
|
|
QTime AutoUpdateTimer = m_configDialog->imageUi.autoUpdateTime->time();
|
|
m_autoUpdateIntervall = AutoUpdateTimer.second() + AutoUpdateTimer.minute() * 60 + AutoUpdateTimer.hour() * 3600;
|
|
cg.writeEntry("autoupdate time", m_autoUpdateIntervall);
|
|
|
|
initSlideShow();
|
|
|
|
emit configNeedsSaving();
|
|
}
|
|
|
|
void Frame::initSlideShow()
|
|
{
|
|
m_mySlideShow->setUpdateInterval(0);
|
|
m_doAutoUpdate = false;
|
|
|
|
if (m_slideShow) {
|
|
m_mySlideShow->setRandom(m_random);
|
|
m_mySlideShow->setDirs(m_slideShowPaths, m_recursiveSlideShow);
|
|
m_mySlideShow->setUpdateInterval(m_slideshowTime * 1000);
|
|
} else { //no slideshow so no random stuff
|
|
m_mySlideShow->setRandom(false);
|
|
m_mySlideShow->setImage(m_currentUrl.url());
|
|
|
|
if (m_autoUpdateIntervall > 0) {
|
|
m_doAutoUpdate = true;
|
|
}
|
|
}
|
|
|
|
scalePictureAndUpdate();
|
|
}
|
|
|
|
void Frame::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
|
|
{
|
|
// kDebug() << event->mimeData()->formats();
|
|
if (event->mimeData()->hasUrls()) {
|
|
event->acceptProposedAction();
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
}
|
|
|
|
void Frame::dropEvent(QGraphicsSceneDragDropEvent *event)
|
|
{
|
|
if (m_slideFrame) {
|
|
m_slideFrame->hide();
|
|
}
|
|
KUrl droppedUrl = (KUrl::List::fromMimeData(event->mimeData())).at(0);
|
|
kDebug() << "dropped URL" << droppedUrl.url();
|
|
// If the url is a local directory start slideshowmode
|
|
if (droppedUrl.isLocalFile() && QFileInfo(droppedUrl.path()).isDir()) {
|
|
m_slideShowPaths.clear();
|
|
m_slideShowPaths.append(droppedUrl.path());
|
|
m_slideShow = true;
|
|
} else {
|
|
kDebug() << "Remote URL" << droppedUrl.url();
|
|
m_currentUrl = droppedUrl;
|
|
setAssociatedApplicationUrls(m_currentUrl);
|
|
m_slideShow = false;
|
|
}
|
|
|
|
m_autoUpdateTimer->stop();
|
|
initSlideShow();
|
|
|
|
KConfigGroup cg = config();
|
|
cg.writeEntry("url", m_currentUrl);
|
|
cg.writeEntry("slideshow", m_slideShow);
|
|
cg.writeEntry("slideshow paths", m_slideShowPaths);
|
|
emit configNeedsSaving();
|
|
}
|
|
|
|
void Frame::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
|
{
|
|
checkSlideFrame();
|
|
if (m_slideShow) {
|
|
m_slideFrame->show();
|
|
}
|
|
Applet::hoverEnterEvent(event);
|
|
}
|
|
|
|
void Frame::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
|
{
|
|
if (m_slideShow) {
|
|
checkSlideFrame();
|
|
m_slideFrame->hide();
|
|
}
|
|
Applet::hoverLeaveEvent( event );
|
|
}
|
|
|
|
void Frame::checkSlideFrame()
|
|
{
|
|
if (m_slideFrame) {
|
|
m_slideFrame->hide();
|
|
return;
|
|
}
|
|
m_slideFrame = new Plasma::Frame( this );
|
|
m_slideFrame->setZValue( 10 );
|
|
|
|
m_backButton = new Plasma::ToolButton(m_slideFrame);
|
|
m_backButton->setIcon(KIcon("go-previous"));
|
|
m_backButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
m_backButton->setMaximumSize(IconSize(KIconLoader::MainToolbar), IconSize(KIconLoader::MainToolbar));
|
|
connect(m_backButton, SIGNAL(clicked()), this , SLOT(previousPicture()));
|
|
|
|
m_nextButton = new Plasma::ToolButton(m_slideFrame);
|
|
m_nextButton->setIcon(KIcon("go-next"));
|
|
m_nextButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
m_nextButton->setMaximumSize(IconSize(KIconLoader::MainToolbar), IconSize(KIconLoader::MainToolbar));
|
|
connect(m_nextButton, SIGNAL(clicked()), this , SLOT(nextPicture()));
|
|
|
|
QGraphicsLinearLayout *buttonsLayout = new QGraphicsLinearLayout();
|
|
buttonsLayout->addItem(m_backButton);
|
|
buttonsLayout->addItem(m_nextButton);
|
|
m_slideFrame->setLayout(buttonsLayout);
|
|
buttonsLayout->activate();
|
|
|
|
m_slideFrame->setFrameShadow( Plasma::Frame::Raised );
|
|
m_slideFrame->hide();
|
|
|
|
constraintsEvent(Plasma::SizeConstraint);
|
|
}
|
|
|
|
void Frame::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &rect)
|
|
{
|
|
Q_UNUSED(option)
|
|
if (m_slideShow) {
|
|
// temporarily suspend the slideshow to allow time for loading the image
|
|
m_mySlideShow->setUpdateInterval(0);
|
|
}
|
|
|
|
p->drawPixmap(rect, m_pixmap);
|
|
|
|
if (m_slideShow) {
|
|
// unsuspend the slideshow to allow time for loading the image
|
|
m_mySlideShow->setUpdateInterval(m_slideshowTime * 1000);
|
|
}
|
|
}
|
|
|
|
void Frame::delayedUpdateSize()
|
|
{
|
|
QSizeF sizeHint = contentSizeHint();
|
|
if (sizeHint != geometry().size()) {
|
|
resize(sizeHint);
|
|
emit appletTransformedItself();
|
|
}
|
|
}
|
|
|
|
void Frame::reloadImage()
|
|
{
|
|
m_mySlideShow->updateImage(m_currentUrl.url());
|
|
}
|
|
|
|
#include "moc_frame.cpp"
|