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 : 2014-09-18 0007 * Description : slideshow OSD widget 0008 * 0009 * SPDX-FileCopyrightText: 2014-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 * SPDX-FileCopyrightText: 2021 by Phuoc Khanh Le <phuockhanhnk94 at gmail dot com> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "slideosd.h" 0018 0019 // Qt includes 0020 0021 #include <QApplication> 0022 #include <QProgressBar> 0023 #include <QLayout> 0024 #include <QTimer> 0025 #include <QEvent> 0026 #include <QStyle> 0027 0028 // Local includes 0029 0030 #include "digikam_debug.h" 0031 #include "slideshowloader.h" 0032 #include "slidetoolbar.h" 0033 #include "slideproperties.h" 0034 #include "ratingwidget.h" 0035 #include "colorlabelwidget.h" 0036 #include "picklabelwidget.h" 0037 #include "dinfointerface.h" 0038 0039 using namespace Digikam; 0040 0041 namespace DigikamGenericSlideShowPlugin 0042 { 0043 0044 class Q_DECL_HIDDEN SlideOSD::Private 0045 { 0046 public: 0047 0048 explicit Private() 0049 : paused (false), 0050 video (false), 0051 blink (false), 0052 ready (false), 0053 refresh (1000), ///< Progress bar refresh in ms 0054 progressBar (nullptr), 0055 progressTimer (nullptr), 0056 labelsBox (nullptr), 0057 progressBox (nullptr), 0058 parent (nullptr), 0059 slideProps (nullptr), 0060 toolBar (nullptr), 0061 ratingWidget (nullptr), 0062 clWidget (nullptr), 0063 plWidget (nullptr), 0064 settings (nullptr) 0065 { 0066 } 0067 0068 bool paused; 0069 bool video; 0070 bool blink; 0071 bool ready; 0072 0073 int const refresh; 0074 0075 QProgressBar* progressBar; 0076 QTimer* progressTimer; 0077 0078 DHBox* labelsBox; 0079 DHBox* progressBox; 0080 0081 SlideShowLoader* parent; 0082 SlideProperties* slideProps; 0083 SlideToolBar* toolBar; 0084 RatingWidget* ratingWidget; 0085 ColorLabelSelector* clWidget; 0086 PickLabelSelector* plWidget; 0087 SlideShowSettings* settings; 0088 }; 0089 0090 SlideOSD::SlideOSD(SlideShowSettings* const settings, SlideShowLoader* const parent) 0091 : QWidget(parent), 0092 d (new Private()) 0093 { 0094 Qt::WindowFlags flags = Qt::FramelessWindowHint | 0095 Qt::WindowStaysOnTopHint | 0096 Qt::X11BypassWindowManagerHint; 0097 0098 setWindowFlags(flags); 0099 setAttribute(Qt::WA_TranslucentBackground, true); 0100 setAttribute(Qt::WA_ShowWithoutActivating, true); 0101 setMouseTracking(true); 0102 0103 d->parent = parent; 0104 d->settings = settings; 0105 0106 d->slideProps = new SlideProperties(d->settings, this); 0107 0108 // --------------------------------------------------------------- 0109 0110 d->labelsBox = new DHBox(this); 0111 0112 d->clWidget = new ColorLabelSelector(d->labelsBox); 0113 d->clWidget->setFocusPolicy(Qt::NoFocus); 0114 d->clWidget->setMouseTracking(true); 0115 0116 d->plWidget = new PickLabelSelector(d->labelsBox); 0117 d->plWidget->setFocusPolicy(Qt::NoFocus); 0118 d->plWidget->setMouseTracking(true); 0119 0120 d->ratingWidget = new RatingWidget(d->labelsBox); 0121 d->ratingWidget->setTracking(false); 0122 d->ratingWidget->setFading(false); 0123 d->ratingWidget->setFocusPolicy(Qt::NoFocus); 0124 d->ratingWidget->setMouseTracking(true); 0125 0126 d->labelsBox->layout()->setAlignment(d->ratingWidget, Qt::AlignVCenter | Qt::AlignLeft); 0127 d->labelsBox->setMouseTracking(true); 0128 0129 d->labelsBox->setVisible(d->settings->printLabels || d->settings->printRating); 0130 d->ratingWidget->setVisible(d->settings->printRating); 0131 d->clWidget->setVisible(d->settings->printLabels); 0132 d->plWidget->setVisible(d->settings->printLabels); 0133 0134 connect(d->ratingWidget, SIGNAL(signalRatingChanged(int)), 0135 parent, SLOT(slotAssignRating(int))); 0136 0137 connect(d->clWidget, SIGNAL(signalColorLabelChanged(int)), 0138 parent, SLOT(slotAssignColorLabel(int))); 0139 0140 connect(d->plWidget, SIGNAL(signalPickLabelChanged(int)), 0141 parent, SLOT(slotAssignPickLabel(int))); 0142 0143 // --------------------------------------------------------------- 0144 0145 d->progressBox = new DHBox(this); 0146 d->progressBox->setVisible(d->settings->showProgressIndicator); 0147 d->progressBox->setMouseTracking(true); 0148 0149 d->progressBar = new QProgressBar(d->progressBox); 0150 d->progressBar->setMinimum(0); 0151 d->progressBar->setMaximum(d->settings->delay); 0152 d->progressBar->setFocusPolicy(Qt::NoFocus); 0153 d->progressBar->setMouseTracking(true); 0154 0155 d->toolBar = new SlideToolBar(d->settings, d->progressBox); 0156 0157 // --------------------------------------------------------------- 0158 0159 d->slideProps->installEventFilter(d->parent); 0160 d->clWidget->installEventFilter(this); 0161 d->clWidget->installEventFilter(d->parent); 0162 d->clWidget->colorLabelWidget()->installEventFilter(this); 0163 d->plWidget->installEventFilter(this); 0164 d->plWidget->installEventFilter(d->parent); 0165 d->plWidget->pickLabelWidget()->installEventFilter(this); 0166 d->ratingWidget->installEventFilter(this); 0167 d->ratingWidget->installEventFilter(d->parent); 0168 d->labelsBox->installEventFilter(d->parent); 0169 d->progressBox->installEventFilter(d->parent); 0170 d->progressBar->installEventFilter(d->parent); 0171 d->toolBar->installEventFilter(this); 0172 d->toolBar->installEventFilter(d->parent); 0173 0174 // --------------------------------------------------------------- 0175 0176 connect(d->toolBar, SIGNAL(signalPause()), 0177 d->parent, SLOT(slotPause())); 0178 0179 connect(d->toolBar, SIGNAL(signalPlay()), 0180 d->parent, SLOT(slotPlay())); 0181 0182 connect(d->toolBar, SIGNAL(signalNext()), 0183 d->parent, SLOT(slotLoadNextItem())); 0184 0185 connect(d->toolBar, SIGNAL(signalPrev()), 0186 d->parent, SLOT(slotLoadPrevItem())); 0187 0188 connect(d->toolBar, SIGNAL(signalClose()), 0189 d->parent, SLOT(close())); 0190 0191 connect(d->toolBar, SIGNAL(signalRemoveImageFromList()), 0192 d->parent, SLOT(slotRemoveImageFromList())); 0193 0194 connect(d->toolBar, SIGNAL(signalUpdateSettings()), 0195 this, SLOT(slotUpdateSettings())); 0196 0197 connect(d->toolBar, SIGNAL(signalScreenSelected(int)), 0198 d->parent, SLOT(slotScreenSelected(int))); 0199 0200 // --------------------------------------------------------------- 0201 0202 QGridLayout* const grid = new QGridLayout(this); 0203 grid->addWidget(d->slideProps, 0, 0, 1, 2); 0204 grid->addWidget(d->labelsBox, 1, 0, 1, 1); 0205 grid->addWidget(d->progressBox, 2, 0, 1, 1); 0206 grid->setRowStretch(0, 10); 0207 grid->setColumnStretch(1, 10); 0208 grid->setContentsMargins(QMargins()); 0209 grid->setSpacing(qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0210 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing))); 0211 0212 // --------------------------------------------------------------- 0213 0214 d->progressTimer = new QTimer(this); 0215 d->progressTimer->setSingleShot(false); 0216 0217 connect(d->progressTimer, SIGNAL(timeout()), 0218 this, SLOT(slotProgressTimer())); 0219 0220 QTimer::singleShot(500, this, SLOT(slotStart())); 0221 } 0222 0223 SlideOSD::~SlideOSD() 0224 { 0225 d->progressTimer->stop(); 0226 0227 delete d; 0228 } 0229 0230 void SlideOSD::slotStart() 0231 { 0232 d->settings->suffleImages(); 0233 d->parent->slotLoadNextItem(); 0234 d->progressTimer->start(d->refresh); 0235 pause(!d->settings->autoPlayEnabled); 0236 } 0237 0238 void SlideOSD::slotUpdateSettings() 0239 { 0240 d->labelsBox->setVisible(d->settings->printLabels || d->settings->printRating); 0241 d->progressBox->setVisible(d->settings->showProgressIndicator); 0242 d->ratingWidget->setVisible(d->settings->printRating); 0243 d->clWidget->setVisible(d->settings->printLabels); 0244 d->plWidget->setVisible(d->settings->printLabels); 0245 d->progressBar->setMaximum(d->settings->delay); 0246 d->settings->suffleImages(); 0247 } 0248 0249 SlideToolBar* SlideOSD::toolBar() const 0250 { 0251 return d->toolBar; 0252 } 0253 0254 void SlideOSD::setCurrentUrl(const QUrl& url) 0255 { 0256 DItemInfo item(d->settings->iface->itemInfo(url)); 0257 0258 // Update info text. 0259 0260 d->slideProps->setCurrentUrl(url); 0261 0262 // Display Labels. 0263 0264 if (d->settings->printLabels) 0265 { 0266 d->clWidget->blockSignals(true); 0267 d->plWidget->blockSignals(true); 0268 d->clWidget->setColorLabel((ColorLabel)item.colorLabel()); 0269 d->plWidget->setPickLabel((PickLabel)item.pickLabel()); 0270 d->clWidget->blockSignals(false); 0271 d->plWidget->blockSignals(false); 0272 } 0273 0274 if (d->settings->printRating) 0275 { 0276 d->ratingWidget->blockSignals(true); 0277 d->ratingWidget->setRating(item.rating()); 0278 d->ratingWidget->blockSignals(false); 0279 } 0280 0281 // Make the OSD the proper size 0282 0283 resize(d->parent->width() - 10, d->parent->height()); 0284 move(10, 0); 0285 raise(); 0286 } 0287 0288 QSize SlideOSD::slideShowSize() const 0289 { 0290 return d->parent->size(); 0291 } 0292 0293 bool SlideOSD::eventFilter(QObject* obj, QEvent* ev) 0294 { 0295 if ( 0296 (obj == d->labelsBox) || 0297 (obj == d->ratingWidget) || 0298 (obj == d->clWidget) || 0299 (obj == d->plWidget) || 0300 (obj == d->clWidget->colorLabelWidget()) || 0301 (obj == d->plWidget->pickLabelWidget()) 0302 ) 0303 { 0304 if (ev->type() == QEvent::Enter) 0305 { 0306 d->paused = isPaused(); 0307 d->parent->slotPause(); 0308 0309 return false; 0310 } 0311 0312 if (ev->type() == QEvent::Leave) 0313 { 0314 if (!d->paused) 0315 { 0316 d->parent->slotPlay(); 0317 } 0318 0319 return false; 0320 } 0321 } 0322 0323 // pass the event on to the parent class 0324 0325 return QWidget::eventFilter(obj, ev); 0326 } 0327 0328 void SlideOSD::slotProgressTimer() 0329 { 0330 QString str = QString::fromUtf8("(%1/%2)") 0331 .arg(d->settings->fileList.indexOf(d->parent->currentItem()) + 1) 0332 .arg(d->settings->fileList.count()); 0333 0334 if (isPaused()) 0335 { 0336 d->blink = !d->blink; 0337 0338 if (d->blink) 0339 { 0340 str = QString(); 0341 } 0342 0343 d->progressBar->setFormat(str); 0344 } 0345 else if (d->video) 0346 { 0347 d->progressBar->setFormat(str); 0348 return; 0349 } 0350 else 0351 { 0352 d->progressBar->setFormat(str); 0353 d->progressBar->setMaximum(d->settings->delay); 0354 0355 if (d->progressBar->value() == d->settings->delay) 0356 { 0357 if (!d->ready) 0358 { 0359 return; 0360 } 0361 0362 d->ready = false; 0363 d->parent->slotLoadNextItem(); 0364 } 0365 0366 d->progressBar->setValue(d->progressBar->value()+1); 0367 } 0368 } 0369 0370 void SlideOSD::pause(bool b) 0371 { 0372 d->toolBar->pause(b); 0373 0374 if (!b) 0375 { 0376 d->progressBar->setValue(0); 0377 } 0378 } 0379 0380 void SlideOSD::video(bool b) 0381 { 0382 d->video = b; 0383 } 0384 0385 bool SlideOSD::isPaused() const 0386 { 0387 return d->toolBar->isPaused(); 0388 } 0389 0390 bool SlideOSD::isUnderMouse() const 0391 { 0392 return ( 0393 d->ratingWidget->underMouse() || 0394 d->progressBar->underMouse() || 0395 d->clWidget->underMouse() || 0396 d->plWidget->underMouse() || 0397 d->toolBar->underMouse() 0398 ); 0399 } 0400 0401 void SlideOSD::setLoadingReady(bool b) 0402 { 0403 d->ready = b; 0404 } 0405 0406 } // namespace DigikamGenericSlideShowPlugin 0407 0408 #include "moc_slideosd.cpp"