File indexing completed on 2025-01-19 03:53:52

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2003-02-10
0007  * Description : a widget to display splash with progress bar
0008  *
0009  * SPDX-FileCopyrightText: 2003-2005 by Renchi Raju <renchi dot raju at gmail dot com>
0010  * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "dsplashscreen.h"
0017 
0018 // Qt includes
0019 
0020 #include <QApplication>
0021 #include <QTimer>
0022 #include <QFont>
0023 #include <QString>
0024 #include <QColor>
0025 #include <QTime>
0026 #include <QTextDocument>
0027 #include <QFontDatabase>
0028 #include <QStandardPaths>
0029 
0030 // Local includes
0031 
0032 #include "digikam_debug.h"
0033 #include "daboutdata.h"
0034 #include "digikam_version.h"
0035 
0036 namespace Digikam
0037 {
0038 
0039 class Q_DECL_HIDDEN DSplashScreen::Private
0040 {
0041 
0042 public:
0043 
0044     explicit Private()
0045       : state               (0),
0046         progressBarSize     (3),
0047         timer               (nullptr),
0048         version             (QLatin1String(digikam_version_short)),
0049         messageColor        (Qt::white),
0050         versionColor        (Qt::white),
0051         lastStateUpdateTime (QTime::currentTime())
0052     {
0053     }
0054 
0055     int     state;
0056     int     progressBarSize;
0057 
0058     QTimer* timer;
0059 
0060     QString message;
0061     QString version;
0062 
0063     QColor  messageColor;
0064     QColor  versionColor;
0065 
0066     QTime   lastStateUpdateTime;
0067 };
0068 
0069 DSplashScreen::DSplashScreen()
0070     : QSplashScreen(QPixmap()),
0071       d            (new Private)
0072 {
0073     QPixmap splash;
0074 
0075     if (QApplication::applicationName() == QLatin1String("digikam"))
0076     {
0077         splash = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/splash-digikam.png"));
0078     }
0079     else
0080     {
0081         splash = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("showfoto/data/splash-showfoto.png"));
0082     }
0083 
0084     if (!QString::fromUtf8(digikam_version_suffix).isEmpty())
0085     {
0086         QPainter p(&splash);
0087         p.drawPixmap(380, 27, QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/logo-beta.png")));
0088         p.end();
0089     }
0090 
0091     setPixmap(splash);
0092 
0093     d->timer = new QTimer(this);
0094 
0095     connect(d->timer, SIGNAL(timeout()),
0096             this, SLOT(slotAnimate()));
0097 
0098     d->timer->start(150);
0099 }
0100 
0101 DSplashScreen::~DSplashScreen()
0102 {
0103     d->timer->stop();
0104 
0105     delete d;
0106 }
0107 
0108 void DSplashScreen::setColor(const QColor& color)
0109 {
0110     d->messageColor = color;
0111 }
0112 
0113 void DSplashScreen::setMessage(const QString& message)
0114 {
0115     d->message = message;
0116     showMessage(d->message,
0117                 (layoutDirection() == Qt::RightToLeft) ? Qt::AlignLeft : Qt::AlignRight,
0118                 d->messageColor);
0119     slotAnimate();
0120     qApp->processEvents();
0121 }
0122 
0123 void DSplashScreen::slotAnimate()
0124 {
0125     QTime currentTime = QTime::currentTime();
0126 
0127     if (d->lastStateUpdateTime.msecsTo(currentTime) > 100)
0128     {
0129         d->state               = ((d->state + 1) % (2 * d->progressBarSize - 1));
0130         d->lastStateUpdateTime = currentTime;
0131     }
0132 
0133     update();
0134 }
0135 
0136 void DSplashScreen::drawContents(QPainter* p)
0137 {
0138     int    position = 0;
0139     QColor basecolor(155, 192, 231);
0140 
0141     // -- Draw background circles ------------------------------------
0142 
0143     QPainter::RenderHints hints = p->renderHints();
0144     p->setRenderHints(QPainter::Antialiasing);
0145     p->setPen(Qt::NoPen);
0146     p->setBrush(QColor(225, 234, 231));
0147     p->drawEllipse(21, 6, 9, 9);
0148     p->drawEllipse(32, 6, 9, 9);
0149     p->drawEllipse(43, 6, 9, 9);
0150     p->setRenderHints(hints);
0151 
0152     // -- Draw animated circles --------------------------------------
0153 
0154     // Increments are chosen to get close to background's color
0155     // (didn't work well with QColor::light function)
0156 
0157     for (int i = 0 ; i < d->progressBarSize ; ++i)
0158     {
0159         position = (d->state + i) % (2 * d->progressBarSize - 1);
0160 
0161         if (position < 3)
0162         {
0163             p->setBrush(QColor(basecolor.red()   - 18*i,
0164                                basecolor.green() - 28*i,
0165                                basecolor.blue()  - 10*i));
0166 
0167             p->drawEllipse(21 + position*11, 6, 9, 9);
0168         }
0169     }
0170 
0171     // We use a device dependent font with a fixed size.
0172 
0173     QFont fnt(QFontDatabase::systemFont(QFontDatabase::GeneralFont));
0174     fnt.setPixelSize(10);
0175     fnt.setBold(false);
0176     p->setFont(fnt);
0177 
0178     QRect r = rect();
0179     r.setCoords(r.x() + 60, r.y() + 4, r.width() - 10, r.height() - 10);
0180 
0181     // -- Draw message --------------------------------------------------------
0182 
0183     // Message is draw at given position, limited to 49 chars
0184     // If message is too long, string is truncated
0185 
0186     if (d->message.length() > 50)
0187     {
0188         d->message.truncate(49);
0189     }
0190 
0191     p->setPen(d->messageColor);
0192     p->drawText(r, d->message);
0193 
0194     // -- Draw version string -------------------------------------------------
0195 
0196     QFontMetrics fontMt(fnt);
0197     QRect r2 = fontMt.boundingRect(rect(), 0, d->version);
0198     r2.moveTopLeft(QPoint(width()-r2.width()-10, r.y()));
0199     p->setPen(d->versionColor);
0200     p->drawText(r2, d->version);
0201 
0202     // -- Draw slogan and family ----------------------------------------------
0203 
0204     // NOTE: splashscreen size is 469*288 pixels
0205 
0206     r = rect();
0207     r.setCoords(r.x() + 190, r.y() + 215, r.x() + 462, r.y() + 315);
0208     p->translate(r.x(), r.y());
0209     QTextDocument slogan;
0210     slogan.setDefaultTextOption(QTextOption(Qt::AlignVCenter));
0211     slogan.setHtml(DAboutData::digiKamSloganFormated());
0212     slogan.setPageSize(r.size());
0213     slogan.setDefaultFont(fnt);
0214     slogan.drawContents(p, QRect(0, 0, r.width(), r.height()));
0215 }
0216 
0217 } // namespace Digikam
0218 
0219 #include "moc_dsplashscreen.cpp"