kis_splash_screen.cpp 9.18 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 *  Copyright (c) 2014 Boudewijn Rempt <boud@valdyas.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
#include "kis_splash_screen.h"

20 21 22
#include <QApplication>
#include <QDesktopWidget>
#include <QPixmap>
23
#include <QPainter>
24
#include <QCheckBox>
25
#include <kis_debug.h>
26
#include <QFile>
27 28
#include <QScreen>
#include <QWindow>
29

30 31
#include <KisPart.h>
#include <KisApplication.h>
32

33
#include <kis_icon.h>
34

35
#include <klocalizedstring.h>
36
#include <kconfig.h>
Boudewijn Rempt's avatar
Boudewijn Rempt committed
37
#include <ksharedconfig.h>
38
#include <kconfiggroup.h>
39
#include <QIcon>
40

41
KisSplashScreen::KisSplashScreen(const QString &version, const QPixmap &pixmap, const QPixmap &pixmap_x2, bool themed, QWidget *parent, Qt::WindowFlags f)
42 43 44 45 46
    : QWidget(parent, Qt::SplashScreen | Qt::FramelessWindowHint
#ifdef Q_OS_LINUX
              | Qt::WindowStaysOnTopHint
#endif
              | f),
47
      m_themed(themed)
48
{
49

50
    setupUi(this);
51
    setWindowIcon(KisIconUtils::loadIcon("krita"));
52

53 54
    QImage img;

55
    if (devicePixelRatioF() > 1.01) {
56
        img = pixmap_x2.toImage();
57 58 59 60 61 62 63
        img.setDevicePixelRatio(devicePixelRatioF());

        // actual size : image size (x1)
        m_scaleFactor = 2 / devicePixelRatioF();
    } else {
        img = pixmap.toImage();
        m_scaleFactor = 1;
64 65
    }

66 67 68 69 70
    setFixedWidth(pixmap.width() * m_scaleFactor);
    setFixedHeight(pixmap.height() * m_scaleFactor);
    lblSplash->setFixedWidth(pixmap.width() * m_scaleFactor);
    lblSplash->setFixedHeight(pixmap.height() * m_scaleFactor);

71
    QFont font = this->font();
72
    font.setPointSize(11);
73 74 75 76 77 78 79 80 81
    font.setBold(true);
    QFontMetrics metrics(font);

    QPainter p(&img);
    p.setFont(font);
    p.setRenderHint(QPainter::Antialiasing);

    // positioning of the text over the image (version)
    // also see setLoadingText() for positiong (loading progress text)
82 83
    qreal leftEdge = 475 * m_scaleFactor - metrics.width(version);
    qreal topEdge = 58 * m_scaleFactor + metrics.ascent();
84 85 86 87

    //draw shadow
    QPen pen(QColor(0, 0, 0, 80));
    p.setPen(pen);
88
    p.drawText(QPointF(leftEdge+1, topEdge+1), version);
89 90
    //draw main text
    p.setPen(QPen(QColor(255, 255, 255, 255)));
91
    p.drawText(QPointF(leftEdge, topEdge), version);
92 93 94 95 96 97 98
    p.end();


    //get this to have the loading text painted on later.
    m_splashImage = img;
    m_textTop = topEdge+metrics.height();

99
    // Maintain the aspect ratio on high DPI screens when scaling
100
    lblSplash->setPixmap(QPixmap::fromImage(img));
101

102 103 104 105 106
    bnClose->hide();
    connect(bnClose, SIGNAL(clicked()), this, SLOT(close()));
    chkShowAtStartup->hide();
    connect(chkShowAtStartup, SIGNAL(toggled(bool)), this, SLOT(toggleShowAtStartup(bool)));

107
    KConfigGroup cfg( KSharedConfig::openConfig(), "SplashScreen");
108 109 110
    bool hideSplash = cfg.readEntry("HideSplashAfterStartup", false);
    chkShowAtStartup->setChecked(hideSplash);

111 112
    connect(lblRecent, SIGNAL(linkActivated(QString)), SLOT(linkClicked(QString)));
    connect(&m_timer, SIGNAL(timeout()), SLOT(raise()));
113

114
    // hide these labels by default
115 116
    displayLinks(false);
    displayRecentFiles(false);
117

118 119 120 121 122 123 124 125 126 127 128 129 130 131
    m_timer.setSingleShot(true);
    m_timer.start(10);
}

void KisSplashScreen::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    updateText();
}

void KisSplashScreen::updateText()
{
    QString color = colorString();

132
    KConfigGroup cfg2( KSharedConfig::openConfig(), "RecentFiles");
133 134 135 136 137
    int i = 1;

    QString recent = i18n("<html>"
                          "<head/>"
                          "<body>"
138
                          "<p><b><span style=\" color:%1;\">Recent Files</span></b></p>", color);
139 140 141 142

    QString path;
    QStringList recentfiles;

143 144
    QFontMetrics metrics(lblRecent->font());

145 146 147 148
    do {
        path = cfg2.readPathEntry(QString("File%1").arg(i), QString());
        if (!path.isEmpty()) {
            QString name = cfg2.readPathEntry(QString("Name%1").arg(i), QString());
149
            QUrl url(path);
150
            if (name.isEmpty()) {
151
                name = url.fileName();
152 153 154
            }

            name = metrics.elidedText(name, Qt::ElideMiddle, lblRecent->width());
155 156

            if (!url.isLocalFile() || QFile::exists(url.toLocalFile())) {
157
                recentfiles.insert(0, QString("<p><a href=\"%1\"><span style=\"color:%3;\">%2</span></a></p>").arg(path).arg(name).arg(color));
158 159 160 161 162 163 164 165
            }
        }

        i++;
    } while (!path.isEmpty() || i <= 8);

    recent += recentfiles.join("\n");
    recent += "</body>"
166
        "</html>";
167
    lblRecent->setText(recent);
168 169
}

