Git commit 15d9f8a2b1462b714e41c90f173535fd66a5264c by Boudewijn Rempt. Committed on 07/09/2018 at 14:03. Pushed by rempt into branch 'krita/4.1'. Port the welcome page to 4.1 M +8 -1 libs/ui/CMakeLists.txt M +1 -21 libs/ui/KisApplication.cpp M +53 -1 libs/ui/KisMainWindow.cpp M +26 -5 libs/ui/KisMainWindow.h M +6 -1 libs/ui/KisMultiFeedRSSModel.cpp M +1 -1 libs/ui/KisMultiFeedRSSModel.h A +34 -0 libs/ui/forms/KisNewsPage.ui A +775 -0 libs/ui/forms/KisWelcomePage.ui A +121 -0 libs/ui/widgets/KisNewsWidget.cpp [License: GPL (v2+)] A +54 -0 libs/ui/widgets/KisNewsWidget.h [License: GPL (v2+)] A +278 -0 libs/ui/widgets/KisWelcomePageWidget.cpp [License: LGPL = (v2+)] A +77 -0 libs/ui/widgets/KisWelcomePageWidget.h [License: LGPL (v= 2+)] https://commits.kde.org/krita/15d9f8a2b1462b714e41c90f173535fd66a5264c diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt index fe7af228024..1e8feaa7a43 100644 --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -152,10 +152,13 @@ set(kritaui_LIB_SRCS kis_tooltip_manager.cpp kis_multinode_property.cpp kis_stopgradient_editor.cpp + widgets/KisWelcomePageWidget.cpp + = kisexiv2/kis_exif_io.cpp kisexiv2/kis_exiv2.cpp kisexiv2/kis_iptc_io.cpp kisexiv2/kis_xmp_io.cpp + = opengl/kis_opengl.cpp opengl/kis_opengl_canvas2.cpp opengl/kis_opengl_canvas_debugger.cpp @@ -262,7 +265,7 @@ set(kritaui_LIB_SRCS widgets/KisVisualTriangleSelectorShape.cpp widgets/KoStrokeConfigWidget.cpp widgets/KoFillConfigWidget.cpp - + widgets/KisNewsWidget.cpp = utils/kis_document_aware_spin_box_unit_manager.cpp = @@ -495,6 +498,10 @@ ki18n_wrap_ui(kritaui_LIB_SRCS forms/wdgstopgradienteditor.ui forms/wdgsessionmanager.ui forms/wdgnewwindowlayout.ui + forms/KisWelcomePage.ui + forms/KisNewsPage.ui + + = brushhud/kis_dlg_brush_hud_config.ui forms/wdgdlginternalcolorselector.ui dialogs/kis_delayed_save_dialog.ui diff --git a/libs/ui/KisApplication.cpp b/libs/ui/KisApplication.cpp index 59995653cc2..1cc067607b7 100644 --- a/libs/ui/KisApplication.cpp +++ b/libs/ui/KisApplication.cpp @@ -119,27 +119,7 @@ public: = ~ResetStarting() { if (m_splash) { - - KConfigGroup cfg( KSharedConfig::openConfig(), "SplashScreen"); - bool hideSplash =3D cfg.readEntry("HideSplashAfterStartup", fa= lse); - if (m_fileCount > 0 || hideSplash) { - m_splash->hide(); - } - else { - m_splash->setWindowFlags(Qt::Dialog); - QRect r(QPoint(), m_splash->size()); - m_splash->move(QApplication::desktop()->availableGeometry(= ).center() - r.center()); - m_splash->setWindowTitle(qAppName()); - m_splash->setParent(0); - Q_FOREACH (QObject *o, m_splash->children()) { - QWidget *w =3D qobject_cast(o); - if (w && w->isHidden()) { - w->setVisible(true); - } - } - m_splash->show(); - m_splash->activateWindow(); - } + m_splash->hide(); } } = diff --git a/libs/ui/KisMainWindow.cpp b/libs/ui/KisMainWindow.cpp index 7d823449ecc..952d3c37608 100644 --- a/libs/ui/KisMainWindow.cpp +++ b/libs/ui/KisMainWindow.cpp @@ -57,6 +57,7 @@ #include #include #include +#include = #include #include @@ -140,6 +141,7 @@ #include #include "KisWindowLayoutManager.h" #include +#include "KisWelcomePageWidget.h" = #include = @@ -176,11 +178,17 @@ public: , windowMenu(new KActionMenu(i18nc("@action:inmenu", "&Window"), p= arent)) , documentMenu(new KActionMenu(i18nc("@action:inmenu", "New &View"= ), parent)) , workspaceMenu(new KActionMenu(i18nc("@action:inmenu", "Wor&kspac= e"), parent)) + , welcomePage(new KisWelcomePageWidget(parent)) + , widgetStack(new QStackedWidget(parent)) , mdiArea(new QMdiArea(parent)) , windowMapper(new QSignalMapper(parent)) , documentMapper(new QSignalMapper(parent)) { if (id.isNull()) this->id =3D QUuid::createUuid(); + + widgetStack->addWidget(welcomePage); + widgetStack->addWidget(mdiArea); + mdiArea->setTabsMovable(true); mdiArea->setActivationOrder(QMdiArea::ActivationHistoryOrder); } @@ -250,6 +258,9 @@ public: = Digikam::ThemeManager *themeManager {0}; = + KisWelcomePageWidget *welcomePage {0}; + QStackedWidget *widgetStack {0}; + QMdiArea *mdiArea; QMdiSubWindow *activeSubWindow {0}; QSignalMapper *windowMapper; @@ -367,7 +378,8 @@ KisMainWindow::KisMainWindow(QUuid uuid) d->mdiArea->setTabPosition(QTabWidget::North); d->mdiArea->setTabsClosable(true); = - setCentralWidget(d->mdiArea); + setCentralWidget(d->widgetStack); + d->widgetStack->setCurrentIndex(0); = connect(d->mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, = SLOT(subWindowActivated())); connect(d->windowMapper, SIGNAL(mapped(QWidget*)), this, SLOT(setActiv= eSubWindow(QWidget*))); @@ -726,6 +738,16 @@ void KisMainWindow::saveRecentFiles() } } = +QList KisMainWindow::recentFilesUrls() +{ + return d->recentFiles->urls(); +} + +void KisMainWindow::clearRecentFiles() +{ + d->recentFiles->clear(); +} + void KisMainWindow::reloadRecentFileList() { d->recentFiles->loadEntries(KSharedConfig::openConfig()->group("Recent= Files")); @@ -879,6 +901,8 @@ void KisMainWindow::showDocument(KisDocument *document)= { = KisView* KisMainWindow::addViewAndNotifyLoadingCompleted(KisDocument *docu= ment) { + showWelcomeScreen(false); // see workaround in function header + KisView *view =3D KisPart::instance()->createView(document, resourceMa= nager(), actionCollection(), this); addView(view); = @@ -1386,6 +1410,12 @@ void KisMainWindow::switchTab(int index) tabBar->setCurrentIndex(index); } = +void KisMainWindow::showWelcomeScreen(bool show) +{ + d->widgetStack->setCurrentIndex(!show); +} + + void KisMainWindow::slotFileNew() { const QStringList mimeFilter =3D KisImportExportManager::supportedMime= Types(KisImportExportManager::Import); @@ -2222,6 +2252,28 @@ void KisMainWindow::updateWindowMenu() } } = + bool showMdiArea =3D windows.count( ) > 0; + if (!showMdiArea) { + showWelcomeScreen(true); // see workaround in function in header + + // keep the recent file list updated when going back to welcome sc= reen + reloadRecentFileList(); + d->welcomePage->populateRecentDocuments(); + } + + // enable/disable the toolbox docker if there are no documents open + Q_FOREACH (QObject* widget, children()) { + if (widget->inherits("QDockWidget")) { + QDockWidget* dw =3D static_cast(widget); + + if ( dw->objectName() =3D=3D "ToolBox") { + dw->setEnabled(showMdiArea); + } + } + } + + + updateCaption(); } = diff --git a/libs/ui/KisMainWindow.h b/libs/ui/KisMainWindow.h index 3ad3960930a..7da391636ad 100644 --- a/libs/ui/KisMainWindow.h +++ b/libs/ui/KisMainWindow.h @@ -107,6 +107,17 @@ public: */ void addRecentURL(const QUrl &url); = + /** + * get list of URL strings for recent files + */ + QList recentFilesUrls(); + + /** + * clears the list of the recent files + */ + void clearRecentFiles(); + + = /** * Load the desired document and show it. * @param url the URL to open @@ -120,6 +131,16 @@ public: */ void showDocument(KisDocument *document); = + /** + * Toggles between showing the welcome screen and the MDI area + * + * hack: There seems to be a bug that prevents events happening to th= e MDI area if it + * isn't actively displayed (set in the widgetStack). This can cause = things like the title bar + * not to update correctly Before doing any actions related to openin= g or creating documents, + * make sure to switch this first to make sure everything can communi= cate to the MDI area correctly + */ + void showWelcomeScreen(bool show); + /** * Saves the document, asking for a filename if necessary. * @@ -405,6 +426,11 @@ public Q_SLOTS: = void windowFocused(); = + /** + * Reloads the recent documents list. + */ + void reloadRecentFileList(); + = private: = friend class KisApplication; @@ -421,11 +447,6 @@ private: = bool openDocumentInternal(const QUrl &url, KisMainWindow::OpenFlags fl= ags =3D 0); = - /** - * Reloads the recent documents list. - */ - void reloadRecentFileList(); - /** * Updates the window caption based on the document info and path. */ diff --git a/libs/ui/KisMultiFeedRSSModel.cpp b/libs/ui/KisMultiFeedRSSMode= l.cpp index 11028fdefe5..20c93ef791c 100644 --- a/libs/ui/KisMultiFeedRSSModel.cpp +++ b/libs/ui/KisMultiFeedRSSModel.cpp @@ -197,7 +197,12 @@ QVariant MultiFeedRssModel::data(const QModelIndex &in= dex, int role) const RssItem item =3D m_aggregatedFeed.at(index.row()); = switch (role) { - case Qt::DisplayRole: // fall through + case Qt::DisplayRole: + { + return QString("" + item.title + "" + "

