Commit 2325bd70 authored by Scott Petrovic's avatar Scott Petrovic

Merge branch 'petrovic/welcome-screen'

parents 6c9272c4 49ee256f
......@@ -81,6 +81,7 @@ set(kritaui_LIB_SRCS
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 @@ set(kritaui_LIB_SRCS
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 @@ set(kritaui_LIB_SRCS
widgets/KoDualColorButton.cpp
widgets/KoStrokeConfigWidget.cpp
widgets/KoFillConfigWidget.cpp
utils/kis_document_aware_spin_box_unit_manager.cpp
......@@ -480,6 +484,8 @@ ki18n_wrap_ui(kritaui_LIB_SRCS
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
......
......@@ -124,28 +124,9 @@ public:
}
~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<QWidget*>(o);
if (w && w->isHidden()) {
w->setVisible(true);
}
}
m_splash->show();
m_splash->activateWindow();
}
if (m_splash) {
m_splash->hide();
}
}
......@@ -626,6 +607,7 @@ void KisApplication::hideSplashScreen()
}
}
bool KisApplication::notify(QObject *receiver, QEvent *event)
{
try {
......
......@@ -212,7 +212,7 @@ KisAutoSaveRecoveryDialog::KisAutoSaveRecoveryDialog(const QStringList &filename
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());
......
......@@ -58,6 +58,8 @@
#include <QMenuBar>
#include <KisMimeDatabase.h>
#include <QMimeData>
#include <QStackedWidget>
#include <kactioncollection.h>
#include <QAction>
......@@ -95,6 +97,7 @@
#include <KoToolManager.h>
#include <KoZoomController.h>
#include "KoToolDocker.h"
#include "KoToolBoxDocker_p.h"
#include <KoToolBoxFactory.h>
#include <KoDockRegistry.h>
#include <KoPluginLoader.h>
......@@ -142,6 +145,7 @@
#include <KisUpdateSchedulerConfigNotifier.h>
#include "KisWindowLayoutManager.h"
#include <KisUndoActionsUpdateManager.h>
#include "KisWelcomePageWidget.h"
#include <mutex>
......@@ -178,11 +182,16 @@ public:
, 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 @@ public:
Digikam::ThemeManager *themeManager {0};
KisWelcomePageWidget *welcomePage {0};
QStackedWidget *widgetStack {0};
QMdiArea *mdiArea;
QMdiSubWindow *activeSubWindow {0};
QSignalMapper *windowMapper;
......@@ -369,14 +383,17 @@ 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(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 @@ void KisMainWindow::saveRecentFiles()
}
}
QList<QUrl> 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 @@ void KisMainWindow::showDocument(KisDocument *document) {
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::setActiveView(KisView* view)
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::dragEnterEvent(QDragEnterEvent *event)
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::dragMoveEvent(QDragMoveEvent * event)
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 @@ void KisMainWindow::switchTab(int index)
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::windowFocused()
}
}
void KisMainWindow::updateWindowMenu()
{
QMenu *menu = d->windowMenu->menu();
......@@ -2216,6 +2246,28 @@ void KisMainWindow::updateWindowMenu()
}
}
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<QDockWidget*>(widget);
if ( dw->objectName() == "ToolBox") {
dw->setEnabled(showMdiArea);
}
}
}
updateCaption();
}
......@@ -2401,6 +2453,8 @@ void KisMainWindow::createActions()
{
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 @@ void KisMainWindow::createActions()
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);
......
......@@ -107,6 +107,17 @@ public:
*/
void addRecentURL(const QUrl &url);
/**
* get list of URL strings for recent files
*/
QList<QUrl> 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 @@ 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 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 @@ public Q_SLOTS:
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 @@ private Q_SLOTS:
*/
void slotReloadFile();
/**
* File --> Import
*
......@@ -370,9 +408,15 @@ private Q_SLOTS:
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 @@ protected:
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 @@ private:
*/
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 @@ private:
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 @@ private:
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()
*/
......
This diff is collapsed.
/* 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.
*/
#ifndef KISWELCOMEPAGEWIDGET_H
#define KISWELCOMEPAGEWIDGET_H
#include "kritaui_export.h"
#include "KisViewManager.h"
#include "KisMainWindow.h"
#include <QWidget>
#include "ui_KisWelcomePage.h"
#include <QStandardItemModel>
/// 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
......@@ -189,8 +189,6 @@ GeneralTab::GeneralTab(QWidget *_parent, const char *_name)
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 @@ void GeneralTab::setDefault()
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 @@ bool GeneralTab::showOutlineWhilePainting()
return m_showOutlinePainting->isChecked();
}
bool GeneralTab::hideSplashScreen()
{
return m_hideSplashScreen->isChecked();
}
int GeneralTab::mdiMode()
{
return m_cmbMDIType->currentIndex();
......@@ -1283,7 +1275,6 @@ bool KisDlgPreferences::editPreferences()
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());
......
......@@ -78,7 +78,6 @@ public:
void setDefault();
int undoStackSize();
bool showOutlineWhilePainting();
bool hideSplashScreen();
int mdiMode();
int favoritePresets();
......
This diff is collapsed.
......@@ -684,28 +684,6 @@
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="KisIntParseSpinBox" name="m_favoritePresetsSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>75</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>30</number>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QCheckBox" name="chkShowRootLayer">
<property name="text">
......@@ -714,13 +692,6 @@
</widget>
</item>
<item row="13" column="1">
<widget class="QCheckBox" name="m_hideSplashScreen">
<property name="text">
<string>Hide splash screen on startup</string>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QCheckBox" name="m_chkNativeFileDialog">
<property name="toolTip">
<string>Warning: if you enable this setting and the file dialogs do weird stuff, do not report a bug.</string>
......@@ -730,14 +701,14 @@
</property>
</widget>
</item>
<item row="16" column="0">
<item row="15" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Maximum brush size:</string>
</property>
</widget>
</item>
<item row="16" column="1">
<item row="15" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="intMaxBrushSize">
......@@ -773,7 +744,7 @@
</item>
</layout>
</item>
<item row="17" column="1">
<item row="16" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
......@@ -786,6 +757,28 @@
</property>
</spacer>
</item>
<item row="10" column="1">
<widget class="KisIntParseSpinBox" name="m_favoritePresetsSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>75</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>30</number>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
......
......@@ -987,18 +987,6 @@ void KisConfig::setForceAlwaysFullSizedOutline(bool value) const
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);
......
......@@ -260,9 +260,6 @@ public:
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,
......
......@@ -234,7 +234,14 @@ void KRecentFilesAction::removeUrl(const QUrl &url)
QList<QUrl> KRecentFilesAction::urls() const
{
Q_D(const KRecentFilesAction);
return d->m_urls.values();
// switch order so last opened file is first
QList<QUrl> 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 @@ void KRecentFilesAction::clearEntries()
d->clearSeparator->setVisible(false);
d->clearAction->setVisible(false);
setEnabled(false);
d_urls.clear();
}
void KRecentFilesAction::loadEntries(const KConfigGroup &_config)
......@@ -281,6 +290,7 @@ void KRecentFilesAction::loadEntries(const KConfigGroup &_config)
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())) {
......
......@@ -186,6 +186,7 @@ private:
using KSelectAction::addAction;
KRecentFilesActionPrivate *d_ptr;