170
void KisSplashScreen::displayLinks(bool show) {
171

172 173 174 175 176 177 178 179 180
    if (show) {
        QString color = colorString();
        lblLinks->setTextFormat(Qt::RichText);
        lblLinks->setText(i18n("<html>"
                               "<head/>"
                               "<body>"
                               "<p><span style=\" color:%1;\"><b>Links</b></span></p>"

                               "<p><a href=\"https://krita.org/support-us/\"><span style=\" text-decoration: underline; color:%1;\">Support Krita</span></a></p>"
181

182
                               "<p><a href=\"https://docs.krita.org/en/user_manual/getting_started.html\"><span style=\" text-decoration: underline; color:%1;\">Getting Started</span></a></p>"
183 184 185
                               "<p><a href=\"https://docs.krita.org/\"><span style=\" text-decoration: underline; color:%1;\">Manual</span></a></p>"
                               "<p><a href=\"https://krita.org/\"><span style=\" text-decoration: underline; color:%1;\">Krita Website</span></a></p>"
                               "<p><a href=\"https://forum.kde.org/viewforum.php?f=136\"><span style=\" text-decoration: underline; color:%1;\">User Community</span></a></p>"
186

187
                               "<p><a href=\"https://phabricator.kde.org/source/krita/\"><span style=\" text-decoration: underline; color:%1;\">Source Code</span></a></p>"
188

189 190
                               "</body>"
                               "</html>", color));
191

192 193 194 195 196 197 198 199
        filesLayout->setContentsMargins(10,10,10,10);
        actionControlsLayout->setContentsMargins(5,5,5,5);

    } else {
        // eliminating margins here allows for the splash screen image to take the entire area with nothing underneath
        filesLayout->setContentsMargins(0,0,0,0);
        actionControlsLayout->setContentsMargins(0,0,0,0);
    }
200

201
    lblLinks->setVisible(show);
202 203 204 205 206

    updateText();
}


207 208 209 210 211 212 213 214
void KisSplashScreen::displayRecentFiles(bool show) {
    lblRecent->setVisible(show);
    line->setVisible(show);
}

void KisSplashScreen::setLoadingText(QString text)
{
    QFont font = this->font();
215
    font.setPointSize(10);
216 217 218 219 220 221 222 223 224
    font.setItalic(true);

    QImage img = m_splashImage;
    QPainter p(&img);
    QFontMetrics metrics(font);
    p.setFont(font);
    p.setRenderHint(QPainter::Antialiasing);

    // position text for loading text
225 226
    qreal leftEdge = 475 *  m_scaleFactor - metrics.width(text);
    qreal topEdge = m_textTop;
227 228 229 230

    //draw shadow
    QPen pen(QColor(0, 0, 0, 80));
    p.setPen(pen);
231
    p.drawText(QPointF(leftEdge+1, topEdge+1), text);
232 233
    //draw main text
    p.setPen(QPen(QColor(255, 255, 255, 255)));
234
    p.drawText(QPointF(leftEdge, topEdge), text);
235 236
    p.end();
    lblSplash->setPixmap(QPixmap::fromImage(img));
237 238 239 240
}



241 242 243 244 245 246 247 248
QString KisSplashScreen::colorString() const
{
    QString color = "#FFFFFF";
    if (m_themed && qApp->palette().background().color().value() > 100) {
        color = "#000000";
    }

    return color;
249 250 251 252 253 254
}


void KisSplashScreen::repaint()
{
    QWidget::repaint();
255
    qApp->sendPostedEvents();
256 257 258 259 260 261
}

void KisSplashScreen::show()
{
    QRect r(QPoint(), sizeHint());
    resize(r.size());
262 263 264 265 266 267 268 269 270 271 272
    if (!this->parentWidget()) {
        this->winId(); // Force creation of native window
        if (this->windowHandle()) {
            // At least on Windows, the window may be created on a non-primary
            // screen with a different scale factor. If we don't explicitly
            // move it to the primary screen, the position will be scaled with
            // the wrong factor and the splash will be offset.
            this->windowHandle()->setScreen(QApplication::primaryScreen());
        }
    }
    move(QApplication::primaryScreen()->availableGeometry().center() - r.center());
273 274 275
    if (isVisible()) {
        repaint();
    }
276 277 278
    m_timer.setSingleShot(true);
    m_timer.start(1);
    QWidget::show();
279 280 281 282
}

void KisSplashScreen::toggleShowAtStartup(bool toggle)
{
283
    KConfigGroup cfg( KSharedConfig::openConfig(), "SplashScreen");
284
    cfg.writeEntry("HideSplashAfterStartup", toggle);
285
}
286 287 288

void KisSplashScreen::linkClicked(const QString &link)
{
289
    KisPart::instance()->openExistingFile(QUrl::fromLocalFile(link));
290 291
    if (isTopLevel()) {
        close();
292 293
    }
}