1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2008-09-09
7  * Description : a presentation tool.
8  *
9  * Copyright (C) 2008-2009 by Valerio Fuoglio <valerio dot fuoglio at gmail dot com>
10  * Copyright (C) 2009      by Andi Clemens <andi dot clemens at googlemail dot com>
11  * Copyright (C) 2012-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
12  *
13  * This program is free software; you can redistribute it
14  * and/or modify it under the terms of the GNU General
15  * Public License as published by the Free Software Foundation;
16  * either version 2, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * ============================================================ */
24 
25 #include "presentationdlg.h"
26 
27 // Qt includes
28 
29 #include <QFileInfo>
30 #include <QFont>
31 #include <QCloseEvent>
32 #include <QIcon>
33 #include <QMenu>
34 #include <QTabWidget>
35 #include <QDialogButtonBox>
36 
37 // KDE includes
38 
39 #include <ksharedconfig.h>
40 #include <kconfiggroup.h>
41 
42 // Local includes
43 
44 #include "digikam_config.h"
45 #include "digikam_debug.h"
46 #include "presentationcontainer.h"
47 #include "presentation_mainpage.h"
48 #include "presentation_captionpage.h"
49 #include "presentation_advpage.h"
50 #include "thumbnailloadthread.h"
51 
52 #ifdef HAVE_MEDIAPLAYER
53 #   include "presentation_audiopage.h"
54 #endif
55 
56 namespace DigikamGenericPresentationPlugin
57 {
58 
59 class Q_DECL_HIDDEN PresentationDlg::Private
60 {
61 
62 public:
63 
Private()64     explicit Private()
65       : buttonBox   (nullptr),
66         startButton (nullptr),
67         tab         (nullptr),
68         sharedData  (nullptr)
69     {
70     }
71 
72     QDialogButtonBox*      buttonBox;
73     QPushButton*           startButton;
74     QTabWidget*            tab;
75     PresentationContainer* sharedData;
76 };
77 
PresentationDlg(QWidget * const parent,PresentationContainer * const sharedData)78 PresentationDlg::PresentationDlg(QWidget* const parent,
79                                  PresentationContainer* const sharedData)
80     : DPluginDialog(parent, QLatin1String("Presentation Settings")),
81       d            (new Private)
82 {
83     setWindowTitle(i18nc("@title", "Presentation"));
84     setModal(false);
85 
86     d->sharedData = sharedData;
87 
88     m_buttons->addButton(QDialogButtonBox::Close);
89     m_buttons->addButton(QDialogButtonBox::Ok);
90     m_buttons->button(QDialogButtonBox::Ok)->setText(i18nc("@action: play presentation", "Start"));
91     m_buttons->button(QDialogButtonBox::Ok)->setToolTip(i18nc("@info:tooltip", "Start Presentation"));
92     m_buttons->button(QDialogButtonBox::Ok)->setIcon(QIcon::fromTheme(QLatin1String("media-playback-start")));
93     m_buttons->button(QDialogButtonBox::Ok)->setDefault(true);
94 
95     // --- Pages settings ---
96 
97     d->tab = new QTabWidget(this);
98 
99     d->sharedData->mainPage = new PresentationMainPage(this, d->sharedData);
100     d->tab->addTab(d->sharedData->mainPage,
101                    QIcon::fromTheme(QLatin1String("view-presentation")),
102                    i18nc("@title: main settings for the presentation", "Main Settings"));
103 
104     d->sharedData->captionPage = new PresentationCaptionPage(this, d->sharedData);
105     d->tab->addTab(d->sharedData->captionPage,
106                    QIcon::fromTheme(QLatin1String("draw-freehand")),
107                    i18nc("@title: caption settings for the presentation", "Caption"));
108 
109 #ifdef HAVE_MEDIAPLAYER
110 
111     d->sharedData->soundtrackPage = new PresentationAudioPage(this, d->sharedData);
112     d->tab->addTab(d->sharedData->soundtrackPage,
113                    QIcon::fromTheme(QLatin1String("speaker")),
114                    i18nc("@title: soundtrack settings for the presentation", "Soundtrack"));
115 
116 #endif
117 
118     d->sharedData->advancedPage = new PresentationAdvPage(this, d->sharedData);
119     d->tab->addTab(d->sharedData->advancedPage,
120                    QIcon::fromTheme(QLatin1String("configure")),
121                    i18nc("@title: avanced presentation settings", "Advanced"));
122 
123     QVBoxLayout* const mainLayout = new QVBoxLayout(this);
124     mainLayout->addWidget(d->tab);
125     mainLayout->addWidget(m_buttons);
126     setLayout(mainLayout);
127 
128     // Slot connections
129 
130     connect(m_buttons->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
131             this, SLOT(slotStartClicked()));
132 
133     connect(m_buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()),
134             this, SLOT(reject()));
135 
136     readSettings();
137 }
138 
~PresentationDlg()139 PresentationDlg::~PresentationDlg ()
140 {
141     delete d;
142 }
143 
readSettings()144 void PresentationDlg::readSettings()
145 {
146     KSharedConfigPtr config = KSharedConfig::openConfig();
147     KConfigGroup grp        = config->group(QLatin1String("Presentation Settings"));
148 
149     d->sharedData->opengl            = grp.readEntry("OpenGL",                   false);
150     d->sharedData->openGlFullScale   = grp.readEntry("OpenGLFullScale",          false);
151     d->sharedData->delay             = grp.readEntry("Delay",                    1500);
152     d->sharedData->printFileName     = grp.readEntry("Print Filename",           true);
153     d->sharedData->printProgress     = grp.readEntry("Print Progress Indicator", true);
154     d->sharedData->printFileComments = grp.readEntry("Print Comments",           false);
155     d->sharedData->loop              = grp.readEntry("Loop",                     false);
156     d->sharedData->shuffle           = grp.readEntry("Shuffle",                  false);
157     d->sharedData->effectName        = grp.readEntry("Effect Name",              "Random");
158     d->sharedData->effectNameGL      = grp.readEntry("Effect Name (OpenGL)",     "Random");
159 
160     d->sharedData->delayMsMaxValue   = 120000;
161     d->sharedData->delayMsMinValue   = 100;
162     d->sharedData->delayMsLineStep   = 100;
163 
164     // Comments tab settings
165 
166     QFont* const savedFont = new QFont();
167     savedFont->setFamily(    grp.readEntry("Comments Font Family"));
168     savedFont->setPointSize( grp.readEntry("Comments Font Size",        10));
169     savedFont->setBold(      grp.readEntry("Comments Font Bold",        false));
170     savedFont->setItalic(    grp.readEntry("Comments Font Italic",      false));
171     savedFont->setUnderline( grp.readEntry("Comments Font Underline",   false));
172     savedFont->setOverline(  grp.readEntry("Comments Font Overline",    false));
173     savedFont->setStrikeOut( grp.readEntry("Comments Font StrikeOut",   false));
174     savedFont->setFixedPitch(grp.readEntry("Comments Font FixedPitch",  false));
175 
176     d->sharedData->captionFont = savedFont;
177 
178     d->sharedData->commentsFontColor   = grp.readEntry("Comments Font Color",   0xffffff);
179     d->sharedData->commentsBgColor     = grp.readEntry("Comments Bg Color",     0x000000);
180     d->sharedData->commentsDrawOutline = grp.readEntry("Comments Text Outline", true);
181     d->sharedData->bgOpacity           = grp.readEntry("Background Opacity",    10);
182     d->sharedData->commentsLinesLength = grp.readEntry("Comments Lines Length", 72);
183 
184 #ifdef HAVE_MEDIAPLAYER
185 
186     // Soundtrack tab
187 
188     d->sharedData->soundtrackLoop             = grp.readEntry("Soundtrack Loop",                     false);
189     d->sharedData->soundtrackPlay             = grp.readEntry("Soundtrack Auto Play",                false);
190     d->sharedData->soundtrackPath             = QUrl::fromLocalFile(grp.readEntry("Soundtrack Path", ""));
191     d->sharedData->soundtrackRememberPlaylist = grp.readEntry("Soundtrack Remember Playlist",        false);
192 
193 #endif
194 
195     // Advanced tab
196 
197     d->sharedData->useMilliseconds     = grp.readEntry("Use Milliseconds",      false);
198     d->sharedData->enableMouseWheel    = grp.readEntry("Enable Mouse Wheel",    true);
199 
200     d->sharedData->kbDisableFadeInOut  = grp.readEntry("KB Disable FadeInOut",  false);
201     d->sharedData->kbDisableCrossFade  = grp.readEntry("KB Disable Crossfade",  false);
202 
203     d->sharedData->enableCache         = grp.readEntry("Enable Cache",          false);
204     d->sharedData->cacheSize           = grp.readEntry("Cache Size",            5);
205 
206     if (d->sharedData->soundtrackRememberPlaylist)
207     {
208         QString groupName(QLatin1String("Presentation Settings") + QLatin1String(" Soundtrack "));
209         KConfigGroup soundGrp = config->group(groupName);
210 
211         // load and check playlist files, if valid, add to tracklist widget
212 
213         QList<QUrl> playlistFiles = soundGrp.readEntry("Tracks", QList<QUrl>());
214 
215         foreach (const QUrl& playlistFile, playlistFiles)
216         {
217             QUrl file(playlistFile);
218             QFileInfo fi(file.toLocalFile());
219 
220             if (fi.isFile())
221             {
222                 d->sharedData->soundtrackUrls << file;
223             }
224         }
225     }
226 
227     d->sharedData->mainPage->readSettings();
228     d->sharedData->captionPage->readSettings();
229     d->sharedData->advancedPage->readSettings();
230 
231 #ifdef HAVE_MEDIAPLAYER
232 
233     d->sharedData->soundtrackPage->readSettings();
234 
235 #endif
236 
237 }
238 
saveSettings()239 void PresentationDlg::saveSettings()
240 {
241     d->sharedData->mainPage->saveSettings();
242     d->sharedData->captionPage->saveSettings();
243     d->sharedData->advancedPage->saveSettings();
244 
245 #ifdef HAVE_MEDIAPLAYER
246 
247     d->sharedData->soundtrackPage->saveSettings();
248 
249 #endif
250 
251     KSharedConfigPtr config = KSharedConfig::openConfig();
252     KConfigGroup grp        = config->group(QLatin1String("Presentation Settings"));
253     grp.writeEntry("OpenGL",                   d->sharedData->opengl);
254     grp.writeEntry("OpenGLFullScale",          d->sharedData->openGlFullScale);
255     grp.writeEntry("Delay",                    d->sharedData->delay);
256     grp.writeEntry("Print Filename",           d->sharedData->printFileName);
257     grp.writeEntry("Print Progress Indicator", d->sharedData->printProgress);
258     grp.writeEntry("Print Comments",           d->sharedData->printFileComments);
259     grp.writeEntry("Loop",                     d->sharedData->loop);
260     grp.writeEntry("Shuffle",                  d->sharedData->shuffle);
261     grp.writeEntry("Use Milliseconds",         d->sharedData->useMilliseconds);
262     grp.writeEntry("Enable Mouse Wheel",       d->sharedData->enableMouseWheel);
263 
264     // Comments tab settings
265 
266     QFont* const commentsFont = d->sharedData->captionFont;
267     grp.writeEntry("Comments Font Family",     commentsFont->family());
268     grp.writeEntry("Comments Font Size",       commentsFont->pointSize());
269     grp.writeEntry("Comments Font Bold",       commentsFont->bold());
270     grp.writeEntry("Comments Font Italic",     commentsFont->italic());
271     grp.writeEntry("Comments Font Underline",  commentsFont->underline());
272     grp.writeEntry("Comments Font Overline",   commentsFont->overline());
273     grp.writeEntry("Comments Font StrikeOut",  commentsFont->strikeOut());
274     grp.writeEntry("Comments Font FixedPitch", commentsFont->fixedPitch());
275     grp.writeEntry("Comments Font Color",      d->sharedData->commentsFontColor);
276     grp.writeEntry("Comments Bg Color",        d->sharedData->commentsBgColor);
277     grp.writeEntry("Comments Text Outline",    d->sharedData->commentsDrawOutline);
278     grp.writeEntry("Background Opacity",       d->sharedData->bgOpacity);
279     grp.writeEntry("Comments Lines Length",    d->sharedData->commentsLinesLength);
280     grp.writeEntry("Effect Name (OpenGL)",     d->sharedData->effectNameGL);
281     grp.writeEntry("Effect Name",              d->sharedData->effectName);
282 
283 #ifdef HAVE_MEDIAPLAYER
284 
285     // Soundtrack tab
286 
287     grp.writeEntry("Soundtrack Loop",              d->sharedData->soundtrackLoop);
288     grp.writeEntry("Soundtrack Auto Play",         d->sharedData->soundtrackPlay);
289     grp.writeEntry("Soundtrack Path",              d->sharedData->soundtrackPath.toLocalFile());
290     grp.writeEntry("Soundtrack Remember Playlist", d->sharedData->soundtrackRememberPlaylist);
291 
292 #endif
293 
294     // Advanced settings
295 
296     grp.writeEntry("KB Disable FadeInOut", d->sharedData->kbDisableFadeInOut);
297     grp.writeEntry("KB Disable Crossfade", d->sharedData->kbDisableCrossFade);
298     grp.writeEntry("Enable Cache",         d->sharedData->enableCache);
299     grp.writeEntry("Cache Size",           d->sharedData->cacheSize);
300 
301     // --------------------------------------------------------
302 
303     // only save tracks when option is set and tracklist is NOT empty, to prevent deletion
304     // of older track entries
305 
306     if (d->sharedData->soundtrackRememberPlaylist && d->sharedData->soundtrackPlayListNeedsUpdate)
307     {
308         QString groupName(QLatin1String("Presentation Settings") + QLatin1String(" Soundtrack "));
309         KConfigGroup soundGrp = config->group(groupName);
310         soundGrp.writeEntry("Tracks", d->sharedData->soundtrackUrls);
311     }
312 
313     config->sync();
314 }
315 
slotStartClicked()316 void PresentationDlg::slotStartClicked()
317 {
318     saveSettings();
319 
320     if (d->sharedData->mainPage->updateUrlList())
321     {
322         emit buttonStartClicked();
323     }
324 
325     return;
326 }
327 
closeEvent(QCloseEvent * e)328 void PresentationDlg::closeEvent(QCloseEvent* e)
329 {
330     saveSettings();
331     e->accept();
332 }
333 
334 } // namespace DigikamGenericPresentationPlugin
335