KisWelcomePageWidget.cpp 11.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/* This file is part of the KDE project
 * Copyright (C) 2018 Scott Petrovic <scottpetrovic@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "KisWelcomePageWidget.h"
#include <QDebug>
Scott Petrovic's avatar
Scott Petrovic committed
22
#include <QDesktopServices>
23 24
#include <QFileInfo>

Scott Petrovic's avatar
Scott Petrovic committed
25 26 27 28
#include "kis_action_manager.h"
#include "kactioncollection.h"
#include "kis_action.h"

29 30 31 32 33 34
#include "KConfigGroup"
#include "KSharedConfig"

#include <QListWidget>
#include <QListWidgetItem>
#include "kis_icon_utils.h"
35
#include "krita_utils.h"
36
#include "KoStore.h"
37
#include "kis_config.h"
38 39

KisWelcomePageWidget::KisWelcomePageWidget(QWidget *parent)
40
    : QWidget(parent)
41
{
42
    setupUi(this);
43

44 45 46
    recentDocumentsListView->setDragEnabled(false);
    recentDocumentsListView->viewport()->setAutoFillBackground(false);
    recentDocumentsListView->setSpacing(2);
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

    // set up URLs that go to web browser
    manualLink->setText(QString("<a href=\"https://docs.krita.org/\">").append(i18n("User Manual")).append("</a>"));
    manualLink->setTextFormat(Qt::RichText);
    manualLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
    manualLink->setOpenExternalLinks(true);

    gettingStartedLink->setText(QString("<a href=\"https://docs.krita.org/en/user_manual/getting_started.html\">").append(i18n("Getting Started")).append("</a>"));
    gettingStartedLink->setTextFormat(Qt::RichText);
    gettingStartedLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
    gettingStartedLink->setOpenExternalLinks(true);

    supportKritaLink->setText(QString("<a href=\"https://krita.org/en/support-us/donations/\">").append(i18n("Support Krita")).append("</a>"));
    supportKritaLink->setTextFormat(Qt::RichText);
    supportKritaLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
    supportKritaLink->setOpenExternalLinks(true);

    userCommunityLink->setText(QString("<a href=\"https://forum.kde.org/viewforum.php?f=136\">").append(i18n("User Community")).append("</a>"));
    userCommunityLink->setTextFormat(Qt::RichText);
    userCommunityLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
    userCommunityLink->setOpenExternalLinks(true);

    kritaWebsiteLink->setText(QString("<a href=\"https://www.krita.org\">").append(i18n("Krita Website")).append("</a>"));
    kritaWebsiteLink->setTextFormat(Qt::RichText);
    kritaWebsiteLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
    kritaWebsiteLink->setOpenExternalLinks(true);

    sourceCodeLink->setText(QString("<a href=\"https://phabricator.kde.org/source/krita/\">").append(i18n("Source Code")).append("</a>"));
    sourceCodeLink->setTextFormat(Qt::RichText);
    sourceCodeLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
    sourceCodeLink->setOpenExternalLinks(true);

    poweredByKDELink->setText(QString("<a href=\"https://userbase.kde.org/What_is_KDE\">").append(i18n("Powered by KDE")).append("</a>"));
    poweredByKDELink->setTextFormat(Qt::RichText);
    poweredByKDELink->setTextInteractionFlags(Qt::TextBrowserInteraction);
    poweredByKDELink->setOpenExternalLinks(true);
    kdeIcon->setIconSize(QSize(20, 20));
    kdeIcon->setIcon(KisIconUtils::loadIcon(QStringLiteral("kde")).pixmap(20));


87
    connect(chkShowNews, SIGNAL(toggled(bool)), newsWidget, SLOT(toggleNews(bool)));
88

89 90 91 92
    // configure the News area
    KisConfig cfg(true);
    bool m_getNews = cfg.readEntry<bool>("FetchNews", false);
    chkShowNews->setChecked(m_getNews);
93

94
}
95

96 97 98
KisWelcomePageWidget::~KisWelcomePageWidget()
{
}
99

100 101 102
void KisWelcomePageWidget::setMainWindow(KisMainWindow* mainWin)
{
    if (mainWin) {
103
        m_mainWindow = mainWin;
104

105 106 107 108 109 110 111 112
        // set the shortcut links from actions (only if a shortcut exists)
        if ( mainWin->viewManager()->actionManager()->actionByName("file_new")->shortcut().toString() != "") {
            newFileLinkShortcut->setText(QString("(") + mainWin->viewManager()->actionManager()->actionByName("file_new")->shortcut().toString() + QString(")"));
        }

        if (mainWin->viewManager()->actionManager()->actionByName("file_open")->shortcut().toString()  != "") {
            openFileShortcut->setText(QString("(") + mainWin->viewManager()->actionManager()->actionByName("file_open")->shortcut().toString() + QString(")"));
        }
113 114 115 116 117
        connect(recentDocumentsListView, SIGNAL(clicked(QModelIndex)), this, SLOT(recentDocumentClicked(QModelIndex)));
        // we need the view manager to actually call actions, so don't create the connections
        // until after the view manager is set
        connect(newFileLink, SIGNAL(clicked(bool)), this, SLOT(slotNewFileClicked()));
        connect(openFileLink, SIGNAL(clicked(bool)), this, SLOT(slotOpenFileClicked()));
118
        connect(clearRecentFilesLink, SIGNAL(clicked(bool)), this, SLOT(slotClearRecentFiles()));
119

120
        slotUpdateThemeColors();
121 122
    }
}
123

124 125 126 127 128 129 130 131 132
void KisWelcomePageWidget::showDropAreaIndicator(bool show)
{
    if (!show) {
        QString dropFrameStyle = "QFrame#dropAreaIndicator { border: 0px }";
        dropFrameBorder->setStyleSheet(dropFrameStyle);
    } else {
        QColor textColor = qApp->palette().color(QPalette::Text);
        QColor backgroundColor = qApp->palette().color(QPalette::Background);
        QColor blendedColor = KritaUtils::blendColors(textColor, backgroundColor, 0.8);
133

134 135 136 137
        // QColor.name() turns it into a hex/web format
        QString dropFrameStyle = QString("QFrame#dropAreaIndicator { border: 2px dotted ").append(blendedColor.name()).append(" }") ;
        dropFrameBorder->setStyleSheet(dropFrameStyle);
    }
138 139
}

140
void KisWelcomePageWidget::slotUpdateThemeColors()
141
{
142 143 144 145 146

    QColor textColor = qApp->palette().color(QPalette::Text);
    QColor backgroundColor = qApp->palette().color(QPalette::Background);

    // make the welcome screen labels a subtle color so it doesn't clash with the main UI elements
147
    QColor blendedColor = KritaUtils::blendColors(textColor, backgroundColor, 0.8);
148 149 150 151 152 153 154 155 156 157 158 159 160
    QString blendedStyle = QString("color: ").append(blendedColor.name());


    // what labels to change the color...
    startTitleLabel->setStyleSheet(blendedStyle);
    recentDocumentsLabel->setStyleSheet(blendedStyle);
    helpTitleLabel->setStyleSheet(blendedStyle);
    manualLink->setStyleSheet(blendedStyle);
    gettingStartedLink->setStyleSheet(blendedStyle);
    supportKritaLink->setStyleSheet(blendedStyle);
    userCommunityLink->setStyleSheet(blendedStyle);
    kritaWebsiteLink->setStyleSheet(blendedStyle);
    sourceCodeLink->setStyleSheet(blendedStyle);
161 162
    newFileLinkShortcut->setStyleSheet(blendedStyle);
    openFileShortcut->setStyleSheet(blendedStyle);
163
    clearRecentFilesLink->setStyleSheet(blendedStyle);
164
    poweredByKDELink->setStyleSheet(blendedStyle);
165 166 167 168
    recentDocumentsListView->setStyleSheet(blendedStyle);

    newFileLink->setStyleSheet(blendedStyle);
    openFileLink->setStyleSheet(blendedStyle);
169

170 171

    // giving the drag area messaging a dotted border
172
    QString dottedBorderStyle = QString("border: 2px dotted ").append(blendedColor.name()).append("; color:").append(blendedColor.name()).append( ";");
173 174 175 176 177
    dragImageHereLabel->setStyleSheet(dottedBorderStyle);


    // make drop area QFrame have a dotted line
    dropFrameBorder->setObjectName("dropAreaIndicator");
178
    QString dropFrameStyle = QString("QFrame#dropAreaIndicator { border: 4px dotted ").append(blendedColor.name()).append("}");
179 180 181 182 183 184 185 186 187 188
    dropFrameBorder->setStyleSheet(dropFrameStyle);

    // only show drop area when we have a document over the empty area
    showDropAreaIndicator(false);

    // add icons for new and open settings to make them stand out a bit more
    openFileLink->setIconSize(QSize(30, 30));
    newFileLink->setIconSize(QSize(30, 30));
    openFileLink->setIcon(KisIconUtils::loadIcon("document-open"));
    newFileLink->setIcon(KisIconUtils::loadIcon("document-new"));
189
}
Scott Petrovic's avatar
Scott Petrovic committed
190

191
void KisWelcomePageWidget::populateRecentDocuments()
Scott Petrovic's avatar
Scott Petrovic committed
192
{
193 194
    m_recentFilesModel.clear(); // clear existing data before it gets re-populated

195
    // grab recent files data
196
    int numRecentFiles = m_mainWindow->recentFilesUrls().length() > 5 ? 5 : m_mainWindow->recentFilesUrls().length(); // grab at most 5
197

198
    for (int i = 0; i < numRecentFiles; i++ ) {
199

200 201
        QStandardItem *recentItem = new QStandardItem(1,2); // 1 row, 1 column
        recentItem->setIcon(KisIconUtils::loadIcon("document-export"));
202

203
        QString recentFileUrlPath = m_mainWindow->recentFilesUrls().at(i).toLocalFile();
204
        QString fileName = recentFileUrlPath.split("/").last();
205

206 207
        if (m_thumbnailMap.contains(recentFileUrlPath)) {
            recentItem->setIcon(m_thumbnailMap[recentFileUrlPath]);
208 209
        }
        else {
210
            if (QFileInfo(recentFileUrlPath).exists()) {
211
                if (recentFileUrlPath.toLower().endsWith("ora") || recentFileUrlPath.toLower().endsWith("kra")) {
212
                    QScopedPointer<KoStore> store(KoStore::createStore(recentFileUrlPath, KoStore::Read));
213 214 215 216 217 218 219 220 221 222 223
                    if (store) {
                        if (store->open(QString("Thumbnails/thumbnail.png"))
                                || store->open(QString("preview.png"))) {

                            QByteArray bytes = store->read(store->size());
                            store->close();
                            QImage img;
                            img.loadFromData(bytes);
                            img.setDevicePixelRatio(devicePixelRatioF());
                            recentItem->setIcon(QIcon(QPixmap::fromImage(img)));
                        }
224 225
                    }
                }
226
                else {
227
                    QImage img;
228
                    img.setDevicePixelRatio(devicePixelRatioF());
229
                    img.load(recentFileUrlPath);
230 231 232
                    if (!img.isNull()) {
                        recentItem->setIcon(QIcon(QPixmap::fromImage(img.scaledToWidth(48))));
                    }
233
                }
234
                m_thumbnailMap[recentFileUrlPath] = recentItem->icon();
235 236
            }
        }
237

238 239 240
        // set the recent object with the data
        recentItem->setText(fileName); // what to display for the item
        recentItem->setToolTip(recentFileUrlPath);
241
        m_recentFilesModel.appendRow(recentItem);
242
    }
243

244
    // hide clear and Recent files title if there are none
245
    bool hasRecentFiles = m_mainWindow->recentFilesUrls().length() > 0;
246

247 248 249
    recentDocumentsLabel->setVisible(hasRecentFiles);
    clearRecentFilesLink->setVisible(hasRecentFiles);

250 251
    recentDocumentsListView->setIconSize(QSize(48, 48));
    recentDocumentsListView->setModel(&m_recentFilesModel);
252 253
}

Scott Petrovic's avatar
Scott Petrovic committed
254

255 256 257
void KisWelcomePageWidget::recentDocumentClicked(QModelIndex index)
{
    QString fileUrl = index.data(Qt::ToolTipRole).toString();
258
    m_mainWindow->openDocument(QUrl::fromLocalFile(fileUrl), KisMainWindow::None );
259
}
Scott Petrovic's avatar
Scott Petrovic committed
260 261 262 263


void KisWelcomePageWidget::slotNewFileClicked()
{
264
    m_mainWindow->slotFileNew();
Scott Petrovic's avatar
Scott Petrovic committed
265 266 267 268
}

void KisWelcomePageWidget::slotOpenFileClicked()
{
269
    m_mainWindow->slotFileOpen();
Scott Petrovic's avatar
Scott Petrovic committed
270 271
}

272 273
void KisWelcomePageWidget::slotClearRecentFiles()
{
274
    m_mainWindow->clearRecentFiles();
275 276
    populateRecentDocuments();
}