File indexing completed on 2025-03-09 03:52:09

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2003-02-16
0007  * Description : a presentation tool.
0008  *
0009  * SPDX-FileCopyrightText: 2006-2009 by Valerio Fuoglio <valerio dot fuoglio at gmail dot com>
0010  * SPDX-FileCopyrightText:      2009 by Andi Clemens <andi dot clemens at googlemail dot com>
0011  * SPDX-FileCopyrightText: 2003-2005 by Renchi Raju <renchi dot raju at gmail dot com>
0012  * SPDX-FileCopyrightText: 2012-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0013  * SPDX-FileCopyrightText:      2021 by Phuoc Khanh Le <phuockhanhnk94 at gmail dot com>
0014  *
0015  * SPDX-License-Identifier: GPL-2.0-or-later
0016  *
0017  * ============================================================ */
0018 
0019 #include "presentationwidget.h"
0020 
0021 // C++ includes
0022 
0023 #include <cmath>
0024 #include <cstdlib>
0025 #include <ctime>
0026 
0027 // Qt includes
0028 
0029 #include <QCursor>
0030 #include <QFont>
0031 #include <QKeyEvent>
0032 #include <QMouseEvent>
0033 #include <QPainter>
0034 #include <QPainterPath>
0035 #include <QTimer>
0036 #include <QWheelEvent>
0037 #include <QApplication>
0038 #include <QScreen>
0039 #include <QWindow>
0040 
0041 #include <QDebug>
0042 
0043 // KDE includes
0044 
0045 #include <klocalizedstring.h>
0046 
0047 // Local includes
0048 
0049 #include "digikam_config.h"
0050 #include "presentationcontainer.h"
0051 #include "presentationctrlwidget.h"
0052 #include "presentationloader.h"
0053 #include "presentation_mainpage.h"
0054 
0055 #ifdef HAVE_MEDIAPLAYER
0056 #   include "presentationaudiowidget.h"
0057 #   include "slidevideo.h"
0058 #endif
0059 
0060 using namespace Digikam;
0061 
0062 namespace DigikamGenericPresentationPlugin
0063 {
0064 
0065 class Q_DECL_HIDDEN PresentationWidget::Private
0066 {
0067 
0068 public:
0069 
0070     explicit Private()
0071       : sharedData      (nullptr),
0072         imageLoader     (nullptr),
0073 
0074 #ifdef HAVE_MEDIAPLAYER
0075 
0076         playbackWidget  (nullptr),
0077         videoView       (nullptr),
0078 
0079 #endif
0080 
0081         timer           (nullptr),
0082         fileIndex       (0),
0083         effect          (nullptr),
0084         effectRunning   (false),
0085         x               (0),
0086         y               (0),
0087         w               (0),
0088         h               (0),
0089         dx              (0),
0090         dy              (0),
0091         ix              (0),
0092         iy              (0),
0093         i               (0),
0094         j               (0),
0095         subType         (0),
0096         x0              (0),
0097         y0              (0),
0098         x1              (0),
0099         y1              (0),
0100         wait            (0),
0101         fx              (0),
0102         fy              (0),
0103         alpha           (0),
0104         fd              (0),
0105         intArray        (nullptr),
0106         pdone           (0),
0107         pixelMatrix     (nullptr),
0108         slideCtrlWidget (nullptr),
0109         mouseMoveTimer  (nullptr),
0110         deskX           (0),
0111         deskY           (0),
0112         deskWidth       (0),
0113         deskHeight      (0)
0114     {
0115     }
0116 
0117     PresentationContainer*      sharedData;
0118 
0119     // -------------------------
0120 
0121     QMap<QString, EffectMethod> Effects;
0122 
0123     PresentationLoader*         imageLoader;
0124     QPixmap                     currImage;
0125 
0126 #ifdef HAVE_MEDIAPLAYER
0127 
0128     PresentationAudioWidget*    playbackWidget;
0129     SlideVideo*                 videoView;
0130 
0131 #endif
0132 
0133     QTimer*                     timer;
0134     int                         fileIndex;
0135 
0136     EffectMethod                effect;
0137     bool                        effectRunning;
0138     QString                     effectName;
0139 
0140     /// values for state of various effects
0141     int                         x;
0142     int                         y;
0143     int                         w;
0144     int                         h;
0145     int                         dx;
0146     int                         dy;
0147     int                         ix;
0148     int                         iy;
0149     int                         i;
0150     int                         j;
0151     int                         subType;
0152     int                         x0;
0153     int                         y0;
0154     int                         x1;
0155     int                         y1;
0156     int                         wait;
0157     double                      fx;
0158     double                      fy;
0159     double                      alpha;
0160     double                      fd;
0161     int*                        intArray;
0162     bool                        pdone;
0163     bool**                      pixelMatrix;
0164 
0165     /// static
0166     QPolygon                    pa;
0167 
0168     PresentationCtrlWidget*     slideCtrlWidget;
0169     QTimer*                     mouseMoveTimer;
0170 
0171     int                         deskX;
0172     int                         deskY;
0173     int                         deskWidth;
0174     int                         deskHeight;
0175 };
0176 
0177 PresentationWidget::PresentationWidget(PresentationContainer* const sharedData)
0178     : QWidget(),
0179       d      (new Private),
0180       randomGenerator(QRandomGenerator::global())
0181 {
0182     setAttribute(Qt::WA_DeleteOnClose);
0183     setContextMenuPolicy(Qt::PreventContextMenu);
0184 
0185 #ifdef Q_OS_WIN
0186 
0187     setWindowFlags(Qt::Popup               |
0188                    Qt::FramelessWindowHint |
0189                    Qt::WindowStaysOnTopHint);
0190 
0191 #else
0192 
0193     setWindowState(windowState() | Qt::WindowFullScreen);
0194 
0195 #endif
0196 
0197     QScreen* screen = qApp->primaryScreen();
0198 
0199     if (QWidget* const widget = qApp->activeWindow())
0200     {
0201         if (QWindow* const window = widget->windowHandle())
0202         {
0203             screen = window->screen();
0204         }
0205     }
0206 
0207     QRect deskRect = screen->geometry();
0208     d->deskX       = deskRect.x();
0209     d->deskY       = deskRect.y();
0210     d->deskWidth   = deskRect.width();
0211     d->deskHeight  = deskRect.height();
0212 
0213     move(d->deskX, d->deskY);
0214     resize(d->deskWidth, d->deskHeight);
0215 
0216     d->sharedData          = sharedData;
0217     d->sharedData->display = this;
0218 
0219     d->slideCtrlWidget = new PresentationCtrlWidget(this, d->sharedData);
0220     d->slideCtrlWidget->hide();
0221 
0222     int w = d->slideCtrlWidget->width() - 1;
0223     d->slideCtrlWidget->move(d->deskX + d->deskWidth - w, d->deskY);
0224 
0225     if (!d->sharedData->loop)
0226     {
0227         d->slideCtrlWidget->setEnabledPrev(false);
0228     }
0229 
0230     connect(d->slideCtrlWidget, SIGNAL(signalPause()),
0231             this, SLOT(slotPause()));
0232 
0233     connect(d->slideCtrlWidget, SIGNAL(signalPlay()),
0234             this, SLOT(slotPlay()));
0235 
0236     connect(d->slideCtrlWidget, SIGNAL(signalNext()),
0237             this, SLOT(slotNext()));
0238 
0239     connect(d->slideCtrlWidget, SIGNAL(signalPrev()),
0240             this, SLOT(slotPrev()));
0241 
0242     connect(d->slideCtrlWidget, SIGNAL(signalClose()),
0243             this, SLOT(slotClose()));
0244 
0245     connect(d->slideCtrlWidget, SIGNAL(signalRemoveImageFromList()),
0246             this, SLOT(slotRemoveImageFromList()));
0247 
0248 #ifdef HAVE_MEDIAPLAYER
0249 
0250     // -- playback widget -------------------------------
0251 
0252     d->playbackWidget = new PresentationAudioWidget(this, d->sharedData->soundtrackUrls, d->sharedData);
0253     d->playbackWidget->hide();
0254     d->playbackWidget->move(d->deskX, d->deskY);
0255 
0256     // -- video preview ---------------------------------
0257 
0258     d->videoView = new SlideVideo(this);
0259 
0260     // TODO: pass mouse events from d->videoView to this ?
0261     //d->videoView->installEventFilter(this);
0262 
0263     connect(d->videoView, SIGNAL(signalVideoLoaded(bool)),
0264             this, SLOT(slotVideoLoaded(bool)));
0265 
0266     connect(d->videoView, SIGNAL(signalVideoFinished()),
0267             this, SLOT(slotVideoFinished()));
0268 
0269     d->videoView->hide();
0270     d->videoView->resize(d->deskWidth, d->deskHeight);
0271 
0272 #endif
0273 
0274     // ---------------------------------------------------------------
0275 
0276     d->fileIndex     = -1; // start with -1
0277     d->effect        = nullptr;
0278     d->effectRunning = false;
0279     d->intArray      = nullptr;
0280     m_endOfShow      = false;
0281     m_simplyShow     = false;
0282     m_startPainter   = false;
0283     m_firstPainter   = true;
0284     d->timer         = new QTimer(this);
0285 
0286     connect(d->timer, SIGNAL(timeout()),
0287             this, SLOT(slotTimeOut()));
0288 
0289     d->pa            = QPolygon(4);
0290     m_buffer         = QPixmap(size());
0291     m_buffer.fill(Qt::black);
0292 
0293     d->imageLoader   = new PresentationLoader(d->sharedData, width(), height(), d->fileIndex);
0294 
0295     // --------------------------------------------------
0296 
0297     registerEffects();
0298 
0299     if (d->sharedData->effectName == QLatin1String("Random"))
0300     {
0301         d->effect = getRandomEffect();
0302     }
0303     else
0304     {
0305         d->effectName = d->sharedData->effectName;
0306         d->effect     = d->Effects[d->sharedData->effectName];
0307 
0308         if (!d->effect)
0309         {
0310             d->effect     = d->Effects[QLatin1String("None")];
0311             d->effectName = QLatin1String("None");
0312         }
0313     }
0314 
0315     d->timer->setSingleShot(true);
0316 
0317     if (d->sharedData->offAutoDelay)
0318     {
0319         d->timer->stop();
0320         slotTimeOut();
0321     }
0322     else
0323     {
0324         d->timer->start(500);
0325     }
0326 
0327     // -- hide cursor when not moved --------------------
0328 
0329     d->mouseMoveTimer = new QTimer(this);
0330     d->mouseMoveTimer->setSingleShot(true);
0331 
0332     connect(d->mouseMoveTimer, SIGNAL(timeout()),
0333             this, SLOT(slotMouseMoveTimeOut()));
0334 
0335     setMouseTracking(true);
0336     slotMouseMoveTimeOut();
0337 
0338 #ifdef HAVE_MEDIAPLAYER
0339 
0340     if (d->sharedData->soundtrackPlay)
0341     {
0342         d->playbackWidget->slotPlay();
0343     }
0344 
0345 #endif
0346 
0347 }
0348 
0349 PresentationWidget::~PresentationWidget()
0350 {
0351 
0352 #ifdef HAVE_MEDIAPLAYER
0353 
0354     d->playbackWidget->slotStop();
0355 
0356 #endif
0357 
0358     d->timer->stop();
0359     d->mouseMoveTimer->stop();
0360 
0361     if (d->intArray)
0362     {
0363         delete [] d->intArray;
0364     }
0365 
0366     delete d->imageLoader;
0367     delete d;
0368 }
0369 
0370 void PresentationWidget::readSettings()
0371 {
0372 }
0373 
0374 void PresentationWidget::loadNextImage()
0375 {
0376     if (!d->currImage.isNull())
0377     {
0378         m_firstPainter = false;
0379         m_buffer       = d->currImage;
0380     }
0381     else
0382     {
0383         m_buffer = QPixmap(size());
0384         m_buffer.fill(Qt::black);
0385     }
0386 
0387     d->fileIndex++;
0388 
0389     d->imageLoader->next();
0390     int num = d->sharedData->urlList.count();
0391 
0392     if (d->fileIndex >= num)
0393     {
0394         if (d->sharedData->loop)
0395         {
0396             d->fileIndex = 0;
0397         }
0398         else
0399         {
0400             d->currImage = QPixmap(0, 0);
0401             d->fileIndex = num - 1;
0402             return;
0403         }
0404     }
0405 
0406     if (!d->sharedData->loop)
0407     {
0408         d->slideCtrlWidget->setEnabledPrev(d->fileIndex > 0);
0409         d->slideCtrlWidget->setEnabledNext(d->fileIndex < num - 1);
0410     }
0411 
0412     QImage img        = d->imageLoader->getCurrent();
0413 
0414     QPixmap newPixmap = QPixmap::fromImage(img);
0415     QPixmap pixmap(width(), height());
0416     pixmap.fill(Qt::black);
0417     QPainter p(&pixmap);
0418 
0419     p.drawPixmap((width()  - newPixmap.width())  / 2,
0420                  (height() - newPixmap.height()) / 2, newPixmap,
0421                  0, 0, newPixmap.width(), newPixmap.height());
0422 
0423     d->currImage = pixmap;
0424 
0425     if (img.isNull())
0426     {
0427 
0428 #ifdef HAVE_MEDIAPLAYER
0429 
0430         d->videoView->setCurrentUrl(d->imageLoader->currPath());
0431 
0432 #endif
0433 
0434     }
0435 }
0436 
0437 void PresentationWidget::loadPrevImage()
0438 {
0439     d->fileIndex--;
0440     d->imageLoader->prev();
0441 
0442     int num = d->sharedData->urlList.count();
0443 
0444     if (d->fileIndex < 0)
0445     {
0446         if (d->sharedData->loop)
0447         {
0448             d->fileIndex = num - 1;
0449         }
0450         else
0451         {
0452             d->fileIndex = -1; // set this to -1.
0453             return;
0454         }
0455     }
0456 
0457     if (!d->sharedData->loop)
0458     {
0459         d->slideCtrlWidget->setEnabledPrev(d->fileIndex > 0);
0460         d->slideCtrlWidget->setEnabledNext(d->fileIndex < num - 1);
0461     }
0462 
0463     QImage img = d->imageLoader->getCurrent();
0464 
0465     QPixmap newPixmap = QPixmap::fromImage(img);
0466     QPixmap pixmap(width(), height());
0467     pixmap.fill(Qt::black);
0468     QPainter p(&pixmap);
0469 
0470     p.drawPixmap((width()  - newPixmap.width())  / 2,
0471                  (height() - newPixmap.height()) / 2, newPixmap,
0472                  0, 0, newPixmap.width(), newPixmap.height());
0473 
0474     d->currImage = pixmap;
0475 
0476     if (img.isNull())
0477     {
0478 
0479 #ifdef HAVE_MEDIAPLAYER
0480 
0481         d->videoView->setCurrentUrl(d->imageLoader->currPath());
0482 
0483 #endif
0484 
0485     }
0486 }
0487 
0488 void PresentationWidget::printFilename()
0489 {
0490     if (d->currImage.isNull())
0491     {
0492         return;
0493     }
0494 
0495     QPainter p;
0496 
0497     p.begin(&d->currImage);
0498     p.setPen(Qt::black);
0499 
0500     for (int x = 9 ; x <= 11 ; ++x)
0501     {
0502         for (int y = 31 ; y >= 29 ; --y)
0503         {
0504             p.drawText(x, height() - y, d->imageLoader->currFileName());
0505         }
0506     }
0507 
0508     p.setPen(QColor(Qt::white));
0509     p.drawText(10, height() - 30, d->imageLoader->currFileName());
0510 }
0511 
0512 void PresentationWidget::printComments()
0513 {
0514     if (d->currImage.isNull())
0515     {
0516         return;
0517     }
0518 
0519     DItemInfo info(d->sharedData->iface->itemInfo(d->imageLoader->currPath()));
0520     QString comments = info.comment();
0521 
0522     int yPos = 30; // Text Y coordinate
0523 
0524     if (d->sharedData->printFileName)
0525     {
0526         yPos = 50;
0527     }
0528 
0529     QStringList commentsByLines;
0530 
0531     uint commentsIndex = 0; // Comments QString index
0532 
0533     while (commentsIndex < (uint)comments.length())
0534     {
0535         QString newLine;
0536         bool breakLine = false; // End Of Line found
0537         uint currIndex; //  Comments QString current index
0538 
0539         // Check minimal lines dimension
0540 
0541         uint commentsLinesLengthLocal = d->sharedData->commentsLinesLength;
0542 
0543         for (currIndex = commentsIndex ; (currIndex < (uint)comments.length()) && !breakLine ; ++currIndex)
0544         {
0545             if ((comments[currIndex] == QLatin1Char('\n')) || comments[currIndex].isSpace())
0546             {
0547                 breakLine = true;
0548             }
0549         }
0550 
0551         if (commentsLinesLengthLocal <= (currIndex - commentsIndex))
0552         {
0553             commentsLinesLengthLocal = (currIndex - commentsIndex);
0554         }
0555 
0556         breakLine = false;
0557 
0558         for (currIndex = commentsIndex ; ((currIndex <= (commentsIndex + commentsLinesLengthLocal)) &&
0559              (currIndex < (uint)comments.length()) && !breakLine) ; ++currIndex)
0560         {
0561             breakLine = (comments[currIndex] == QLatin1Char('\n')) ? true : false;
0562 
0563             if (breakLine)
0564             {
0565                 newLine.append(QLatin1Char(' '));
0566             }
0567             else
0568             {
0569                 newLine.append(comments[currIndex]);
0570             }
0571         }
0572 
0573         commentsIndex = currIndex; // The line is ended
0574 
0575         if (commentsIndex != (uint)comments.length())
0576         {
0577             while (!newLine.endsWith(QLatin1Char(' ')))
0578             {
0579                 newLine.truncate(newLine.length() - 1);
0580                 commentsIndex--;
0581             }
0582         }
0583 
0584         commentsByLines.prepend(newLine.trimmed());
0585     }
0586 
0587     QPainter p;
0588 
0589     p.begin(&d->currImage);
0590     p.setFont(*d->sharedData->captionFont);
0591 
0592     for (int lineNumber = 0 ; lineNumber < (int)commentsByLines.count() ; ++lineNumber)
0593     {
0594         p.setPen(QColor(d->sharedData->commentsBgColor));
0595 
0596         // coefficient 1.5 is used to maintain distance between different lines
0597 
0598         for (int x = 9 ; x <= 11 ; ++x)
0599         {
0600             for (int y = (int)(yPos + lineNumber * 1.5 * d->sharedData->captionFont->pointSize() + 1) ;
0601                  y >= (int)(yPos + lineNumber * 1.5 * d->sharedData->captionFont->pointSize() - 1) ; --y)
0602             {
0603                 p.drawText(x, height() - y, commentsByLines[lineNumber]);
0604             }
0605         }
0606 
0607         p.setPen(QColor(d->sharedData->commentsFontColor));
0608         p.drawText(10, height() - (int)(lineNumber * 1.5 * d->sharedData->captionFont->pointSize() + yPos),
0609                    commentsByLines[lineNumber]);
0610     }
0611 }
0612 
0613 void PresentationWidget::printProgress()
0614 {
0615     if (d->currImage.isNull())
0616     {
0617         return;
0618     }
0619 
0620     QPainter p;
0621     p.begin(&d->currImage);
0622 
0623     QString progress(QString::number(d->fileIndex + 1) + QLatin1Char('/') +
0624                                      QString::number(d->sharedData->urlList.count()));
0625 
0626     int stringLength = p.fontMetrics().horizontalAdvance(progress) * progress.length();
0627 
0628     p.setPen(QColor(Qt::black));
0629 
0630     for (int x = 9 ; x <= 11 ; ++x)
0631     {
0632         for (int y = 21 ; y >= 19 ; --y)
0633         {
0634             p.drawText(width() - stringLength - x, y, progress);
0635         }
0636     }
0637 
0638     p.setPen(QColor(Qt::white));
0639     p.drawText(width() - stringLength - 10, 20, progress);
0640 }
0641 
0642 void PresentationWidget::showEndOfShow()
0643 {
0644     m_endOfShow = true;
0645     update();
0646 
0647     d->slideCtrlWidget->setEnabledPlay(false);
0648     d->slideCtrlWidget->setEnabledNext(false);
0649     d->slideCtrlWidget->setEnabledPrev(false);
0650 }
0651 
0652 void PresentationWidget::showOverlays()
0653 {
0654     if (d->slideCtrlWidget->isHidden())
0655     {
0656         int w = d->slideCtrlWidget->width() - 1;
0657         d->slideCtrlWidget->move(d->deskWidth - w, 0);
0658         d->slideCtrlWidget->show();
0659     }
0660 
0661 #ifdef HAVE_MEDIAPLAYER
0662 
0663     if (d->playbackWidget->isHidden())
0664     {
0665         d->playbackWidget->move(0, 0);
0666         d->playbackWidget->show();
0667     }
0668 
0669 #endif
0670 
0671 }
0672 
0673 void PresentationWidget::hideOverlays()
0674 {
0675     d->slideCtrlWidget->hide();
0676 
0677 #ifdef HAVE_MEDIAPLAYER
0678 
0679     d->playbackWidget->hide();
0680 
0681 #endif
0682 
0683 }
0684 
0685 void PresentationWidget::keyPressEvent(QKeyEvent* event)
0686 {
0687     if (!event)
0688     {
0689         return;
0690     }
0691 
0692 #ifdef HAVE_MEDIAPLAYER
0693 
0694     d->playbackWidget->keyPressEvent(event);
0695 
0696 #endif
0697 
0698     d->slideCtrlWidget->keyPressEvent(event);
0699 }
0700 
0701 void PresentationWidget::mousePressEvent(QMouseEvent* e)
0702 {
0703     if (m_endOfShow)
0704     {
0705         slotClose();
0706     }
0707 
0708     if      (e->button() == Qt::LeftButton)
0709     {
0710         d->timer->stop();
0711         d->slideCtrlWidget->setPaused(!d->sharedData->offAutoDelay);
0712         slotNext();
0713     }
0714     else if ((e->button() == Qt::RightButton) && ((d->fileIndex - 1) >= 0))
0715     {
0716         d->timer->stop();
0717         d->slideCtrlWidget->setPaused(!d->sharedData->offAutoDelay);
0718         slotPrev();
0719     }
0720 }
0721 
0722 void PresentationWidget::mouseMoveEvent(QMouseEvent* e)
0723 {
0724     setCursor(QCursor(Qt::ArrowCursor));
0725     d->mouseMoveTimer->start(1000);
0726 
0727     if (!d->slideCtrlWidget->canHide()
0728 
0729 #ifdef HAVE_MEDIAPLAYER
0730 
0731         || !d->playbackWidget->canHide()
0732 
0733 #endif
0734 
0735        )
0736     {
0737         return;
0738     }
0739 
0740     QPoint pos(e->pos());
0741 
0742     if ((pos.y() > 20)                     &&
0743         (pos.y() < (d->deskHeight - 20 - 1)))
0744     {
0745         if (!d->slideCtrlWidget->canHide()
0746 
0747 #ifdef HAVE_MEDIAPLAYER
0748 
0749             || !d->playbackWidget->canHide()
0750 
0751 #endif
0752 
0753            )
0754         {
0755             return;
0756         }
0757         else
0758         {
0759             hideOverlays();
0760         }
0761 
0762         return;
0763     }
0764 
0765     showOverlays();
0766 }
0767 
0768 void PresentationWidget::wheelEvent(QWheelEvent* e)
0769 {
0770     if (!d->sharedData->enableMouseWheel)
0771     {
0772         return;
0773     }
0774 
0775     if (m_endOfShow)
0776     {
0777         slotClose();
0778     }
0779 
0780     int delta = e->angleDelta().y();
0781 
0782     if      (delta < 0)
0783     {
0784         d->timer->stop();
0785         d->slideCtrlWidget->setPaused(true);
0786         slotNext();
0787     }
0788     else if ((delta > 0) && ((d->fileIndex - 1) >= 0))
0789     {
0790         d->timer->stop();
0791         d->slideCtrlWidget->setPaused(true);
0792         slotPrev();
0793     }
0794 }
0795 
0796 void PresentationWidget::slotMouseMoveTimeOut()
0797 {
0798     QPoint pos(QCursor::pos());
0799 
0800     if ((pos.y() < 20)                       ||
0801         (pos.y() > (d->deskHeight - 20 - 1)) ||
0802         !d->timer->isActive()                ||
0803         d->slideCtrlWidget->underMouse()
0804 
0805 #ifdef HAVE_MEDIAPLAYER
0806 
0807         || d->playbackWidget->underMouse()
0808 
0809 #endif
0810 
0811        )
0812     {
0813         return;
0814     }
0815 
0816     setCursor(QCursor(Qt::BlankCursor));
0817 }
0818 
0819 void PresentationWidget::paintEvent(QPaintEvent*)
0820 {
0821     QPainter p(this);
0822 
0823     if (m_simplyShow || m_firstPainter)
0824     {
0825         if (d->sharedData->printFileName)
0826         {
0827             printFilename();
0828         }
0829 
0830         if (d->sharedData->printProgress)
0831         {
0832             printProgress();
0833         }
0834 
0835         if (d->sharedData->printFileComments)
0836         {
0837             printComments();
0838         }
0839 
0840         double ratio   = devicePixelRatioF();
0841         QSize fullSize = QSizeF(ratio * width(), ratio * height()).toSize();
0842 
0843         QPixmap pixmap = d->currImage.scaled(fullSize, Qt::KeepAspectRatio,
0844                                                        Qt::SmoothTransformation);
0845 
0846         p.drawPixmap(0, 0, width(), height(), pixmap,
0847                      0, 0, pixmap.width(), pixmap.height());
0848 
0849         p.end();
0850 
0851         m_simplyShow = false;
0852 
0853         return;
0854     }
0855 
0856     if (m_endOfShow)
0857     {
0858         p.fillRect(0, 0, width(), height(), Qt::black);
0859 
0860         QFont fn(font());
0861         fn.setPointSize(fn.pointSize() + 10);
0862         fn.setBold(true);
0863 
0864         p.setFont(fn);
0865         p.setPen(Qt::white);
0866         p.drawText(100, 100, i18n("Slideshow Completed"));
0867         p.drawText(100, 100 + 10 + fn.pointSize(), i18n("Click to Exit..."));
0868 
0869         p.end();
0870         return;
0871     }
0872 
0873     // If execution reach this line, an effect is running
0874 
0875     p.drawPixmap(0, 0, m_buffer);
0876 }
0877 
0878 void PresentationWidget::startPainter()
0879 {
0880     m_startPainter = true;
0881     repaint();
0882 }
0883 
0884 void PresentationWidget::slotPause()
0885 {
0886     d->timer->stop();
0887     showOverlays();
0888 }
0889 
0890 void PresentationWidget::slotPlay()
0891 {
0892     hideOverlays();
0893     slotTimeOut();
0894 }
0895 
0896 void PresentationWidget::slotPrev()
0897 {
0898     loadPrevImage();
0899 
0900     if (d->currImage.isNull() || d->sharedData->urlList.isEmpty())
0901     {
0902         showEndOfShow();
0903         return;
0904     }
0905 
0906     d->effectRunning = false;
0907 
0908     showCurrentImage();
0909 }
0910 
0911 void PresentationWidget::slotNext()
0912 {
0913     loadNextImage();
0914 
0915     if (d->currImage.isNull() || d->sharedData->urlList.isEmpty())
0916     {
0917         showEndOfShow();
0918         return;
0919     }
0920 
0921     d->effectRunning = false;
0922 
0923     showCurrentImage();
0924 }
0925 
0926 void PresentationWidget::slotClose()
0927 {
0928     close();
0929 }
0930 
0931 void PresentationWidget::slotRemoveImageFromList()
0932 {
0933     QUrl url = d->imageLoader->currPath();
0934 
0935     // Delete or move to trash by url
0936 
0937     d->sharedData->iface->deleteImage(url);
0938 
0939     // Delete from list of presentation
0940 
0941     d->sharedData->urlList.removeOne(url);
0942 
0943     // Delete from list of mainpage
0944 
0945     d->sharedData->mainPage->removeImageFromList(url);
0946 }
0947 
0948 void PresentationWidget::slotVideoLoaded(bool loaded)
0949 {
0950     if (loaded)
0951     {
0952 
0953 #ifdef HAVE_MEDIAPLAYER
0954 
0955         slotPause();
0956         d->videoView->show();
0957 
0958 #endif
0959 
0960     }
0961 }
0962 
0963 void PresentationWidget::slotVideoFinished()
0964 {
0965 
0966 #ifdef HAVE_MEDIAPLAYER
0967 
0968     d->videoView->hide();
0969     slotPlay();
0970 
0971 #endif
0972 
0973 }
0974 
0975 // -- Effects rules --------------------------------------------------------------------------------------------------------
0976 
0977 void PresentationWidget::registerEffects()
0978 {
0979     d->Effects.insert(QLatin1String("None"),             &PresentationWidget::effectNone);
0980     d->Effects.insert(QLatin1String("Chess Board"),      &PresentationWidget::effectChessboard);
0981     d->Effects.insert(QLatin1String("Melt Down"),        &PresentationWidget::effectMeltdown);
0982     d->Effects.insert(QLatin1String("Sweep"),            &PresentationWidget::effectSweep);
0983     d->Effects.insert(QLatin1String("Mosaic"),           &PresentationWidget::effectMosaic);
0984     d->Effects.insert(QLatin1String("Cubism"),           &PresentationWidget::effectCubism);
0985     d->Effects.insert(QLatin1String("Growing"),          &PresentationWidget::effectGrowing);
0986     d->Effects.insert(QLatin1String("Horizontal Lines"), &PresentationWidget::effectHorizLines);
0987     d->Effects.insert(QLatin1String("Vertical Lines"),   &PresentationWidget::effectVertLines);
0988     d->Effects.insert(QLatin1String("Circle Out"),       &PresentationWidget::effectCircleOut);
0989     d->Effects.insert(QLatin1String("MultiCircle Out"),  &PresentationWidget::effectMultiCircleOut);
0990     d->Effects.insert(QLatin1String("Spiral In"),        &PresentationWidget::effectSpiralIn);
0991     d->Effects.insert(QLatin1String("Blobs"),            &PresentationWidget::effectBlobs);
0992 }
0993 
0994 QStringList PresentationWidget::effectNames()
0995 {
0996     QStringList effects;
0997 
0998     effects.append(QLatin1String("None"));
0999     effects.append(QLatin1String("Chess Board"));
1000     effects.append(QLatin1String("Melt Down"));
1001     effects.append(QLatin1String("Sweep"));
1002     effects.append(QLatin1String("Mosaic"));
1003     effects.append(QLatin1String("Cubism"));
1004     effects.append(QLatin1String("Growing"));
1005     effects.append(QLatin1String("Horizontal Lines"));
1006     effects.append(QLatin1String("Vertical Lines"));
1007     effects.append(QLatin1String("Circle Out"));
1008     effects.append(QLatin1String("MultiCircle Out"));
1009     effects.append(QLatin1String("Spiral In"));
1010     effects.append(QLatin1String("Blobs"));
1011     effects.append(QLatin1String("Random"));
1012 
1013     return effects;
1014 }
1015 
1016 QMap<QString, QString> PresentationWidget::effectNamesI18N()
1017 {
1018     QMap<QString, QString> effects;
1019 
1020     effects[QLatin1String("None")]             = i18nc("Filter Effect: No effect",        "None");
1021     effects[QLatin1String("Chess Board")]      = i18nc("Filter Effect: Chess Board",      "Chess Board");
1022     effects[QLatin1String("Melt Down")]        = i18nc("Filter Effect: Melt Down",        "Melt Down");
1023     effects[QLatin1String("Sweep")]            = i18nc("Filter Effect: Sweep",            "Sweep");
1024     effects[QLatin1String("Mosaic")]           = i18nc("Filter Effect: Mosaic",           "Mosaic");
1025     effects[QLatin1String("Cubism")]           = i18nc("Filter Effect: Cubism",           "Cubism");
1026     effects[QLatin1String("Growing")]          = i18nc("Filter Effect: Growing",          "Growing");
1027     effects[QLatin1String("Horizontal Lines")] = i18nc("Filter Effect: Horizontal Lines", "Horizontal Lines");
1028     effects[QLatin1String("Vertical Lines")]   = i18nc("Filter Effect: Vertical Lines",   "Vertical Lines");
1029     effects[QLatin1String("Circle Out")]       = i18nc("Filter Effect: Circle Out",       "Circle Out");
1030     effects[QLatin1String("MultiCircle Out")]  = i18nc("Filter Effect: Multi-Circle Out", "Multi-Circle Out");
1031     effects[QLatin1String("Spiral In")]        = i18nc("Filter Effect: Spiral In",        "Spiral In");
1032     effects[QLatin1String("Blobs")]            = i18nc("Filter Effect: Blobs",            "Blobs");
1033     effects[QLatin1String("Random")]           = i18nc("Filter Effect: Random effect",    "Random");
1034 
1035     return effects;
1036 }
1037 
1038 void PresentationWidget::slotTimeOut()
1039 {
1040     if (!d->effect)
1041     {
1042         return;                     // No effect -> bye !
1043     }
1044 
1045     int tmout = -1;
1046 
1047     if (d->effectRunning)           // Effect under progress ?
1048     {
1049         tmout = (this->*d->effect)(false);
1050     }
1051     else
1052     {
1053         loadNextImage();
1054 
1055         if (d->sharedData->offAutoDelay)
1056         {
1057             showCurrentImage();
1058         }
1059         else
1060         {
1061             if (d->currImage.isNull() || d->sharedData->urlList.isEmpty())   // End of slideshow ?
1062             {
1063                 showEndOfShow();
1064                 return;
1065             }
1066 
1067             if (d->sharedData->effectName == QLatin1String("Random")) // Take a random effect.
1068             {
1069                 d->effect = getRandomEffect();
1070 
1071                 if (!d->effect)
1072                 {
1073                     return;
1074                 }
1075             }
1076 
1077             d->effectRunning = true;
1078 
1079             tmout = (this->*d->effect)(true);
1080         }
1081     }
1082 
1083     if (tmout <= 0)                 // Effect finished -> delay.
1084     {
1085         tmout            = d->sharedData->delay;
1086         d->effectRunning = false;
1087     }
1088 
1089     if (d->sharedData->offAutoDelay)
1090     {
1091         d->timer->stop();
1092     }
1093     else
1094     {
1095         d->timer->setSingleShot(true);
1096         d->timer->start(tmout);
1097     }
1098 }
1099 
1100 void PresentationWidget::showCurrentImage()
1101 {
1102     if (d->currImage.isNull())
1103     {
1104         return;
1105     }
1106 
1107     m_simplyShow = true;
1108 
1109     repaint();
1110 }
1111 
1112 PresentationWidget::EffectMethod PresentationWidget::getRandomEffect()
1113 {
1114     QStringList effs = d->Effects.keys();
1115     effs.removeAt(effs.indexOf(QLatin1String("None")));
1116 
1117     int i            = randomGenerator->bounded(effs.count());
1118     QString key      = effs[i];
1119     d->effectName    = key;
1120 
1121     return d->Effects[key];
1122 }
1123 
1124 int PresentationWidget::effectNone(bool /* aInit */)
1125 {
1126     showCurrentImage();
1127 
1128     return -1;
1129 }
1130 
1131 int PresentationWidget::effectChessboard(bool aInit)
1132 {
1133     if (aInit)
1134     {
1135         d->w    = width();
1136         d->h    = height();
1137         d->dx   = 8;                             // width of one tile
1138         d->dy   = 8;                             // height of one tile
1139         d->j    = (d->w + d->dx - 1) / d->dx;    // number of tiles
1140         d->x    = d->j * d->dx;                  // shrinking x-offset from screen border
1141         d->ix   = 0;                             // growing x-offset from screen border
1142         d->iy   = 0;                             // 0 or d->dy for growing tiling effect
1143         d->y    = (d->j & 1) ? 0 : d->dy;        // 0 or d->dy for shrinking tiling effect
1144         d->wait = 800 / d->j;                    // timeout between effects
1145     }
1146 
1147     if (d->ix >= d->w)
1148     {
1149         showCurrentImage();
1150         return -1;
1151     }
1152 
1153     d->ix += d->dx;
1154     d->x  -= d->dx;
1155     d->iy  = d->iy ? 0 : d->dy;
1156     d->y   = d->y  ? 0 : d->dy;
1157 
1158     QPainter bufferPainter(&m_buffer);
1159     QBrush brush = QBrush(d->currImage);
1160 
1161     for (int y = 0 ; y < d->w ; y += (d->dy << 1))
1162     {
1163         bufferPainter.fillRect(d->ix, y + d->iy, d->dx, d->dy, brush);
1164         bufferPainter.fillRect(d->x,  y + d->y,  d->dx, d->dy, brush);
1165     }
1166 
1167     repaint();
1168 
1169     return d->wait;
1170 }
1171 
1172 int PresentationWidget::effectMeltdown(bool aInit)
1173 {
1174     int i;
1175 
1176     if (aInit)
1177     {
1178         delete [] d->intArray;
1179         d->w        = width();
1180         d->h        = height();
1181         d->dx       = 4;
1182         d->dy       = 16;
1183         d->ix       = d->w / d->dx;
1184         d->intArray = new int[d->ix];
1185 
1186         for (i = d->ix - 1 ; i >= 0 ; --i)
1187         {
1188             d->intArray[i] = 0;
1189         }
1190     }
1191 
1192     d->pdone = true;
1193 
1194     int y, x;
1195     QPainter bufferPainter(&m_buffer);
1196 
1197     for (i = 0, x = 0 ; i < d->ix ; ++i, x += d->dx)
1198     {
1199         y = d->intArray[i];
1200 
1201         if (y >= d->h)
1202         {
1203             continue;
1204         }
1205 
1206         d->pdone = false;
1207 
1208         if (randomGenerator->bounded(16U) < 6)
1209         {
1210             continue;
1211         }
1212 /*
1213         bufferPainter.drawPixmap(x, y + d->dy, m_buffer, x, y, d->dx, d->h - y - d->dy);
1214 */
1215         bufferPainter.drawPixmap(x, y, d->currImage, x, y, d->dx, d->dy);
1216 
1217         d->intArray[i] += d->dy;
1218     }
1219 
1220     bufferPainter.end();
1221 
1222     repaint();
1223 
1224     if (d->pdone)
1225     {
1226         delete [] d->intArray;
1227         d->intArray = nullptr;
1228         showCurrentImage();
1229 
1230         return -1;
1231     }
1232 
1233     return 15;
1234 }
1235 
1236 int PresentationWidget::effectSweep(bool aInit)
1237 {
1238     if (aInit)
1239     {
1240         // subtype: 0=sweep right to left, 1=sweep left to right
1241         //          2=sweep bottom to top, 3=sweep top to bottom
1242 
1243         d->subType = randomGenerator->bounded(4);
1244         d->w       = width();
1245         d->h       = height();
1246         d->dx      = ((d->subType == 1) ? 16 : -16);
1247         d->dy      = ((d->subType == 3) ? 16 : -16);
1248         d->x       = ((d->subType == 1) ? 0  : d->w);
1249         d->y       = ((d->subType == 3) ? 0  : d->h);
1250     }
1251 
1252     if ((d->subType == 0) || (d->subType == 1))
1253     {
1254         // horizontal sweep
1255 
1256         if (((d->subType == 0) && (d->x < -64)) || ((d->subType == 1) && (d->x > d->w + 64)))
1257         {
1258             showCurrentImage();
1259             return -1;
1260         }
1261 
1262         int w;
1263         int x;
1264         int i;
1265 
1266         for (w = 2, i = 4, x = d->x ; i > 0 ; --i, w <<= 1, x -= d->dx)
1267         {
1268             m_px  = x;
1269             m_py  = 0;
1270             m_psx = w;
1271             m_psy = d->h;
1272 
1273             QPainter bufferPainter(&m_buffer);
1274             bufferPainter.fillRect(m_px, m_py, m_psx, m_psy, QBrush(d->currImage));
1275             bufferPainter.end();
1276 
1277             repaint();
1278         }
1279 
1280         d->x += d->dx;
1281     }
1282     else
1283     {
1284         // vertical sweep
1285 
1286         if (((d->subType == 2) && (d->y < -64)) || ((d->subType == 3) && (d->y > d->h + 64)))
1287         {
1288             showCurrentImage();
1289             return -1;
1290         }
1291 
1292         int h;
1293         int y;
1294         int i;
1295 
1296         for (h = 2, i = 4, y = d->y ; i > 0 ; --i, h <<= 1, y -= d->dy)
1297         {
1298             m_px  = 0;
1299             m_py  = y;
1300             m_psx = d->w;
1301             m_psy = h;
1302 
1303             QPainter bufferPainter(&m_buffer);
1304             bufferPainter.fillRect(m_px, m_py, m_psx, m_psy, QBrush(d->currImage));
1305             bufferPainter.end();
1306 
1307             repaint();
1308         }
1309 
1310         d->y += d->dy;
1311     }
1312 
1313     return 20;
1314 }
1315 
1316 int PresentationWidget::effectMosaic(bool aInit)
1317 {
1318     int dim    = 10;         // Size of a cell (dim x dim)
1319     int margin = dim + (int)(dim / 4);
1320 
1321     if (aInit)
1322     {
1323         d->i           = 30; // giri totaly
1324         d->pixelMatrix = new bool*[width()];
1325 
1326         for (int x = 0 ; x < width() ; ++x)
1327         {
1328             d->pixelMatrix[x] = new bool[height()];
1329 
1330             for (int y = 0 ; y < height() ; ++y)
1331             {
1332                 d->pixelMatrix[x][y] = false;
1333             }
1334         }
1335     }
1336 
1337     if (d->i <= 0)
1338     {
1339         showCurrentImage();
1340         return -1;
1341     }
1342 
1343     int w = width();
1344     int h = height();
1345 
1346     QPainter bufferPainter(&m_buffer);
1347 
1348     for (int x = 0 ; x < w ; x += randomGenerator->bounded(margin, margin+dim))
1349     {
1350         for (int y = 0 ; y < h ; y += randomGenerator->bounded(margin, margin+dim))
1351         {
1352             if (d->pixelMatrix[x][y] == true)
1353             {
1354                 if (y != 0)
1355                 {
1356                     y--;
1357                 }
1358 
1359                 continue;
1360             }
1361 
1362             bufferPainter.fillRect(x, y, dim, dim, QBrush(d->currImage));
1363 
1364             for (int i = 0 ; i < dim && (x + i) < w ; ++i)
1365             {
1366                 for (int j = 0 ; j < dim && (y + j) < h ; ++j)
1367                 {
1368                     d->pixelMatrix[x+i][y+j] = true;
1369                 }
1370             }
1371         }
1372     }
1373 
1374     bufferPainter.end();
1375     repaint();
1376     d->i--;
1377 
1378     return 20;
1379 }
1380 
1381 int PresentationWidget::effectCubism(bool aInit)
1382 {
1383     if (aInit)
1384     {
1385         d->alpha = M_PI * 2;
1386         d->w     = width();
1387         d->h     = height();
1388         d->i     = 150;
1389     }
1390 
1391     if (d->i <= 0)
1392     {
1393         showCurrentImage();
1394         return -1;
1395     }
1396 
1397     QPainterPath painterPath;
1398     QPainter bufferPainter(&m_buffer);
1399 
1400     d->x   = randomGenerator->bounded(d->w);
1401     d->y   = randomGenerator->bounded(d->h);
1402     int r  = randomGenerator->bounded(100, 200);
1403     m_px   = d->x - r;
1404     m_py   = d->y - r;
1405     m_psx  = r;
1406     m_psy  = r;
1407 
1408     QTransform transform;
1409     transform.rotate(randomGenerator->bounded(-10, 10));
1410     QRect rect(m_px, m_py, m_psx, m_psy);
1411     bufferPainter.setTransform(transform);
1412     bufferPainter.fillRect(rect, QBrush(d->currImage));
1413     bufferPainter.end();
1414     repaint();
1415 
1416     d->i--;
1417 
1418     return 10;
1419 }
1420 
1421 int PresentationWidget::effectRandom(bool /*aInit*/)
1422 {
1423     d->fileIndex--;
1424 
1425     return -1;
1426 }
1427 
1428 int PresentationWidget::effectGrowing(bool aInit)
1429 {
1430     if (aInit)
1431     {
1432         d->w  = width();
1433         d->h  = height();
1434         d->x  = d->w >> 1;
1435         d->y  = d->h >> 1;
1436         d->i  = 0;
1437         d->fx = d->x / 100.0;
1438         d->fy = d->y / 100.0;
1439     }
1440 
1441     d->x = (d->w >> 1) - (int)(d->i * d->fx);
1442     d->y = (d->h >> 1) - (int)(d->i * d->fy);
1443     d->i++;
1444 
1445     if ((d->x < 0) || (d->y < 0))
1446     {
1447         showCurrentImage();
1448 
1449         return -1;
1450     }
1451 
1452     m_px  = d->x;
1453     m_py  = d->y;
1454     m_psx = d->w - (d->x << 1);
1455     m_psy = d->h - (d->y << 1);
1456 
1457     QPainter bufferPainter(&m_buffer);
1458     bufferPainter.fillRect(m_px, m_py, m_psx, m_psy, QBrush(d->currImage));
1459     bufferPainter.end();
1460     repaint();
1461 
1462     return 20;
1463 }
1464 
1465 int PresentationWidget::effectHorizLines(bool aInit)
1466 {
1467     static const int iyPos[] = { 0, 4, 2, 6, 1, 5, 3, 7, -1 };
1468 
1469     if (aInit)
1470     {
1471         d->w = width();
1472         d->h = height();
1473         d->i = 0;
1474     }
1475 
1476     if (iyPos[d->i] < 0)
1477     {
1478         return -1;
1479     }
1480 
1481     int iPos;
1482     int until    = d->h;
1483 
1484     QPainter bufferPainter(&m_buffer);
1485     QBrush brush = QBrush(d->currImage);
1486 
1487     for (iPos = iyPos[d->i] ; iPos < until ; iPos += 8)
1488     {
1489         bufferPainter.fillRect(0, iPos, d->w, 1, brush);
1490     }
1491 
1492     bufferPainter.end();
1493     repaint();
1494 
1495     d->i++;
1496 
1497     if (iyPos[d->i] >= 0)
1498     {
1499         return 160;
1500     }
1501 
1502     showCurrentImage();
1503 
1504     return -1;
1505 }
1506 
1507 int PresentationWidget::effectVertLines(bool aInit)
1508 {
1509     static const int ixPos[] = { 0, 4, 2, 6, 1, 5, 3, 7, -1 };
1510 
1511     if (aInit)
1512     {
1513         d->w = width();
1514         d->h = height();
1515         d->i = 0;
1516     }
1517 
1518     if (ixPos[d->i] < 0)
1519     {
1520         return -1;
1521     }
1522 
1523     int iPos;
1524     int until = d->w;
1525 
1526     QPainter bufferPainter(&m_buffer);
1527     QBrush brush = QBrush(d->currImage);
1528 
1529     for (iPos = ixPos[d->i] ; iPos < until ; iPos += 8)
1530     {
1531         bufferPainter.fillRect(iPos, 0, 1, d->h, brush);
1532     }
1533 
1534     bufferPainter.end();
1535     repaint();
1536 
1537     d->i++;
1538 
1539     if (ixPos[d->i] >= 0)
1540     {
1541         return 160;
1542     }
1543 
1544     showCurrentImage();
1545 
1546     return -1;
1547 }
1548 
1549 int PresentationWidget::effectMultiCircleOut(bool aInit)
1550 {
1551     int x, y, i;
1552     double alpha;
1553 
1554     if (aInit)
1555     {
1556         startPainter();
1557         d->w     = width();
1558         d->h     = height();
1559         d->x     = d->w;
1560         d->y     = d->h >> 1;
1561         d->pa.setPoint(0, d->w >> 1, d->h >> 1);
1562         d->pa.setPoint(3, d->w >> 1, d->h >> 1);
1563         d->fy    = sqrt((double)d->w * d->w + d->h * d->h) / 2;
1564         d->i     = randomGenerator->bounded(2, 17);
1565         d->fd    = M_PI * 2 / d->i;
1566         d->alpha = d->fd;
1567         d->wait  = 10 * d->i;
1568         d->fx    = M_PI / 32;  // divisor must be powers of 8
1569     }
1570 
1571     if (d->alpha < 0)
1572     {
1573         showCurrentImage();
1574 
1575         return -1;
1576     }
1577 
1578     for (alpha = d->alpha, i = d->i ; i >= 0 ; --i, alpha += d->fd)
1579     {
1580         x    = (d->w >> 1) + (int)(d->fy * cos(-alpha));
1581         y    = (d->h >> 1) + (int)(d->fy * sin(-alpha));
1582         d->x = (d->w >> 1) + (int)(d->fy * cos(-alpha + d->fx));
1583         d->y = (d->h >> 1) + (int)(d->fy * sin(-alpha + d->fx));
1584 
1585         d->pa.setPoint(1, x, y);
1586         d->pa.setPoint(2, d->x, d->y);
1587 
1588         QPainterPath painterPath;
1589         painterPath.addPolygon(QPolygon(d->pa));
1590 
1591         QPainter bufferPainter(&m_buffer);
1592         bufferPainter.fillPath(painterPath, QBrush(d->currImage));
1593         bufferPainter.end();
1594 
1595         repaint();
1596     }
1597 
1598     d->alpha -= d->fx;
1599 
1600     return d->wait;
1601 }
1602 
1603 int PresentationWidget::effectSpiralIn(bool aInit)
1604 {
1605     if (aInit)
1606     {
1607         update();
1608         d->w  = width();
1609         d->h  = height();
1610         d->ix = d->w / 8;
1611         d->iy = d->h / 8;
1612         d->x0 = 0;
1613         d->x1 = d->w - d->ix;
1614         d->y0 = d->iy;
1615         d->y1 = d->h - d->iy;
1616         d->dx = d->ix;
1617         d->dy = 0;
1618         d->i  = 0;
1619         d->j  = 16 * 16;
1620         d->x  = 0;
1621         d->y  = 0;
1622     }
1623 
1624     if ((d->i == 0) && (d->x0 >= d->x1))
1625     {
1626         showCurrentImage();
1627 
1628         return -1;
1629     }
1630 
1631     if      ((d->i == 0) && (d->x >= d->x1))      // switch to: down on right side
1632     {
1633         d->i   = 1;
1634         d->dx  = 0;
1635         d->dy  = d->iy;
1636         d->x1 -= d->ix;
1637     }
1638     else if ((d->i == 1) && (d->y >= d->y1)) // switch to: right to left on bottom side
1639     {
1640         d->i   = 2;
1641         d->dx  = -d->ix;
1642         d->dy  = 0;
1643         d->y1 -= d->iy;
1644     }
1645     else if ((d->i == 2) && (d->x <= d->x0)) // switch to: up on left side
1646     {
1647         d->i   = 3;
1648         d->dx  = 0;
1649         d->dy  = -d->iy;
1650         d->x0 += d->ix;
1651     }
1652     else if ((d->i == 3) && (d->y <= d->y0)) // switch to: left to right on top side
1653     {
1654         d->i   = 0;
1655         d->dx  = d->ix;
1656         d->dy  = 0;
1657         d->y0 += d->iy;
1658     }
1659 
1660     m_px  = d->x;
1661     m_py  = d->y;
1662     m_psx = d->ix;
1663     m_psy = d->iy;
1664 
1665     QPainter bufferPainter(&m_buffer);
1666     bufferPainter.fillRect(m_px, m_py, m_psx, m_psy, QBrush(d->currImage));
1667     bufferPainter.end();
1668     repaint();
1669 
1670     d->x += d->dx;
1671     d->y += d->dy;
1672     d->j--;
1673 
1674     return 8;
1675 }
1676 
1677 int PresentationWidget::effectCircleOut(bool aInit)
1678 {
1679     int x, y;
1680 
1681     if (aInit)
1682     {
1683         startPainter();
1684         d->w     = width();
1685         d->h     = height();
1686         d->x     = d->w;
1687         d->y     = d->h >> 1;
1688         d->alpha = 2 * M_PI;
1689         d->pa.setPoint(0, d->w >> 1, d->h >> 1);
1690         d->pa.setPoint(3, d->w >> 1, d->h >> 1);
1691         d->fx    = M_PI / 16;                       // divisor must be powers of 8
1692         d->fy    = sqrt((double)d->w * d->w + d->h * d->h) / 2;
1693     }
1694 
1695     if (d->alpha < 0)
1696     {
1697         showCurrentImage();
1698 
1699         return -1;
1700     }
1701 
1702     x         = d->x;
1703     y         = d->y;
1704     d->x      = (d->w >> 1) + (int)(d->fy * cos(d->alpha));
1705     d->y      = (d->h >> 1) + (int)(d->fy * sin(d->alpha));
1706     d->alpha -= d->fx;
1707 
1708     d->pa.setPoint(1, x, y);
1709     d->pa.setPoint(2, d->x, d->y);
1710 
1711     QPainterPath painterPath;
1712     painterPath.addPolygon(QPolygon(d->pa));
1713     QPainter bufferPainter(&m_buffer);
1714     bufferPainter.fillPath(painterPath, QBrush(d->currImage));
1715     bufferPainter.end();
1716     repaint();
1717 
1718     return 20;
1719 }
1720 
1721 int PresentationWidget::effectBlobs(bool aInit)
1722 {
1723     int r;
1724 
1725     if (aInit)
1726     {
1727         d->alpha = M_PI * 2;
1728         d->w     = width();
1729         d->h     = height();
1730         d->i     = 150;
1731     }
1732 
1733     if (d->i <= 0)
1734     {
1735         showCurrentImage();
1736 
1737         return -1;
1738     }
1739 
1740     d->x   = randomGenerator->bounded(d->w);
1741     d->y   = randomGenerator->bounded(d->h);
1742     r      = randomGenerator->bounded(50, 250);
1743     m_px   = d->x - r;
1744     m_py   = d->y - r;
1745     m_psx  = r;
1746     m_psy  = r;
1747 
1748     QPainterPath painterPath;
1749     painterPath.addEllipse(m_px, m_py, m_psx, m_psy);
1750     QPainter bufferPainter(&m_buffer);
1751     bufferPainter.fillPath(painterPath, QBrush(d->currImage));
1752     bufferPainter.end();
1753     repaint();
1754 
1755     d->i--;
1756 
1757     return 10;
1758 }
1759 
1760 } // namespace DigikamGenericPresentationPlugin
1761 
1762 #include "moc_presentationwidget.cpp"