" + item.pubDate.toString("dd-MM-yyyy hh:mm") + = "

" + "

" + item.description + "


"); + } case TitleRole: return item.title; case DescriptionRole: diff --git a/libs/ui/KisMultiFeedRSSModel.h b/libs/ui/KisMultiFeedRSSModel.h index c87773e46a0..613d9a49fce 100644 --- a/libs/ui/KisMultiFeedRSSModel.h +++ b/libs/ui/KisMultiFeedRSSModel.h @@ -68,7 +68,7 @@ class KRITAUI_EXPORT MultiFeedRssModel : public QAbstract= ListModel public: explicit MultiFeedRssModel(QObject *parent =3D 0); ~MultiFeedRssModel() override; - QHash roleNames() const; + QHash roleNames() const override; void addFeed(const QString& feed); void removeFeed(const QString& feed); = diff --git a/libs/ui/forms/KisNewsPage.ui b/libs/ui/forms/KisNewsPage.ui new file mode 100644 index 00000000000..8b061cee318 --- /dev/null +++ b/libs/ui/forms/KisNewsPage.ui @@ -0,0 +1,34 @@ + + + KisNewsPage + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + Show news about Krita: this needs internet to retrieve infor= mation from the krita.org website + + + Show News about Krita + + + + + + + + + + + diff --git a/libs/ui/forms/KisWelcomePage.ui b/libs/ui/forms/KisWelcomePage= .ui new file mode 100644 index 00000000000..0d2214d990a --- /dev/null +++ b/libs/ui/forms/KisWelcomePage.ui @@ -0,0 +1,775 @@ + + + KisWelcomePage + + + + 0 + 0 + 1061 + 538 + + + + + 0 + 0 + + + + false + + + + + + QFrame::Box + + + QFrame::Plain + + + 4 + + + 0 + + + + + + Qt::Vertical + + + + 5 + 5 + + + + + + + + Qt::Horizontal + + + + 5 + 5 + + + + + + + + 5 + + + 0 + + + 20 + + + + + + 18 + + + + Start + + + + + + + 0 + + + + + + true + + + + Qt::NoFocus + + + New File + + + false + + + true + + + + + + + + 20 + 0 + + + + + false + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + + + 30 + + + + + + true + + + + Qt::NoFocus + + + Open File + + + false + + + true + + + + + + + + 20 + 0 + + + + + false + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 18 + + + + Recent Documents + + + + + + + + 0 + 0 + + + + + true + + + + Qt::NoFocus + + + Clear + + + false + + + true + + + + + + + Qt::Horizontal + + + + 5 + 20 + + + + + + + + + + + 0 + 0 + + + + + 300 + 250 + + + + + true + false + + + + Qt::NoFocus + + + false + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + false + + + false + + + QAbstractItemView::SelectItems + + + QListView::Snap + + + QListView::Fixed + + + 0 + + + QListView::ListMode + + + true + + + false + + + + + + + + + 5 + + + 0 + + + 0 + + + 30 + + + 0 + + + + + + 18 + + + + Community + + + 0 + + + + + + + 0 + + + + + + 0 + 0 + + + + + true + + + + Qt::NoFocus + + + User Manual + + + false + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 5 + + + + + + + + + + 0 + + + + + + true + + + + Qt::NoFocus + + + Getting Started + + + false + + + true + + + + + + + Qt::Horizontal + + + + 40 + 5 + + + + + + + + + + + + + true + + + + Qt::NoFocus + + + Support Krita + + + false + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + true + + + + Qt::NoFocus + + + User Community + + + false + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + true + + + + Qt::NoFocus + + + Krita Website + + + false + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + + + 0 + + + + + + true + + + + Qt::NoFocus + + + Source Code + + + false + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 20 + + + + + + true + + + + Qt::NoFocus + + + Powered by KDE + + + false + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + QFrame::Box + + + 2 + + + Drag Image in window to open + + + Qt::AlignCenter + + + true + + + 30 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + + + + + + 18 + + + + News + + + 0 + + + + + + + + + + + + Qt::Horizontal + + + + 5 + 5 + + + + + + + + Qt::Vertical + + + + 5 + 5 + + + + + + + + + + + + KisNewsWidget + QWidget +
widgets/KisNewsWidget.h
+ 1 +
+
+ + +
diff --git a/libs/ui/widgets/KisNewsWidget.cpp b/libs/ui/widgets/KisNewsWid= get.cpp new file mode 100644 index 00000000000..812f1afdb0d --- /dev/null +++ b/libs/ui/widgets/KisNewsWidget.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2018 boud + * + * 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-13= 01, USA. + */ +#include "KisNewsWidget.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "kis_config.h" +#include "KisMultiFeedRSSModel.h" + + +KisNewsDelegate::KisNewsDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ + qDebug() << "Delegate created"; +} + +void KisNewsDelegate::paint(QPainter *painter, const QStyleOptionViewItem = &option, const QModelIndex &index) const +{ + painter->save(); + + QStyleOptionViewItem optionCopy =3D option; + initStyleOption(&optionCopy, index); + + QStyle *style =3D optionCopy.widget? optionCopy.widget->style() : QApp= lication::style(); + + QTextDocument doc; + doc.setHtml(optionCopy.text); + + /// Painting item without text + optionCopy.text =3D QString(); + style->drawControl(QStyle::CE_ItemViewItem, &optionCopy, painter); + + QAbstractTextDocumentLayout::PaintContext ctx; + + // Highlighting text if item is selected + if (optionCopy.state & QStyle::State_Selected) { + ctx.palette.setColor(QPalette::Text, optionCopy.palette.color(QPal= ette::Active, QPalette::HighlightedText)); + } + + painter->translate(optionCopy.rect.left(), optionCopy.rect.top()); + QRect clip(0, 0, optionCopy.rect.width(), optionCopy.rect.height()); + doc.setPageSize(clip.size()); + doc.drawContents(painter, clip); + painter->restore(); +} + +QSize KisNewsDelegate::sizeHint(const QStyleOptionViewItem &option, const = QModelIndex &index) const +{ + QStyleOptionViewItem optionCopy =3D option; + initStyleOption(&optionCopy, index); + + QTextDocument doc; + doc.setHtml(optionCopy.text); + doc.setTextWidth(optionCopy.rect.width()); + return QSize(doc.idealWidth(), doc.size().height()); +} + +KisNewsWidget::KisNewsWidget(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + KisConfig cfg; + m_getNews =3D cfg.readEntry("FetchNews", false); + chkShowNews->setChecked(m_getNews); + connect(chkShowNews, SIGNAL(toggled(bool)), this, SLOT(toggleNews(bool= ))); + m_rssModel =3D new MultiFeedRssModel(this); + + if (m_getNews) { + m_rssModel->addFeed(QLatin1String("https://krita.org/en/feed/")); + } + else { + m_rssModel->removeFeed(QLatin1String("https://krita.org/en/feed/")= ); + } + + listNews->setModel(m_rssModel); + listNews->setItemDelegate(new KisNewsDelegate(listNews)); + connect(listNews, SIGNAL(clicked(const QModelIndex&)), this, SLOT(item= Selected(const QModelIndex&))); +} + +void KisNewsWidget::toggleNews(bool toggle) +{ + KisConfig cfg; + cfg.writeEntry("FetchNews", toggle); + m_getNews =3D toggle; + + if (m_getNews) { + m_rssModel->addFeed(QLatin1String("https://krita.org/en/feed/")); + } + else { + m_rssModel->removeFeed(QLatin1String("https://krita.org/en/feed/")= ); + } +} + +void KisNewsWidget::itemSelected(const QModelIndex &idx) +{ + if (idx.isValid()) { + QString link =3D idx.data(RssRoles::LinkRole).toString(); + QDesktopServices::openUrl(QUrl(link)); + } +} diff --git a/libs/ui/widgets/KisNewsWidget.h b/libs/ui/widgets/KisNewsWidge= t.h new file mode 100644 index 00000000000..acb3e66b3ae --- /dev/null +++ b/libs/ui/widgets/KisNewsWidget.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018 boud + * + * 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-13= 01, USA. + */ +#ifndef KISNEWSWIDGET_H +#define KISNEWSWIDGET_H + +#include +#include +#include + +#include + +class MultiFeedRssModel; + +class KisNewsDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + KisNewsDelegate(QObject *parent =3D 0); + void paint(QPainter *painter, const QStyleOptionViewItem &option, cons= t QModelIndex &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &= index) const override; +}; + +/** + * @brief The KisNewsWidget class shows the latest news from Krita.org + */ +class KisNewsWidget : public QWidget, public Ui::KisNewsPage +{ + Q_OBJECT +public: + explicit KisNewsWidget(QWidget *parent =3D nullptr); +private Q_SLOTS: + void toggleNews(bool toggle); + void itemSelected(const QModelIndex &idx); +private: + bool m_getNews {false}; + MultiFeedRssModel *m_rssModel {0}; +}; + +#endif // KISNEWSWIDGET_H diff --git a/libs/ui/widgets/KisWelcomePageWidget.cpp b/libs/ui/widgets/Kis= WelcomePageWidget.cpp new file mode 100644 index 00000000000..fa4b6316ec6 --- /dev/null +++ b/libs/ui/widgets/KisWelcomePageWidget.cpp @@ -0,0 +1,278 @@ +/* This file is part of the KDE project + * Copyright (C) 2018 Scott Petrovic + * + * 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 Licen= se + * 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 +#include +#include "kis_action_manager.h" +#include "kactioncollection.h" +#include "kis_action.h" + +#include "KConfigGroup" +#include "KSharedConfig" + +#include +#include +#include "kis_icon_utils.h" +#include "krita_utils.h" +#include "KoStore.h" + + +KisWelcomePageWidget::KisWelcomePageWidget(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + recentDocumentsListView->viewport()->setAutoFillBackground(false); + recentDocumentsListView->setSpacing(2); +} + +KisWelcomePageWidget::~KisWelcomePageWidget() +{ +} + +void KisWelcomePageWidget::setMainWindow(KisMainWindow* mainWin) +{ + if (mainWin) { + mainWindow =3D mainWin; + + + // set the shortcut links from actions (only if a shortcut exists) + if ( mainWin->viewManager()->actionManager()->actionByName("file_n= ew")->shortcut().toString() !=3D "") { + newFileLinkShortcut->setText(QString("(") + mainWin->viewManag= er()->actionManager()->actionByName("file_new")->shortcut().toString() + QS= tring(")")); + } + + if (mainWin->viewManager()->actionManager()->actionByName("file_op= en")->shortcut().toString() !=3D "") { + openFileShortcut->setText(QString("(") + mainWin->viewManager(= )->actionManager()->actionByName("file_open")->shortcut().toString() + QStr= ing(")")); + } + + + populateRecentDocuments(); + connect(recentDocumentsListView, SIGNAL(clicked(QModelIndex)), thi= s, SLOT(recentDocumentClicked(QModelIndex))); + + + // we need the view manager to actually call actions, so don't cre= ate the connections + // until after the view manager is set + connect(newFileLink, SIGNAL(clicked(bool)), this, SLOT(slotNewFile= Clicked())); + connect(openFileLink, SIGNAL(clicked(bool)), this, SLOT(slotOpenFi= leClicked())); + + // URL link connections + connect(manualLink, SIGNAL(clicked(bool)), this, SLOT(slotGoToManu= al())); + + connect(gettingStartedLink, SIGNAL(clicked(bool)), this, SLOT(slot= GettingStarted())); + connect(supportKritaLink, SIGNAL(clicked(bool)), this, SLOT(slotSu= pportKrita())); + connect(userCommunityLink, SIGNAL(clicked(bool)), this, SLOT(slotU= serCommunity())); + connect(kritaWebsiteLink, SIGNAL(clicked(bool)), this, SLOT(slotKr= itaWebsite())); + connect(sourceCodeLink, SIGNAL(clicked(bool)), this, SLOT(slotSour= ceCode())); + connect(clearRecentFilesLink, SIGNAL(clicked(bool)), this, SLOT(sl= otClearRecentFiles())); + connect(poweredByKDELink, SIGNAL(clicked(bool)), this, SLOT(slotKD= ESiteLink())); + + + slotUpdateThemeColors(); + } +} + +void KisWelcomePageWidget::showDropAreaIndicator(bool show) +{ + if (!show) { + QString dropFrameStyle =3D "QFrame#dropAreaIndicator { border: 0px= }"; + dropFrameBorder->setStyleSheet(dropFrameStyle); + } else { + QColor textColor =3D qApp->palette().color(QPalette::Text); + QColor backgroundColor =3D qApp->palette().color(QPalette::Backgro= und); + QColor blendedColor =3D KritaUtils::blendColors(textColor, backgro= undColor, 0.8); + + // QColor.name() turns it into a hex/web format + QString dropFrameStyle =3D QString("QFrame#dropAreaIndicator { bor= der: 2px dotted ").append(blendedColor.name()).append(" }") ; + dropFrameBorder->setStyleSheet(dropFrameStyle); + } +} + +void KisWelcomePageWidget::slotUpdateThemeColors() +{ + + QColor textColor =3D qApp->palette().color(QPalette::Text); + QColor backgroundColor =3D qApp->palette().color(QPalette::Background); + + // make the welcome screen labels a subtle color so it doesn't clash w= ith the main UI elements + QColor blendedColor =3D KritaUtils::blendColors(textColor, backgroundC= olor, 0.8); + QString blendedStyle =3D 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); + newFileLinkShortcut->setStyleSheet(blendedStyle); + openFileShortcut->setStyleSheet(blendedStyle); + clearRecentFilesLink->setStyleSheet(blendedStyle); + poweredByKDELink->setStyleSheet(blendedStyle); + recentDocumentsListView->setStyleSheet(blendedStyle); + + newFileLink->setStyleSheet(blendedStyle); + openFileLink->setStyleSheet(blendedStyle); + + + // giving the drag area messaging a dotted border + QString dottedBorderStyle =3D QString("border: 2px dotted ").append(bl= endedColor.name()).append("; color:").append(blendedColor.name()).append( "= ;"); + dragImageHereLabel->setStyleSheet(dottedBorderStyle); + + + // make drop area QFrame have a dotted line + dropFrameBorder->setObjectName("dropAreaIndicator"); + QString dropFrameStyle =3D QString("QFrame#dropAreaIndicator { border:= 4px dotted ").append(blendedColor.name()).append("}"); + 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 mo= re + openFileLink->setIconSize(QSize(30, 30)); + newFileLink->setIconSize(QSize(30, 30)); + openFileLink->setIcon(KisIconUtils::loadIcon("document-open")); + newFileLink->setIcon(KisIconUtils::loadIcon("document-new")); + + // needed for updating icon color for files that don't have a preview + if (mainWindow) { + populateRecentDocuments(); + } +} + +void KisWelcomePageWidget::populateRecentDocuments() +{ + // grab recent files data + recentFilesModel =3D new QStandardItemModel(); + int recentDocumentsIterator =3D mainWindow->recentFilesUrls().length()= > 5 ? 5 : mainWindow->recentFilesUrls().length(); // grab at most 5 + + for (int i =3D 0; i < recentDocumentsIterator; i++ ) { + + QStandardItem *recentItem =3D new QStandardItem(1,2); // 1 row, 1 c= olumn + QString recentFileUrlPath =3D mainWindow->recentFilesUrls().at(i).t= oString(); + QString fileName =3D recentFileUrlPath.split("/").last(); + + + // get thumbnail -- almost all Krita-supported formats save a thumb= nail + // this was mostly copied from the KisAutoSaveRecovery file + QScopedPointer store(KoStore::createStore(QUrl(recentFileU= rlPath), KoStore::Read)); + + if (store) { + if (store->open(QString("Thumbnails/thumbnail.png")) + || store->open(QString("preview.png"))) { + + QByteArray bytes =3D store->read(store->size()); + store->close(); + QImage img; + img.loadFromData(bytes); + recentItem->setIcon(QIcon(QPixmap::fromImage(img))); + + } + else { + recentItem->setIcon(KisIconUtils::loadIcon("document-export= ")); + } + + } + else { + recentItem->setIcon(KisIconUtils::loadIcon("document-export")); + } + + + // set the recent object with the data + recentItem->setText(fileName); // what to display for the item + recentItem->setToolTip(recentFileUrlPath); + recentFilesModel->appendRow(recentItem); + + + } + + + // hide clear and Recent files title if there are none + bool hasRecentFiles =3D mainWindow->recentFilesUrls().length() > 0; + recentDocumentsLabel->setVisible(hasRecentFiles); + clearRecentFilesLink->setVisible(hasRecentFiles); + + + recentDocumentsListView->setIconSize(QSize(40, 40)); + recentDocumentsListView->setModel(recentFilesModel); +} + + +void KisWelcomePageWidget::recentDocumentClicked(QModelIndex index) +{ + QString fileUrl =3D index.data(Qt::ToolTipRole).toString(); + mainWindow->openDocument(QUrl(fileUrl), KisMainWindow::None ); +} + + +void KisWelcomePageWidget::slotNewFileClicked() +{ + mainWindow->slotFileNew(); +} + +void KisWelcomePageWidget::slotOpenFileClicked() +{ + mainWindow->slotFileOpen(); +} + +void KisWelcomePageWidget::slotClearRecentFiles() +{ + mainWindow->clearRecentFiles(); + mainWindow->reloadRecentFileList(); + populateRecentDocuments(); +} + +void KisWelcomePageWidget::slotGoToManual() +{ + QDesktopServices::openUrl(QUrl("https://docs.krita.org")); +} + +void KisWelcomePageWidget::slotGettingStarted() +{ + QDesktopServices::openUrl(QUrl("https://docs.krita.org/en/user_manual/= getting_started.html")); +} + +void KisWelcomePageWidget::slotSupportKrita() +{ + QDesktopServices::openUrl(QUrl("https://krita.org/en/support-us/donati= ons/")); +} + +void KisWelcomePageWidget::slotUserCommunity() +{ + QDesktopServices::openUrl(QUrl("https://forum.kde.org/viewforum.php?f= =3D136")); +} + +void KisWelcomePageWidget::slotKritaWebsite() +{ + QDesktopServices::openUrl(QUrl("https://www.krita.org")); +} + +void KisWelcomePageWidget::slotSourceCode() +{ + QDesktopServices::openUrl(QUrl("https://phabricator.kde.org/source/kri= ta/")); +} + +void KisWelcomePageWidget::slotKDESiteLink() +{ + QDesktopServices::openUrl(QUrl("https://userbase.kde.org/What_is_KDE")= ); +} diff --git a/libs/ui/widgets/KisWelcomePageWidget.h b/libs/ui/widgets/KisWe= lcomePageWidget.h new file mode 100644 index 00000000000..1e4d33e48b4 --- /dev/null +++ b/libs/ui/widgets/KisWelcomePageWidget.h @@ -0,0 +1,77 @@ +/* This file is part of the KDE project + * Copyright (C) 2018 Scott Petrovic + * + * 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 Licen= se + * 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. + */ + +#ifndef KISWELCOMEPAGEWIDGET_H +#define KISWELCOMEPAGEWIDGET_H + +#include "kritaui_export.h" +#include "KisViewManager.h" +#include "KisMainWindow.h" + +#include +#include "ui_KisWelcomePage.h" +#include + +/// A widget for diplaying if no documents are open. This will display in = the MDI area +class KRITAUI_EXPORT KisWelcomePageWidget : public QWidget, public Ui::Kis= WelcomePage +{ + Q_OBJECT + + public: + explicit KisWelcomePageWidget(QWidget *parent); + ~KisWelcomePageWidget() override; + + void setMainWindow(KisMainWindow* mainWindow); + +public Q_SLOTS: + /// if a document is placed over this area, a dotted line will appear = as an indicator + /// that it is a droppable area. KisMainwindow is what triggers this + void showDropAreaIndicator(bool show); + + void slotUpdateThemeColors(); + + /// this could be called multiple times. If a recent document doesn't + /// have a preview, an icon is used that needs to be updated + void populateRecentDocuments(); + + +private: + KisMainWindow* mainWindow; + QStandardItemModel *recentFilesModel; + +private Q_SLOTS: + void slotNewFileClicked(); + void slotOpenFileClicked(); + void slotClearRecentFiles(); + + void recentDocumentClicked(QModelIndex index); + + /// go to URL links + void slotGoToManual(); + + void slotGettingStarted(); + void slotSupportKrita(); + void slotUserCommunity(); + void slotKritaWebsite(); + void slotSourceCode(); + void slotKDESiteLink(); + +}; + +#endif // KISWELCOMEPAGEWIDGET_H