diff --git a/core/utilities/slideshow/slideimage.cpp b/core/utilities/slideshow/slideimage.cpp index d97a68c792..43358450eb 100644 --- a/core/utilities/slideshow/slideimage.cpp +++ b/core/utilities/slideshow/slideimage.cpp @@ -1,194 +1,200 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2014-09-18 * Description : slideshow image widget * * Copyright (C) 2014-2020 by Gilles Caulier * * 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, 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. * * ============================================================ */ #include "slideimage.h" // Qt includes #include #include #include #include // Local includes #include "digikam_debug.h" #include "dimg.h" #include "previewloadthread.h" namespace Digikam { class Q_DECL_HIDDEN SlideImage::Private { public: explicit Private() : previewThread(nullptr), previewPreloadThread(nullptr) { } PreviewSettings previewSettings; QPixmap pixmap; QUrl currentImage; DImg preview; PreviewLoadThread* previewThread; PreviewLoadThread* previewPreloadThread; }; SlideImage::SlideImage(QWidget* const parent) : QWidget(parent), d(new Private) { setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_OpaquePaintEvent); setWindowFlags(Qt::FramelessWindowHint); setMouseTracking(true); d->previewThread = new PreviewLoadThread(); d->previewPreloadThread = new PreviewLoadThread(); connect(d->previewThread, SIGNAL(signalImageLoaded(LoadingDescription,DImg)), this, SLOT(slotGotImagePreview(LoadingDescription,DImg))); } SlideImage::~SlideImage() { delete d->previewThread; delete d->previewPreloadThread; delete d; } void SlideImage::setPreviewSettings(const PreviewSettings& settings) { d->previewSettings = settings; } void SlideImage::setLoadUrl(const QUrl& url) { d->currentImage = url; // calculate preview size which is used for fast previews QScreen* screen = qApp->primaryScreen(); if (QWidget* const widget = nativeParentWidget()) { if (QWindow* const window = widget->windowHandle()) + { screen = window->screen(); + } } QSize desktopSize = screen->geometry().size(); int deskSize = qMax(640, qMax(desktopSize.height(), desktopSize.width())); d->previewThread->load(url.toLocalFile(), d->previewSettings, deskSize); } void SlideImage::setPreloadUrl(const QUrl& url) { // calculate preview size which is used for fast previews + QScreen* screen = qApp->primaryScreen(); if (QWidget* const widget = nativeParentWidget()) { if (QWindow* const window = widget->windowHandle()) + { screen = window->screen(); + } } QSize desktopSize = screen->geometry().size(); int deskSize = qMax(640, qMax(desktopSize.height(), desktopSize.width())); d->previewPreloadThread->load(url.toLocalFile(), d->previewSettings, deskSize); } void SlideImage::paintEvent(QPaintEvent*) { QPainter p(this); p.drawPixmap(0, 0, width(), height(), d->pixmap, 0, 0, d->pixmap.width(), d->pixmap.height()); p.end(); } void SlideImage::slotGotImagePreview(const LoadingDescription& desc, const DImg& preview) { if (desc.filePath != d->currentImage.toLocalFile() || desc.isThumbnail()) { return; } d->preview.reset(); if (!DImg::isAnimatedImage(desc.filePath)) // Special case for animated images as GIF or NMG { d->preview = preview; } if (!d->preview.isNull()) { updatePixmap(); update(); emit signalImageLoaded(true); return; } emit signalImageLoaded(false); } void SlideImage::updatePixmap() { - /* For high resolution ("retina") displays, Mac OS X / Qt - report only half of the physical resolution in terms of - pixels, i.e. every logical pixels corresponds to 2x2 - physical pixels. However, UI elements and fonts are - nevertheless rendered at full resolution, and pixmaps - as well, provided their resolution is high enough (that - is, higher than the reported, logical resolution). - - To work around this, we render the photos not a logical - resolution, but with the photo's full resolution, but - at the screen's aspect ratio. When we later draw this - high resolution bitmap, it is up to Qt to scale the - photo to the true physical resolution. The ratio - computed below is the ratio between the photo and - screen resolutions, or equivalently the factor by which - we need to increase the pixel size of the rendered - pixmap. - */ + /** + * For high resolution ("retina") displays, Mac OS X / Qt + * report only half of the physical resolution in terms of + * pixels, i.e. every logical pixels corresponds to 2x2 + * physical pixels. However, UI elements and fonts are + * nevertheless rendered at full resolution, and pixmaps + * as well, provided their resolution is high enough (that + * is, higher than the reported, logical resolution). + * + * To work around this, we render the photos not a logical + * resolution, but with the photo's full resolution, but + * at the screen's aspect ratio. When we later draw this + * high resolution bitmap, it is up to Qt to scale the + * photo to the true physical resolution. The ratio + * computed below is the ratio between the photo and + * screen resolutions, or equivalently the factor by which + * we need to increase the pixel size of the rendered + * pixmap. + */ double ratio = qApp->devicePixelRatio(); QSize fullSize = QSizeF(ratio*width(), ratio*height()).toSize(); d->pixmap = QPixmap(fullSize); d->pixmap.fill(Qt::black); QPainter p(&(d->pixmap)); QPixmap pix(d->preview.smoothScale(d->pixmap.width(), d->pixmap.height(), Qt::KeepAspectRatio).convertToPixmap()); p.drawPixmap((d->pixmap.width() - pix.width()) / 2, (d->pixmap.height() - pix.height()) / 2, pix, 0, 0, pix.width(), pix.height()); } } // namespace Digikam diff --git a/core/utilities/slideshow/slideosd.cpp b/core/utilities/slideshow/slideosd.cpp index 4dd9021c5b..50b4f2fc96 100644 --- a/core/utilities/slideshow/slideosd.cpp +++ b/core/utilities/slideshow/slideosd.cpp @@ -1,398 +1,407 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2014-09-18 * Description : slideshow OSD widget * * Copyright (C) 2014-2020 by Gilles Caulier * * 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, 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. * * ============================================================ */ #include "slideosd.h" // Qt includes #include #include #include #include #include #include #include #include // Windows includes #ifdef Q_OS_WIN # include #endif // Local includes #include "digikam_debug.h" #include "slideshow.h" #include "slidetoolbar.h" #include "slideproperties.h" #include "ratingwidget.h" #include "colorlabelwidget.h" #include "picklabelwidget.h" #include "dinfointerface.h" namespace Digikam { class Q_DECL_HIDDEN SlideOSD::Private { public: explicit Private() : paused(false), video(false), blink(false), ready(false), - refresh(1000), // Progress bar refresh in ms + refresh(1000), ///< Progress bar refresh in ms progressBar(nullptr), progressTimer(nullptr), labelsBox(nullptr), progressBox(nullptr), parent(nullptr), slideProps(nullptr), toolBar(nullptr), ratingWidget(nullptr), clWidget(nullptr), plWidget(nullptr) { } bool paused; bool video; bool blink; bool ready; int const refresh; QProgressBar* progressBar; QTimer* progressTimer; DHBox* labelsBox; DHBox* progressBox; SlideShow* parent; SlideProperties* slideProps; SlideToolBar* toolBar; RatingWidget* ratingWidget; ColorLabelSelector* clWidget; PickLabelSelector* plWidget; SlideShowSettings settings; }; SlideOSD::SlideOSD(const SlideShowSettings& settings, SlideShow* const parent) : QWidget(parent), d(new Private) { Qt::WindowFlags flags = Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint; setWindowFlags(flags); setAttribute(Qt::WA_TranslucentBackground, true); setAttribute(Qt::WA_ShowWithoutActivating, true); setMouseTracking(true); d->settings = settings; d->parent = parent; d->slideProps = new SlideProperties(d->settings, this); d->slideProps->installEventFilter(d->parent); // --------------------------------------------------------------- d->labelsBox = new DHBox(this); d->clWidget = new ColorLabelSelector(d->labelsBox); d->clWidget->installEventFilter(this); d->clWidget->installEventFilter(d->parent); d->clWidget->colorLabelWidget()->installEventFilter(this); d->clWidget->setFocusPolicy(Qt::NoFocus); d->clWidget->setMouseTracking(true); d->plWidget = new PickLabelSelector(d->labelsBox); d->plWidget->installEventFilter(this); d->plWidget->installEventFilter(d->parent); d->plWidget->setFocusPolicy(Qt::NoFocus); d->plWidget->pickLabelWidget()->installEventFilter(this); d->plWidget->setMouseTracking(true); d->ratingWidget = new RatingWidget(d->labelsBox); d->ratingWidget->setTracking(false); d->ratingWidget->setFading(false); d->ratingWidget->installEventFilter(this); d->ratingWidget->installEventFilter(d->parent); d->ratingWidget->setFocusPolicy(Qt::NoFocus); d->ratingWidget->setMouseTracking(true); d->labelsBox->layout()->setAlignment(d->ratingWidget, Qt::AlignVCenter | Qt::AlignLeft); d->labelsBox->installEventFilter(d->parent); d->labelsBox->setMouseTracking(true); d->labelsBox->setVisible(d->settings.printLabels || d->settings.printRating); d->ratingWidget->setVisible(d->settings.printRating); d->clWidget->setVisible(d->settings.printLabels); d->plWidget->setVisible(d->settings.printLabels); connect(d->ratingWidget, SIGNAL(signalRatingChanged(int)), parent, SLOT(slotAssignRating(int))); connect(d->clWidget, SIGNAL(signalColorLabelChanged(int)), parent, SLOT(slotAssignColorLabel(int))); connect(d->plWidget, SIGNAL(signalPickLabelChanged(int)), parent, SLOT(slotAssignPickLabel(int))); // --------------------------------------------------------------- d->progressBox = new DHBox(this); d->progressBox->setVisible(d->settings.showProgressIndicator); d->progressBox->installEventFilter(d->parent); d->progressBox->setMouseTracking(true); d->progressBar = new QProgressBar(d->progressBox); d->progressBar->setMinimum(0); d->progressBar->setMaximum(d->settings.delay); d->progressBar->setFocusPolicy(Qt::NoFocus); d->progressBar->installEventFilter(d->parent); d->progressBar->setMouseTracking(true); d->toolBar = new SlideToolBar(d->settings, d->progressBox); d->toolBar->installEventFilter(this); d->toolBar->installEventFilter(d->parent); connect(d->toolBar, SIGNAL(signalPause()), d->parent, SLOT(slotPause())); connect(d->toolBar, SIGNAL(signalPlay()), d->parent, SLOT(slotPlay())); connect(d->toolBar, SIGNAL(signalNext()), d->parent, SLOT(slotLoadNextItem())); connect(d->toolBar, SIGNAL(signalPrev()), d->parent, SLOT(slotLoadPrevItem())); connect(d->toolBar, SIGNAL(signalClose()), d->parent, SLOT(close())); connect(d->toolBar, SIGNAL(signalScreenSelected(int)), d->parent, SLOT(slotScreenSelected(int))); // --------------------------------------------------------------- QGridLayout* const grid = new QGridLayout(this); grid->addWidget(d->slideProps, 1, 0, 1, 2); grid->addWidget(d->labelsBox, 2, 0, 1, 1); grid->addWidget(d->progressBox, 3, 0, 1, 1); grid->setRowStretch(0, 10); grid->setColumnStretch(1, 10); grid->setContentsMargins(QMargins()); grid->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing)); // --------------------------------------------------------------- d->progressTimer = new QTimer(this); d->progressTimer->setSingleShot(false); connect(d->progressTimer, SIGNAL(timeout()), this, SLOT(slotProgressTimer())); QTimer::singleShot(500, this, SLOT(slotStart())); } SlideOSD::~SlideOSD() { d->progressTimer->stop(); delete d; } void SlideOSD::slotStart() { d->parent->slotLoadNextItem(); d->progressTimer->start(d->refresh); pause(!d->settings.autoPlayEnabled); } SlideToolBar* SlideOSD::toolBar() const { return d->toolBar; } void SlideOSD::setCurrentUrl(const QUrl& url) { DInfoInterface::DInfoMap info = d->settings.iface->itemInfo(url); DItemInfo item(info); // Update info text. d->slideProps->setCurrentUrl(url); // Display Labels. if (d->settings.printLabels) { d->clWidget->blockSignals(true); d->plWidget->blockSignals(true); d->clWidget->setColorLabel((ColorLabel)item.colorLabel()); d->plWidget->setPickLabel((PickLabel)item.pickLabel()); d->clWidget->blockSignals(false); d->plWidget->blockSignals(false); } if (d->settings.printRating) { d->ratingWidget->blockSignals(true); d->ratingWidget->setRating(item.rating()); d->ratingWidget->blockSignals(false); } // Make the OSD the proper size + layout()->activate(); resize(sizeHint()); QScreen* screen = qApp->primaryScreen(); if (QWidget* const widget = nativeParentWidget()) { if (QWindow* const window = widget->windowHandle()) + { screen = window->screen(); + } } QRect geometry(screen->availableGeometry()); move(10, geometry.bottom() - height()); show(); raise(); } bool SlideOSD::eventFilter(QObject* obj, QEvent* ev) { - if (obj == d->labelsBox || - obj == d->ratingWidget || - obj == d->clWidget || - obj == d->plWidget || - obj == d->clWidget->colorLabelWidget() || - obj == d->plWidget->pickLabelWidget()) + if ( + (obj == d->labelsBox) || + (obj == d->ratingWidget) || + (obj == d->clWidget) || + (obj == d->plWidget) || + (obj == d->clWidget->colorLabelWidget()) || + (obj == d->plWidget->pickLabelWidget()) + ) { if (ev->type() == QEvent::Enter) { d->paused = isPaused(); d->parent->slotPause(); + return false; } if (ev->type() == QEvent::Leave) { if (!d->paused) { d->parent->slotPlay(); } return false; } } // pass the event on to the parent class + return QWidget::eventFilter(obj, ev); } void SlideOSD::slotProgressTimer() { QString str = QString::fromUtf8("(%1/%2)") .arg(QString::number(d->settings.fileList.indexOf(d->parent->currentItem()) + 1)) .arg(QString::number(d->settings.fileList.count())); - if (isPaused()) + if (isPaused()) { d->blink = !d->blink; if (d->blink) { str = QString(); } d->progressBar->setFormat(str); } else if (d->video) { d->progressBar->setFormat(str); return; } else { d->progressBar->setFormat(str); if (d->progressBar->value() == d->settings.delay) { if (!d->ready) { return; } d->ready = false; d->parent->slotLoadNextItem(); } d->progressBar->setValue(d->progressBar->value()+1); } } void SlideOSD::pause(bool b) { d->toolBar->pause(b); if (!b) { d->progressBar->setValue(0); } } void SlideOSD::video(bool b) { d->video = b; } bool SlideOSD::isPaused() const { return d->toolBar->isPaused(); } bool SlideOSD::isUnderMouse() const { - return (d->ratingWidget->underMouse() || + return ( + d->ratingWidget->underMouse() || d->progressBar->underMouse() || d->clWidget->underMouse() || d->plWidget->underMouse() || - d->toolBar->underMouse()); + d->toolBar->underMouse() + ); } void SlideOSD::toggleProperties() { d->slideProps->togglePaintEnabled(); } void SlideOSD::setLoadingReady(bool b) { d->ready = b; } } // namespace Digikam diff --git a/core/utilities/slideshow/slideosd.h b/core/utilities/slideshow/slideosd.h index 88ecdc457e..1a5302b9bb 100644 --- a/core/utilities/slideshow/slideosd.h +++ b/core/utilities/slideshow/slideosd.h @@ -1,82 +1,82 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2014-09-18 * Description : slideshow OSD widget * * Copyright (C) 2014-2020 by Gilles Caulier * * 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, 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. * * ============================================================ */ #ifndef DIGIKAM_SLIDE_OSD_H #define DIGIKAM_SLIDE_OSD_H // Qt includes #include #include // Local includes #include "slideshowsettings.h" class QEvent; namespace Digikam { class SlideShow; class SlideToolBar; class SlideOSD : public QWidget { Q_OBJECT public: explicit SlideOSD(const SlideShowSettings& settings, SlideShow* const parent = nullptr); ~SlideOSD(); void setCurrentUrl(const QUrl& url); void pause(bool b); void video(bool b); - bool isPaused() const; - bool isUnderMouse() const; + bool isPaused() const; + bool isUnderMouse() const; void toggleProperties(); void setLoadingReady(bool b); - SlideToolBar* toolBar() const; + SlideToolBar* toolBar() const; private Q_SLOTS: void slotProgressTimer(); void slotStart(); private: bool eventFilter(QObject* obj, QEvent* ev) override; private: class Private; Private* const d; }; } // namespace Digikam #endif // DIGIKAM_SLIDE_OSD_H diff --git a/core/utilities/slideshow/slideproperties.cpp b/core/utilities/slideshow/slideproperties.cpp index ccce9ac696..0e357fc3a3 100644 --- a/core/utilities/slideshow/slideproperties.cpp +++ b/core/utilities/slideshow/slideproperties.cpp @@ -1,393 +1,395 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2014-09-19 * Description : slide properties widget * * Copyright (C) 2014-2020 by Gilles Caulier * * 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, 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. * * ============================================================ */ #include "slideproperties.h" // Qt includes #include #include #include #include #include #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "dinfointerface.h" #include "itempropertiestab.h" namespace Digikam { class Q_DECL_HIDDEN SlideProperties::Private { public: explicit Private() : maxStringLen(80), paintEnabled(true) { } const int maxStringLen; bool paintEnabled; QUrl url; SlideShowSettings settings; DInfoInterface::DInfoMap infoMap; }; SlideProperties::SlideProperties(const SlideShowSettings& settings, QWidget* const parent) : QWidget(parent), d(new Private) { d->settings = settings; setMouseTracking(true); } SlideProperties::~SlideProperties() { delete d; } void SlideProperties::setCurrentUrl(const QUrl& url) { QScreen* screen = qApp->primaryScreen(); if (QWidget* const widget = nativeParentWidget()) { if (QWindow* const window = widget->windowHandle()) { screen = window->screen(); } } setFixedSize(screen->availableGeometry().size() / 1.5); d->infoMap = d->settings.iface->itemInfo(url); d->url = url; update(); } void SlideProperties::paintEvent(QPaintEvent*) { if (!d->paintEnabled) { return; } QPainter p(this); p.setFont(d->settings.captionFont); DItemInfo item(d->infoMap); QString str; - //PhotoInfoContainer photoInfo = d->info.photoInfo; +/* + PhotoInfoContainer photoInfo = d->info.photoInfo; +*/ QString comment = item.comment(); QString title = item.title(); QStringList tags = item.keywords(); int offset = 0; // Display tag names. if (d->settings.printTags) { printTags(p, offset, tags); } // Display Titles. if (d->settings.printTitle) { str.clear(); if (!title.isEmpty()) { str += title; printInfoText(p, offset, str); } } // Display Captions if no Titles. if (d->settings.printCapIfNoTitle) { str.clear(); if (title.isEmpty()) { str += comment; printComments(p, offset, str); } } // Display Comments. if (d->settings.printComment) { str = comment; printComments(p, offset, str); } // Display Make and Model. if (d->settings.printMakeModel) { str.clear(); QString make = item.make(); QString model = item.model(); if (!make.isEmpty()) { ItemPropertiesTab::shortenedMakeInfo(make); str = make; } if (!model.isEmpty()) { if (!make.isEmpty()) { str += QLatin1String(" / "); } ItemPropertiesTab::shortenedModelInfo(model); str += model; } printInfoText(p, offset, str); } // Display Exposure and Sensitivity. if (d->settings.printExpoSensitivity) { str.clear(); QString exposureTime = item.exposureTime(); QString sensitivity = item.sensitivity(); if (!exposureTime.isEmpty()) { str = exposureTime; } if (!sensitivity.isEmpty()) { if (!exposureTime.isEmpty()) { str += QLatin1String(" / "); } str += i18n("%1 ISO", sensitivity); } printInfoText(p, offset, str); } // Display Aperture and Focal. if (d->settings.printApertureFocal) { str.clear(); QString aperture = item.aperture(); QString focalLength = item.focalLength(); QString focalLength35mm = item.focalLength35mm(); if (!aperture.isEmpty()) { str = aperture; } if (focalLength35mm.isEmpty()) { if (!focalLength.isEmpty()) { if (!aperture.isEmpty()) { str += QLatin1String(" / "); } str += focalLength; } } else { if (!aperture.isEmpty()) { str += QLatin1String(" / "); } if (!focalLength.isEmpty()) { str += QString::fromUtf8("%1 (%2)").arg(focalLength).arg(focalLength35mm); } else { str += QString::fromUtf8("%1").arg(focalLength35mm); } } printInfoText(p, offset, str); } // Display Creation Date. if (d->settings.printDate) { QDateTime dateTime = item.dateTime(); if (dateTime.isValid()) { str = QLocale().toString(dateTime, QLocale::ShortFormat); printInfoText(p, offset, str); } } // Display image File Name. if (d->settings.printName) { printInfoText(p, offset, d->url.fileName()); } } void SlideProperties::printInfoText(QPainter& p, int& offset, const QString& str, const QColor& pcol) { if (!str.isEmpty()) { offset += QFontMetrics(p.font()).lineSpacing(); p.setPen(Qt::black); for (int x = -1 ; x <= 1 ; ++x) { for (int y = offset + 1 ; y >= offset - 1 ; --y) { p.drawText(x, p.window().height() - y, str); } } p.setPen(pcol); p.drawText(0, p.window().height() - offset, str); } } void SlideProperties::printComments(QPainter& p, int& offset, const QString& comments) { QStringList commentsByLines; uint commentsIndex = 0; // Comments QString index while (commentsIndex < (uint)comments.length()) { QString newLine; bool breakLine = false; // End Of Line found uint currIndex; // Comments QString current index // Check minimal lines dimension uint commentsLinesLengthLocal = d->maxStringLen; for (currIndex = commentsIndex ; - currIndex < (uint)comments.length() && !breakLine ; ++currIndex) + (currIndex < (uint)comments.length()) && !breakLine ; ++currIndex) { - if (comments.at(currIndex) == QLatin1Char('\n') || comments.at(currIndex).isSpace()) + if ((comments.at(currIndex) == QLatin1Char('\n')) || comments.at(currIndex).isSpace()) { breakLine = true; } } if (commentsLinesLengthLocal <= (currIndex - commentsIndex)) { commentsLinesLengthLocal = (currIndex - commentsIndex); } breakLine = false; for (currIndex = commentsIndex ; - currIndex <= commentsIndex + commentsLinesLengthLocal && - currIndex < (uint)comments.length() && !breakLine ; + (currIndex <= (commentsIndex + commentsLinesLengthLocal)) && + (currIndex < (uint)comments.length()) && !breakLine ; ++currIndex) { breakLine = (comments.at(currIndex) == QLatin1Char('\n')) ? true : false; if (breakLine) { newLine.append(QLatin1Char(' ')); } else { newLine.append(comments.at(currIndex)); } } commentsIndex = currIndex; // The line is ended if (commentsIndex != (uint)comments.length()) { while (!newLine.endsWith(QLatin1Char(' '))) { newLine.truncate(newLine.length() - 1); --commentsIndex; } } commentsByLines.prepend(newLine.trimmed()); } for (int i = 0 ; i < (int)commentsByLines.count() ; ++i) { printInfoText(p, offset, commentsByLines.at(i)); } } void SlideProperties::printTags(QPainter& p, int& offset, QStringList& tags) { tags.sort(); QString str = tags.join(QLatin1String(", ")); if (!str.isEmpty()) { printInfoText(p, offset, str, qApp->palette().color(QPalette::Link).name()); } } void SlideProperties::togglePaintEnabled() { d->paintEnabled = !d->paintEnabled; update(); } } // namespace Digikam diff --git a/core/utilities/slideshow/slideshow.cpp b/core/utilities/slideshow/slideshow.cpp index 639b16cb09..eff7a81feb 100644 --- a/core/utilities/slideshow/slideshow.cpp +++ b/core/utilities/slideshow/slideshow.cpp @@ -1,720 +1,787 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2005-04-21 * Description : slide show tool using preview of pictures. * * Copyright (C) 2005-2020 by Gilles Caulier * Copyright (C) 2004 by Enrico Ros * Copyright (C) 2019 by Minh Nghia Duong * * 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, 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. * * ============================================================ */ #include "slideshow.h" #include "digikam_config.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_DBUS # include # include # include #endif // KDE includes #include // Local includes #include "digikam_debug.h" #include "slidetoolbar.h" #include "slideimage.h" #include "slideerror.h" #include "slideosd.h" #include "slideend.h" #ifdef HAVE_MEDIAPLAYER # include "slidevideo.h" #endif //HAVE_MEDIAPLAYER namespace Digikam { class Q_DECL_HIDDEN SlideShow::Private { public: explicit Private() : fileIndex(-1), screenSaverCookie(-1), mouseMoveTimer(nullptr), imageView(nullptr), + #ifdef HAVE_MEDIAPLAYER + videoView(nullptr), + #endif + errorView(nullptr), endView(nullptr), osd(nullptr) { } int fileIndex; int screenSaverCookie; - QTimer* mouseMoveTimer; // To hide cursor when not moved. + QTimer* mouseMoveTimer; ///< To hide cursor when not moved. SlideImage* imageView; + #ifdef HAVE_MEDIAPLAYER + SlideVideo* videoView; + #endif + SlideError* errorView; SlideEnd* endView; SlideOSD* osd; SlideShowSettings settings; }; SlideShow::SlideShow(DInfoInterface* const iface, const SlideShowSettings& settings) : QStackedWidget(nullptr), d(new Private) { d->settings = settings; d->settings.iface = iface; setAttribute(Qt::WA_DeleteOnClose); setWindowFlags(Qt::FramelessWindowHint); setContextMenuPolicy(Qt::PreventContextMenu); setWindowState(windowState() | Qt::WindowFullScreen); setWindowTitle(i18n("Slideshow")); setMouseTracking(true); // --------------------------------------------------------------- d->errorView = new SlideError(this); d->errorView->installEventFilter(this); insertWidget(ErrorView, d->errorView); // --------------------------------------------------------------- d->imageView = new SlideImage(this); d->imageView->setPreviewSettings(d->settings.previewSettings); d->imageView->installEventFilter(this); connect(d->imageView, SIGNAL(signalImageLoaded(bool)), this, SLOT(slotImageLoaded(bool))); insertWidget(ImageView, d->imageView); // --------------------------------------------------------------- #ifdef HAVE_MEDIAPLAYER + d->videoView = new SlideVideo(this); d->videoView->setInfoInterface(d->settings.iface); d->videoView->installEventFilter(this); connect(d->videoView, SIGNAL(signalVideoLoaded(bool)), this, SLOT(slotVideoLoaded(bool))); connect(d->videoView, SIGNAL(signalVideoFinished()), this, SLOT(slotVideoFinished())); insertWidget(VideoView, d->videoView); + #endif // --------------------------------------------------------------- d->endView = new SlideEnd(this); d->endView->installEventFilter(this); insertWidget(EndView, d->endView); // --------------------------------------------------------------- d->osd = new SlideOSD(d->settings, this); d->osd->installEventFilter(this); // --------------------------------------------------------------- d->mouseMoveTimer = new QTimer(this); d->mouseMoveTimer->setSingleShot(true); d->mouseMoveTimer->setInterval(1000); connect(d->mouseMoveTimer, SIGNAL(timeout()), this, SLOT(slotMouseMoveTimeOut())); // --------------------------------------------------------------- QScreen* screen = qApp->primaryScreen(); if (QWidget* const widget = qApp->activeWindow()) { if (QWindow* const window = widget->windowHandle()) + { screen = window->screen(); + } } const int activeScreenIndex = qMax(qApp->screens().indexOf(screen), 0); const int preferenceScreen = d->settings.slideScreen; int screenIndex = 0; - if (preferenceScreen == -2) + if (preferenceScreen == -2) { screenIndex = activeScreenIndex; } else if (preferenceScreen == -1) { QScreen* const primaryScreen = qApp->primaryScreen(); screenIndex = qApp->screens().indexOf(primaryScreen); } else if ((preferenceScreen >= 0) && (preferenceScreen < qApp->screens().count())) { screenIndex = preferenceScreen; } else { screenIndex = activeScreenIndex; d->settings.slideScreen = -2; d->settings.writeToConfig(); } if (d->settings.suffle) { d->settings.suffleImages(); } slotScreenSelected(screenIndex); // --------------------------------------------------------------- inhibitScreenSaver(); slotMouseMoveTimeOut(); setCurrentIndex(ImageView); } SlideShow::~SlideShow() { emit signalLastItemUrl(currentItem()); d->mouseMoveTimer->stop(); allowScreenSaver(); delete d; } void SlideShow::setCurrentView(SlideShowViewMode view) { switch(view) { case ErrorView: d->osd->video(false); d->errorView->setCurrentUrl(currentItem()); setCurrentIndex(view); d->osd->setCurrentUrl(currentItem()); break; case ImageView: + #ifdef HAVE_MEDIAPLAYER + d->videoView->stop(); d->osd->video(false); + #endif + setCurrentIndex(view); d->osd->setCurrentUrl(currentItem()); break; case VideoView: + #ifdef HAVE_MEDIAPLAYER + d->osd->video(true); d->osd->pause(false); setCurrentIndex(view); d->osd->setCurrentUrl(currentItem()); + #endif + break; default : // EndView + #ifdef HAVE_MEDIAPLAYER + d->videoView->stop(); d->osd->video(false); + #endif + d->osd->pause(true); setCurrentIndex(view); break; } } void SlideShow::setCurrentItem(const QUrl& url) { int index = d->settings.indexOf(url); if (index != -1) { d->fileIndex = index - 1; } } QUrl SlideShow::currentItem() const { return d->settings.fileList.value(d->fileIndex); } void SlideShow::slotLoadNextItem() { int num = d->settings.count(); if (d->fileIndex == (num - 1)) { if (d->settings.loop) { d->fileIndex = -1; } } d->fileIndex++; qCDebug(DIGIKAM_GENERAL_LOG) << "fileIndex: " << d->fileIndex; if (!d->settings.loop) { d->osd->toolBar()->setEnabledPrev(d->fileIndex > 0); d->osd->toolBar()->setEnabledNext(d->fileIndex < (num - 1)); } if (d->fileIndex >= 0 && d->fileIndex < num) { #ifdef HAVE_MEDIAPLAYER + QMimeDatabase mimeDB; if (mimeDB.mimeTypeForFile(currentItem().toLocalFile()) .name().startsWith(QLatin1String("video/"))) { d->videoView->setCurrentUrl(currentItem()); return; } + #endif d->imageView->setLoadUrl(currentItem()); } else { endOfSlide(); } } void SlideShow::slotLoadPrevItem() { int num = d->settings.count(); if (d->fileIndex == 0) { if (d->settings.loop) { d->fileIndex = num; } } d->fileIndex--; qCDebug(DIGIKAM_GENERAL_LOG) << "fileIndex: " << d->fileIndex; if (!d->settings.loop) { d->osd->toolBar()->setEnabledPrev(d->fileIndex > 0); d->osd->toolBar()->setEnabledNext(d->fileIndex < (num - 1)); } - if (d->fileIndex >= 0 && d->fileIndex < num) + if ((d->fileIndex >= 0) && (d->fileIndex < num)) { #ifdef HAVE_MEDIAPLAYER QMimeDatabase mimeDB; if (mimeDB.mimeTypeForFile(currentItem().toLocalFile()) .name().startsWith(QLatin1String("video/"))) { d->videoView->setCurrentUrl(currentItem()); return; } #endif d->imageView->setLoadUrl(currentItem()); } else { endOfSlide(); } } void SlideShow::slotImageLoaded(bool loaded) { if (loaded) { setCurrentView(ImageView); if (d->fileIndex != -1) { if (!d->osd->isPaused()) { d->osd->pause(false); } preloadNextItem(); } } else { + #ifdef HAVE_MEDIAPLAYER + // Try to load only GIF Images + QMimeDatabase mimeDB; if (mimeDB.mimeTypeForFile(currentItem().toLocalFile()) .name() == QLatin1String("image/gif")) { d->videoView->setCurrentUrl(currentItem()); } + #else + preloadNextItem(); + #endif + } d->osd->setLoadingReady(true); } void SlideShow::slotVideoLoaded(bool loaded) { if (loaded) { setCurrentView(VideoView); } else { // Failed to load item + setCurrentView(ErrorView); if (d->fileIndex != -1) { if (!d->osd->isPaused()) { d->osd->pause(false); } } } preloadNextItem(); } void SlideShow::slotVideoFinished() { if (d->fileIndex != -1) { d->osd->video(false); slotLoadNextItem(); } } void SlideShow::endOfSlide() { setCurrentView(EndView); d->fileIndex = -1; d->osd->toolBar()->setEnabledPlay(false); d->osd->toolBar()->setEnabledNext(false); d->osd->toolBar()->setEnabledPrev(false); } void SlideShow::preloadNextItem() { int index = d->fileIndex + 1; int num = d->settings.count(); if (index >= num) { if (d->settings.loop) { index = 0; } } if (index < num) { QUrl nextItem = d->settings.fileList.value(index); #ifdef HAVE_MEDIAPLAYER + QMimeDatabase mimeDB; if (mimeDB.mimeTypeForFile(nextItem.toLocalFile()) .name().startsWith(QLatin1String("video/"))) { return; } + #endif d->imageView->setPreloadUrl(nextItem); } } void SlideShow::wheelEvent(QWheelEvent* e) { if (e->delta() < 0) { d->osd->pause(true); slotLoadNextItem(); } if (e->delta() > 0) { if (d->fileIndex == -1) { // EndView => backward. + d->fileIndex = d->settings.count(); } d->osd->pause(true); slotLoadPrevItem(); } } void SlideShow::mousePressEvent(QMouseEvent* e) { if (d->fileIndex == -1) { // EndView => close Slideshow view. + close(); } - if (e->button() == Qt::LeftButton) + if (e->button() == Qt::LeftButton) { d->osd->pause(true); slotLoadNextItem(); } else if (e->button() == Qt::RightButton) { if (d->fileIndex == -1) { // EndView => backward. + d->fileIndex = d->settings.count() - 1; } d->osd->pause(true); slotLoadPrevItem(); } } void SlideShow::keyPressEvent(QKeyEvent* e) { if (!e) { return; } if (e->key() == Qt::Key_F4) { d->osd->toggleProperties(); return; } d->osd->toolBar()->keyPressEvent(e); } bool SlideShow::eventFilter(QObject* obj, QEvent* ev) { if (ev->type() == QEvent::MouseMove) { setCursor(QCursor(Qt::ArrowCursor)); #ifdef HAVE_MEDIAPLAYER + d->videoView->showIndicator(true); + #endif d->mouseMoveTimer->start(); return false; } // pass the event on to the parent class + return QWidget::eventFilter(obj, ev); } void SlideShow::slotMouseMoveTimeOut() { if (!d->osd->isUnderMouse()) { setCursor(QCursor(Qt::BlankCursor)); } #ifdef HAVE_MEDIAPLAYER + d->videoView->showIndicator(false); + #endif + } -// From Okular's presentation widget -// TODO: Add OSX and Windows support +/** + * Inspired from Okular's presentation widget + * TODO: Add OSX and Windows support + */ void SlideShow::inhibitScreenSaver() { + #ifdef HAVE_DBUS + QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.ScreenSaver"), QLatin1String("/ScreenSaver"), QLatin1String("org.freedesktop.ScreenSaver"), QLatin1String("Inhibit")); message << QLatin1String("digiKam"); message << i18nc("Reason for inhibiting the screensaver activation, when the presentation mode is active", "Giving a slideshow"); QDBusReply reply = QDBusConnection::sessionBus().call(message); if (reply.isValid()) { d->screenSaverCookie = reply.value(); } + #endif + } void SlideShow::allowScreenSaver() { + #ifdef HAVE_DBUS + if (d->screenSaverCookie != -1) { QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.ScreenSaver"), QLatin1String("/ScreenSaver"), QLatin1String("org.freedesktop.ScreenSaver"), QLatin1String("UnInhibit")); message << (uint)d->screenSaverCookie; QDBusConnection::sessionBus().send(message); } + #endif + } void SlideShow::slotAssignRating(int rating) { DInfoInterface::DInfoMap info; DItemInfo item(info); item.setRating(rating); d->settings.iface->setItemInfo(currentItem(), info); dispatchCurrentInfoChange(currentItem()); + emit signalRatingChanged(currentItem(), rating); } void SlideShow::slotAssignColorLabel(int color) { DInfoInterface::DInfoMap info; DItemInfo item(info); item.setColorLabel(color); d->settings.iface->setItemInfo(currentItem(), info); dispatchCurrentInfoChange(currentItem()); + emit signalColorLabelChanged(currentItem(), color); } void SlideShow::slotAssignPickLabel(int pick) { DInfoInterface::DInfoMap info; DItemInfo item(info); item.setPickLabel(pick); d->settings.iface->setItemInfo(currentItem(), info); dispatchCurrentInfoChange(currentItem()); + emit signalPickLabelChanged(currentItem(), pick); } void SlideShow::updateTags(const QUrl& url, const QStringList& /*tags*/) { dispatchCurrentInfoChange(url); } void SlideShow::toggleTag(int tag) { emit signalToggleTag(currentItem(), tag); } void SlideShow::dispatchCurrentInfoChange(const QUrl& url) { if (currentItem() == url) { d->osd->setCurrentUrl(currentItem()); } } void SlideShow::slotPause() { + #ifdef HAVE_MEDIAPLAYER + if (currentIndex() == VideoView) { d->videoView->pause(true); } else + #endif + { d->osd->pause(true); } } void SlideShow::slotPlay() { + #ifdef HAVE_MEDIAPLAYER + if (currentIndex() == VideoView) { d->videoView->pause(false); } else + #endif + { d->osd->pause(false); } } void SlideShow::slotScreenSelected(int screen) { if (screen >= qApp->screens().count()) { return; } QRect deskRect = qApp->screens().at(screen)->geometry(); setWindowState(windowState() & ~Qt::WindowFullScreen); move(deskRect.x(), deskRect.y()); resize(deskRect.width(), deskRect.height()); setWindowState(windowState() | Qt::WindowFullScreen); // update OSD position + if (d->fileIndex != -1) { qApp->processEvents(); d->osd->setCurrentUrl(currentItem()); } qCDebug(DIGIKAM_GENERAL_LOG) << "Slideshow: move to screen: " << screen << " :: " << deskRect; } } // namespace Digikam diff --git a/core/utilities/slideshow/slideshow.h b/core/utilities/slideshow/slideshow.h index 6937168627..e08ade83f5 100644 --- a/core/utilities/slideshow/slideshow.h +++ b/core/utilities/slideshow/slideshow.h @@ -1,127 +1,127 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2005-04-21 * Description : slide show tool using preview of pictures. * * Copyright (C) 2005-2020 by Gilles Caulier * Copyright (C) 2019 by Minh Nghia Duong * * 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, 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. * * ============================================================ */ #ifndef DIGIKAM_SLIDE_SHOW_H #define DIGIKAM_SLIDE_SHOW_H // Qt includes #include #include #include #include #include // Local includes #include "digikam_export.h" #include "dinfointerface.h" #include "loadingdescription.h" #include "slideshowsettings.h" namespace Digikam { class DImg; class DIGIKAM_EXPORT SlideShow : public QStackedWidget { Q_OBJECT public: enum SlideShowViewMode { ErrorView=0, ImageView, VideoView, EndView }; public: explicit SlideShow(DInfoInterface* const iface, const SlideShowSettings& settings); ~SlideShow(); void setCurrentItem(const QUrl& url); QUrl currentItem() const; void toggleTag(int tag); void updateTags(const QUrl& url, const QStringList& tags); Q_SIGNALS: void signalRatingChanged(const QUrl&, int); void signalColorLabelChanged(const QUrl&, int); void signalPickLabelChanged(const QUrl&, int); void signalToggleTag(const QUrl&, int); void signalLastItemUrl(const QUrl&); public Q_SLOTS: void slotLoadNextItem(); void slotLoadPrevItem(); void slotPause(); void slotPlay(); void slotAssignRating(int); void slotAssignColorLabel(int); void slotAssignPickLabel(int); protected: - void mousePressEvent(QMouseEvent*) override; - void keyPressEvent(QKeyEvent*) override; - void wheelEvent(QWheelEvent*) override; + void mousePressEvent(QMouseEvent*) override; + void keyPressEvent(QKeyEvent*) override; + void wheelEvent(QWheelEvent*) override; private Q_SLOTS: void slotMouseMoveTimeOut(); void slotImageLoaded(bool); void slotScreenSelected(int); void slotVideoLoaded(bool); void slotVideoFinished(); private: void setCurrentView(SlideShowViewMode); - bool eventFilter(QObject* obj, QEvent* ev) override; + bool eventFilter(QObject* obj, QEvent* ev) override; void preloadNextItem(); void endOfSlide(); void inhibitScreenSaver(); void allowScreenSaver(); void dispatchCurrentInfoChange(const QUrl& url); void makeCornerRectangles(const QRect& desktopRect, const QSize& size, QRect* const topLeft, QRect* const topRight, QRect* const topLeftLarger, QRect* const topRightLarger); private: class Private; Private* const d; }; } // namespace Digikam #endif // DIGIKAM_SLIDE_SHOW_H diff --git a/core/utilities/slideshow/slideshowsettings.h b/core/utilities/slideshow/slideshowsettings.h index 3a6bd36d0d..fbccf92966 100644 --- a/core/utilities/slideshow/slideshowsettings.h +++ b/core/utilities/slideshow/slideshowsettings.h @@ -1,188 +1,212 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2007-02-13 * Description : slide show settings container. * * Copyright (C) 2007-2020 by Gilles Caulier * Copyright (C) 2019 by Minh Nghia Duong * * 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, 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. * * ============================================================ */ #ifndef DIGIKAM_SLIDESHOW_SETTINGS_H #define DIGIKAM_SLIDESHOW_SETTINGS_H // Qt includes #include #include #include #include #include // Local includes #include "digikam_export.h" #include "previewsettings.h" #include "dinfointerface.h" namespace Digikam { /** This class contain all settings to perform a slide show of a group of pictures */ class DIGIKAM_EXPORT SlideShowSettings { public: explicit SlideShowSettings(); ~SlideShowSettings(); void readFromConfig(); void writeToConfig(); int indexOf(const QUrl&) const; int count() const; void suffleImages(); public: - // Global Slide Show Settings + /// Global Slide Show Settings - /** Start Slide with current selected item + /** + * Start Slide with current selected item */ bool startWithCurrent; - /** Auto-rotate image accordingly with Exif Rotation tag + /** + * Auto-rotate image accordingly with Exif Rotation tag */ bool exifRotate; - /** Print picture file name while slide + /** + * Print picture file name while slide */ bool printName; - /** Print picture creation date while slide + /** + * Print picture creation date while slide */ bool printDate; - /** Print camera Aperture and Focal while slide + /** + * Print camera Aperture and Focal while slide */ bool printApertureFocal; - /** Print camera Make and Model while slide + /** + * Print camera Make and Model while slide */ bool printMakeModel; - /** Print camera Exposure and Sensitivity while slide + /** + * Print camera Exposure and Sensitivity while slide */ bool printExpoSensitivity; - /** Print picture comment while slide + /** + * Print picture comment while slide */ bool printComment; - /** Print image title while slide + /** + * Print image title while slide */ bool printTitle; - /** Print image captions if no title available while slide + /** + * Print image captions if no title available while slide */ bool printCapIfNoTitle; - /** Print tag names while slide + /** + * Print tag names while slide */ bool printTags; - /** Print color label and pick label while slide + /** + * Print color label and pick label while slide */ bool printLabels; - /** Print rating while slide + /** + * Print rating while slide */ bool printRating; - /** Slide pictures in loop + /** + * Slide pictures in loop */ bool loop; - /** Suffle pictures - */ + /** + * Suffle pictures + */ bool suffle; - /** Delay in seconds + /** + * Delay in seconds */ int delay; - /** Whether to enable the auto-move feature. + /** + * Whether to enable the auto-move feature. */ bool autoPlayEnabled; - /** Screen to use in case of multi-monitor computer. + /** + * Screen to use in case of multi-monitor computer. */ int slideScreen; - /** Show progress indicator + /** + * Show progress indicator */ bool showProgressIndicator; - /** Load images (previews) in full size, not reduced version + /** + * Load images (previews) in full size, not reduced version */ PreviewSettings previewSettings; - /** List of pictures URL to slide + /** + * List of pictures URL to slide */ QList fileList; - /** URL of the first image to show if requested + /** + * URL of the first image to show if requested */ QUrl imageUrl; - /** Font for the display of caption text + /** + * Font for the display of caption text */ QFont captionFont; - /** Interface to access to host application data + /** + * Interface to access to host application data */ DInfoInterface* iface; private: static const QString configGroupName; static const QString configSlideShowStartCurrentEntry; static const QString configSlideShowDelayEntry; static const QString configSlideShowLoopEntry; static const QString configSlideShowSuffleEntry; static const QString configSlideShowPrintApertureFocalEntry; static const QString configSlideShowPrintCommentEntry; static const QString configSlideShowPrintTitleEntry; static const QString configSlideShowPrintCapIfNoTitleEntry; static const QString configSlideShowPrintDateEntry; static const QString configSlideShowPrintExpoSensitivityEntry; static const QString configSlideShowPrintMakeModelEntry; static const QString configSlideShowPrintNameEntry; static const QString configSlideShowPrintTagsEntry; static const QString configSlideShowPrintLabelsEntry; static const QString configSlideShowPrintRatingEntry; static const QString configSlideShowProgressIndicatorEntry; static const QString configSlideShowCaptionFontEntry; static const QString configSlideScreenEntry; }; } // namespace Digikam #endif // DIGIKAM_SLIDESHOW_SETTINGS_H diff --git a/core/utilities/slideshow/slidetoolbar.cpp b/core/utilities/slideshow/slidetoolbar.cpp index 3d3f78f07b..43a713b9c0 100644 --- a/core/utilities/slideshow/slidetoolbar.cpp +++ b/core/utilities/slideshow/slidetoolbar.cpp @@ -1,283 +1,290 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2004-10-05 * Description : a tool bar for slideshow * * Copyright (C) 2004-2005 by Renchi Raju * Copyright (C) 2006-2020 by Gilles Caulier * * 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, 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. * * ============================================================ */ #include "slidetoolbar.h" // Qt includes #include #include #include #include #include #include // KDE includes #include // Local includes #include "slidehelp.h" #include "digikam_debug.h" namespace Digikam { class Q_DECL_HIDDEN SlideToolBar::Private { public: explicit Private() : playBtn(nullptr), stopBtn(nullptr), nextBtn(nullptr), prevBtn(nullptr), screenSelectBtn(nullptr) { } QToolButton* playBtn; QToolButton* stopBtn; QToolButton* nextBtn; QToolButton* prevBtn; QToolButton* screenSelectBtn; }; SlideToolBar::SlideToolBar(const SlideShowSettings& settings, QWidget* const parent) : DHBox(parent), d(new Private) { setMouseTracking(true); setContentsMargins(QMargins()); d->playBtn = new QToolButton(this); d->prevBtn = new QToolButton(this); d->nextBtn = new QToolButton(this); d->stopBtn = new QToolButton(this); d->playBtn->setCheckable(true); d->playBtn->setChecked(!settings.autoPlayEnabled); d->playBtn->setFocusPolicy(Qt::NoFocus); d->prevBtn->setFocusPolicy(Qt::NoFocus); d->nextBtn->setFocusPolicy(Qt::NoFocus); d->stopBtn->setFocusPolicy(Qt::NoFocus); QSize s(32, 32); d->playBtn->setIconSize(s); d->prevBtn->setIconSize(s); d->nextBtn->setIconSize(s); d->stopBtn->setIconSize(s); QString iconString = settings.autoPlayEnabled ? QLatin1String("media-playback-pause") : QLatin1String("media-playback-start"); d->playBtn->setIcon(QIcon::fromTheme(iconString)); d->prevBtn->setIcon(QIcon::fromTheme(QLatin1String("media-skip-backward"))); d->nextBtn->setIcon(QIcon::fromTheme(QLatin1String("media-skip-forward"))); d->stopBtn->setIcon(QIcon::fromTheme(QLatin1String("media-playback-stop"))); int num = qApp->screens().count(); if (num > 1) { d->screenSelectBtn = new QToolButton(this); QMenu* const screenMenu = new QMenu(d->screenSelectBtn); d->screenSelectBtn->setToolTip(i18n("Switch Screen")); d->screenSelectBtn->setIconSize(s); d->screenSelectBtn->setIcon(QIcon::fromTheme(QLatin1String("video-display"))); d->screenSelectBtn->setMenu(screenMenu); d->screenSelectBtn->setPopupMode(QToolButton::InstantPopup); d->screenSelectBtn->setFocusPolicy(Qt::NoFocus); QActionGroup* const group = new QActionGroup(screenMenu); group->setExclusive(true); for (int i = 0 ; i < num ; ++i) { QString model = qApp->screens().at(i)->model(); QAction* const act = screenMenu->addAction(i18nc("%1 is the screen number (0, 1, ...)", "Screen %1", i) + QString::fromUtf8(" (%1)").arg(model.left(model.length() - 1))); act->setData(qVariantFromValue(i)); act->setCheckable(true); group->addAction(act); if (i == settings.slideScreen) - act->setChecked(true); + { + act->setChecked(true); + } } connect(screenMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotScreenSelected(QAction*))); } connect(d->playBtn, SIGNAL(toggled(bool)), this, SLOT(slotPlayBtnToggled())); connect(d->nextBtn, SIGNAL(clicked()), this, SLOT(slotNexPrevClicked())); connect(d->prevBtn, SIGNAL(clicked()), this, SLOT(slotNexPrevClicked())); connect(d->nextBtn, SIGNAL(clicked()), this, SIGNAL(signalNext())); connect(d->prevBtn, SIGNAL(clicked()), this, SIGNAL(signalPrev())); connect(d->stopBtn, SIGNAL(clicked()), this, SIGNAL(signalClose())); } SlideToolBar::~SlideToolBar() { delete d; } bool SlideToolBar::isPaused() const { return d->playBtn->isChecked(); } void SlideToolBar::pause(bool val) { if (val == isPaused()) { return; } d->playBtn->setChecked(val); slotPlayBtnToggled(); } void SlideToolBar::setEnabledPlay(bool val) { d->playBtn->setEnabled(val); } void SlideToolBar::setEnabledNext(bool val) { d->nextBtn->setEnabled(val); } void SlideToolBar::setEnabledPrev(bool val) { d->prevBtn->setEnabled(val); } void SlideToolBar::slotPlayBtnToggled() { if (d->playBtn->isChecked()) { d->playBtn->setIcon(QIcon::fromTheme(QLatin1String("media-playback-start"))); + emit signalPause(); } else { d->playBtn->setIcon(QIcon::fromTheme(QLatin1String("media-playback-pause"))); + emit signalPlay(); } } void SlideToolBar::slotNexPrevClicked() { if (!d->playBtn->isChecked()) { d->playBtn->setChecked(true); d->playBtn->setIcon(QIcon::fromTheme(QLatin1String("media-playback-start"))); + emit signalPause(); } } void SlideToolBar::keyPressEvent(QKeyEvent* e) { switch (e->key()) { case (Qt::Key_F1): { d->playBtn->animateClick(); SlideHelp* const help = new SlideHelp(); help->exec(); d->playBtn->animateClick(); break; } case (Qt::Key_Space): { if (d->playBtn->isEnabled()) { d->playBtn->animateClick(); } break; } case (Qt::Key_Left): case (Qt::Key_Up): case (Qt::Key_PageUp): { if (d->prevBtn->isEnabled()) { d->prevBtn->animateClick(); } break; } case (Qt::Key_Right): case (Qt::Key_Down): case (Qt::Key_PageDown): { if (d->nextBtn->isEnabled()) { d->nextBtn->animateClick(); } break; } case (Qt::Key_Escape): { if (d->stopBtn->isEnabled()) { d->stopBtn->animateClick(); } break; } default: break; } e->accept(); } void SlideToolBar::slotScreenSelected(QAction* act) { - if (!act || act->data().type() != QVariant::Int) + if (!act || (act->data().type() != QVariant::Int)) + { return; + } emit signalScreenSelected(act->data().toInt()); } } // namespace Digikam