1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2017-05-25
7  * Description : a tool to generate video slideshow from images.
8  *
9  * Copyright (C) 2017-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
10  *
11  * This program is free software; you can redistribute it
12  * and/or modify it under the terms of the GNU General
13  * Public License as published by the Free Software Foundation;
14  * either version 2, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * ============================================================ */
22 
23 #include "vidslidefinalpage.h"
24 
25 // Qt includes
26 
27 #include <QIcon>
28 #include <QSpacerItem>
29 #include <QVBoxLayout>
30 #include <QDesktopServices>
31 #include <QUrl>
32 #include <QApplication>
33 #include <QStyle>
34 #include <QTimer>
35 #include <QDir>
36 
37 // KDE includes
38 
39 #include <klocalizedstring.h>
40 
41 // Local includes
42 
43 #include "vidslidewizard.h"
44 #include "dlayoutbox.h"
45 #include "digikam_debug.h"
46 #include "dprogresswdg.h"
47 #include "dhistoryview.h"
48 #include "vidslidethread.h"
49 #include "vidplayerdlg.h"
50 
51 namespace DigikamGenericVideoSlideShowPlugin
52 {
53 
54 class Q_DECL_HIDDEN VidSlideFinalPage::Private
55 {
56 public:
57 
Private(QWizard * const dialog)58     explicit Private(QWizard* const dialog)
59       : progressView(nullptr),
60         progressBar(nullptr),
61         complete(false),
62         encoder(nullptr),
63         wizard(nullptr),
64         settings(nullptr),
65         iface(nullptr)
66     {
67         wizard = dynamic_cast<VidSlideWizard*>(dialog);
68 
69         if (wizard)
70         {
71             iface    = wizard->iface();
72             settings = wizard->settings();
73         }
74     }
75 
76     DHistoryView*     progressView;
77     DProgressWdg*     progressBar;
78     bool              complete;
79     VidSlideThread*   encoder;
80     VidSlideWizard*   wizard;
81     VidSlideSettings* settings;
82     DInfoInterface*   iface;
83 };
84 
VidSlideFinalPage(QWizard * const dialog,const QString & title)85 VidSlideFinalPage::VidSlideFinalPage(QWizard* const dialog, const QString& title)
86     : DWizardPage(dialog, title),
87       d(new Private(dialog))
88 {
89     setObjectName(QLatin1String("FinalPage"));
90 
91     DVBox* const vbox = new DVBox(this);
92     d->progressView   = new DHistoryView(vbox);
93     d->progressBar    = new DProgressWdg(vbox);
94 
95     vbox->setStretchFactor(d->progressBar, 10);
96     vbox->setContentsMargins(QMargins());
97     vbox->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing));
98 
99     setPageWidget(vbox);
100     setLeftBottomPix(QIcon::fromTheme(QLatin1String("system-run")));
101 }
102 
~VidSlideFinalPage()103 VidSlideFinalPage::~VidSlideFinalPage()
104 {
105     if (d->encoder)
106         d->encoder->cancel();
107 
108     delete d;
109 }
110 
initializePage()111 void VidSlideFinalPage::initializePage()
112 {
113     d->complete = false;
114     emit completeChanged();
115     QTimer::singleShot(0, this, SLOT(slotProcess()));
116 }
117 
slotProcess()118 void VidSlideFinalPage::slotProcess()
119 {
120     if (!d->wizard)
121     {
122         d->progressView->addEntry(i18n("Internal Error"),
123                                   DHistoryView::ErrorEntry);
124         return;
125     }
126 
127     d->progressView->clear();
128     d->progressBar->reset();
129 
130     d->progressView->addEntry(i18n("Starting to generate video slideshow..."),
131                               DHistoryView::ProgressEntry);
132 
133     d->progressView->addEntry(i18n("%1 input images to process", d->settings->inputImages.count()),
134                                   DHistoryView::ProgressEntry);
135 
136     foreach (const QUrl& url, d->settings->inputImages)
137     {
138         d->progressView->addEntry(QDir::toNativeSeparators(url.toLocalFile()),
139                                   DHistoryView::ProgressEntry);
140     }
141 
142     if (!d->settings->inputAudio.isEmpty())
143     {
144         d->progressView->addEntry(i18n("%1 input audio stream to process:",
145                                        d->settings->inputAudio.count()),
146                                   DHistoryView::ProgressEntry);
147 
148         foreach (const QUrl& url, d->settings->inputAudio)
149         {
150             d->progressView->addEntry(QDir::toNativeSeparators(url.toLocalFile()),
151                                       DHistoryView::ProgressEntry);
152         }
153     }
154 
155     d->progressBar->setMinimum(0);
156     d->progressBar->setMaximum(d->settings->inputImages.count());
157 
158     d->encoder = new VidSlideThread(this);
159 
160     connect(d->encoder, SIGNAL(signalProgress(int)),
161             d->progressBar, SLOT(setValue(int)));
162 
163     connect(d->encoder, SIGNAL(signalMessage(QString,bool)),
164             this, SLOT(slotMessage(QString,bool)));
165 
166     connect(d->encoder, SIGNAL(signalDone(bool)),
167             this, SLOT(slotDone(bool)));
168 
169     d->encoder->processStream(d->settings);
170     d->encoder->start();
171 }
172 
cleanupPage()173 void VidSlideFinalPage::cleanupPage()
174 {
175     if (d->encoder)
176         d->encoder->cancel();
177 }
178 
slotMessage(const QString & mess,bool err)179 void VidSlideFinalPage::slotMessage(const QString& mess, bool err)
180 {
181     d->progressView->addEntry(mess, err ? DHistoryView::ErrorEntry
182                                         : DHistoryView::ProgressEntry);
183 }
184 
slotDone(bool completed)185 void VidSlideFinalPage::slotDone(bool completed)
186 {
187     d->progressBar->progressCompleted();
188     d->complete = completed;
189 
190     if (!d->complete)
191     {
192         d->progressView->addEntry(i18n("Video Slideshow is not completed"),
193                                   DHistoryView::WarningEntry);
194     }
195     else
196     {
197         d->progressView->addEntry(i18n("Video Slideshow completed."),
198                                   DHistoryView::ProgressEntry);
199 
200         if (d->settings->outputPlayer != VidSlideSettings::NOPLAYER)
201         {
202             d->progressView->addEntry(i18n("Opening video stream in player..."),
203                                       DHistoryView::ProgressEntry);
204 
205             if (d->settings->outputPlayer == VidSlideSettings::INTERNAL)
206             {
207                 VidPlayerDlg* const player = new VidPlayerDlg(d->settings->outputVideo, this);
208                 player->show();
209                 player->resize(800, 600);
210             }
211             else
212             {
213                 QDesktopServices::openUrl(QUrl::fromLocalFile(d->settings->outputVideo));
214             }
215         }
216     }
217 
218     emit completeChanged();
219 }
220 
isComplete() const221 bool VidSlideFinalPage::isComplete() const
222 {
223     return d->complete;
224 }
225 
226 } // namespace DigikamGenericVideoSlideShowPlugin
227