1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2004-10-05
7 * Description : a tool bar for slideshow
8 *
9 * Copyright (C) 2004-2005 by Renchi Raju <renchi dot raju at gmail dot com>
10 * Copyright (C) 2006-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11 * Copyright (C) 2019-2020 by Minh Nghia Duong <minhnghiaduong997 at gmail dot com>
12 * Copyright (C) 2021 by Phuoc Khanh Le <phuockhanhnk94 at gmail dot com>
13 *
14 * This program is free software; you can redistribute it
15 * and/or modify it under the terms of the GNU General
16 * Public License as published by the Free Software Foundation;
17 * either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * ============================================================ */
26
27 #include "slidetoolbar.h"
28
29 // Qt includes
30
31 #include <QApplication>
32 #include <QActionGroup>
33 #include <QToolButton>
34 #include <QPixmap>
35 #include <QScreen>
36 #include <QMenu>
37 #include <QInputDialog>
38 #include <QMessageBox>
39
40 // KDE includes
41
42 #include <klocalizedstring.h>
43
44 // Local includes
45
46 #include "dpluginaboutdlg.h"
47 #include "digikam_debug.h"
48 #include "setupslideshow_dialog.h"
49
50 namespace DigikamGenericSlideShowPlugin
51 {
52
53 class Q_DECL_HIDDEN SlideToolBar::Private
54 {
55 public:
56
Private()57 explicit Private()
58 : playBtn (nullptr),
59 prevBtn (nullptr),
60 nextBtn (nullptr),
61 stopBtn (nullptr),
62 delayBtn (nullptr),
63 deleteBtn (nullptr),
64 setupBtn (nullptr),
65 screenSelectBtn (nullptr),
66 currentlyPause (false),
67 configDialog (nullptr),
68 settings (nullptr)
69 {
70 }
71
72 QToolButton* playBtn;
73 QToolButton* prevBtn;
74 QToolButton* nextBtn;
75 QToolButton* stopBtn;
76 QToolButton* delayBtn;
77 QToolButton* deleteBtn;
78 QToolButton* setupBtn;
79 QToolButton* screenSelectBtn;
80
81 bool currentlyPause;
82
83 SetupSlideShowDialog* configDialog;
84 SlideShowSettings* settings;
85 };
86
SlideToolBar(SlideShowSettings * const settings,QWidget * const parent)87 SlideToolBar::SlideToolBar(SlideShowSettings* const settings, QWidget* const parent)
88 : DHBox(parent),
89 d (new Private)
90 {
91 setMouseTracking(true);
92 setContentsMargins(QMargins());
93
94 d->settings = settings;
95
96 d->playBtn = new QToolButton(this);
97 d->prevBtn = new QToolButton(this);
98 d->nextBtn = new QToolButton(this);
99 d->stopBtn = new QToolButton(this);
100 d->delayBtn = new QToolButton(this);
101 d->deleteBtn = new QToolButton(this);
102 d->setupBtn = new QToolButton(this);
103
104 d->configDialog = new SetupSlideShowDialog(d->settings);
105
106 d->playBtn->setCheckable(true);
107 d->playBtn->setChecked(!d->settings->autoPlayEnabled);
108 d->playBtn->setFocusPolicy(Qt::NoFocus);
109 d->prevBtn->setFocusPolicy(Qt::NoFocus);
110 d->nextBtn->setFocusPolicy(Qt::NoFocus);
111 d->stopBtn->setFocusPolicy(Qt::NoFocus);
112 d->delayBtn->setFocusPolicy(Qt::NoFocus);
113 d->deleteBtn->setFocusPolicy(Qt::NoFocus);
114 d->setupBtn->setFocusPolicy(Qt::NoFocus);
115
116 QSize s(32, 32);
117 d->playBtn->setIconSize(s);
118 d->prevBtn->setIconSize(s);
119 d->nextBtn->setIconSize(s);
120 d->stopBtn->setIconSize(s);
121 d->delayBtn->setIconSize(s);
122 d->deleteBtn->setIconSize(s);
123 d->setupBtn->setIconSize(s);
124
125 QString iconString = d->settings->autoPlayEnabled ? QLatin1String("media-playback-pause")
126 : QLatin1String("media-playback-start");
127 d->playBtn->setIcon(QIcon::fromTheme(iconString));
128 d->prevBtn->setIcon(QIcon::fromTheme(QLatin1String("media-skip-backward")));
129 d->nextBtn->setIcon(QIcon::fromTheme(QLatin1String("media-skip-forward")));
130 d->stopBtn->setIcon(QIcon::fromTheme(QLatin1String("media-playback-stop")));
131 d->delayBtn->setIcon(QIcon::fromTheme(QLatin1String("appointment-new")));
132 d->deleteBtn->setIcon(QIcon::fromTheme(QLatin1String("user-trash")));
133 d->setupBtn->setIcon(QIcon::fromTheme(QLatin1String("systemsettings")));
134
135 int num = qApp->screens().count();
136
137 if (num > 1)
138 {
139 d->screenSelectBtn = new QToolButton(this);
140 QMenu* const screenMenu = new QMenu(d->screenSelectBtn);
141 d->screenSelectBtn->setToolTip(i18n("Switch Screen"));
142 d->screenSelectBtn->setIconSize(s);
143 d->screenSelectBtn->setIcon(QIcon::fromTheme(QLatin1String("video-display")));
144 d->screenSelectBtn->setMenu(screenMenu);
145 d->screenSelectBtn->setPopupMode(QToolButton::InstantPopup);
146 d->screenSelectBtn->setFocusPolicy(Qt::NoFocus);
147
148 QActionGroup* const group = new QActionGroup(screenMenu);
149 group->setExclusive(true);
150
151 for (int i = 0 ; i < num ; ++i)
152 {
153 QString model = qApp->screens().at(i)->model();
154 QAction* const act = screenMenu->addAction(i18nc("%1 is the screen number (0, 1, ...)", "Screen %1", i) +
155 QString::fromUtf8(" (%1)").arg(model.left(model.length() - 1)));
156 act->setData(QVariant::fromValue(i));
157 act->setCheckable(true);
158 group->addAction(act);
159
160 if (i == d->settings->slideScreen)
161 {
162 act->setChecked(true);
163 }
164 }
165
166 connect(screenMenu, SIGNAL(triggered(QAction*)),
167 this, SLOT(slotScreenSelected(QAction*)));
168 }
169
170 connect(d->playBtn, SIGNAL(toggled(bool)),
171 this, SLOT(slotPlayBtnToggled()));
172
173 connect(d->nextBtn, SIGNAL(clicked()),
174 this, SLOT(slotNexPrevClicked()));
175
176 connect(d->prevBtn, SIGNAL(clicked()),
177 this, SLOT(slotNexPrevClicked()));
178
179 connect(d->nextBtn, SIGNAL(clicked()),
180 this, SIGNAL(signalNext()));
181
182 connect(d->prevBtn, SIGNAL(clicked()),
183 this, SIGNAL(signalPrev()));
184
185 connect(d->stopBtn, SIGNAL(clicked()),
186 this, SIGNAL(signalClose()));
187
188 connect(d->delayBtn, SIGNAL(clicked()),
189 this, SLOT(slotChangeDelayButtonPressed()));
190
191 connect(d->deleteBtn, SIGNAL(clicked()),
192 this, SLOT(slotRemoveImage()));
193
194 connect(d->setupBtn, SIGNAL(clicked()),
195 this, SLOT(slotMenuSlideShowConfiguration()));
196
197 connect(d->configDialog, SIGNAL(finished(int)),
198 this, SIGNAL(signalUpdateSettings()));
199
200 connect(d->configDialog, SIGNAL(finished(int)),
201 this, SLOT(slotConfigurationAccepted()));
202 }
203
~SlideToolBar()204 SlideToolBar::~SlideToolBar()
205 {
206 delete d->configDialog;
207 delete d;
208 }
209
isPaused() const210 bool SlideToolBar::isPaused() const
211 {
212 return d->playBtn->isChecked();
213 }
214
pause(bool val)215 void SlideToolBar::pause(bool val)
216 {
217 if (val == isPaused())
218 {
219 return;
220 }
221
222 d->playBtn->setChecked(val);
223 slotPlayBtnToggled();
224 }
225
setEnabledPlay(bool val)226 void SlideToolBar::setEnabledPlay(bool val)
227 {
228 d->playBtn->setEnabled(val);
229 }
230
setEnabledNext(bool val)231 void SlideToolBar::setEnabledNext(bool val)
232 {
233 d->nextBtn->setEnabled(val);
234 }
235
setEnabledPrev(bool val)236 void SlideToolBar::setEnabledPrev(bool val)
237 {
238 d->prevBtn->setEnabled(val);
239 }
240
closeConfigurationDialog()241 void SlideToolBar::closeConfigurationDialog()
242 {
243 if (d->configDialog->isVisible())
244 {
245 d->configDialog->reject();
246 }
247 }
248
slotPlayBtnToggled()249 void SlideToolBar::slotPlayBtnToggled()
250 {
251 if (d->playBtn->isChecked())
252 {
253 d->playBtn->setIcon(QIcon::fromTheme(QLatin1String("media-playback-start")));
254
255 emit signalPause();
256 }
257 else
258 {
259 d->playBtn->setIcon(QIcon::fromTheme(QLatin1String("media-playback-pause")));
260
261 emit signalPlay();
262 }
263 }
264
slotChangeDelayButtonPressed()265 void SlideToolBar::slotChangeDelayButtonPressed()
266 {
267 bool ok;
268 int delay = d->settings->delay;
269 bool running = (!isPaused() && d->playBtn->isEnabled());
270
271 if (running)
272 {
273 d->playBtn->animateClick();
274 }
275
276 delay = QInputDialog::getInt(this, i18n("Specify delay for slide show"),
277 i18n("Delay:"), delay, 1, 3600, 1, &ok);
278
279 if (ok)
280 {
281 d->settings->delay = delay;
282 }
283
284 if (running)
285 {
286 d->playBtn->animateClick();
287 }
288 }
289
slotNexPrevClicked()290 void SlideToolBar::slotNexPrevClicked()
291 {
292 if (!d->playBtn->isChecked())
293 {
294 d->playBtn->setChecked(true);
295 d->playBtn->setIcon(QIcon::fromTheme(QLatin1String("media-playback-start")));
296
297 emit signalPause();
298 }
299 }
300
slotMenuSlideShowConfiguration()301 void SlideToolBar::slotMenuSlideShowConfiguration()
302 {
303 if (d->configDialog->isVisible())
304 {
305 d->configDialog->reject();
306
307 return;
308 }
309
310 d->currentlyPause = isPaused();
311
312 if (!d->currentlyPause && d->playBtn->isEnabled())
313 {
314 d->playBtn->animateClick();
315 }
316
317 d->configDialog->show();
318 }
319
slotConfigurationAccepted()320 void SlideToolBar::slotConfigurationAccepted()
321 {
322 if (!d->currentlyPause && d->playBtn->isEnabled())
323 {
324 d->playBtn->animateClick();
325 }
326 }
327
keyPressEvent(QKeyEvent * e)328 void SlideToolBar::keyPressEvent(QKeyEvent* e)
329 {
330 switch (e->key())
331 {
332 case (Qt::Key_F1):
333 {
334 d->currentlyPause = isPaused();
335
336 if (!d->currentlyPause && d->playBtn->isEnabled())
337 {
338 d->playBtn->animateClick();
339 }
340
341 QPointer<DPluginAboutDlg> help = new DPluginAboutDlg(d->settings->plugin);
342 help->exec();
343 delete help;
344
345 if (!d->currentlyPause && d->playBtn->isEnabled())
346 {
347 d->playBtn->animateClick();
348 }
349
350 break;
351 }
352
353 case (Qt::Key_F2):
354 {
355 slotMenuSlideShowConfiguration();
356 break;
357 }
358
359 case (Qt::Key_Space):
360 {
361 if (d->playBtn->isEnabled())
362 {
363 d->playBtn->animateClick();
364 }
365
366 break;
367 }
368
369 case (Qt::Key_Left):
370 case (Qt::Key_Up):
371 case (Qt::Key_PageUp):
372 {
373 if (d->prevBtn->isEnabled())
374 {
375 d->prevBtn->animateClick();
376 }
377
378 break;
379 }
380
381 case (Qt::Key_Right):
382 case (Qt::Key_Down):
383 case (Qt::Key_PageDown):
384 {
385 if (d->nextBtn->isEnabled())
386 {
387 d->nextBtn->animateClick();
388 }
389
390 break;
391 }
392
393 case (Qt::Key_Escape):
394 {
395 if (d->stopBtn->isEnabled())
396 {
397 d->stopBtn->animateClick();
398 }
399
400 break;
401 }
402
403 default:
404 {
405 break;
406 }
407 }
408
409 e->accept();
410 }
411
slotScreenSelected(QAction * act)412 void SlideToolBar::slotScreenSelected(QAction* act)
413 {
414 if (!act || (act->data().type() != QVariant::Int))
415 {
416 return;
417 }
418
419 emit signalScreenSelected(act->data().toInt());
420 }
421
slotRemoveImage()422 void SlideToolBar::slotRemoveImage()
423 {
424 bool running = (!isPaused() && d->playBtn->isEnabled());
425
426 if (running)
427 {
428 d->playBtn->animateClick();
429 }
430
431 QPointer<QMessageBox> msgBox = new QMessageBox(QMessageBox::Question,
432 i18n("Delete image"),
433 i18n("Do you want to move this image to the trash?"),
434 QMessageBox::Yes | QMessageBox::No, this);
435
436 msgBox->setDefaultButton(QMessageBox::Yes);
437
438 int ret = msgBox->exec();
439 delete msgBox;
440
441 if (ret == QMessageBox::Yes)
442 {
443 emit signalRemoveImageFromList();
444 }
445
446 if (running)
447 {
448 d->playBtn->animateClick();
449 }
450 }
451
452 } // namespace DigikamGenericSlideShowPlugin
453