File indexing completed on 2025-03-09 03:52:09
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2005-04-21 0007 * Description : slide show tool using preview of pictures. 0008 * 0009 * SPDX-FileCopyrightText: 2005-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2004 by Enrico Ros <eros dot kde at email dot it> 0011 * SPDX-FileCopyrightText: 2019-2020 by Minh Nghia Duong <minhnghiaduong997 at gmail dot com> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "slideshowloader.h" 0018 0019 // Qt includes 0020 0021 #include <QMimeDatabase> 0022 #include <QApplication> 0023 #include <QScreen> 0024 #include <QWindow> 0025 #include <QCursor> 0026 #include <QTimer> 0027 #include <QColor> 0028 #include <QFont> 0029 0030 #ifdef HAVE_DBUS 0031 # include <QDBusConnection> 0032 # include <QDBusMessage> 0033 # include <QDBusReply> 0034 #endif 0035 0036 // KDE includes 0037 0038 #include <klocalizedstring.h> 0039 0040 // Local includes 0041 0042 #include "digikam_debug.h" 0043 #include "slidetoolbar.h" 0044 #include "slideimage.h" 0045 #include "slideerror.h" 0046 #include "slideosd.h" 0047 #include "slideend.h" 0048 0049 #ifdef HAVE_MEDIAPLAYER 0050 # include "slidevideo.h" 0051 #endif //HAVE_MEDIAPLAYER 0052 0053 #ifdef Q_OS_WIN 0054 # include "windows.h" 0055 #endif 0056 0057 using namespace Digikam; 0058 0059 namespace DigikamGenericSlideShowPlugin 0060 { 0061 0062 class Q_DECL_HIDDEN SlideShowLoader::Private 0063 { 0064 0065 public: 0066 0067 explicit Private() 0068 : fileIndex (-1), 0069 screenSaverCookie (-1), 0070 mouseMoveTimer (nullptr), 0071 imageView (nullptr), 0072 0073 #ifdef HAVE_MEDIAPLAYER 0074 0075 videoView (nullptr), 0076 0077 #endif 0078 0079 errorView (nullptr), 0080 endView (nullptr), 0081 osd (nullptr), 0082 settings (nullptr) 0083 { 0084 } 0085 0086 int fileIndex; 0087 int screenSaverCookie; 0088 0089 QTimer* mouseMoveTimer; ///< To hide cursor when not moved. 0090 0091 SlideImage* imageView; 0092 0093 #ifdef HAVE_MEDIAPLAYER 0094 0095 SlideVideo* videoView; 0096 0097 #endif 0098 0099 SlideError* errorView; 0100 SlideEnd* endView; 0101 SlideOSD* osd; 0102 0103 SlideShowSettings* settings; 0104 0105 QMap<QString, QString> shortcutPrefixes; 0106 }; 0107 0108 SlideShowLoader::SlideShowLoader(SlideShowSettings* const settings) 0109 : QStackedWidget(nullptr), 0110 d (new Private) 0111 { 0112 d->settings = settings; 0113 0114 setAttribute(Qt::WA_DeleteOnClose); 0115 setWindowFlags(Qt::FramelessWindowHint); 0116 setContextMenuPolicy(Qt::PreventContextMenu); 0117 setWindowState(windowState() | Qt::WindowFullScreen); 0118 0119 setWindowTitle(i18nc("@title:window", "Slideshow")); 0120 setObjectName(QLatin1String("Slideshow")); 0121 setMouseTracking(true); 0122 0123 // --------------------------------------------------------------- 0124 0125 d->errorView = new SlideError(this); 0126 0127 insertWidget(ErrorView, d->errorView); 0128 0129 // --------------------------------------------------------------- 0130 0131 d->imageView = new SlideImage(this); 0132 d->imageView->setPreviewSettings(d->settings->previewSettings); 0133 0134 connect(d->imageView, SIGNAL(signalImageLoaded(bool)), 0135 this, SLOT(slotImageLoaded(bool))); 0136 0137 insertWidget(ImageView, d->imageView); 0138 0139 // --------------------------------------------------------------- 0140 0141 #ifdef HAVE_MEDIAPLAYER 0142 0143 d->videoView = new SlideVideo(this); 0144 d->videoView->setInfoInterface(d->settings->iface); 0145 0146 connect(d->videoView, SIGNAL(signalVideoLoaded(bool)), 0147 this, SLOT(slotVideoLoaded(bool))); 0148 0149 connect(d->videoView, SIGNAL(signalVideoFinished()), 0150 this, SLOT(slotVideoFinished())); 0151 0152 insertWidget(VideoView, d->videoView); 0153 0154 #endif 0155 0156 // --------------------------------------------------------------- 0157 0158 d->endView = new SlideEnd(this); 0159 0160 insertWidget(EndView, d->endView); 0161 0162 // --------------------------------------------------------------- 0163 0164 d->osd = new SlideOSD(d->settings, this); 0165 0166 // --------------------------------------------------------------- 0167 0168 d->mouseMoveTimer = new QTimer(this); 0169 d->mouseMoveTimer->setSingleShot(true); 0170 d->mouseMoveTimer->setInterval(1000); 0171 0172 connect(d->mouseMoveTimer, SIGNAL(timeout()), 0173 this, SLOT(slotMouseMoveTimeOut())); 0174 0175 // --------------------------------------------------------------- 0176 0177 d->errorView->installEventFilter(this); 0178 d->imageView->installEventFilter(this); 0179 d->endView->installEventFilter(this); 0180 d->osd->installEventFilter(this); 0181 0182 #ifdef HAVE_MEDIAPLAYER 0183 0184 d->videoView->installEventFilter(this); 0185 0186 #endif 0187 0188 // --------------------------------------------------------------- 0189 0190 QScreen* screen = qApp->primaryScreen(); 0191 0192 if (QWidget* const widget = qApp->activeWindow()) 0193 { 0194 if (QWindow* const window = widget->windowHandle()) 0195 { 0196 screen = window->screen(); 0197 } 0198 } 0199 0200 const int activeScreenIndex = qMax(qApp->screens().indexOf(screen), 0); 0201 const int preferenceScreen = d->settings->slideScreen; 0202 int screenIndex = 0; 0203 0204 if (preferenceScreen == -2) 0205 { 0206 screenIndex = activeScreenIndex; 0207 } 0208 else if (preferenceScreen == -1) 0209 { 0210 QScreen* const primaryScreen = qApp->primaryScreen(); 0211 screenIndex = qApp->screens().indexOf(primaryScreen); 0212 } 0213 else if ((preferenceScreen >= 0) && (preferenceScreen < qApp->screens().count())) 0214 { 0215 screenIndex = preferenceScreen; 0216 } 0217 else 0218 { 0219 screenIndex = activeScreenIndex; 0220 d->settings->slideScreen = -2; 0221 d->settings->writeToConfig(); 0222 } 0223 0224 slotScreenSelected(screenIndex); 0225 0226 // --------------------------------------------------------------- 0227 0228 inhibitScreenSaver(); 0229 slotMouseMoveTimeOut(); 0230 setCurrentIndex(ImageView); 0231 } 0232 0233 SlideShowLoader::~SlideShowLoader() 0234 { 0235 Q_EMIT signalLastItemUrl(currentItem()); 0236 0237 d->mouseMoveTimer->stop(); 0238 0239 allowScreenSaver(); 0240 0241 delete d->settings; 0242 delete d; 0243 } 0244 0245 void SlideShowLoader::setCurrentView(SlideShowViewMode view) 0246 { 0247 switch (view) 0248 { 0249 case ErrorView: 0250 { 0251 d->osd->video(false); 0252 d->errorView->setCurrentUrl(currentItem()); 0253 0254 setCurrentIndex(view); 0255 d->osd->setCurrentUrl(currentItem()); 0256 0257 break; 0258 } 0259 0260 case ImageView: 0261 { 0262 0263 #ifdef HAVE_MEDIAPLAYER 0264 0265 d->videoView->stop(); 0266 d->osd->video(false); 0267 0268 #endif 0269 0270 setCurrentIndex(view); 0271 d->osd->setCurrentUrl(currentItem()); 0272 0273 break; 0274 } 0275 0276 #ifdef HAVE_MEDIAPLAYER 0277 0278 case VideoView: 0279 { 0280 0281 0282 d->osd->video(true); 0283 d->osd->pause(false); 0284 setCurrentIndex(view); 0285 d->osd->setCurrentUrl(currentItem()); 0286 0287 0288 break; 0289 } 0290 0291 #endif 0292 0293 default: // EndView 0294 { 0295 0296 #ifdef HAVE_MEDIAPLAYER 0297 0298 d->videoView->stop(); 0299 d->osd->video(false); 0300 0301 #endif 0302 0303 d->osd->pause(true); 0304 setCurrentIndex(view); 0305 0306 break; 0307 } 0308 } 0309 } 0310 0311 void SlideShowLoader::setCurrentItem(const QUrl& url) 0312 { 0313 int index = d->settings->indexOf(url); 0314 0315 if (index != -1) 0316 { 0317 d->fileIndex = index - 1; 0318 } 0319 } 0320 0321 QUrl SlideShowLoader::currentItem() const 0322 { 0323 return d->settings->fileList.value(d->fileIndex); 0324 } 0325 0326 void SlideShowLoader::setShortCutPrefixes(const QMap<QString, QString>& prefixes) 0327 { 0328 d->shortcutPrefixes = prefixes; 0329 } 0330 0331 void SlideShowLoader::slotLoadNextItem() 0332 { 0333 int num = d->settings->count(); 0334 0335 if (d->fileIndex == (num - 1)) 0336 { 0337 if (d->settings->loop) 0338 { 0339 d->fileIndex = -1; 0340 } 0341 } 0342 0343 d->fileIndex++; 0344 0345 qCDebug(DIGIKAM_GENERAL_LOG) << "fileIndex: " << d->fileIndex; 0346 0347 if (!d->settings->loop) 0348 { 0349 d->osd->toolBar()->setEnabledPrev(d->fileIndex > 0); 0350 d->osd->toolBar()->setEnabledNext(d->fileIndex < (num - 1)); 0351 } 0352 0353 if ((d->fileIndex >= 0) && (d->fileIndex < num)) 0354 { 0355 0356 #ifdef HAVE_MEDIAPLAYER 0357 0358 QMimeDatabase mimeDB; 0359 0360 if (mimeDB.mimeTypeForFile(currentItem().toLocalFile()) 0361 .name().startsWith(QLatin1String("video/"))) 0362 { 0363 d->videoView->setCurrentUrl(currentItem()); 0364 0365 return; 0366 } 0367 0368 #endif 0369 0370 d->imageView->setLoadUrl(currentItem()); 0371 } 0372 else 0373 { 0374 endOfSlide(); 0375 } 0376 } 0377 0378 void SlideShowLoader::slotLoadPrevItem() 0379 { 0380 int num = d->settings->count(); 0381 0382 if (d->fileIndex == 0) 0383 { 0384 if (d->settings->loop) 0385 { 0386 d->fileIndex = num; 0387 } 0388 } 0389 0390 d->fileIndex--; 0391 0392 qCDebug(DIGIKAM_GENERAL_LOG) << "fileIndex: " << d->fileIndex; 0393 0394 if (!d->settings->loop) 0395 { 0396 d->osd->toolBar()->setEnabledPrev(d->fileIndex > 0); 0397 d->osd->toolBar()->setEnabledNext(d->fileIndex < (num - 1)); 0398 } 0399 0400 if ((d->fileIndex >= 0) && (d->fileIndex < num)) 0401 { 0402 0403 #ifdef HAVE_MEDIAPLAYER 0404 0405 QMimeDatabase mimeDB; 0406 0407 if (mimeDB.mimeTypeForFile(currentItem().toLocalFile()) 0408 .name().startsWith(QLatin1String("video/"))) 0409 { 0410 d->videoView->setCurrentUrl(currentItem()); 0411 0412 return; 0413 } 0414 0415 #endif 0416 0417 d->imageView->setLoadUrl(currentItem()); 0418 } 0419 else 0420 { 0421 endOfSlide(); 0422 } 0423 } 0424 0425 void SlideShowLoader::slotImageLoaded(bool loaded) 0426 { 0427 if (loaded) 0428 { 0429 setCurrentView(ImageView); 0430 0431 if (d->fileIndex != -1) 0432 { 0433 if (!d->osd->isPaused()) 0434 { 0435 d->osd->pause(false); 0436 } 0437 0438 preloadNextItem(); 0439 } 0440 } 0441 else 0442 { 0443 0444 #ifdef HAVE_MEDIAPLAYER 0445 0446 // Try to load only GIF Images 0447 0448 QMimeDatabase mimeDB; 0449 0450 if (mimeDB.mimeTypeForFile(currentItem().toLocalFile()) 0451 .name() == QLatin1String("image/gif")) 0452 { 0453 d->videoView->setCurrentUrl(currentItem()); 0454 } 0455 0456 #else 0457 0458 preloadNextItem(); 0459 0460 #endif 0461 0462 } 0463 0464 d->osd->setLoadingReady(true); 0465 } 0466 0467 void SlideShowLoader::slotRemoveImageFromList() 0468 { 0469 QUrl url = currentItem(); 0470 0471 // Delete or move to trash by url 0472 0473 d->settings->iface->deleteImage(url); 0474 0475 // Delete from list of slide show 0476 0477 d->settings->fileList.removeOne(url); 0478 0479 slotLoadNextItem(); 0480 } 0481 0482 void SlideShowLoader::slotVideoLoaded(bool loaded) 0483 { 0484 if (loaded) 0485 { 0486 0487 #ifdef HAVE_MEDIAPLAYER 0488 0489 setCurrentView(VideoView); 0490 0491 #endif 0492 0493 } 0494 else 0495 { 0496 // Failed to load item 0497 0498 setCurrentView(ErrorView); 0499 0500 if (d->fileIndex != -1) 0501 { 0502 if (!d->osd->isPaused()) 0503 { 0504 d->osd->pause(false); 0505 } 0506 } 0507 } 0508 0509 preloadNextItem(); 0510 } 0511 0512 void SlideShowLoader::slotVideoFinished() 0513 { 0514 if (d->fileIndex != -1) 0515 { 0516 d->osd->video(false); 0517 slotLoadNextItem(); 0518 } 0519 } 0520 0521 void SlideShowLoader::endOfSlide() 0522 { 0523 setCurrentView(EndView); 0524 d->fileIndex = -1; 0525 d->osd->toolBar()->setEnabledPlay(false); 0526 d->osd->toolBar()->setEnabledNext(false); 0527 d->osd->toolBar()->setEnabledPrev(false); 0528 } 0529 0530 void SlideShowLoader::preloadNextItem() 0531 { 0532 int index = d->fileIndex + 1; 0533 int num = d->settings->count(); 0534 0535 if (index >= num) 0536 { 0537 if (d->settings->loop) 0538 { 0539 index = 0; 0540 } 0541 } 0542 0543 if (index < num) 0544 { 0545 QUrl nextItem = d->settings->fileList.value(index); 0546 0547 #ifdef HAVE_MEDIAPLAYER 0548 0549 QMimeDatabase mimeDB; 0550 0551 if (mimeDB.mimeTypeForFile(nextItem.toLocalFile()) 0552 .name().startsWith(QLatin1String("video/"))) 0553 { 0554 return; 0555 } 0556 0557 #endif 0558 0559 d->imageView->setPreloadUrl(nextItem); 0560 } 0561 } 0562 0563 void SlideShowLoader::wheelEvent(QWheelEvent* e) 0564 { 0565 if (e->angleDelta().y() < 0) 0566 { 0567 d->osd->pause(true); 0568 slotLoadNextItem(); 0569 } 0570 0571 if (e->angleDelta().y() > 0) 0572 { 0573 if (d->fileIndex == -1) 0574 { 0575 // EndView => backward. 0576 0577 d->fileIndex = d->settings->count(); 0578 } 0579 0580 d->osd->pause(true); 0581 slotLoadPrevItem(); 0582 } 0583 } 0584 0585 void SlideShowLoader::mousePressEvent(QMouseEvent* e) 0586 { 0587 if (e->button() == Qt::LeftButton) 0588 { 0589 if (d->fileIndex == -1) 0590 { 0591 // EndView => close Slideshow view. 0592 0593 close(); 0594 0595 return; 0596 } 0597 0598 d->osd->pause(true); 0599 slotLoadNextItem(); 0600 } 0601 else if (e->button() == Qt::RightButton) 0602 { 0603 if (d->fileIndex == -1) 0604 { 0605 // EndView => backward. 0606 0607 d->fileIndex = d->settings->count(); 0608 } 0609 0610 d->osd->pause(true); 0611 slotLoadPrevItem(); 0612 } 0613 } 0614 0615 void SlideShowLoader::keyPressEvent(QKeyEvent* e) 0616 { 0617 if (!e) 0618 { 0619 return; 0620 } 0621 0622 if (e->key() == Qt::Key_F4) 0623 { 0624 d->osd->setVisible(!d->osd->isVisible()); 0625 0626 return; 0627 } 0628 0629 d->osd->toolBar()->keyPressEvent(e); 0630 } 0631 0632 bool SlideShowLoader::eventFilter(QObject* obj, QEvent* ev) 0633 { 0634 if (ev->type() == QEvent::MouseMove) 0635 { 0636 setCursor(QCursor(Qt::ArrowCursor)); 0637 0638 #ifdef HAVE_MEDIAPLAYER 0639 0640 d->videoView->showIndicator(true); 0641 0642 #endif 0643 0644 d->mouseMoveTimer->start(); 0645 0646 return false; 0647 } 0648 0649 // pass the event on to the parent class 0650 0651 return QWidget::eventFilter(obj, ev); 0652 } 0653 0654 void SlideShowLoader::slotMouseMoveTimeOut() 0655 { 0656 if (!d->osd->isUnderMouse()) 0657 { 0658 setCursor(QCursor(Qt::BlankCursor)); 0659 } 0660 0661 #ifdef HAVE_MEDIAPLAYER 0662 0663 d->videoView->showIndicator(false); 0664 0665 #endif 0666 0667 } 0668 0669 /** 0670 * Inspired from Okular's presentation widget 0671 * TODO: Add OSX support 0672 */ 0673 void SlideShowLoader::inhibitScreenSaver() 0674 { 0675 0676 #ifdef Q_OS_WIN 0677 0678 SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_CONTINUOUS); 0679 0680 #elif defined HAVE_DBUS 0681 0682 QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.ScreenSaver"), 0683 QLatin1String("/ScreenSaver"), 0684 QLatin1String("org.freedesktop.ScreenSaver"), 0685 QLatin1String("Inhibit")); 0686 message << QLatin1String("digiKam"); 0687 message << i18nc("Reason for inhibiting the screensaver activation, when the presentation mode is active", 0688 "Giving a slideshow"); 0689 0690 QDBusReply<uint> reply = QDBusConnection::sessionBus().call(message); 0691 0692 if (reply.isValid()) 0693 { 0694 d->screenSaverCookie = reply.value(); 0695 } 0696 0697 #endif 0698 0699 } 0700 0701 void SlideShowLoader::allowScreenSaver() 0702 { 0703 0704 #ifdef Q_OS_WIN 0705 0706 SetThreadExecutionState(ES_CONTINUOUS); 0707 0708 #elif defined HAVE_DBUS 0709 0710 if (d->screenSaverCookie != -1) 0711 { 0712 QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.ScreenSaver"), 0713 QLatin1String("/ScreenSaver"), 0714 QLatin1String("org.freedesktop.ScreenSaver"), 0715 QLatin1String("UnInhibit")); 0716 message << (uint)d->screenSaverCookie; 0717 QDBusConnection::sessionBus().send(message); 0718 } 0719 0720 #endif 0721 0722 } 0723 0724 void SlideShowLoader::slotAssignRating(int rating) 0725 { 0726 DItemInfo item; 0727 item.setRating(rating); 0728 d->settings->iface->setItemInfo(currentItem(), item.infoMap()); 0729 0730 dispatchCurrentInfoChange(currentItem()); 0731 } 0732 0733 void SlideShowLoader::slotAssignColorLabel(int color) 0734 { 0735 DItemInfo item; 0736 item.setColorLabel(color); 0737 d->settings->iface->setItemInfo(currentItem(), item.infoMap()); 0738 0739 dispatchCurrentInfoChange(currentItem()); 0740 } 0741 0742 void SlideShowLoader::slotAssignPickLabel(int pick) 0743 { 0744 DItemInfo item; 0745 item.setPickLabel(pick); 0746 d->settings->iface->setItemInfo(currentItem(), item.infoMap()); 0747 0748 dispatchCurrentInfoChange(currentItem()); 0749 } 0750 0751 void SlideShowLoader::slotToggleTag(int tag) 0752 { 0753 DInfoInterface::DInfoMap info; 0754 info.insert(QLatin1String("tag"), tag); 0755 0756 d->settings->iface->setItemInfo(currentItem(), info); 0757 0758 dispatchCurrentInfoChange(currentItem()); 0759 } 0760 0761 void SlideShowLoader::slotHandleShortcut(const QString& shortcut, int val) 0762 { 0763 /* 0764 qCDebug(DIGIKAM_GENERAL_LOG) << "SlideShowLoader::slotHandleShortcut"; 0765 */ 0766 if (d->shortcutPrefixes.contains(QLatin1String("rating")) && 0767 shortcut.startsWith(d->shortcutPrefixes[QLatin1String("rating")])) 0768 { 0769 slotAssignRating(val); 0770 0771 return; 0772 } 0773 0774 if (d->shortcutPrefixes.contains(QLatin1String("colorlabel")) && 0775 shortcut.startsWith(d->shortcutPrefixes[QLatin1String("colorlabel")])) 0776 { 0777 slotAssignColorLabel(val); 0778 0779 return; 0780 } 0781 0782 if (d->shortcutPrefixes.contains(QLatin1String("picklabel")) && 0783 shortcut.startsWith(d->shortcutPrefixes[QLatin1String("picklabel")])) 0784 { 0785 slotAssignPickLabel(val); 0786 0787 return; 0788 } 0789 0790 if (d->shortcutPrefixes.contains(QLatin1String("tag")) && 0791 shortcut.startsWith(d->shortcutPrefixes[QLatin1String("tag")])) 0792 { 0793 slotToggleTag(val); 0794 0795 return; 0796 } 0797 0798 qCWarning(DIGIKAM_GENERAL_LOG) << "Shortcut is not yet supported in SlideShowLoader::slotHandleShortcut():" 0799 << shortcut; 0800 } 0801 0802 void SlideShowLoader::dispatchCurrentInfoChange(const QUrl& url) 0803 { 0804 if (currentItem() == url) 0805 { 0806 d->osd->setCurrentUrl(currentItem()); 0807 } 0808 } 0809 0810 void SlideShowLoader::slotPause() 0811 { 0812 0813 #ifdef HAVE_MEDIAPLAYER 0814 0815 if (currentIndex() == VideoView) 0816 { 0817 d->videoView->pause(true); 0818 } 0819 else 0820 0821 #endif 0822 0823 { 0824 d->osd->pause(true); 0825 } 0826 } 0827 0828 void SlideShowLoader::slotPlay() 0829 { 0830 #ifdef HAVE_MEDIAPLAYER 0831 0832 if (currentIndex() == VideoView) 0833 { 0834 d->videoView->pause(false); 0835 } 0836 else 0837 0838 #endif 0839 0840 { 0841 d->osd->pause(false); 0842 } 0843 } 0844 0845 void SlideShowLoader::slotScreenSelected(int screen) 0846 { 0847 if (screen >= qApp->screens().count()) 0848 { 0849 return; 0850 } 0851 0852 QRect deskRect = qApp->screens().at(screen)->geometry(); 0853 0854 setWindowState(windowState() & ~Qt::WindowFullScreen); 0855 0856 move(deskRect.x(), deskRect.y()); 0857 resize(deskRect.width(), deskRect.height()); 0858 0859 setWindowState(windowState() | Qt::WindowFullScreen); 0860 0861 // update OSD position 0862 0863 if (d->fileIndex != -1) 0864 { 0865 qApp->processEvents(); 0866 d->osd->setCurrentUrl(currentItem()); 0867 } 0868 0869 qCDebug(DIGIKAM_GENERAL_LOG) << "Slideshow: move to screen: " << screen 0870 << " :: " << deskRect; 0871 } 0872 0873 } // namespace DigikamGenericSlideShowPlugin 0874 0875 #include "moc_slideshowloader.cpp"