File indexing completed on 2025-03-09 03:52:10
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2018-07-30 0007 * Description : a plugin to render slideshow. 0008 * 0009 * SPDX-FileCopyrightText: 2018-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2019-2020 by Minh Nghia Duong <minhnghiaduong997 at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "slideshowplugin.h" 0017 0018 // Qt includes 0019 0020 #include <QPointer> 0021 #include <QMenu> 0022 #include <QDebug> 0023 #include <QString> 0024 #include <QApplication> 0025 0026 // KDE includes 0027 0028 #include <klocalizedstring.h> 0029 #include <kactioncollection.h> 0030 #include <kxmlguiwindow.h> 0031 0032 // Local includes 0033 0034 #include "metaenginesettings.h" 0035 #include "setupslideshow_dialog.h" 0036 #include "slideshowloader.h" 0037 0038 using namespace Digikam; 0039 0040 namespace DigikamGenericSlideShowPlugin 0041 { 0042 0043 SlideShowPlugin::SlideShowPlugin(QObject* const parent) 0044 : DPluginGeneric(parent) 0045 { 0046 } 0047 0048 SlideShowPlugin::~SlideShowPlugin() 0049 { 0050 } 0051 0052 QString SlideShowPlugin::name() const 0053 { 0054 return i18n("SlideShow"); 0055 } 0056 0057 QString SlideShowPlugin::iid() const 0058 { 0059 return QLatin1String(DPLUGIN_IID); 0060 } 0061 0062 QIcon SlideShowPlugin::icon() const 0063 { 0064 return QIcon::fromTheme(QLatin1String("view-presentation")); 0065 } 0066 0067 QString SlideShowPlugin::description() const 0068 { 0069 return i18n("A tool to render slideshow"); 0070 } 0071 0072 QString SlideShowPlugin::details() const 0073 { 0074 return i18n("<p>This tool render a series of items as a simple slide-show.</p>" 0075 "<p>Plenty of items properties can be displayed as overlay while running.</p>" 0076 "<p>This tool can play album contents in recursive mode with children albums if any.</p>" 0077 "<p><u>Usage:</u></p>" 0078 0079 "<table>" 0080 0081 "<tr>" 0082 "<td colspan=\"2\"><nobr><center>" 0083 "<b><h1>Item Access</h1></b>" 0084 "</center></nobr></td>" 0085 "</tr>" 0086 0087 "<tr><td>Previous Item:</td>" "<td><i>Up</i> key</td></tr>" 0088 "<tr><td></td>" "<td><i>PgUp</i> key</td></tr>" 0089 "<tr><td></td>" "<td><i>Left</i> key</td></tr>" 0090 "<tr><td></td>" "<td>Mouse wheel up</td></tr>" 0091 "<tr><td></td>" "<td>Left mouse button</td></tr>" 0092 "<tr><td>Next Item:</td>" "<td><i>Down</i> key</td></tr>" 0093 "<tr><td></td>" "<td><i>PgDown</i> key</td></tr>" 0094 "<tr><td></td>" "<td><i>Right</i> key</td></tr>" 0095 "<tr><td></td>" "<td>Mouse wheel down</td></tr>" 0096 "<tr><td></td>" "<td>Right mouse button</td></tr>" 0097 "<tr><td>Pause/Start:</td>" "<td><i>Space</i> key</td></tr>" 0098 "<tr><td>Slideshow Settings:</td>" "<td><i>F2</i> key</td></tr>" 0099 "<tr><td>Hide/Show Overlays:</td>" "<td><i>F4</i> key</td></tr>" 0100 "<tr><td>Quit:</td>" "<td><i>Esc</i> key</td></tr>" 0101 0102 "<tr>" 0103 "<td colspan=\"2\"><nobr><center>" 0104 "<b><h1>Item Properties</h1></b>" 0105 "</center></nobr></td>" 0106 "</tr>" 0107 0108 "<tr><td>Change Tags:</td>" "<td>Use Tags keyboard shortcuts</td></tr>" 0109 "<tr><td>Change Rating:</td>" "<td>Use Rating keyboard shortcuts</td></tr>" 0110 "<tr><td>Change Color Label:</td>" "<td>Use Color label keyboard shortcuts</td></tr>" 0111 "<tr><td>Change Pick Label:</td>" "<td>Use Pick label keyboard shortcuts</td></tr>" 0112 0113 "<tr>" 0114 "<td colspan=\"2\"><nobr><center>" 0115 "<b><h1>Others</h1></b>" 0116 "</center></nobr></td>" 0117 "</tr>" 0118 0119 "<tr><td>Show this help:</td>" "<td><i>F1</i> key</td></tr>" 0120 0121 "</table>"); 0122 } 0123 0124 QString SlideShowPlugin::handbookSection() const 0125 { 0126 return QLatin1String("slideshow_tools"); 0127 } 0128 0129 QString SlideShowPlugin::handbookChapter() const 0130 { 0131 return QLatin1String("slide_tool"); 0132 } 0133 0134 QList<DPluginAuthor> SlideShowPlugin::authors() const 0135 { 0136 return QList<DPluginAuthor>() 0137 << DPluginAuthor(QString::fromUtf8("Enrico Ros"), 0138 QString::fromUtf8("eros dot kde at email dot it"), 0139 QString::fromUtf8("(C) 2004")) 0140 << DPluginAuthor(QString::fromUtf8("Renchi Raju"), 0141 QString::fromUtf8("renchi dot raju at gmail dot com"), 0142 QString::fromUtf8("(C) 2004-2005")) 0143 << DPluginAuthor(QString::fromUtf8("Gilles Caulier"), 0144 QString::fromUtf8("caulier dot gilles at gmail dot com"), 0145 QString::fromUtf8("(C) 2005-2023")) 0146 << DPluginAuthor(QString::fromUtf8("Minh Nghia Duong"), 0147 QString::fromUtf8("minhnghiaduong997 at gmail dot com"), 0148 QString::fromUtf8("(C) 2019-2021")) 0149 << DPluginAuthor(QString::fromUtf8("Phuoc Khanh Le"), 0150 QString::fromUtf8("phuockhanhnk94 at gmail dot com"), 0151 QString::fromUtf8("(C) 2021")) 0152 << DPluginAuthor(QString::fromUtf8("Fady Khalaf"), 0153 QString::fromUtf8("fadykhalaf01 at gmail dot com"), 0154 QString::fromUtf8("(C) 2019")) 0155 ; 0156 } 0157 void SlideShowPlugin::setup(QObject* const parent) 0158 { 0159 DPluginAction* const ac = new DPluginAction(parent); 0160 ac->setIcon(icon()); 0161 ac->setText(i18nc("@action", "Slideshow")); 0162 ac->setObjectName(QLatin1String("slideshow_plugin")); 0163 ac->setActionCategory(DPluginAction::GenericView); 0164 0165 DInfoInterface* const iface = infoIface(ac); 0166 0167 if (iface && (parent->objectName() == QLatin1String("Digikam"))) 0168 { 0169 0170 QMenu* const slideShowActions = new QMenu(i18n("Slideshow")); 0171 slideShowActions->setIcon(icon()); 0172 ac->setMenu(slideShowActions); 0173 0174 // Action show all 0175 0176 QAction* const slideShowAllAction = new QAction(i18n("Play All"), ac); 0177 slideShowAllAction->setObjectName(QLatin1String("slideshow_all")); 0178 slideShowActions->addAction(slideShowAllAction); 0179 0180 connect(slideShowAllAction, SIGNAL(triggered()), 0181 this, SLOT(slotMenuSlideShowAll())); 0182 0183 // Action show selection 0184 0185 QAction* const slideShowSelectionAction = new QAction(i18n("Play Selection"), ac); 0186 slideShowSelectionAction->setObjectName(QLatin1String("slideshow_selected")); 0187 slideShowActions->addAction(slideShowSelectionAction); 0188 0189 connect(slideShowSelectionAction, SIGNAL(triggered()), 0190 this, SLOT(slotMenuSlideShowSelection())); 0191 0192 // Action show recursive 0193 0194 QAction* const slideShowRecursiveAction = new QAction(i18n("Play With Sub-Albums"), ac); 0195 slideShowRecursiveAction->setObjectName(QLatin1String("slideshow_recursive")); 0196 slideShowActions->addAction(slideShowRecursiveAction); 0197 0198 connect(slideShowRecursiveAction, SIGNAL(triggered()), 0199 this, SLOT(slotMenuSlideShowRecursive())); 0200 0201 connect(ac, SIGNAL(triggered(bool)), 0202 this, SLOT(slotShowManual())); 0203 0204 // See bug #425425: register all sub-actions to collection instance to be able to edit keyboard shortcuts 0205 0206 KXmlGuiWindow* const gui = dynamic_cast<KXmlGuiWindow*>(parent); 0207 0208 if (gui) 0209 { 0210 KActionCollection* const collection = gui->actionCollection(); 0211 collection->setShortcutsConfigurable(slideShowActions->menuAction(), false); 0212 0213 collection->addAction(slideShowAllAction->objectName(), slideShowAllAction); 0214 collection->addAction(slideShowSelectionAction->objectName(), slideShowSelectionAction); 0215 collection->addAction(slideShowRecursiveAction->objectName(), slideShowRecursiveAction); 0216 0217 collection->setDefaultShortcut(slideShowAllAction, Qt::Key_F9); 0218 collection->setDefaultShortcut(slideShowSelectionAction, Qt::ALT | Qt::Key_F9); 0219 collection->setDefaultShortcut(slideShowRecursiveAction, Qt::SHIFT | Qt::Key_F9); 0220 } 0221 } 0222 else 0223 { 0224 ac->setShortcut(Qt::Key_F9); 0225 0226 connect(ac, SIGNAL(triggered(bool)), 0227 this, SLOT(slotMenuSlideShow())); 0228 } 0229 0230 addAction(ac); 0231 } 0232 0233 void SlideShowPlugin::addConnectionSlideEnd(QObject* const obj) 0234 { 0235 Q_UNUSED(obj); 0236 } 0237 0238 void SlideShowPlugin::slotMenuSlideShow() 0239 { 0240 QUrl startFrom; 0241 DPluginAction* const ac = dynamic_cast<DPluginAction*>(sender()); 0242 0243 if (ac) 0244 { 0245 startFrom = ac->data().toUrl(); 0246 ac->setData(QVariant()); 0247 } 0248 0249 SlideShowSettings* const settings = new SlideShowSettings(); 0250 settings->iface = infoIface(ac); 0251 settings->readFromConfig(); 0252 settings->exifRotate = MetaEngineSettings::instance()->settings().exifRotate; 0253 settings->fileList = settings->iface->currentAlbumItems(); 0254 0255 slideshow(settings, true, startFrom); 0256 } 0257 0258 void SlideShowPlugin::slotMenuSlideShowAll() 0259 { 0260 SlideShowSettings* const settings = new SlideShowSettings(); 0261 settings->iface = infoIface(sender()->parent()); 0262 settings->readFromConfig(); 0263 settings->fileList = settings->iface->currentAlbumItems(); 0264 0265 slideshow(settings); 0266 } 0267 0268 void SlideShowPlugin::slotMenuSlideShowSelection() 0269 { 0270 SlideShowSettings* const settings = new SlideShowSettings(); 0271 settings->iface = infoIface(sender()->parent()); 0272 settings->readFromConfig(); 0273 settings->fileList = settings->iface->currentSelectedItems(); 0274 0275 slideshow(settings); 0276 } 0277 0278 void SlideShowPlugin::slotMenuSlideShowRecursive() 0279 { 0280 DInfoInterface* const iface = infoIface(sender()->parent()); 0281 0282 connect(iface, SIGNAL(signalAlbumItemsRecursiveCompleted(QList<QUrl>)), 0283 this, SLOT(slotShowRecursive(QList<QUrl>))); 0284 0285 iface->parseAlbumItemsRecursive(); 0286 } 0287 0288 void SlideShowPlugin::slotShowRecursive(const QList<QUrl>& imageList) 0289 { 0290 SlideShowSettings* const settings = new SlideShowSettings(); 0291 settings->iface = dynamic_cast<DInfoInterface*>(sender()); 0292 settings->readFromConfig(); 0293 settings->fileList = imageList; 0294 0295 slideshow(settings); 0296 } 0297 0298 void SlideShowPlugin::slotShowManual() 0299 { 0300 DPluginAction* const ac = dynamic_cast<DPluginAction*>(sender()); 0301 0302 if (!ac) 0303 { 0304 return; 0305 } 0306 0307 QUrl startFrom(ac->data().toUrl()); 0308 ac->setData(QVariant()); 0309 0310 SlideShowSettings* const settings = new SlideShowSettings(); 0311 settings->iface = infoIface(ac); 0312 settings->readFromConfig(); 0313 settings->exifRotate = MetaEngineSettings::instance()->settings().exifRotate; 0314 settings->fileList = settings->iface->currentAlbumItems(); 0315 0316 slideshow(settings, !startFrom.isValid(), startFrom); 0317 } 0318 0319 void SlideShowPlugin::slideshow(SlideShowSettings* const settings, bool autoPlayEnabled, const QUrl& startFrom) 0320 { 0321 settings->autoPlayEnabled = autoPlayEnabled; 0322 settings->plugin = this; 0323 0324 // TODO: preview settings for digikam 0325 //settings.previewSettings = ApplicationSettings::instance()->getPreviewSettings(); 0326 0327 if (startFrom.isValid()) 0328 { 0329 settings->imageUrl = startFrom; 0330 } 0331 0332 SlideShowLoader* const slide = new SlideShowLoader(settings); 0333 slide->setShortCutPrefixes(settings->iface->passShortcutActionsToWidget(slide)); 0334 0335 if (settings->imageUrl.isValid()) 0336 { 0337 slide->setCurrentItem(settings->imageUrl); 0338 } 0339 else if (settings->startWithCurrent) 0340 { 0341 if (!settings->iface->currentSelectedItems().isEmpty()) 0342 { 0343 slide->setCurrentItem(settings->iface->currentSelectedItems()[0]); 0344 } 0345 else 0346 { 0347 // no current selection, do nothing. 0348 0349 return; 0350 } 0351 } 0352 0353 connect(slide, SIGNAL(signalLastItemUrl(QUrl)), 0354 settings->iface, SIGNAL(signalLastItemUrl(QUrl))); 0355 0356 connect(settings->iface, SIGNAL(signalShortcutPressed(QString,int)), 0357 slide, SLOT(slotHandleShortcut(QString,int))); 0358 0359 slide->show(); 0360 } 0361 0362 } // namespace DigikamGenericSlideShowPlugin 0363 0364 #include "moc_slideshowplugin.cpp"