diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -81,6 +81,7 @@ brushhud/kis_dlg_brush_hud_config.cpp brushhud/kis_brush_hud_properties_list.cpp brushhud/kis_brush_hud_properties_config.cpp + kis_aspect_ratio_locker.cpp kis_autogradient.cc kis_bookmarked_configurations_editor.cc @@ -150,10 +151,13 @@ kis_tooltip_manager.cpp kis_multinode_property.cpp kis_stopgradient_editor.cpp + 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 @@ -251,7 +255,7 @@ widgets/KoDualColorButton.cpp widgets/KoStrokeConfigWidget.cpp widgets/KoFillConfigWidget.cpp - + utils/kis_document_aware_spin_box_unit_manager.cpp @@ -480,6 +484,8 @@ forms/wdgstopgradienteditor.ui forms/wdgsessionmanager.ui forms/wdgnewwindowlayout.ui + forms/KisWelcomePage.ui + brushhud/kis_dlg_brush_hud_config.ui dialogs/kis_delayed_save_dialog.ui input/config/kis_input_configuration_page.ui diff --git a/libs/ui/KisApplication.cpp b/libs/ui/KisApplication.cpp --- a/libs/ui/KisApplication.cpp +++ b/libs/ui/KisApplication.cpp @@ -124,28 +124,9 @@ } ~ResetStarting() { - if (m_splash) { - KConfigGroup cfg( KSharedConfig::openConfig(), "SplashScreen"); - bool hideSplash = cfg.readEntry("HideSplashAfterStartup", false); - 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 = qobject_cast(o); - if (w && w->isHidden()) { - w->setVisible(true); - } - } - m_splash->show(); - m_splash->activateWindow(); - } + if (m_splash) { + m_splash->hide(); } } @@ -626,6 +607,7 @@ } } + bool KisApplication::notify(QObject *receiver, QEvent *event) { try { diff --git a/libs/ui/KisAutoSaveRecoveryDialog.cpp b/libs/ui/KisAutoSaveRecoveryDialog.cpp --- a/libs/ui/KisAutoSaveRecoveryDialog.cpp +++ b/libs/ui/KisAutoSaveRecoveryDialog.cpp @@ -212,7 +212,7 @@ KoStore* store = KoStore::createStore(path, KoStore::Read); if (store) { - if(store->open(QString("Thumbnails/thumbnail.png")) + if (store->open(QString("Thumbnails/thumbnail.png")) || store->open(QString("preview.png"))) { // Hooray! No long delay for the user... QByteArray bytes = store->read(store->size()); diff --git a/libs/ui/KisMainWindow.h b/libs/ui/KisMainWindow.h --- a/libs/ui/KisMainWindow.h +++ b/libs/ui/KisMainWindow.h @@ -108,6 +108,17 @@ 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,18 @@ */ 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 the 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 opening or creating documents, + * make sure to switch this first to make sure everything can communicate to the MDI area correctly + */ + void showWelcomeScreen(bool show); + + /** * Saves the document, asking for a filename if necessary. * @@ -260,6 +283,20 @@ void notifyChildViewDestroyed(KisView *view); + /// Set the active view, this will update the undo/redo actions + void setActiveView(KisView *view); + + void subWindowActivated(); + + void windowFocused(); + + /** + * Reloads the recent documents list. + */ + void reloadRecentFileList(); + + + private Q_SLOTS: /** * Save the list of recent files. @@ -337,6 +374,7 @@ */ void slotReloadFile(); + /** * File --> Import * @@ -370,9 +408,15 @@ void newWindow(); void closeCurrentWindow(); void checkSanity(); + /// Quits Krita with error message from m_errorMessage. void showErrorAndDie(); + void initializeGeometry(); + void showManual(); + void switchTab(int index); + + protected: void closeEvent(QCloseEvent * e) override; @@ -384,7 +428,7 @@ void dragMoveEvent(QDragMoveEvent * event) override; void dragLeaveEvent(QDragLeaveEvent * event) override; - void mouseReleaseEvent(QMouseEvent *event) override; + void moveEvent(QMoveEvent *e) override; private: @@ -396,18 +440,6 @@ */ void addView(KisView *view); -public Q_SLOTS: - - /// Set the active view, this will update the undo/redo actions - void setActiveView(KisView *view); - - void subWindowActivated(); - - void windowFocused(); - -private: - - friend class KisApplication; friend class KisPart; @@ -421,10 +453,6 @@ bool openDocumentInternal(const QUrl &url, KisMainWindow::OpenFlags flags = 0); - /** - * Reloads the recent documents list. - */ - void reloadRecentFileList(); /** * Updates the window caption based on the document info and path. @@ -444,18 +472,9 @@ QByteArray borrowWorkspace(KisMainWindow *borrower); -protected: - - void moveEvent(QMoveEvent *e) override; - -private Q_SLOTS: - void initializeGeometry(); - void showManual(); - void switchTab(int index); private: - /** * Struct used in the list created by createCustomDocumentWidgets() */ diff --git a/libs/ui/KisMainWindow.cpp b/libs/ui/KisMainWindow.cpp --- a/libs/ui/KisMainWindow.cpp +++ b/libs/ui/KisMainWindow.cpp @@ -58,6 +58,8 @@ #include #include #include +#include + #include #include @@ -95,6 +97,7 @@ #include #include #include "KoToolDocker.h" +#include "KoToolBoxDocker_p.h" #include #include #include @@ -142,6 +145,7 @@ #include #include "KisWindowLayoutManager.h" #include +#include "KisWelcomePageWidget.h" #include @@ -178,11 +182,16 @@ , windowMenu(new KActionMenu(i18nc("@action:inmenu", "&Window"), parent)) , documentMenu(new KActionMenu(i18nc("@action:inmenu", "New &View"), parent)) , workspaceMenu(new KActionMenu(i18nc("@action:inmenu", "Wor&kspace"), 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 = QUuid::createUuid(); + + widgetStack->addWidget(welcomePage); + widgetStack->addWidget(mdiArea); mdiArea->setTabsMovable(true); mdiArea->setActivationOrder(QMdiArea::ActivationHistoryOrder); } @@ -252,6 +261,11 @@ Digikam::ThemeManager *themeManager {0}; + KisWelcomePageWidget *welcomePage {0}; + + + QStackedWidget *widgetStack {0}; + QMdiArea *mdiArea; QMdiSubWindow *activeSubWindow {0}; QSignalMapper *windowMapper; @@ -369,14 +383,17 @@ 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(setActiveSubWindow(QWidget*))); - connect(d->documentMapper, SIGNAL(mapped(QObject*)), this, SLOT(newView(QObject*))); + connect(d->windowMapper, SIGNAL(mapped(QWidget*)), this, SLOT(setActiveSubWindow(QWidget*))); connect(d->documentMapper, SIGNAL(mapped(QObject*)), this, SLOT(newView(QObject*))); createActions(); + // the welcome screen needs to grab actions...so make sure this line goes after the createAction() so they exist + d->welcomePage->setMainWindow(this); + setAutoSaveSettings(d->windowStateConfig, false); subWindowActivated(); @@ -728,11 +745,24 @@ } } +QList KisMainWindow::recentFilesUrls() +{ + return d->recentFiles->urls(); +} + +void KisMainWindow::clearRecentFiles() +{ + d->recentFiles->clear(); +} + + void KisMainWindow::reloadRecentFileList() { d->recentFiles->loadEntries(KSharedConfig::openConfig()->group("RecentFiles")); } + + void KisMainWindow::updateCaption() { if (!d->mdiArea->activeSubWindow()) { @@ -881,6 +911,8 @@ KisView* KisMainWindow::addViewAndNotifyLoadingCompleted(KisDocument *document) { + showWelcomeScreen(false); // see workaround in function header + KisView *view = KisPart::instance()->createView(document, resourceManager(), actionCollection(), this); addView(view); @@ -1312,6 +1344,9 @@ void KisMainWindow::dragEnterEvent(QDragEnterEvent *event) { + d->welcomePage->showDropAreaIndicator(true); + + if (event->mimeData()->hasUrls() || event->mimeData()->hasFormat("application/x-krita-node") || event->mimeData()->hasFormat("application/x-qt-image")) { @@ -1322,6 +1357,8 @@ void KisMainWindow::dropEvent(QDropEvent *event) { + d->welcomePage->showDropAreaIndicator(false); + if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() > 0) { Q_FOREACH (const QUrl &url, event->mimeData()->urls()) { if (url.toLocalFile().endsWith(".bundle")) { @@ -1359,26 +1396,13 @@ void KisMainWindow::dragLeaveEvent(QDragLeaveEvent * /*event*/) { + d->welcomePage->showDropAreaIndicator(false); + if (d->tabSwitchCompressor->isActive()) { d->tabSwitchCompressor->stop(); } } -void KisMainWindow::mouseReleaseEvent(QMouseEvent *event) -{ - /** - * This ensures people who do not understand that you - * need to make a canvas first, will find the new image - * dialog on click. - */ - if (centralWidget()->geometry().contains(event->pos()) - && KisPart::instance()->documents().size()==0 && event->button() == Qt::LeftButton) { - this->slotFileNew(); - event->accept(); - } else { - event->ignore(); - } -} void KisMainWindow::switchTab(int index) { @@ -1388,6 +1412,11 @@ tabBar->setCurrentIndex(index); } +void KisMainWindow::showWelcomeScreen(bool show) +{ + d->widgetStack->setCurrentIndex(!show); +} + void KisMainWindow::slotFileNew() { const QStringList mimeFilter = KisImportExportManager::supportedMimeTypes(KisImportExportManager::Import); @@ -2090,6 +2119,7 @@ } } + void KisMainWindow::updateWindowMenu() { QMenu *menu = d->windowMenu->menu(); @@ -2216,6 +2246,28 @@ } } + + + bool showMdiArea = windows.count( ) > 0; + if (!showMdiArea) { + showWelcomeScreen(true); // see workaround in function in header + + // keep the recent file list updated when going back to welcome screen + 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 = static_cast(widget); + + if ( dw->objectName() == "ToolBox") { + dw->setEnabled(showMdiArea); + } + } + } + updateCaption(); } @@ -2401,6 +2453,8 @@ { KisActionManager *actionManager = d->actionManager(); + + actionManager->createStandardAction(KStandardAction::New, this, SLOT(slotFileNew())); actionManager->createStandardAction(KStandardAction::Open, this, SLOT(slotFileOpen())); actionManager->createStandardAction(KStandardAction::Quit, this, SLOT(slotFileQuit())); @@ -2462,6 +2516,9 @@ d->themeManager->registerThemeActions(actionCollection()); connect(d->themeManager, SIGNAL(signalThemeChanged()), this, SLOT(slotThemeChanged())); + + connect(d->themeManager, SIGNAL(signalThemeChanged()), d->welcomePage, SLOT(slotUpdateThemeColors())); + d->toggleDockers = actionManager->createAction("view_toggledockers"); KisConfig(true).showDockers(true); d->toggleDockers->setChecked(true); diff --git a/libs/ui/KisWelcomePageWidget.h b/libs/ui/KisWelcomePageWidget.h new file mode 100644 --- /dev/null +++ b/libs/ui/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 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. + */ + +#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::KisWelcomePage +{ + 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 diff --git a/libs/ui/KisWelcomePageWidget.cpp b/libs/ui/KisWelcomePageWidget.cpp new file mode 100644 --- /dev/null +++ b/libs/ui/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 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 +#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) +{ + Q_UNUSED(parent); + setupUi(this); + + recentDocumentsListView->viewport()->setAutoFillBackground(false); + recentDocumentsListView->setSpacing(2); +} + +KisWelcomePageWidget::~KisWelcomePageWidget() +{ +} + +void KisWelcomePageWidget::setMainWindow(KisMainWindow* mainWin) +{ + if (mainWin) { + mainWindow = mainWin; + + + // 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(")")); + } + + + populateRecentDocuments(); + 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())); + + // URL link connections + connect(manualLink, SIGNAL(clicked(bool)), this, SLOT(slotGoToManual())); + + connect(gettingStartedLink, SIGNAL(clicked(bool)), this, SLOT(slotGettingStarted())); + connect(supportKritaLink, SIGNAL(clicked(bool)), this, SLOT(slotSupportKrita())); + connect(userCommunityLink, SIGNAL(clicked(bool)), this, SLOT(slotUserCommunity())); + connect(kritaWebsiteLink, SIGNAL(clicked(bool)), this, SLOT(slotKritaWebsite())); + connect(sourceCodeLink, SIGNAL(clicked(bool)), this, SLOT(slotSourceCode())); + connect(clearRecentFilesLink, SIGNAL(clicked(bool)), this, SLOT(slotClearRecentFiles())); + connect(poweredByKDELink, SIGNAL(clicked(bool)), this, SLOT(slotKDESiteLink())); + + + slotUpdateThemeColors(); + } +} + +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); + + // QColor.name() turns it into a hex/web format + QString dropFrameStyle = QString("QFrame#dropAreaIndicator { border: 2px dotted ").append(blendedColor.name()).append(" }") ; + dropFrameBorder->setStyleSheet(dropFrameStyle); + } +} + +void KisWelcomePageWidget::slotUpdateThemeColors() +{ + + 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 + QColor blendedColor = KritaUtils::blendColors(textColor, backgroundColor, 0.8); + 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); + 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 = QString("border: 2px dotted ").append(blendedColor.name()).append("; color:").append(blendedColor.name()).append( ";"); + dragImageHereLabel->setStyleSheet(dottedBorderStyle); + + + // make drop area QFrame have a dotted line + dropFrameBorder->setObjectName("dropAreaIndicator"); + QString dropFrameStyle = 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 more + 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 = new QStandardItemModel(); + int recentDocumentsIterator = mainWindow->recentFilesUrls().length() > 5 ? 5 : mainWindow->recentFilesUrls().length(); // grab at most 5 + + for (int i = 0; i < recentDocumentsIterator; i++ ) { + + QStandardItem *recentItem = new QStandardItem(1,2); // 1 row, 1 column + QString recentFileUrlPath = mainWindow->recentFilesUrls().at(i).toString(); + QString fileName = recentFileUrlPath.split("/").last(); + + + // get thumbnail -- almost all Krita-supported formats save a thumbnail + // this was mostly copied from the KisAutoSaveRecovery file + QScopedPointer store(KoStore::createStore(QUrl(recentFileUrlPath), KoStore::Read)); + + 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); + 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 = 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 = 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/donations/")); +} + +void KisWelcomePageWidget::slotUserCommunity() +{ + QDesktopServices::openUrl(QUrl("https://forum.kde.org/viewforum.php?f=136")); +} + +void KisWelcomePageWidget::slotKritaWebsite() +{ + QDesktopServices::openUrl(QUrl("https://www.krita.org")); +} + +void KisWelcomePageWidget::slotSourceCode() +{ + QDesktopServices::openUrl(QUrl("https://phabricator.kde.org/source/krita/")); +} + +void KisWelcomePageWidget::slotKDESiteLink() +{ + QDesktopServices::openUrl(QUrl("https://userbase.kde.org/What_is_KDE")); +} diff --git a/libs/ui/dialogs/kis_dlg_preferences.h b/libs/ui/dialogs/kis_dlg_preferences.h --- a/libs/ui/dialogs/kis_dlg_preferences.h +++ b/libs/ui/dialogs/kis_dlg_preferences.h @@ -78,7 +78,6 @@ void setDefault(); int undoStackSize(); bool showOutlineWhilePainting(); - bool hideSplashScreen(); int mdiMode(); int favoritePresets(); diff --git a/libs/ui/dialogs/kis_dlg_preferences.cc b/libs/ui/dialogs/kis_dlg_preferences.cc --- a/libs/ui/dialogs/kis_dlg_preferences.cc +++ b/libs/ui/dialogs/kis_dlg_preferences.cc @@ -189,8 +189,6 @@ chkShowRootLayer->setChecked(cfg.showRootLayer()); - m_hideSplashScreen->setChecked(cfg.hideSplashScreen()); - KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs"); bool dontUseNative = true; #ifdef Q_OS_UNIX @@ -220,7 +218,6 @@ m_backupFileCheckBox->setChecked(cfg.backupFile(true)); m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting(true)); m_changeBrushOutline->setChecked(!cfg.forceAlwaysFullSizedOutline(true)); - m_hideSplashScreen->setChecked(cfg.hideSplashScreen(true)); m_chkNativeFileDialog->setChecked(false); intMaxBrushSize->setValue(1000); @@ -292,11 +289,6 @@ return m_showOutlinePainting->isChecked(); } -bool GeneralTab::hideSplashScreen() -{ - return m_hideSplashScreen->isChecked(); -} - int GeneralTab::mdiMode() { return m_cmbMDIType->currentIndex(); @@ -1283,7 +1275,6 @@ cfg.setShowRootLayer(dialog->m_general->showRootLayer()); cfg.setShowOutlineWhilePainting(dialog->m_general->showOutlineWhilePainting()); cfg.setForceAlwaysFullSizedOutline(!dialog->m_general->m_changeBrushOutline->isChecked()); - cfg.setHideSplashScreen(dialog->m_general->hideSplashScreen()); cfg.setSessionOnStartup(dialog->m_general->sessionOnStartup()); cfg.setSaveSessionOnQuit(dialog->m_general->saveSessionOnQuit()); diff --git a/libs/ui/forms/KisWelcomePage.ui b/libs/ui/forms/KisWelcomePage.ui new file mode 100644 --- /dev/null +++ b/libs/ui/forms/KisWelcomePage.ui @@ -0,0 +1,760 @@ + + + KisWelcomePage + + + + 0 + 0 + 650 + 538 + + + + + 0 + 0 + + + + false + + + + + + QFrame::Box + + + QFrame::Plain + + + 4 + + + 0 + + + + 10 + + + 10 + + + 10 + + + 10 + + + 15 + + + + + Qt::Horizontal + + + + 5 + 5 + + + + + + + + 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 + + + + + + + + + + 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 + + + + + + + + + Qt::Vertical + + + + 5 + 5 + + + + + + + + + + + + diff --git a/libs/ui/forms/wdggeneralsettings.ui b/libs/ui/forms/wdggeneralsettings.ui --- a/libs/ui/forms/wdggeneralsettings.ui +++ b/libs/ui/forms/wdggeneralsettings.ui @@ -684,28 +684,6 @@ - - - - - 0 - 0 - - - - - 75 - 0 - - - - 10 - - - 30 - - - @@ -714,13 +692,6 @@ - - - Hide splash screen on startup - - - - Warning: if you enable this setting and the file dialogs do weird stuff, do not report a bug. @@ -730,14 +701,14 @@ - + Maximum brush size: - + @@ -773,7 +744,7 @@ - + Qt::Vertical @@ -786,6 +757,28 @@ + + + + + 0 + 0 + + + + + 75 + 0 + + + + 10 + + + 30 + + + diff --git a/libs/ui/kis_config.h b/libs/ui/kis_config.h --- a/libs/ui/kis_config.h +++ b/libs/ui/kis_config.h @@ -260,9 +260,6 @@ bool forceAlwaysFullSizedOutline(bool defaultValue = false) const; void setForceAlwaysFullSizedOutline(bool value) const; - bool hideSplashScreen(bool defaultValue = false) const; - void setHideSplashScreen(bool hideSplashScreen) const; - enum SessionOnStartup { SOS_BlankSession, SOS_PreviousSession, diff --git a/libs/ui/kis_config.cc b/libs/ui/kis_config.cc --- a/libs/ui/kis_config.cc +++ b/libs/ui/kis_config.cc @@ -987,18 +987,6 @@ m_cfg.writeEntry("forceAlwaysFullSizedOutline", value); } -bool KisConfig::hideSplashScreen(bool defaultValue) const -{ - KConfigGroup cfg( KSharedConfig::openConfig(), "SplashScreen"); - return (defaultValue ? true : cfg.readEntry("HideSplashAfterStartup", true)); -} - -void KisConfig::setHideSplashScreen(bool hideSplashScreen) const -{ - KConfigGroup cfg( KSharedConfig::openConfig(), "SplashScreen"); - cfg.writeEntry("HideSplashAfterStartup", hideSplashScreen); -} - KisConfig::SessionOnStartup KisConfig::sessionOnStartup(bool defaultValue) const { int value = defaultValue ? SOS_BlankSession : m_cfg.readEntry("sessionOnStartup", (int)SOS_BlankSession); diff --git a/libs/widgetutils/config/krecentfilesaction.h b/libs/widgetutils/config/krecentfilesaction.h --- a/libs/widgetutils/config/krecentfilesaction.h +++ b/libs/widgetutils/config/krecentfilesaction.h @@ -186,6 +186,7 @@ using KSelectAction::addAction; KRecentFilesActionPrivate *d_ptr; + QList d_urls; Q_PRIVATE_SLOT(d_func(), void _k_urlSelected(QAction *)) }; diff --git a/libs/widgetutils/config/krecentfilesaction.cpp b/libs/widgetutils/config/krecentfilesaction.cpp --- a/libs/widgetutils/config/krecentfilesaction.cpp +++ b/libs/widgetutils/config/krecentfilesaction.cpp @@ -234,7 +234,14 @@ QList KRecentFilesAction::urls() const { Q_D(const KRecentFilesAction); - return d->m_urls.values(); + + // switch order so last opened file is first + QList sortedList; + for (int i=(d_urls.length()-1); i >= 0; i--) { + sortedList.append(d_urls[i]); + } + + return sortedList; } void KRecentFilesAction::clear() @@ -253,6 +260,8 @@ d->clearSeparator->setVisible(false); d->clearAction->setVisible(false); setEnabled(false); + + d_urls.clear(); } void KRecentFilesAction::loadEntries(const KConfigGroup &_config) @@ -281,6 +290,7 @@ continue; } url = QUrl::fromUserInput(value); + d_urls.append(QUrl(url)); // will be used to retrieve on the welcome screen // Don't restore if file doesn't exist anymore if (url.isLocalFile() && !QFile::exists(url.toLocalFile())) {